diff --git a/arangod/Cluster/HeartbeatThread.cpp b/arangod/Cluster/HeartbeatThread.cpp index e7ddc3187e..e2ca69c995 100644 --- a/arangod/Cluster/HeartbeatThread.cpp +++ b/arangod/Cluster/HeartbeatThread.cpp @@ -615,6 +615,10 @@ bool HeartbeatThread::syncDBServerStatusQuo() { std::unique_ptr job(new ServerJob(this)); auto dispatcher = DispatcherFeature::DISPATCHER; + if (dispatcher == nullptr) { + LOG(ERR) << "could not schedule dbserver sync - dispatcher gone."; + return false; + } if (dispatcher->addJob(job) == TRI_ERROR_NO_ERROR) { LOG(TRACE) << "scheduled dbserver sync"; return true; diff --git a/arangod/RestHandler/RestJobHandler.cpp b/arangod/RestHandler/RestJobHandler.cpp index 5e36ff8b1c..4a9c633eff 100644 --- a/arangod/RestHandler/RestJobHandler.cpp +++ b/arangod/RestHandler/RestJobHandler.cpp @@ -122,6 +122,11 @@ void RestJobHandler::putJobMethod() { uint64_t jobId = StringUtils::uint64(value); if (method == "cancel") { + if (DispatcherFeature::DISPATCHER == nullptr) { + generateError(GeneralResponse::ResponseCode::SERVER_ERROR, + TRI_ERROR_HTTP_NOT_FOUND); + } + bool status = DispatcherFeature::DISPATCHER->cancelJob(jobId); // unknown or already fetched job diff --git a/arangod/V8Server/V8PeriodicTask.cpp b/arangod/V8Server/V8PeriodicTask.cpp index 6b5d11a1e0..cb94b9277e 100644 --- a/arangod/V8Server/V8PeriodicTask.cpp +++ b/arangod/V8Server/V8PeriodicTask.cpp @@ -82,6 +82,11 @@ bool V8PeriodicTask::handlePeriod() { _vocbase, "(function (params) { " + _command + " } )(params);", _parameters, _allowUseDatabase)); + if (DispatcherFeature::DISPATCHER == nullptr) { + LOG(WARN) << "could not add task " << _command << " to non existing queue"; + return false; + } + DispatcherFeature::DISPATCHER->addJob(job); return true; diff --git a/arangod/V8Server/V8TimerTask.cpp b/arangod/V8Server/V8TimerTask.cpp index 1f84987245..66ac6d59e2 100644 --- a/arangod/V8Server/V8TimerTask.cpp +++ b/arangod/V8Server/V8TimerTask.cpp @@ -83,6 +83,11 @@ bool V8TimerTask::handleTimeout() { new V8Job(_vocbase, "(function (params) { " + _command + " } )(params);", _parameters, _allowUseDatabase)); + if (DispatcherFeature::DISPATCHER == nullptr) { + LOG(WARN) << "could not add task " << _command << " to non existing queue"; + return false; + } + int res = DispatcherFeature::DISPATCHER->addJob(job); if (res != TRI_ERROR_NO_ERROR) { diff --git a/js/client/modules/@arangodb/testing.js b/js/client/modules/@arangodb/testing.js index f682555153..1ec86946f9 100644 --- a/js/client/modules/@arangodb/testing.js +++ b/js/client/modules/@arangodb/testing.js @@ -85,6 +85,8 @@ const optionsDocumentation = [ ' - `skipTimeCritical`: if set to true, time critical tests will be skipped.', ' - `skipNondeterministic`: if set, nondeterministic tests are skipped.', ' - `skipShebang`: if set, the shebang tests are skipped.', + ' - `testBuckets`: split tests in to buckets and execute on, for example', + ' 10/2 will split into 10 buckets and execute the third bucket.', '', ' - `onlyNightly`: execute only the nightly tests', ' - `loopEternal`: to loop one test over and over.', @@ -163,6 +165,7 @@ const optionsDefaults = { "skipSsl": false, "skipTimeCritical": false, "test": undefined, + "testBuckets": undefined, "username": "root", "valgrind": false, "valgrindFileBase": "", @@ -1813,6 +1816,44 @@ function filterTestcaseByOptions(testname, options, whichFilter) { return true; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief split into buckets +//////////////////////////////////////////////////////////////////////////////// + +function splitBuckets(options, cases) { + if (!options.testBuckets || cases.length === 0) { + return cases; + } + + let m = cases.length; + let n = options.testBuckets.split("/"); + let r = parseInt(n[0]); + let s = parseInt(n[1]); + + if (r < 1) { + r = 1; + } + + if (r === 1) { + return cases; + } + + if (s < 0) { + s = 0; + } + if (r <= s) { + s = r - 1; + } + + let result = []; + + for (let i = s % m; i < cases.length; i = i + r) { + result.push(cases[i]); + } + + return result; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief test functions for all //////////////////////////////////////////////////////////////////////////////// @@ -2364,11 +2405,11 @@ testFuncs.authentication_parameters = function(options) { //////////////////////////////////////////////////////////////////////////////// function locateBoostTest(name) { - var file = fs.join(UNITTESTS_DIR,name); + var file = fs.join(UNITTESTS_DIR, name); if (platform.substr(0, 3) === 'win') { file += ".exe"; } - + if (!fs.exists(file)) { return ""; } @@ -2385,11 +2426,11 @@ testFuncs.boost = function(options) { if (run !== "") { results.basics = executeAndWait(run, args, options, "basics"); - } - else { + } else { results.basics = { status: false, - message: "binary 'basics_suite' not found"}; + message: "binary 'basics_suite' not found" + }; } } @@ -2398,11 +2439,11 @@ testFuncs.boost = function(options) { if (run !== "") { results.geo_suite = executeAndWait(run, args, options, "geo_suite"); - } - else { + } else { results.geo_suite = { status: false, - message: "binary 'geo_suite' not found"}; + message: "binary 'geo_suite' not found" + }; } } @@ -3328,15 +3369,21 @@ testFuncs.shell_server = function(options) { testFuncs.shell_server_aql = function(options) { findTests(); + let cases; + let name; + if (!options.skipAql) { if (options.skipRanges) { - return performTests(options, testsCases.server_aql, - 'shell_server_aql_skipranges'); + cases = testsCases.server_aql; + name = 'shell_server_aql_skipranges'; } else { - return performTests(options, - testsCases.server_aql.concat(testsCases.server_aql_extended), - 'shell_server_aql'); + cases = testsCases.server_aql.concat(testsCases.server_aql_extended); + name = 'shell_server_aql'; } + + cases = splitBuckets(options, cases); + + return performTests(options, cases, name); } return {