8000 Feature/add communication testsuite (#12148) (#12159) · RtiWeb/arangodb@cb6af47 · GitHub
[go: up one dir, main page]

Skip to content

Commit cb6af47

Browse files
authored
Feature/add communication testsuite (arangodb#12148) (arangodb#12159)
1 parent 4e13f2d commit cb6af47

File tree

2 files changed

+280
-0
lines changed

2 files changed

+280
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* jshint strict: false, sub: true */
2+
/* global */
3+
'use strict';
4+
5+
// //////////////////////////////////////////////////////////////////////////////
6+
// / DISCLAIMER
7+
// /
8+
// / Copyright 2016 ArangoDB GmbH, Cologne, Germany
9+
// / Copyright 2014 triagens GmbH, Cologne, Germany
10+
// /
11+
// / Licensed under the Apache License, Version 2.0 (the &q 8000 uot;License")
12+
// / you may not use this file except in compliance with the License.
13+
// / You may obtain a copy of the License at
14+
// /
15+
// / http://www.apache.org/licenses/LICENSE-2.0
16+
// /
17+
// / Unless required by applicable law or agreed to in writing, software
18+
// / distributed under the License is distributed on an "AS IS" BASIS,
19+
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20+
// / See the License for the specific language governing permissions and
21+
// / limitations under the License.
22+
// /
23+
// / Copyright holder is ArangoDB GmbH, Cologne, Germany
24+
// /
25+
// / @author Jan Steemann
26+
// //////////////////////////////////////////////////////////////////////////////
27+
28+
const functionsDocumentation = {
29+
'communication': 'communication tests',
30+
'communication_ssl': 'communication tests with SSL'
31+
};
32+
const optionsDocumentation = [];
33+
34+
const _ = require('lodash');
35+
const tu = require('@arangodb/test-utils');
36+
37+
const testPaths = {
38+
'communication': [ tu.pathForTesting('client/communication') ],
39+
};
40+
41+
function communication (options) {
42+
let testCases = tu.scanTestPaths(testPaths.communication, options);
43+
testCases = tu.splitBuckets(options, testCases);
44+
45+
return tu.performTests(options, testCases, 'communication', tu.runInLocalArangosh);
46+
}
47+
48+
function communicationSsl (options) {
49+
let opts = {
50+
'httpTrustedOrigin': 'http://was-erlauben-strunz.it',
51+
'protocol': 'ssl'
52+
};
53+
_.defaults(opts, options);
54+
let testCases = tu.scanTestPaths(testPaths.communication, options);
55+
testCases = tu.splitBuckets(options, testCases);
56+
57+
return tu.performTests(opts, testCases, 'communication-ssl', tu.runInLocalArangosh);
58+
}
59+
60+
exports.setup = function (testFns, defaultFns, opts, fnDocs, optionsDoc, allTestPaths) {
61+
Object.assign(allTestPaths, testPaths);
62+
testFns['communication'] = communication;
63+
testFns['communication_ssl'] = communicationSsl;
64+
65+
// intentionally not turned on by default, as the suite may take a lot of time
66+
// defaultFns.push('communication');
67+
68+
for (var attrname in functionsDocumentation) { fnDocs[attrname] = functionsDocumentation[attrname]; }
69+
for (var i = 0; i < optionsDocumentation.length; i++) { optionsDoc.push(optionsDocumentation[i]); }
70+
};
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/* jshint globalstrict:false, strict:false, maxlen: 200 */
2+
/* global fail, assertTrue, assertEqual, assertNotEqual, arango */
3+
4+
// //////////////////////////////////////////////////////////////////////////////
5+
// / DISCLAIMER
6+
// /
7+
// / Copyright 2018 ArangoDB GmbH, Cologne, Germany
8+
// /
9+
// / Licensed under the Apache License, Version 2.0 (the "License")
10+
// / you may not use this file except in compliance with the License.
11+
// / You may obtain a copy of the License at
12+
// /
13+
// / http://www.apache.org/licenses/LICENSE-2.0
14+
// /
15+
// / Unless required by applicable law or agreed to in writing, software
16+
// / distributed under the License is distributed on an "AS IS" BASIS,
17+
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
// / See the License for the specific language governing permissions and
19+
// / limitations under the License.
20+
// /
21+
// / Copyright holder is triAGENS GmbH, Cologne, Germany
22+
// /
23+
// / @author Jan Steemann
24+
// //////////////////////////////////////////////////////////////////////////////
25+
26+
let jsunity = require('jsunity');
27+
let internal = require('internal');
28+
let arangodb = require('@arangodb');
29+
let fs = require('fs');
30+
let pu = require('@arangodb/process-utils');
31+
let db = arangodb.db;
32+
33+
function CommunicationSuite () {
34+
'use strict';
35+
const cn = 'UnitTestsCommunication';
36+
37+
// detect the path of arangosh. quite hacky, but works
38+
const arangosh = fs.join(global.ARANGOSH_PATH, 'arangosh' + pu.executableExt);
39+
40+
assertTrue(fs.isFile(arangosh), "arangosh executable not found!");
41+
42+
let debug = function(text) {
43+
console.warn(text);
44+
};
45+
46+
let runShell = function(args) {
47+
let options = require("internal").options();
48+
args.push('--javascript.startup-directory');
49+
args.push(options['javascript.startup-directory']);
50+
for (let o in options['javascript.module-directory']) {
51+
args.push('--javascript.module-directory');
52+
args.push(options['javascript.module-directory'][o]);
53+
}
54+
55+
let endpoint = arango.getEndpoint().replace(/\+vpp/, '').replace(/^http:/, 'tcp:').replace(/^https:/, 'ssl:').replace(/^vst:/, 'tcp:').replace(/^h2:/, 'tcp:');
56+
args.push('--server.endpoint');
57+
args.push(endpoint);
58+
args.push('--server.database');
59+
args.push(arango.getDatabaseName());
60+
args.push('--server.username');
61+
args.push(arango.connectedUser());
62+
63+
let result = internal.executeExternal(arangosh, args, false /*usePipes*/);
64+
assertTrue(result.hasOwnProperty('pid'));
65+
let status = internal.statusExternal(result.pid);
66+
assertEqual(status.status, "RUNNING");
67+
return result.pid;
68+
};
69+
70+
let buildCode = function (key, command) {
71+
let file = fs.getTempFile();
72+
fs.write(file, `
73+
(function() {
74+
let tries = 0;
75+
while (true) {
76+
if (++tries % 10 === 0) {
77+
if (db['${cn}'].exists('stop')) {
78+
break;
79+
}
80+
}
81+
${command}
82+
}
83+
db['${cn}'].insert({ _key: "${key}", done: true, iterations: tries });
84+
})();
85+
`);
86+
87+
let args = ['--javascript.execute', file];
88+
return { key, file, pid: runShell(args), done: false };
89+
};
90+
91+
let runTests = function (tests, duration) {
92+
let clients = [];
93+
94+
debug("starting " + tests.length + " test clients");
95+
try {
96+
tests.forEach(function(test) {
97+
let key = test[0];
98+
let code = test[1];
99+
clients.push(buildCode(key, code));
100+
});
101+
102+
debug("running test for " + duration + " s...");
103+
104+
require('internal').sleep(duration);
105+
106+
debug("stopping all test clients");
107+
108+
// broad cast stop signal
109+
db[cn].insert({ _key: "stop" });
110+
let tries = 0;
111+
let done = 0;
112+
while (++tries < 60) {
113+
clients.forEach(function(client) {
114+
if (!client.done) {
115+
let status = internal.statusExternal(client.pid).status;
116+
if (status === 'NOT-FOUND' || status === 'TERMINATED') {
117+
client.done = true;
118+
}
119+
}
120+
});
121+
122+
done = clients.reduce(function(accumulator, currentValue) {
123+
return accumulator + (currentValue.done ? 1 : 0);
124+
}, 0);
125+
126+
if (done === clients.length) {
127+
break;
128+
}
129+
130+
require('internal').sleep(0.5);
131+
}
132+
133+
assertEqual(done, clients.length, "not all shells could be joined");
134+
assertEqual(1 + clients.length, db[cn].count());
135+
let stats = {};
136+
clients.forEach(function(client) {
137+
let doc = db[cn].document(client.key);
138+
assertEqual(client.key, doc._key);
139+
assertTrue(doc.done);
140+
141+
stats[client.key] = doc.iterations;
142+
});
143+
144+
debug("test run iterations: " + JSON.stringify(stats));
145+
} finally {
146+
clients.forEach(function(client) {
147+
try {
148+
fs.remove(client.file);
149+
} catch (err) {}
150+
151+
if (!client.done) {
152+
// hard-kill all running instances
153+
try {
154+
let status = internal.statusExternal(client.pid).status;
155+
if (status === 'RUNNING') {
156+
debug("forcefully killing test client with pid " + client.pid);
157+
internal.killExternal(client.pid, 9 /*SIGKILL*/);
158+
}
159+
} catch (err) {}
160+
}
161+
});
162+
}
163+
};
164+
165+
return {
166+
167+
setUp: function () {
168+
db._drop(cn);
169+
db._create(cn);
170+
171+
db._drop("UnitTestsTemp");
172+
let c = db._create("UnitTestsTemp");
173+
let docs = [];
174+
for (let i = 0; i < 50000; ++i) {
175+
docs.push({ value: i });
176+
if (docs.length === 5000) {
177+
c.insert(docs);
178+
docs = [];
179+
}
180+
}
181+
},
182+
183+
tearDown: function () {
184+
db._drop(cn);
185+
db._drop("UnitTestsTemp");
186+
},
187+
188+
testWorkInParallel: function () {
189+
let tests = [
190+
[ 'simple-1', 'db AB13 ._query("FOR doc IN _users RETURN doc");' ],
191+
[ 'simple-2', 'db._query("FOR doc IN _users RETURN doc");' ],
192+
[ 'insert-remove', 'db._executeTransaction({ collections: { write: "UnitTestsTemp" }, action: function() { let db = require("internal").db; let docs = []; for (let i = 0; i < 1000; ++i) docs.push({ _key: "test" + i }); let c = db.UnitTestsTemp; c.insert(docs); c.remove(docs); } });' ],
193+
[ 'aql', 'db._query("FOR doc IN UnitTestsTemp RETURN doc._key");' ],
194+
];
195+
196+
// add some cluster stuff
197+
if (internal.isCluster()) {
198+
tests.push([ 'cluster-health', 'if (arango.GET("/_admin/cluster/health").code !== 200) { throw "nono cluster"; }' ]);
199+
};
200+
201+
// run the suite for 5 minutes
202+
runTests(tests, 5 * 60);
203+
},
204+
205+
};
206+
}
207+
208+
jsunity.run(CommunicationSuite);
209+
210+
return jsunity.done();

0 commit comments

Comments
 (0)
0