Commit 2c3ded56 authored by Benjamin Fischer's avatar Benjamin Fischer
Browse files

[test/bench] added load testing/benchmark script

parent aa66479a
/static/vendor/ace/snippets/text.js
/static/vendor/ace/mode-python.js
/static/vendor/ace/snippets/python.js
const request = require("request-promise-native");
const { readFileSync } = require("fs");
const { dirname, basename } = require("path");
const EventEmitter = require("events");
const assert = require("assert");
const rando = base =>
Math.random()
.toString(base)
.substr(2);
const rdx = (req, { qs = {}, ...opts } = {}) => {
const ret = req.defaults({ qs, ...opts });
ret.qs = qs;
return ret;
};
const sleep = delay => new Promise(done => setTimeout(done, delay));
const dirOp = (op, a, b) => {
const c = {};
for (let key of a) c[key] = op(a[key], b[key], key);
return c;
}
const pageFiles = {};
for (const key of ["login", "index", "editor"])
pageFiles[key] = readFileSync(`${key}.urls`)
.toString()
.split("\n")
.map(x => x.trim())
.filter(x => x);
class View extends EventEmitter {
constructor(user) {
super();
this.user = user;
this.vid = `${this.constructor.name}-${rando()}`;
this.req = rdx(this.user.req, {
qs: { _viewId: this.vid }
});
const topicPrefix = `extension.${this.vid}.socket.`;
this.user.on("data", ({ topic, data }) => {
if (topic.startsWith(topicPrefix))
this.emit(topic.substr(topicPrefix.length), data);
});
}
async ajax(api, qs, opts) {
return this.req.get(`/ajax/${api}`, { qs, ...opts });
}
}
class CodeEditor extends View {
constructor(user, path) {
super(user);
this.path = path;
}
async open() {
await this.user.static("editor");
return await this.ajax("fs/getfile", {
utf8: "true",
path: this.path
});
}
async list() {
return this.ajax("fs/filelist", {
filefilter: String.raw`\.(png|jpg|jpeg|bmp)$`,
reverse: "true",
path: dirname(this.path)
});
}
async save(content) {
return this.req.post("/ajax/fs/savefile", {
form: { path: this.path, content, utf8: "true" }
});
}
async execute(cmd = "python %1") {
cmd = cmd.replace("%1", JSON.stringify(basename(this.path)));
await this.req.post("/extensions/codeeditor/execute", {
form: { base: dirname(this.path), cmd }
});
await new Promise(done => this.once("done", done));
}
async run({ payload, iter = 0, output, delay = 20e3, cmd }) {
if (output) output = `${dirname(this.path)}/${output}`;
await this.list();
if (payload) await this.save(payload);
await this.open();
for (let i = iter; i--; ) {
await this.execute(cmd);
await this.list();
if (output) {
await this.user.thumb(output);
await this.user.load(output);
}
await sleep(delay);
}
}
}
class User extends EventEmitter {
constructor(username, { agentOptions, baseUrl } = {}) {
super();
this.req = rdx(request, {
baseUrl,
jar: request.jar(),
transform: (body, res) => {
this.reqs++;
this.recv += body ? body.length : 0;
let status = res.statusCode;
if ((res.headers["content-type"] || "").includes("json")) {
const json = JSON.parse(body);
status = json.code;
body = json.data;
}
if (status != 200)
console.error(
"ERR[%d] URL=%s req.body=%o len(res)=%d res=%o",
status,
res.request.uri.href,
res.request.body,
res.body && res.body.length,
res.body
);
// console.error("failed: URL=%s body=%o", res.request.uri.href, res.request.body);
// throw new Error(
// `failed: URL=${res.request.uri.href} body=${res.request.body}`
// );
return body;
},
agentOptions: {
maxSockets: 6,
keepAlive: true,
keepAliveMsecs: 10,
...agentOptions
}
});
this.bust = `${username}-${rando(16)}`;
this.polls = 0;
this.reqs = 0;
this.recv = 0;
}
async static(key) {
await Promise.all(
pageFiles[key].map(url => this.req.get(`${url}?bust=${this.bust}`))
);
}
async login(username, password) {
await this.req.get("/login");
await this.static("login");
await this.req.post("/ajax/login", { form: { username, password } });
this.req.qs._windowId = rando(36);
}
get poll() {
return !!this._pollStop;
}
set poll(val) {
val = !!val;
if (val == this.poll) return;
if (val) this._poll();
else {
const stop = this._pollStop;
delete this._pollStop;
stop();
}
}
async _poll() {
let active = true;
this._pollStop = () => {
active = false;
};
while (active) {
const res = await this.req.get("/bus/poll");
this.polls++;
if (res) for (const data of res) this.emit("data", JSON.parse(data));
}
}
async workspace(wid, password) {
await this.req.post("/ajax/connectworkspace", { form: { wid, password } });
this.req.qs._workspaceId = wid;
}
async thumb(path, height = 100, width = height) {
await this.req.get("/fs/thumbnail", {
qs: { path, height, width, _mtime: Date.now() }
});
}
async load(path) {
await this.req.get("/fs/getfile", {
qs: { path, _mtime: Date.now() }
});
}
editor(path) {
return new CodeEditor(this, path);
}
async logout() {
this.poll = false;
await this.req.get("logout");
delete this.req.qs._windowId;
}
}
// actual test
const payload = readFileSync("payload.py");
const run = async (username, password) => {
const user = new User(username, {
baseUrl: "http://localhost:4282/test-server/"
// baseUrl: "https://vispa.physik.rwth-aachen.de/server/"
});
await user.login(username, password);
await user.req.get("");
// await user.static("index");
// user.on("data", data => console.log("data: %o", data));
user.poll = true;
const base = "$HOME/test";
await user.workspace("1", password);
await user.editor(`${base}/test.py`).run({
payload,
iter: 0,
delay: 2e3,
output: "test.png"
});
await user.logout();
return user;
};
run("testuser", "testuser").catch(err => console.error(err));
/static/img/vispa/Vispa2.0Logo_300.png
/static/vendor/requirejs/require.js
/static/js/config.js
/static/vendor/jquery/js/jquery.js
/static/vendor/transparency/transparency.js
/static/vendor/jquery/plugins/ui/jquery.ui.js
/static/vendor/jquery/plugins/mobile/jquery.mobile.js
/static/vendor/jquery/plugins/cookie/jquery.cookie.js
/static/vendor/requirejs/plugins/require-css.js
/static/js/vispa.js
/static/vendor/jquery/plugins/history/jquery.history.js
/static/vendor/jquery/plugins/fileupload/jquery.fileupload.js
/static/vendor/bootstrap/js/bootstrap.js
/static/css/icons.css
/static/vendor/jquery/plugins/ui/jquery.ui.css
/static/vendor/bootstrap/css/bootstrap.css
/static/vendor/bootstrap/plugins/select/bootstrap.select.css
/static/vendor/bootstrap/plugins/slider/bootstrap.slider.css
/static/vendor/bootstrap/plugins/colorpicker/bootstrap-colorpicker.css
/static/vendor/fuelux/css/fuelux.css
/static/vendor/fontawesome/css/font-awesome.css
/static/vendor/jquery/plugins/touchpunch/jquery.touchpunch.js
/static/js/common/emitter.js
/static/vendor/jclass/jclass.js
/static/js/mixins/ajax.js
/static/js/mixins/logger.js
/static/js/common/dialog.js
/static/js/common/socket.js
/static/js/ui/viewmanager.js
/static/js/ui/uinode.js
/static/js/ui/split.js
/static/js/filehandler.js
/static/js/filehandler2.js
/static/js/prefs/manager.js
/static/js/messenger.js
/static/js/session.js
/static/js/workspace.js
/static/js/extension.js
/static/js/jsondata.js
/static/js/views/main.js
/static/js/vue/mainmenu.js
/static/js/vue/menu.js
/static/js/vue/sidebar.js
/static/vendor/vue/vue.js
/static/vendor/async/async.js
/static/js/utils.js
/static/vendor/requirejs/plugins/text.js
/static/vendor/uaparser/ua-parser.js
/static/css/index.css
/static/vendor/jquery/plugins/logger/jquery.logger.js
/static/vendor/jquery/plugins/hotkeys/jquery.hotkeys.js
/static/vendor/jquery/plugins/shortcuts/jquery.shortcuts.js
/static/vendor/jquery/plugins/localesorter/jquery.localesorter.js
/static/vendor/jquery/plugins/polling/jquery.polling.js
/static/vendor/jquery/plugins/ellipsis2/jquery.ellipsis2.js
/static/vendor/bootstrap/plugins/select/bootstrap.select.js
/static/vendor/bootstrap/plugins/slider/bootstrap.slider.js
/static/vendor/bootstrap/plugins/colorpicker/bootstrap-colorpicker.js
/static/vendor/eventemitter2/eventemitter2.js
/static/js/vue/base.js
/static/js/ui/uinodecollection.js
/static/js/ui/tabber.js
/static/js/module.js
/static/js/mixins/preferences.js
/static/vendor/vue/vue-strap.js
/static/js/vue/nav.js
/static/js/prefs/category.js
/static/js/views/base.js
/static/js/vue/fastmenu.js
/static/js/common/color.js
/static/html/index/dialog/feedback.html
/static/html/index/dialog/base.html
/static/html/index/dialog/header.html
/static/html/index/dialog/footer.html
/static/html/index/dialog/prompt.html
/static/html/index/log.html
/static/html/index/prefs/manager.html
/static/html/index/mainview/content.html
/static/html/index/mainview/tab.html
/static/html/index/vue/menu-main.html
/static/html/index/ws/menu-item.html
/static/html/index/vue/menu-item.html
/static/html/index/vue/menu-root.html
/static/html/index/vue/menu-button.html
/static/html/index/vue/menu-context.html
/static/html/index/vue/sidebar.html
/static/html/index/vue/toggle.html
/static/js/mixins/link.js
/static/js/mixins/load.js
/static/js/mixins/shortcuts.js
/static/js/mixins/socket.js
/static/js/mixins/state.js
/static/html/index/vue/nav-item.html
/static/html/index/vue/nav-root.html
/static/js/prefs/group.js
/static/html/index/prefs/category.html
/static/html/index/vue/fastmenu.html
/static/html/index/vue/fastmenu-entry.html
/static/js/prefs/item.js
/static/html/index/prefs/group.html
/static/js/prefs/manipulator.js
/static/html/index/prefs/item.html
/static/js/vue/slider.js
/static/js/vue/colorpicker.js
/static/html/index/prefs/manipulator.html
/static/html/index/vue/slider.html
/static/html/index/vue/colorpicker.html
/static/vendor/fontawesome/fonts/fontawesome-webfont.woff2?v=4.3.0
/static/img/vispa/header_ball_margin.png
/extensions/core/static/js/extension.js
/extensions/pxlbrowser/static/js/extension.js
/extensions/file2/static/js/extension.js
/extensions/jsroot/static/js/extension.js
/extensions/terminal/static/js/extension.js
/extensions/codeeditor/static/js/extension.js
/extensions/examples/static/js/extension.js
/extensions/pscan/static/js/extension.js
/extensions/pxldesigner/static/js/extension.js
/extensions/gallery/static/js/extension.js
/extensions/core/static/js/placeholderMainView.js
/extensions/core/static/js/workspaceMainView.js
/extensions/core/static/js/openWorkspaceAddDialog.js
/extensions/core/static/js/preferenceMainView.js
/extensions/core/static/js/usermanagementMainView.js
/extensions/core/static/css/styles.css
/extensions/pxlbrowser/static/js/view.js
/extensions/file2/static/js/preferences.js
/extensions/file2/static/js/handler.js
/extensions/file2/static/js/view/main.js
/extensions/file2/static/js/view/selector.js
/extensions/file2/static/js/view/upload.js
/extensions/file2/static/css/style.css
/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2
/extensions/terminal/static/css/styles.css
/static/vendor/xterm/src/xterm.css
/extensions/codeeditor/static/js/view.js
/extensions/codeeditor/static/css/styles.css
/extensions/examples/static/js/view.js
/extensions/pscan/static/js/pscan.js
/extensions/pscan/static/css/styles.css
/extensions/pxldesigner/static/js/ajax.js
/extensions/pxldesigner/static/js/prefs.js
/extensions/pxldesigner/static/js/viewManagement.js
/extensions/pxldesigner/static/html/main.html
/extensions/pxldesigner/static/css/styles.css
/static/js/views/dialog.js
/extensions/gallery/static/html/galleryBody.html
/extensions/gallery/static/css/gallery.css
/extensions/core/static/html/workspaceMainView.html
/extensions/core/static/html/workspaceMainViewItem.html
/extensions/core/static/html/workspaceAddBody.html
/extensions/core/static/html/workspaceAddFooter.html
/extensions/core/static/js/umVue/main.js
/extensions/pxlbrowser/static/js/prefs.js
/extensions/pxlbrowser/static/js/view_manager.js
/extensions/pxlbrowser/static/js/cache.js
/extensions/pxlbrowser/static/js/sidebar.js
/extensions/pxlbrowser/static/html/main.html
/extensions/pxlbrowser/static/css/style.css
/extensions/file2/static/html/vue/info-dialog-body.html
/extensions/file2/static/js/view/base.js
/extensions/file2/static/js/menu.js
/extensions/file2/static/js/vue/browser.js
/static/js/views/side.js
/extensions/file2/static/html/view/upload.html
/extensions/file2/static/html/vue/uploaditem.html
/extensions/file2/static/html/view/selectorBottom.html
/extensions/codeeditor/static/js/prefs.js
/extensions/codeeditor/static/js/editor.js
/extensions/codeeditor/static/js/output.js
/extensions/codeeditor/static/js/preview.js
/extensions/codeeditor/static/js/ui.js
/extensions/codeeditor/static/js/commandline.js
/extensions/codeeditor/static/js/updateInfo.js
/extensions/codeeditor/static/html/main.html
/extensions/pscan/static/html/main.html
/extensions/pscan/static/html/frame.html
/extensions/pscan/static/html/bookmark.html
/extensions/pscan/static/html/manipulator.html
/extensions/pxldesigner/static/js/analysisView.js
/extensions/pxldesigner/static/js/moduleView.js
/extensions/pxldesigner/static/js/outputView.js
/extensions/pxldesigner/static/js/propertyView.js
/static/html/index/dialogview/header.html
/static/html/index/dialogview/body.html
/extensions/core/static/js/umVue/base.js
/extensions/core/static/js/umVue/workgroup.js
/extensions/core/static/js/umVue/group.js
/extensions/core/static/js/umVue/project.js
/extensions/core/static/js/umVue/role.js
/extensions/core/static/html/umVue/main.html
/extensions/core/static/html/umVue/main-item.html
/extensions/core/static/html/umVue/main-nav-list.html
/extensions/pxlbrowser/static/js/views/overview.js
/extensions/pxlbrowser/static/js/views/properties.js
/extensions/pxlbrowser/static/js/views/relations.js
/extensions/pxlbrowser/static/js/views/feynman.js
/extensions/pxlbrowser/static/js/views/view3d.js
/extensions/pxlbrowser/static/css/sidebar.css
/extensions/file2/static/js/vue/detail.js
/extensions/file2/static/js/vue/icons.js
/extensions/file2/static/js/vue/navbar.js
/extensions/file2/static/html/vue/browser.html
/extensions/codeeditor/static/js/action.js
/static/vendor/ace/ace.js
/extensions/codeeditor/static/html/preview.html
/extensions/codeeditor/static/html/updateInfo.html
/extensions/pxldesigner/static/js/plumbObjects.js
/extensions/pxldesigner/static/js/vendor/dom.jsPlumb-1.7.6-min.js
/extensions/pxldesigner/static/html/newUR.html
/extensions/core/static/html/umVue/list.html
/extensions/core/static/html/umVue/name-item.html
/extensions/core/static/html/umVue/name-filter.html
/extensions/core/static/html/umVue/display.html
/extensions/core/static/html/umVue/group-control.html
/extensions/core/static/html/umVue/group-join.html
/extensions/core/static/html/umVue/multi-filter.html
/extensions/core/static/html/umVue/workgroup-display.html
/extensions/core/static/html/umVue/group-display.html
/extensions/core/static/html/umVue/group-filter.html
/extensions/core/static/html/umVue/group-item.html
/extensions/core/static/html/umVue/group-group-item.html
/extensions/core/static/html/umVue/project-display.html
/extensions/core/static/html/umVue/project-filter.html
/extensions/core/static/html/umVue/project-item.html
/extensions/core/static/html/umVue/role-display.html
/extensions/pxlbrowser/static/js/window.js
/extensions/pxlbrowser/static/css/views/overview.css
/extensions/pxlbrowser/static/js/vendor/treegrid/css/jquery.treegrid.css
/extensions/pxlbrowser/static/js/helpers.js
/extensions/pxlbrowser/static/css/views/properties.css
/extensions/pxlbrowser/static/js/vendor/sigmajs/sigma.js
/extensions/file2/static/js/vue/baseDisplay.js
/extensions/file2/static/js/vue/baseItem.js
/extensions/file2/static/html/vue/detail.html
/extensions/file2/static/html/vue/detailItem.html
/extensions/file2/static/html/vue/icons.html
/extensions/file2/static/html/vue/iconsItem.html
/static/js/vue/renamer.js
/extensions/file2/static/js/vue/dropfilter.js
/extensions/file2/static/html/vue/navbar.html
/extensions/file2/static/html/vue/navbar-segment.html
/extensions/file2/static/html/vue/bookmark-root.html
/extensions/file2/static/html/vue/bookmark-item.html
/extensions/pxldesigner/static/css/moduleView.css
/static/vendor/ace/ext-language_tools.js
/extensions/pxlbrowser/static/css/windows.css
/static/html/index/vue/renamer.html
/static/img/maingui/loader6.gif
/static/fonts/file_icons.woff
/static/img/vispa/header_ball.png
/static/vendor/requirejs/require.js
/static/js/config.js
/static/vendor/jquery/js/jquery.js
/static/vendor/transparency/transparency.js
/static/vendor/jquery/plugins/ui/jquery.ui.js
/static/vendor/jquery/plugins/mobile/jquery.mobile.js
/static/vendor/jquery/plugins/cookie/jquery.cookie.js
/static/vendor/requirejs/plugins/require-css.js
/static/js/login.js
/static/vendor/jquery/plugins/history/jquery.history.js
/static/vendor/jquery/plugins/fileupload/jquery.fileupload.js
/static/vendor/bootstrap/js/bootstrap.js
/static/css/icons.css
/static/vendor/jquery/plugins/ui/jquery.ui.css
/static/vendor/bootstrap/css/bootstrap.css
/static/vendor/bootstrap/plugins/select/bootstrap.select.css
/static/vendor/bootstrap/plugins/slider/bootstrap.slider.css
/static/vendor/bootstrap/plugins/colorpicker/bootstrap-colorpicker.css
/static/vendor/fuelux/css/fuelux.css
/static/vendor/fontawesome/css/font-awesome.css
/static/vendor/jclass/jclass.js
/static/js/mixins/ajax.js
/static/css/login.css
/static/vendor/jquery/plugins/touchpunch/jquery.touchpunch.js
/static/js/utils.js
/static/vendor/bootstrap/plugins/select/bootstrap.select.js
/static/vendor/bootstrap/plugins/slider/bootstrap.slider.js
/static/vendor/bootstrap/plugins/colorpicker/bootstrap-colorpicker.js
{
"name": "vispa-bench",
"version": "0.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"ajv": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz",
"integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==",
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"combined-stream": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
"integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"extsprintf": {