10000 Build out load_test tool · keithrob/plotly.js@b532f2f · GitHub
[go: up one dir, main page]

Skip to content

Commit b532f2f

Browse files
author
Jody McIntyre
committed
Build out load_test tool
1 parent 6fa0ad0 commit b532f2f

File tree

2 files changed

+89
-53
lines changed

2 files changed

+89
-53
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
"gl-surface3d": "^1.3.1",
8686
"has-hover": "^1.0.1",
8787
"kdgrass": "^1.0.1",
88+
"knuth-shuffle": "^1.0.8",
8889
"mapbox-gl": "^0.22.0",
8990
"matrix-camera-controller": "^2.1.3",
9091
"minify-stream": "^1.1.0",

test/image/load_test

Lines changed: 88 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,119 @@
11
#!/usr/bin/env node
22

33
var fs = require('fs');
4-
5-
var getMockList = require('./assets/get_mock_list');
6-
var getRequestOpts = require('./assets/get_image_request_options');
7-
var getImagePaths = require('./assets/get_image_paths');
8-
9-
// packages inside the image server docker
4+
var glob = require('glob');
5+
var shuffle = require('knuth-shuffle').knuthShuffle;
106
var request = require('request');
117

12-
// wait time between each baseline generation
13-
var QUEUE_WAIT = 10;
8+
const BATCH_SIZE = 5;
9+
const BATCH_WAIT = 500;
10+
const REQ_TIMEOUT = 40000;
1411

1512
/**
16-
* Baseline image generation script.
17-
*
18-
* Called by `tasks/baseline.sh in `npm run baseline`.
19-
*
20-
* CLI arguments:
13+
* Load Tester for imageservers
2114
*
22-
* 1. 'pattern' : glob determining the baseline(s) to be generated
15+
* Usage:
2316
*
24-
* Examples:
17+
* load_test ENDPOINT_URL REQUEST_DIR
2518
*
26-
* Generate or (re-generate) all baselines (in queue):
19+
* ENDPOINT_URL is the URL to the image generation endpoint.
2720
*
28-
* npm run baseline
21+
* REQUEST_DIR is a directory containing sorted requests:
22+
* REQUEST_DIR/success/* - requests expected to succeed
23+
* REQUEST_DIR/failure/* - requests expected to fail
2924
*
30-
* Generate or (re-generate) the 'contour_nolines' baseline:
31-
*
32-
* npm run baseline -- contour_nolines
33-
*
34-
* Generate or (re-generate) all gl3d baseline (in queue):
35-
*
36-
* npm run baseline -- gl3d_*
25+
*/
26+
var endpointUrl = process.argv[2];
27+
var requestDir = process.argv[3];
28+
29+
var failReqs = getRequests(requestDir + '/failure/*', {'success': false});
30+
var successReqs = getRequests(requestDir + '/success/*', {'success': true});
31+
var allReqs = failReqs.concat(successReqs);
32+
33+
/**
34+
* Return object containing paths to all requests matching the glob.
3735
*
36+
* @param {string} requestGlob
37+
* @param {Object} extraObj - data in this object will be appended to each match
3838
*/
39-
var pattern = process.argv[2];
40-
var mockList = getMockList(pattern);
39+
function getRequests(requestGlob, extraObj) {
40+
var matches = glob.sync(requestGlob);
4141

42-
if(mockList.length === 0) {
43-
throw new Error('No mocks found with pattern ' + pattern);
42+
return matches.map(function(match) {
43+
return Object.assign({"filename": match}, extraObj);
44+
});
4445
}
4546

46-
// main
47+
if(allReqs.length === 0) {
48+
throw new Error('No requests found in ' + requestDir);
49+
}
50+
51+
allReqs = shuffle(allReqs);
52+
4753
console.log('test run starting');
48-
runInQueue(mockList);
54+
runInBatch(allReqs);
4955

50-
function runInQueue(mockList) {
51-
var index = 0;
56+
function runInBatch(reqs) {
57+
var running = 0;
5258

53-
run(mockList[index]);
59+
for(var i = 0; i < reqs.length; i++) {
60+
queueReq(reqs[i]);
61+
}
5462

55-
function run(mockName) {
56-
makeBaseline(mockName, function() {
57-
console.log('generated ' + mockName + ' successfully');
63+
function queueReq(req) {
64+
if(running >= BATCH_SIZE) {
65+
setTimeout(function() {
66+
queueReq(req);
67+
}, BATCH_WAIT);
68+
return;
69+
}
70+
running++;
71+
72+
// throttle the number of tests running concurrently
5873

59-
index++;
60-
if(index < mockList.length) {
61-
setTimeout(function() {
62-
run(mockList[index]);
63-
}, QUEUE_WAIT);
64-
}
74+
runReq(req, function() {
75+
running--;
6576
});
6677
}
6778
}
6879

69-
function makeBaseline(mockName, cb) {
70-
var requestOpts = getRequestOpts({ mockName: mockName }),
71-
imagePaths = getImagePaths(mockName),
72-
saveImageStream = fs.createWriteStream(imagePaths.baseline);
80+
/**
81+
* Run a test based on the request, then call the completion function
82+
*
83+
* @param {Object} req - the request
84+
* @param {function} completion - function to run on completion, no args
85+
*/
86+
function runReq(req, completion) {
87+
function onResponse(response) {
88+
if(req.success && +response.statusCode !== 200) {
89+
console.log('Unexpected error response on ' + req.filename);
90+
}
91+
92+
return completion();
93+
}
7394

74-
function checkFormat(err, res) {
75-
if(err) throw err;
76-
if(res.headers['content-type'] !== 'image/png') {
77-
throw new Error('Generated image is not a valid png');
95+
function onError(err) {
96+
if(req.success) {
97+
console.log('Unexpected request failure on ' + req.filename + ': ' + err);
98+
} else {
99+
console.log('Expected failure on ' + req.filename);
78100
}
101+
102+
return completion();
103+
}
104+
105+
try {
106+
var body = require(req.filename);
107+
}
108+
catch(SyntaxError) {
109+
if(req.success) {
110+
console.log('Unexpected parse failure on ' + req.filename);
111+
}
112+
113+
return completion();
79114
}
80115

81-
request(requestOpts, checkFormat)
82-
.pipe(saveImageStream)
83-
.on('close', cb);
116+
request.post({uri: endpointUrl, body: body, json: true, timeout: REQ_TIMEOUT})
117+
.on('error', onError)
118+
.on('response', onResponse);
84119
}

0 commit comments

Comments
 (0)
0