8000 [PREGEL] Make pregel js tests more stable (#18025) · olegrok/arangodb@9c49b71 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9c49b71

Browse files
authored
[PREGEL] Make pregel js tests more stable (arangodb#18025)
* Use a function everywhere to wait for pregel to finish successfully * Improved readability of random garbage collection test * Extract unique pregel results function * Make jslint happy * More jslint * Fix garbage collection test * Reformatting * More reformatting to make jenkins run
1 parent 692d69e commit 9c49b71

10 files changed

+399
-570
lines changed

js/common/modules/@arangodb/graph/pregel-test-effective-closeness-helpers.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
// //////////////////////////////////////////////////////////////////////////////
2626

2727
let db = require("@arangodb").db;
28+
let pregel = require("@arangodb/pregel");
29+
2830
const isEnterprise = require('internal').isEnterprise();
2931
let smart_graph_module;
3032
if (isEnterprise) {
@@ -45,7 +47,7 @@ const {
4547
} = require("@arangodb/graph/graphs-generation");
4648

4749
const {
48-
runPregelInstance,
50+
waitUntilRunFinishedSuccessfully,
4951
assertAlmostEquals,
5052
epsilon,
5153
makeSetUp,
@@ -74,14 +76,15 @@ const computeCloseness = function (graph) {
7476
const testEffectiveClosenessOnGraph = function (vertices, edges) {
7577
db[vColl].save(vertices);
7678
db[eColl].save(edges);
77-
const query = `
78-
FOR v in ${vColl}
79-
RETURN {"_key": v._key, "closeness": v.closeness, "v": v}
80-
`;
8179

8280
let parameters = {resultField: "closeness"};
8381
let algName = "effectivecloseness";
84-
const result = runPregelInstance(algName, graphName, parameters, query);
82+
const pid = pregel.start("effectivecloseness", graphName, parameters);
83+
waitUntilRunFinishedSuccessfully(pid);
84+
const result = db._query(`
85+
FOR v in ${vColl}
86+
RETURN {"_key": v._key, "closeness": v.closeness, "v": v}
87+
`).toArray();;
8588

8689
let graph = new Graph(vertices, edges);
8790
computeCloseness(graph); // write result into the closenessFromTestAlgorithm field
@@ -150,4 +153,4 @@ function makeEffectiveClosenessTestSuite(isSmart, smartAttribute, numberOfShards
150153
// (the ad-hoc test computeCloseness gives for the same vertex which is a leaf of the path 70.5).
151154
// For shorter paths, the error reaches 16%.
152155

153-
// exports.makeEffectiveClosenessTestSuite = makeEffectiveClosenessTestSuite;
156+
// exports.makeEffectiveClosenessTestSuite = makeEffectiveClosenessTestSuite;

js/common/modules/@arangodb/graph/pregel-test-helpers.js

Lines changed: 90 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,41 @@ const Graph = graphGeneration.Graph;
5151

5252
const epsilon = 0.00001;
5353

54+
const runFinishedSuccessfully = (stats) => stats.state === "done";
55+
const runFinishedUnsuccessfully = (stats) => stats.state === "canceled" || stats.state === "fatal error";
56+
const runFinished = (stats) => runFinishedSuccessfully(stats) || runFinishedUnsuccessfully(stats);
57+
const runCanceled = (stats) => stats.state === "canceled";
58+
59+
const waitUntilRunFinishedSuccessfully = function (pid, maxWaitSeconds = 120, sleepIntervalSeconds = 0.2) {
60+
let wakeupsLeft = maxWaitSeconds / sleepIntervalSeconds;
61+
var status;
62+
do {
63+
internal.sleep(0.2);
64+
status = pregel.status(pid);
65+
if (wakeupsLeft-- === 0) {
66+
assertTrue(false, "timeout in pregel execution");
67+
return;
68+
}
69+
} while (!runFinished(status));
70+
71+
if (runFinishedUnsuccessfully(status)) {
72+
assertTrue(false, "Pregel run finished unsuccessfully in state " + status.state);
73+
return;
74+
}
75+
76+
return status;
77+
};
78+
79+
const uniquePregelResults = function(documentCursor) {
80+
let myset = new Set();
81+
while (documentCursor.hasNext()) {
82+
const doc = documentCursor.next();
83+
assertTrue(doc.result !== undefined, "Found no pregel result in document " + doc);
84+
myset.add(doc.result);
85+
}
86+
return myset;
87+
};
88+
5489
/**
5590
* Assert that expected and actual are of the same type and that they are equal up to the tolerance epsilon.
5691
* @param expected the expected value, a number
@@ -77,34 +112,21 @@ const assertAlmostEquals = function (expected, actual, epsilon, msg, expectedDes
77112
}
78113
};
79114

80-
const runPregelInstance = function (algName, graphName, parameters, query, maxWaitTimeSecs = 120) {
81-
const pid = pregel.start(algName, graphName, parameters);
82-
const sleepIntervalSecs = 0.2;
83-
let wakeupsLeft = maxWaitTimeSecs / sleepIntervalSecs;
84-
while (pregel.status(pid).state !== "done" && wakeupsLeft > 0) {
85-
wakeupsLeft--;
86-
internal.sleep(0.2);
87-
}
88-
const statusState = pregel.status(pid).state;
89-
assertEqual(statusState, "done", `Pregel Job did never succeed. Status: ${statusState}`);
90-
return db._query(query).toArray();
91-
};
92-
93115
const dampingFactor = 0.85;
94116

95-
96117
const testPageRankOnGraph = function (vertices, edges, seeded = false) {
97118
db[vColl].save(vertices);
98119
db[eColl].save(edges);
99-
const query = `
100-
FOR v in ${vColl}
101-
RETURN {"_key": v._key, "value": v.pagerank}
102-
`;
103120
let parameters = {maxGSS: 100, resultField: "pagerank"};
104121
if (seeded) {
105122
parameters.sourceField = "input";
106123
}
107-
const result = runPregelInstance("pagerank", graphName, parameters, query);
124+
const pid = pregel.start("pagerank", graphName, parameters);
125+
waitUntilRunFinishedSuccessfully(pid);
126+
const result = db._query(`
127+
FOR v in ${vColl}
128+
RETURN {"_key": v._key, "value": v.pagerank}
129+
`).toArray();
108130

109131
const graph = new Graph(vertices, edges);
110132
for (const v of result) {
@@ -130,15 +152,15 @@ const testPageRankOnGraph = function (vertices, edges, seeded = false) {
130152
const testHITSKleinbergOnGraph = function (vertices, edges) {
131153
db[vColl].save(vertices);
132154
db[eColl].save(edges);
133-
const query = `
134-
FOR v in ${vColl}
135-
RETURN {"_key": v._key, "value": {hits_hub: v.hits_hub, hits_auth: v.hits_auth}}
136-
`;
137155
const numberIterations = 50;
138156

139157
let parameters = {resultField: "hits", maxNumIterations: numberIterations};
140-
let algName = "hitskleinberg";
141-
const result = runPregelInstance(algName, graphName, parameters, query);
158+
const pid = pregel.start("hitskleinberg", graphName, parameters);
159+
waitUntilRunFinishedSuccessfully(pid);
160+
const result = db._query(`
161+
FOR v in ${vColl}
162+
RETURN {"_key": v._key, "value": {hits_hub: v.hits_hub, hits_auth: v.hits_auth}}
163+
`).toArray();
142164

143165
const hits = new HITS();
144166
const graph = new Graph(vertices, edges);
@@ -177,16 +199,16 @@ const testHITSKleinbergOnGraph = function (vertices, edges) {
177199
const testHITSKleinbergThresholdOnGraph = function (vertices, edges) {
178200
db[vColl].save(vertices);
179201
db[eColl].save(edges);
180-
const query = `
181-
FOR v in ${vColl}
182-
RETURN {"_key": v._key, "value": {hits_hub: v.hits_hub, hits_auth: v.hits_auth}}
183-
`;
184202
const numberIterations = 50;
185203
const threshold = 200.0; // must be less than 1000.0, the value added in HITSKleinberg in reportFakeDifference()
186204

187205
let parameters = {resultField: "hits", maxNumIterations: numberIterations, threshold: threshold};
188-
let algName = "hitskleinberg";
189-
const result = runPregelInstance(algName, graphName, parameters, query);
206+
const pid = pregel.start("hitskleinberg", graphName, parameters);
207+
waitUntilRunFinishedSuccessfully(pid);
208+
const result = db._query(`
209+
FOR v in ${vColl}
210+
RETURN {"_key": v._key, "value": {hits_hub: v.hits_hub, hits_auth: v.hits_auth}}
211+
`).toArray();
190212

191213
const hits = new HITS();
192214
const graph = new Graph(vertices, edges);
@@ -230,13 +252,14 @@ const pregelRunSmallInstanceGetComponents = function (algName, graphName, parame
230252
assertTrue(parameters.hasOwnProperty("resultField"),
231253
`Malformed test: the parameter "parameters" of pregelRunSmallInstanceGetComponents
232254
must have an attribute "resultField"`);
233-
const query = `
255+
const pid = pregel.start(algName, graphName, parameters);
256+
waitUntilRunFinishedSuccessfully(pid);
257+
return db._query(`
234258
FOR v IN ${vColl}
235259
COLLECT ${parameters.resultField} = v.result WITH COUNT INTO size
236260
SORT size DESC
237261
RETURN {${parameters.resultField}, size}
238-
`;
239-
return runPregelInstance(algName, graphName, parameters, query);
262+
`).toArray();
240263
};
241264

242265
const makeSetUp = function (smart, smartAttribute, numberOfShards) {
@@ -294,11 +317,12 @@ const testSubgraphs = function (algName, graphName, parameters, expectedSizes) {
294317
});
295318
if (parameters.hasOwnProperty("test") && parameters.test) {
296319
delete parameters.test;
297-
const query = `
298-
FOR v in ${vColl}
299-
RETURN {"vertex": v._key, "result": v.result}
300-
`;
301-
runPregelInstance(algName, graphName, parameters, query);
320+
const pid = pregel.start(algName, graphName, parameters);
321+
waitUntilRunFinishedSuccessfully(pid);
322+
db._query(`
323+
FOR v in ${vColl}
324+
RETURN {"vertex": v._key, "result": v.result}
325+
`).toArray();
302326
return;
303327
}
304328
const computedComponents = pregelRunSmallInstanceGetComponents(algName, graphName, parameters);
@@ -1035,12 +1059,14 @@ function makeLabelPropagationTestSuite(isSmart, smartAttribute, numberOfShards)
10351059
const {vertices, edges} = graphGenerator(verticesEdgesGenerator(vColl, "v")).makeDirectedCycle(length);
10361060
db[vColl].save(vertices);
10371061
db[eColl].save(edges);
1038-
const query = `
1062+
1063+
const pid = pregel.start("labelpropagation", graphName, {maxGSS: 100, resultField: "community"});
1064+
waitUntilRunFinishedSuccessfully(pid);
1065+
const result = db._query(`
10391066
FOR v in ${vColl}
10401067
RETURN {"_key": v._key, "community": v.community}
1041-
`;
1042-
const result = runPregelInstance("labelpropagation", graphName,
1043-
{maxGSS: 100, resultField: "community"}, query);
1068+
`).toArray();
1069+
10441070
assertEqual(result.length, length);
10451071
for (const value of result) {
10461072
assertEqual(value.community, result[0].community);
@@ -1056,14 +1082,15 @@ function makeLabelPropagationTestSuite(isSmart, smartAttribute, numberOfShards)
10561082
db[vColl].save(verticesEdges.vertices);
10571083
db[eColl].save(verticesEdges.edges);
10581084

1059-
const query = `
1085+
const pid = pregel.start("labelpropagation", graphName, {maxGSS: 100, resultField: "community"});
1086+
waitUntilRunFinishedSuccessfully(pid);
1087+
const result = db._query(`
10601088
FOR v in ${vColl}
10611089
COLLECT community = v.community WITH COUNT INTO size
10621090
SORT size DESC
10631091
RETURN {community, size}
1064-
`;
1065-
const result = runPregelInstance("labelpropagation", graphName,
1066-
{maxGSS: 100, resultField: "community"}, query);
1092+
`).toArray();
1093+
10671094
assertEqual(result.length, 2);
10681095
assertEqual(result[0].size, length);
10691096
assertEqual(result[1].size, length);
@@ -1080,19 +1107,20 @@ function makeLabelPropagationTestSuite(isSmart, smartAttribute, numberOfShards)
10801107

10811108
db[eColl].save(makeEdgeBetweenVertices(vColl, 0, "v0", 0, "v1"));
10821109

1083-
const query = `
1110+
const pid = pregel.start("labelpropagation", graphName, {maxGSS: 100, resultField: "community"});
1111+
waitUntilRunFinishedSuccessfully(pid);
1112+
const result = db._query(`
10841113
FOR v in ${vColl}
10851114
COLLECT community = v.community WITH COUNT INTO size
10861115
SORT size DESC
10871116
RETURN {community, size}
1088-
`;
1117+
`).toArray();
1118+
10891119
// expected (depending on the "random" distribution of initial ids) that
10901120
// - all vertices are in one community:
10911121
// if the least initial value of vertices in the component with label v0,
10921122
// is less than the least initial value of vertices in the component with label v1,
10931123
// - or two communities otherwise.
1094-
const result = runPregelInstance("labelpropagation", graphName,
1095-
{maxGSS: 100, resultField: "community"}, query);
10961124
assertTrue(result.length === 1 || result.length === 2, `Expected 1 or 2, obtained ${result}`);
10971125
if (result.length === 1) {
10981126
assertEqual(result[0].size, 2 * size);
@@ -1480,12 +1508,14 @@ function makeSSSPTestSuite(isSmart, smartAttribute, numberOfShards) {
14801508

14811509
db[vColl].save(vertices);
14821510
db[eColl].save(edges);
1483-
const query = `
1511+
let parameters = {source: `${vColl}/${source}`, resultField: "distance"};
1512+
const pid = pregel.start("sssp", graphName, parameters);
1513+
waitUntilRunFinishedSuccessfully(pid);
1514+
const result = 10000 db._query(`
14841515
FOR v in ${vColl}
14851516
RETURN {"_key": v._key, "result": v.distance}
1486-
`;
1487-
let parameters = {source: `${vColl}/${source}`, resultField: "distance"};
1488-
const result = runPregelInstance("sssp", graphName, parameters, query);
1517+
`).toArray();
1518+
14891519
const graph = new Graph(vertices, edges);
14901520
// assign to each vertex.value infinity
14911521
// (This is what Pregel, in fact, returns if a vertex is not reachable.
@@ -1712,8 +1742,12 @@ exports.makePagerankTestSuite = makePagerankTestSuite;
17121742
exports.makeSeededPagerankTestSuite = makeSeededPagerankTestSuite;
17131743
exports.makeSSSPTestSuite = makeSSSPTestSuite;
17141744
exports.makeHITSTestSuite = makeHITSTestSuite;
1715-
exports.runPregelInstance = runPregelInstance;
17161745
exports.epsilon = epsilon;
17171746
exports.makeSetUp = makeSetUp;
17181747
exports.makeTearDown = makeTearDown;
17191748
exports.assertAlmostEquals = assertAlmostEquals;
1749+
exports.runFinished = runFinished;
1750+
exports.runCanceled = runCanceled;
1751+
exports.runFinishedSuccessfully = runFinishedSuccessfully;
1752+
exports.waitUntilRunFinishedSuccessfully = waitUntilRunFinishedSuccessfully;
1753+
exports.uniquePregelResults = uniquePregelResults;

js/common/modules/@arangodb/graph/pregel-test-read-write-helpers.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
// //////////////////////////////////////////////////////////////////////////////
2525

2626
let db = require("@arangodb").db;
27+
let pregel = require("@arangodb/pregel");
28+
2729
const isEnterprise = require('internal').isEnterprise();
2830
let smart_graph_module;
2931
if (isEnterprise) {
@@ -43,7 +45,7 @@ const {
4345
} = require("@arangodb/graph/graphs-generation");
4446

4547
const {
46-
runPregelInstance,
48+
waitUntilRunFinishedSuccessfully,
4749
assertAlmostEquals,
4850
epsilon,
4951
makeSetUp,
@@ -53,14 +55,14 @@ const {
5355
const testReadWriteOnGraph = function (vertices, edges) {
5456
db[vColl].save(vertices);
5557
db[eColl].save(edges);
56-
const query = `
57-
FOR v in ${vColl}
58-
RETURN {"_key": v._key, "input": v.input, "output": v.output}
59-
`;
6058

6159
let parameters = {sourceField: "input", resultField: "output"};
62-
let algName = "readwrite";
63-
const result = runPregelInstance(algName, graphName, parameters, query);
60+
const pid = pregel.start("readwrite", graphName, parameters);
61+
waitUntilRunFinishedSuccessfully(pid);
62+
const result = db._query(`
63+
FOR v in ${vColl}
64+
RETURN {"_key": v._key, "input": v.input, "output": v.output}
65+
`).toArray();
6466

6567
for (const resultV of result) {
6668
const vKey = resultV._key;
@@ -127,4 +129,4 @@ function makeReadWriteTestSuite(isSmart, smartAttribute, numberOfShards) {
127129
};
128130
}
129131

130-
exports.makeReadWriteTestSuite = makeReadWriteTestSuite;
132+
exports.makeReadWriteTestSuite = makeReadWriteTestSuite;

tests/js/client/load-balancing/load-balancing-pregel-auth-cluster.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const url = require('url');
3535
const userModule = require("@arangodb/users");
3636
const _ = require("lodash");
3737
const getCoordinatorEndpoints = require('@arangodb/test-helper').getCoordinatorEndpoints;
38+
let pregelTestHelpers = require("@arangodb/graph/pregel-test-helpers");
3839

3940
const servers = getCoordinatorEndpoints();
4041

tests/js/client/load-balancing/load-balancing-pregel-noauth-cluster.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ function PregelSuite () {
138138

139139
assertFalse(result === undefined || result === {});
140140
assertEqual(result.status, 200);
141-
assertTrue(result.body.state === 'loading' || result.body.state === 'running' || result.body.state === 'done');
142141
});
143142

144143
require('internal').wait(5.0, false);
@@ -176,7 +175,6 @@ function PregelSuite () {
176175

177176
assertFalse(result === undefined || result === {});
178177
assertEqual(result.status, 200);
179-
assertTrue(result.body.state === "loading" || result.body.state === "running");
180178

181179
require('internal').wait(5.0, false);
182180

@@ -210,7 +208,6 @@ function PregelSuite () {
210208

211209
assertFalse(result === undefined || result === {});
212210
assertEqual(result.status, 200);
213-
assertTrue(result.body.state === "loading" || result.body.state === "running");
214211

215212
require('internal').wait(5.0, false);
216213

0 commit comments

Comments
 (0)
0