8000 [devel] - Add rocksdb.exclusive-write tests (#10738) · nginxpre/arangodb@a8618a3 · GitHub
[go: up one dir, main page]

Skip to content

Commit a8618a3

Browse files
hkernbachKVS85
authored andcommitted
[devel] - Add rocksdb.exclusive-write tests (arangodb#10738)
* :) * fixed new tests * forgotten fail * renamed file * jslint * fixed test
1 parent 5568a32 commit a8618a3

File tree

4 files changed

+438
-0
lines changed

4 files changed

+438
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*jshint globalstrict:false, strict:false */
2+
/*global assertEqual, assertNotEqual, assertTrue, getOptions, fail, assertFalse */
3+
4+
////////////////////////////////////////////////////////////////////////////////
5+
/// @brief test the deadlock detection
6+
///
7+
/// @file
8+
///
9+
/// DISCLAIMER
10+
///
11+
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
12+
///
13+
/// Licensed under the Apache License, Version 2.0 (the "License");
14+
/// you may not use this file except in compliance with the License.
15+
/// You may obtain a copy of the License at
16+
///
17+
/// http://www.apache.org/licenses/LICENSE-2.0
18+
///
19+
/// Unless required by applicable law or agreed to in writing, software
20+
/// distributed under the License is distributed on an "AS IS" BASIS,
21+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
/// See the License for the specific language governing permissions and
23+
/// limitations under the License.
24+
///
25+
/// Copyright holder is triAGENS GmbH, Cologne, Germany
26+
///
27+
/// @author Jan Christoph Uhde
28+
/// @author Copyright 2019, triAGENS GmbH, Cologne, Germany
29+
////////////////////////////////////////////////////////////////////////////////
30+
31+
if (getOptions === true) {
32+
return {
33+
'rocksdb.exclusive-writes': 'false',
34+
};
35+
}
36+
37+
var jsunity = require("jsunity");
38+
var tasks = require("@arangodb/tasks");
39+
var arangodb = require("@arangodb");
40+
var db = arangodb.db;
41+
42+
var ERRORS = arangodb.errors;
43+
44+
////////////////////////////////////////////////////////////////////////////////
45+
/// @brief test suite
46+
////////////////////////////////////////////////////////////////////////////////
47+
48+
function OptionsTestSuite () {
49+
var cn1 = "UnitTestsExclusiveCollection1"; // used for test data
50+
var cn2 = "UnitTestsExclusiveCollection2"; // used for communication
51+
var c1, c2;
52+
53+
return {
54+
55+
////////////////////////////////////////////////////////////////////////////////
56+
/// @brief set up
57+
////////////////////////////////////////////////////////////////////////////////
58+
59+
setUp : function () {
60+
db._drop(cn1);
61+
db._drop(cn2);
62+
c1 = db._create(cn1);
63+
c2 = db._create(cn2);
64+
},
65+
66+
////////////////////////////////////////////////////////////////////////////////
67+
/// @brief tear down
68+
////////////////////////////////////////////////////////////////////////////////
69+
70+
tearDown : function () {
71+
db._drop(cn1);
72+
db._drop(cn2);
73+
},
74+
75+
testExclusiveExpectConflictWithoutOption : function () {
76+
c1.insert({ "_key" : "XXX" , "name" : "initial" });
77+
let task = tasks.register({
78+
command: function() {
79+
let db = require("internal").db;
80+
db.UnitTestsExclusiveCollection2.insert({ _key: "runner1", value: false });
81+
82+
while (!db.UnitTestsExclusiveCollection2.exists("runner2")) {
83+
require("internal").sleep(0.02);
84+
}
85+
86+
db._executeTransaction({
87+
collections: { write: [ "UnitTestsExclusiveCollection1", "UnitTestsExclusiveCollection2" ] },
88+
action: function () {
89+
let db = require("internal").db;
90+
for (let i = 0; i < 100000; ++i) {
91+
db.UnitTestsExclusiveCollection1.update("XXX", { name : "runner1" });
92+
}
93+
db.UnitTestsExclusiveCollection2.update("runner1", { value: true });
94+
}
95+
});
96+
}
97+
});
98+
99+
db.UnitTestsExclusiveCollection2.insert({ _key: "runner2", value: false });
100+
while (!db.UnitTestsExclusiveCollection2.exists("runner1")) {
101+
require("internal").sleep(0.02);
102+
}
103+
104+
try {
105+
db._executeTransaction({
106+
collections: { write: [ "UnitTestsExclusiveCollection1", "UnitTestsExclusiveCollection2" ] },
107+
action: function () {
108+
let db = require("internal").db;
109+
for (let i = 0; i < 100000; ++i) {
110+
db.UnitTestsExclusiveCollection1.update("XXX", { name : "runner2" });
111+
}
112+
db.UnitTestsExclusiveCollection2.update("runner2", { value: true });
113+
}
114+
});
115+
fail();
116+
} catch (< 10000 /span>err) {
117+
assertEqual(ERRORS.ERROR_ARANGO_CONFLICT.code, err.errorNum);
118+
assertEqual(409, err.code); // conflict
119+
assertEqual("timeout waiting to lock key Operation timed out: Timeout waiting to lock key", err.errorMessage);
120+
}
121+
122+
while (true) {
123+
try {
124+
tasks.get(task);
125+
require("internal").wait(0.25, false);
126+
} catch (err) {
127+
// "task not found" means the task is finished
128+
break;
129+
}
130+
}
131+
132+
// only one transaction should have succeeded
133+
assertEqual(2, c2.count());
134+
assertTrue(c2.document("runner1").value); // runner1 transaction should succeed
135+
assertFalse(c2.document("runner2").value); // runner2 transaction should fail
136+
}
137+
138+
};
139+
}
140+
141+
////////////////////////////////////////////////////////////////////////////////
142+
/// @brief executes the test suite
143+
////////////////////////////////////////////////////////////////////////////////
144+
145+
jsunity.run(OptionsTestSuite);
146+
147+
return jsunity.done();
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*jshint globalstrict:false, strict:false */
2+
/*global assertEqual, assertNotEqual, assertTrue, getOptions, fail, assertFalse */
3+
4+
////////////////////////////////////////////////////////////////////////////////
5+
/// @brief test the deadlock detection
6+
///
7+
/// @file
8+
///
9+
/// DISCLAIMER
10+
///
11+
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
12+
///
13+
/// Licensed under the Apache License, Version 2.0 (the "License");
14+
/// you may not use this file except in compliance with the License.
15+
/// You may obtain a copy of the License at
16+
///
17+
/// http://www.apache.org/licenses/LICENSE-2.0
18+
///
19+
/// Unless required by applicable law or agreed to in writing, software
20+
/// distributed under the License is distributed on an "AS IS" BASIS,
21+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
/// See the License for the specific language governing permissions and
23+
/// limitations under the License.
24+
///
25+
/// Copyright holder is triAGENS GmbH, Cologne, Germany
26+
///
27+
/// @author Jan Christoph Uhde
28+
/// @author Copyright 2019, triAGENS GmbH, Cologne, Germany
29+
////////////////////////////////////////////////////////////////////////////////
30+
31+
if (getOptions === true) {
32+
return {
33+
'rocksdb.exclusive-writes': 'false',
34+
};
35+
}
36+
37+
var jsunity = require("jsunity");
38+
var tasks = require("@arangodb/tasks");
39+
var arangodb = require("@arangodb");
40+
var db = arangodb.db;
41+
42+
var ERRORS = arangodb.errors;
43+
44+
////////////////////////////////////////////////////////////////////////////////
45+
/// @brief test suite
46+
////////////////////////////////////////////////////////////////////////////////
47+
48+
function OptionsTestSuite () {
49+
var cn1 = "UnitTestsExclusiveCollection1"; // used for test data
50+
var cn2 = "UnitTestsExclusiveCollection2"; // used for communication
51+
var c1, c2;
52+
53+
return {
54+
55+
////////////////////////////////////////////////////////////////////////////////
56+
/// @brief set up
57+
////////////////////////////////////////////////////////////////////////////////
58+
59+
setUp : function () {
60+
db._drop(cn1);
61+
db._drop(cn2);
62+
c1 = db._create(cn1);
63+
c2 = db._create(cn2);
64+
},
65+
66+
////////////////////////////////////////////////////////////////////////////////
67+
/// @brief tear down
68+
////////////////////////////////////////////////////////////////////////////////
69+
70+
tearDown : function () {
71+
db._drop(cn1);
72+
db._drop(cn2);
73+
},
74+
75+
testExclusiveExpectConflictWithoutOption : function () {
76+
c1.insert({ "_key" : "XXX" , "name" : "initial" });
77+
let task = tasks.register({
78+
command: function() {
79+
let db = require("internal").db;
80+
db.UnitTestsExclusiveCollection2.insert({ _key: "runner1", value: false });
81+
82+
while (!db.UnitTestsExclusiveCollection2.exists("runner2")) {
83+
require("internal").sleep(0.02);
84+
}
85+
86+
db._executeTransaction({
87+
collections: { write: [ "UnitTestsExclusiveCollection1", "UnitTestsExclusiveCollection2" ] },
88+
action: function () {
89+
let db = require("internal").db;
90+
for (let i = 0; i < 100000; ++i) {
91+
db.UnitTestsExclusiveCollection1.update("XXX", { name : "runner1" });
92+
}
93+
db.UnitTestsExclusiveCollection2.update("runner1", { value: true });
94+
}
95+
});
96+
}
97+
});
98+
99+
db.UnitTestsExclusiveCollection2.insert({ _key: "runner2", value: false });
100+
while (!db.UnitTestsExclusiveCollection2.exists("runner1")) {
101+
require("internal").sleep(0.02);
102+
}
103+
104+
try {
105+
db._executeTransaction({
106+
collections: { write: [ "UnitTestsExclusiveCollection1", "UnitTestsExclusiveCollection2" ] },
107+
action: function () {
108+
let db = require("internal").db;
109+
for (let i = 0; i < 100000; ++i) {
110+
db.UnitTestsExclusiveCollection1.update("XXX", { name : "runner2" });
111+
}
112+
db.UnitTestsExclusiveCollection2.update("runner2", { value: true });
113+
}
114+
});
115+
fail();
116+
} catch (err) {
117+
assertEqual(ERRORS.ERROR_ARANGO_CONFLICT.code, err.errorNum);
118+
assertEqual(409, err.code); // conflict
119+
assertTrue( // it is possible to get two different errors messages here (two different internal states can appear)
120+
(("precondition failed" === err.errorMessage) || ("timeout waiting to lock key Operation timed out: Timeout waiting to lock key" === err.errorMessage))
121+
);
122+
}
123+
124+
while (true) {
125+
try {
126+
tasks.get(task);
127+
require("internal").wait(0.25, false);
128+
} catch (err) {
129+
// "task not found" means the task is finished
130+
break;
131+
}
132+
}
133+
134+
// only one transaction should have succeeded
135+
assertEqual(2, c2.count());
136+
assertTrue(c2.document("runner1").value); // runner1 transaction should succeed
137+
assertFalse(c2.document("runner2").value); // runner2 transaction should fail
138+
}
139+
140+
};
141+
}
142+
143+
////////////////////////////////////////////////////////////////////////////////
144+
/// @brief executes the test suite
145+
////////////////////////////////////////////////////////////////////////////////
146+
147+
jsunity.run(OptionsTestSuite);
148+
149+
return jsunity.done();

0 commit comments

Comments
 (0)
0