mirror of https://gitee.com/bigwinds/arangodb
1369 lines
42 KiB
JavaScript
1369 lines
42 KiB
JavaScript
/*jslint sloppy: true, white: true, indent: 2, nomen: true, maxlen: 80 */
|
|
/*global require, assertEqual, assertTrue, arango */
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test the replication
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// @author Jan Steemann
|
|
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var jsunity = require("jsunity");
|
|
var arangodb = require("org/arangodb");
|
|
var errors = arangodb.errors;
|
|
var db = arangodb.db;
|
|
|
|
var replication = require("org/arangodb/replication");
|
|
var console = require("console");
|
|
var internal = require("internal");
|
|
var masterEndpoint = arango.getEndpoint();
|
|
var slaveEndpoint = masterEndpoint.replace(/:3(\d+)$/, ':4$1');
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- replication tests
|
|
// -----------------------------------------------------------------------------
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function ReplicationSuite () {
|
|
var cn = "UnitTestsReplication";
|
|
var cn2 = "UnitTestsReplication2";
|
|
|
|
// these must match the values in the Makefile!
|
|
var replicatorUser = "replicator-user";
|
|
var replicatorPassword = "replicator-password";
|
|
|
|
var connectToMaster = function () {
|
|
arango.reconnect(masterEndpoint, db._name(), replicatorUser, replicatorPassword);
|
|
};
|
|
|
|
var connectToSlave = function () {
|
|
arango.reconnect(slaveEndpoint, db._name(), "root", "");
|
|
};
|
|
|
|
var collectionChecksum = function (name) {
|
|
var c = db._collection(name).checksum(true, true);
|
|
return c.checksum;
|
|
};
|
|
|
|
var collectionCount = function (name) {
|
|
return db._collection(name).count();
|
|
};
|
|
|
|
var compareTicks = function (l, r) {
|
|
if (l === null) {
|
|
l = "0";
|
|
}
|
|
if (r === null) {
|
|
r = "0";
|
|
}
|
|
if (l.length != r.length) {
|
|
return l.length - r.length < 0 ? -1 : 1;
|
|
}
|
|
|
|
// length is equal
|
|
for (i = 0; i < l.length; ++i) {
|
|
if (l[i] != r[i]) {
|
|
return l[i] < r[i] ? -1 : 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
|
|
var compare = function (masterFunc, slaveFunc, applierConfiguration) {
|
|
var state = { };
|
|
|
|
db._flushCache();
|
|
masterFunc(state);
|
|
|
|
connectToSlave();
|
|
replication.applier.stop();
|
|
|
|
internal.wait(1, false);
|
|
|
|
var syncResult = replication.sync({
|
|
endpoint: masterEndpoint,
|
|
username: replicatorUser,
|
|
password: replicatorPassword,
|
|
verbose: true
|
|
});
|
|
|
|
assertTrue(syncResult.hasOwnProperty('lastLogTick'));
|
|
|
|
if (typeof applierConfiguration === 'object') {
|
|
console.log("using special applier configuration: " + JSON.stringify(applierConfiguration));
|
|
}
|
|
|
|
applierConfiguration = applierConfiguration || { };
|
|
applierConfiguration.endpoint = masterEndpoint;
|
|
applierConfiguration.username = replicatorUser;
|
|
applierConfiguration.password = replicatorPassword;
|
|
|
|
if (! applierConfiguration.hasOwnProperty('chunkSize')) {
|
|
applierConfiguration.chunkSize = 16384;
|
|
}
|
|
|
|
replication.applier.properties(applierConfiguration);
|
|
replication.applier.start(syncResult.lastLogTick);
|
|
|
|
var printed = false;
|
|
|
|
while (1) {
|
|
var slaveState = replication.applier.state();
|
|
|
|
if (! slaveState.state.running || slaveState.state.lastError.errorNum > 0) {
|
|
break;
|
|
}
|
|
|
|
if (compareTicks(slaveState.state.lastAppliedContinuousTick, syncResult.lastLogTick) > 0 ||
|
|
compareTicks(slaveState.state.lastProcessedContinuousTick, syncResult.lastLogTick) > 0 ||
|
|
compareTicks(slaveState.state.lastAvailableContinuousTick, syncResult.lastLogTick) > 0) {
|
|
break;
|
|
}
|
|
|
|
if (! printed) {
|
|
console.log("waiting for slave to catch up");
|
|
printed = true;
|
|
}
|
|
internal.wait(1.0, false);
|
|
}
|
|
|
|
db._flushCache();
|
|
slaveFunc(state);
|
|
};
|
|
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief set up
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
setUp : function () {
|
|
connectToMaster();
|
|
|
|
db._drop(cn);
|
|
db._drop(cn2);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tear down
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
tearDown : function () {
|
|
connectToMaster();
|
|
|
|
db._drop(cn);
|
|
db._drop(cn2);
|
|
|
|
connectToSlave();
|
|
replication.applier.stop();
|
|
db._drop(cn);
|
|
db._drop(cn2);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test invalid credentials
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testInvalidCredentials1 : function () {
|
|
var configuration = {
|
|
endpoint: masterEndpoint,
|
|
username: replicatorUser,
|
|
password: replicatorPassword + "xx" // invalid
|
|
};
|
|
|
|
try {
|
|
replication.applier.properties(configuration);
|
|
}
|
|
catch (err) {
|
|
require("internal").print(err);
|
|
assertEqual(errors.ERROR_HTTP_UNAUTHORIZED.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test invalid credentials
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testInvalidCredentials2 : function () {
|
|
var configuration = {
|
|
endpoint: masterEndpoint,
|
|
username: replicatorUser + "xx", // invalid
|
|
password: replicatorPassword
|
|
};
|
|
|
|
try {
|
|
replication.applier.properties(configuration);
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_HTTP_UNAUTHORIZED.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test invalid credentials
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testInvalidCredentials3 : function () {
|
|
var configuration = {
|
|
endpoint: masterEndpoint,
|
|
username: "root",
|
|
password: "abc"
|
|
};
|
|
|
|
try {
|
|
replication.applier.properties(configuration);
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_HTTP_UNAUTHORIZED.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test few documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testFew : function () {
|
|
connectToMaster();
|
|
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 5000; ++i) {
|
|
c.save({ "value" : i });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(5000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test many documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMany : function () {
|
|
connectToMaster();
|
|
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 50000; ++i) {
|
|
c.save({ "value" : i });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(50000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test many documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testManyMore : function () {
|
|
connectToMaster();
|
|
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 150000; ++i) {
|
|
c.save({ "value" : i });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(150000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test big markers
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testBigMarkersArray : function () {
|
|
connectToMaster();
|
|
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
var doc = { };
|
|
for (i = 0; i < 1000; ++i) {
|
|
doc["test" + i] = "the quick brown foxx jumped over the LAZY dog";
|
|
}
|
|
|
|
for (i = 0; i < 100; ++i) {
|
|
c.save({ "value" : i, "values": doc });
|
|
}
|
|
|
|
var d = c.any();
|
|
assertEqual(1000, Object.keys(d.values).length);
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(100, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test big markers
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testBigMarkersList : function () {
|
|
connectToMaster();
|
|
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
var doc = [ ];
|
|
for (i = 0; i < 1000; ++i) {
|
|
doc.push("the quick brown foxx jumped over the LAZY dog");
|
|
}
|
|
|
|
for (i = 0; i < 100; ++i) {
|
|
c.save({ "value" : i, "values": doc });
|
|
}
|
|
|
|
var d = c.any();
|
|
assertEqual(1000, d.values.length);
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(100, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test heterogenous markers
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testHeterogenousMarkers : function () {
|
|
connectToMaster();
|
|
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
var doc = { };
|
|
doc["test" + i] = "the quick brown foxx jumped over the LAZY dog";
|
|
c.save({ "value" : i, "values": doc });
|
|
}
|
|
|
|
var d = c.any();
|
|
assertEqual(1, Object.keys(d.values).length);
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(1000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test empty markers
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testEmptyMarkers : function () {
|
|
connectToMaster();
|
|
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(1000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocuments1 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "value" : i, "foo" : true, "bar" : [ i , false ], "value2" : null, "mydata" : { "test" : [ "abc", "def" ] } });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(1000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocuments2 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "abc" : true, "_key" : "test" + i });
|
|
if (i % 3 == 0) {
|
|
c.remove(c.last());
|
|
}
|
|
else if (i % 5 == 0) {
|
|
c.update("test" + i, { "def" : "hifh" });
|
|
}
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(666, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocuments3 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 50000; ++i) {
|
|
c.save({ "_key" : "test" + i, "foo" : "bar", "baz" : "bat" });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(50000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocuments4 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 50000; ++i) {
|
|
c.save({ "_key" : "test" + i, "foo" : "bar", "baz" : "bat" });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(50000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
},
|
|
{
|
|
chunkSize: 512
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test documents
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocuments5 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 100; ++i) {
|
|
c.save({ "abc" : true, "_key" : "test" + i });
|
|
if (i % 3 == 0) {
|
|
c.remove(c.last());
|
|
}
|
|
else if (i % 5 == 0) {
|
|
c.update("test" + i, { "def" : "hifh" });
|
|
}
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(66, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test edges
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testEdges : function () {
|
|
compare(
|
|
function (state) {
|
|
var v = db._create(cn), i;
|
|
var e = db._createEdgeCollection(cn2);
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
v.save({ "_key" : "test" + i });
|
|
}
|
|
|
|
for (i = 0; i < 5000; i += 10) {
|
|
e.save(cn + "/test" + i, cn + "/test" + i, { "foo" : "bar", "value" : i });
|
|
}
|
|
|
|
state.checksum1 = collectionChecksum(cn);
|
|
state.count1 = collectionCount(cn);
|
|
assertEqual(1000, state.count1);
|
|
|
|
state.checksum2 = collectionChecksum(cn2);
|
|
state.count2 = collectionCount(cn2);
|
|
assertEqual(500, state.count2);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count1, collectionCount(cn));
|
|
assertEqual(state.checksum1, collectionChecksum(cn));
|
|
|
|
assertEqual(state.count2, collectionCount(cn2));
|
|
assertEqual(state.checksum2, collectionChecksum(cn2));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test transactions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTransaction1 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
try {
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function () {
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "_key" : "test" + i });
|
|
}
|
|
|
|
throw "rollback!";
|
|
}
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(0, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test transactions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTransaction2 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "_key" : "test" + i });
|
|
}
|
|
|
|
try {
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function () {
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.remove("test" + i);
|
|
}
|
|
}
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(1000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test transactions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTransaction3 : function () {
|
|
compare(
|
|
function (state) {
|
|
db._create(cn);
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn), i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "_key" : "test" + i });
|
|
}
|
|
},
|
|
params: { "cn": cn },
|
|
});
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(1000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test transactions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTransaction4 : function () {
|
|
compare(
|
|
function (state) {
|
|
db._create(cn);
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn), i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "_key" : "test" + i });
|
|
}
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.update("test" + i, { "foo" : "bar" + i });
|
|
}
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.update("test" + i, { "foo" : "baz" + i });
|
|
}
|
|
|
|
for (i = 0; i < 1000; i += 10) {
|
|
c.remove("test" + i);
|
|
}
|
|
},
|
|
params: { "cn": cn },
|
|
});
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(900, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test big transaction
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTransactionBig : function () {
|
|
compare(
|
|
function (state) {
|
|
db._create(cn);
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn), i;
|
|
|
|
for (i = 0; i < 50000; ++i) {
|
|
c.save({ "_key" : "test" + i, value : i });
|
|
c.update("test" + i, { value : i + 1 });
|
|
|
|
if (i % 5 == 0) {
|
|
c.remove("test" + i);
|
|
}
|
|
}
|
|
},
|
|
params: { "cn" : cn },
|
|
});
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(40000, state.count);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
},
|
|
{
|
|
chunkSize: 2048
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test transactions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTransactionMulti : function () {
|
|
compare(
|
|
function (state) {
|
|
db._create(cn);
|
|
db._create(cn2);
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn, cn2 ]
|
|
},
|
|
action: function (params) {
|
|
var c1 = require("internal").db._collection(params.cn);
|
|
var c2 = require("internal").db._collection(params.cn2);
|
|
var i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c1.save({ "_key" : "test" + i });
|
|
c2.save({ "_key" : "test" + i, "foo": "bar" });
|
|
}
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c1.update("test" + i, { "foo" : "bar" + i });
|
|
}
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c1.update("test" + i, { "foo" : "baz" + i });
|
|
c2.update("test" + i, { "foo" : "baz" + i });
|
|
}
|
|
|
|
for (i = 0; i < 1000; i += 10) {
|
|
c1.remove("test" + i);
|
|
c2.remove("test" + i);
|
|
}
|
|
},
|
|
params: { "cn": cn, "cn2": cn2 },
|
|
});
|
|
|
|
state.checksum1 = collectionChecksum(cn);
|
|
state.checksum2 = collectionChecksum(cn2);
|
|
state.count1 = collectionCount(cn);
|
|
state.count2 = collectionCount(cn2);
|
|
assertEqual(900, state.count1);
|
|
assertEqual(900, state.count2);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count1, collectionCount(cn));
|
|
assertEqual(state.count2, collectionCount(cn2));
|
|
assertEqual(state.checksum1, collectionChecksum(cn));
|
|
assertEqual(state.checksum2, collectionChecksum(cn2));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test transactions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTransactionAbort : function () {
|
|
compare(
|
|
function (state) {
|
|
db._create(cn);
|
|
db._create(cn2);
|
|
|
|
db._collection(cn).save({ foo: "bar" });
|
|
db._collection(cn2).save({ bar: "baz" });
|
|
|
|
try {
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn, cn2 ]
|
|
},
|
|
action: function (params) {
|
|
var c1 = require("internal").db._collection(params.cn);
|
|
var c2 = require("internal").db._collection(params.cn2);
|
|
var i;
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c1.save({ "_key" : "test" + i });
|
|
c2.save({ "_key" : "test" + i, "foo": "bar" });
|
|
}
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c1.update("test" + i, { "foo" : "bar" + i });
|
|
}
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c1.update("test" + i, { "foo" : "baz" + i });
|
|
c2.update("test" + i, { "foo" : "baz" + i });
|
|
}
|
|
|
|
for (i = 0; i < 1000; i += 10) {
|
|
c1.remove("test" + i);
|
|
c2.remove("test" + i);
|
|
}
|
|
|
|
throw "rollback!";
|
|
},
|
|
params: { "cn": cn, "cn2": cn2 },
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
state.checksum1 = collectionChecksum(cn);
|
|
state.checksum2 = collectionChecksum(cn2);
|
|
state.count1 = collectionCount(cn);
|
|
state.count2 = collectionCount(cn2);
|
|
assertEqual(1, state.count1);
|
|
assertEqual(1, state.count2);
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count1, collectionCount(cn));
|
|
assertEqual(state.count2, collectionCount(cn2));
|
|
assertEqual(state.checksum1, collectionChecksum(cn));
|
|
assertEqual(state.checksum2, collectionChecksum(cn2));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test rename collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testRenameCollection1 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn, {
|
|
isVolatile : true,
|
|
waitForSync : false,
|
|
doCompact : false,
|
|
journalSize : 1048576,
|
|
keyOptions : {
|
|
allowUserKeys : false
|
|
},
|
|
});
|
|
|
|
c.rename(cn2);
|
|
|
|
state.cid = c._id;
|
|
state.properties = c.properties();
|
|
},
|
|
function (state) {
|
|
try {
|
|
db._collection(cn).properties();
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
// original collection was renamed
|
|
}
|
|
|
|
var properties = db._collection(cn2).properties();
|
|
assertEqual(state.cid, db._collection(cn2)._id);
|
|
assertEqual(cn2, db._collection(cn2).name());
|
|
assertTrue(properties.isVolatile);
|
|
assertFalse(properties.waitForSync);
|
|
assertFalse(properties.deleted);
|
|
assertFalse(properties.doCompact);
|
|
assertEqual(1048576, properties.journalSize);
|
|
assertFalse(properties.keyOptions.allowUserKeys);
|
|
assertEqual("traditional", properties.keyOptions.type);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test rename collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testRenameCollection2 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn);
|
|
c.rename(cn2);
|
|
c.rename(cn);
|
|
|
|
state.cid = c._id;
|
|
state.properties = c.properties();
|
|
},
|
|
function (state) {
|
|
try {
|
|
db._collection(cn2).properties();
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
// collection was renamed
|
|
}
|
|
|
|
assertEqual(state.cid, db._collection(cn)._id);
|
|
assertEqual(cn, db._collection(cn).name());
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test change collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testChangeCollection1 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn, {
|
|
waitForSync : false,
|
|
doCompact : false,
|
|
journalSize : 1048576
|
|
});
|
|
|
|
var properties = c.properties();
|
|
assertFalse(properties.waitForSync);
|
|
assertFalse(properties.doCompact);
|
|
assertEqual(1048576, properties.journalSize);
|
|
|
|
properties = c.properties({ waitForSync: true, doCompact: true, journalSize: 2097152 });
|
|
assertTrue(properties.waitForSync);
|
|
assertTrue(properties.doCompact);
|
|
assertEqual(2097152, properties.journalSize);
|
|
|
|
state.cid = c._id;
|
|
state.properties = c.properties();
|
|
},
|
|
function (state) {
|
|
var properties = db._collection(cn).properties();
|
|
assertEqual(state.cid, db._collection(cn)._id);
|
|
assertEqual(cn, db._collection(cn).name());
|
|
assertTrue(properties.waitForSync);
|
|
assertTrue(properties.doCompact);
|
|
assertEqual(2097152, properties.journalSize);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test change collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testChangeCollection2 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn, {
|
|
waitForSync : true,
|
|
doCompact : true,
|
|
journalSize : 2097152
|
|
});
|
|
|
|
var properties = c.properties();
|
|
assertTrue(properties.waitForSync);
|
|
assertTrue(properties.doCompact);
|
|
assertEqual(2097152, properties.journalSize);
|
|
|
|
properties = c.properties({ waitForSync: false, doCompact: false, journalSize: 1048576 });
|
|
assertFalse(properties.waitForSync);
|
|
assertFalse(properties.doCompact);
|
|
assertEqual(1048576, properties.journalSize);
|
|
|
|
state.cid = c._id;
|
|
state.properties = c.properties();
|
|
},
|
|
function (state) {
|
|
var properties = db._collection(cn).properties();
|
|
assertEqual(state.cid, db._collection(cn)._id);
|
|
assertEqual(cn, db._collection(cn).name());
|
|
assertFalse(properties.waitForSync);
|
|
assertFalse(properties.doCompact);
|
|
assertEqual(1048576, properties.journalSize);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test create collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testCreateCollection1 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn, {
|
|
isVolatile : true,
|
|
waitForSync : false,
|
|
doCompact : false,
|
|
journalSize : 1048576
|
|
});
|
|
|
|
state.cid = c._id;
|
|
state.properties = c.properties();
|
|
},
|
|
function (state) {
|
|
var properties = db._collection(cn).properties();
|
|
assertEqual(state.cid, db._collection(cn)._id);
|
|
assertEqual(cn, db._collection(cn).name());
|
|
assertTrue(properties.isVolatile);
|
|
assertFalse(properties.waitForSync);
|
|
assertFalse(properties.deleted);
|
|
assertFalse(properties.doCompact);
|
|
assertEqual(1048576, properties.journalSize);
|
|
assertTrue(properties.keyOptions.allowUserKeys);
|
|
assertEqual("traditional", properties.keyOptions.type);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test create collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testCreateCollection2 : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn, {
|
|
keyOptions : {
|
|
type : "autoincrement",
|
|
allowUserKeys : false
|
|
},
|
|
isVolatile : false,
|
|
waitForSync : true,
|
|
doCompact : true,
|
|
journalSize : 2097152
|
|
});
|
|
|
|
state.cid = c._id;
|
|
state.properties = c.properties();
|
|
},
|
|
function (state) {
|
|
var properties = db._collection(cn).properties();
|
|
assertEqual(state.cid, db._collection(cn)._id);
|
|
assertEqual(cn, db._collection(cn).name());
|
|
assertFalse(properties.isVolatile);
|
|
assertTrue(properties.waitForSync);
|
|
assertFalse(properties.deleted);
|
|
assertTrue(properties.doCompact);
|
|
assertEqual(2097152, properties.journalSize);
|
|
assertFalse(properties.keyOptions.allowUserKeys);
|
|
assertEqual("autoincrement", properties.keyOptions.type);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test drop collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDropCollection : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn);
|
|
c.drop();
|
|
},
|
|
function (state) {
|
|
assertNull(db._collection(cn));
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test cap constraint
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testCapConstraint : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
c.ensureCapConstraint(128);
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "_key" : "test" + i });
|
|
}
|
|
state.last = c.last(3);
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(128, state.count);
|
|
assertEqual("test999", state.last[0]._key);
|
|
assertEqual("test998", state.last[1]._key);
|
|
assertEqual("test997", state.last[2]._key);
|
|
|
|
state.idx = c.getIndexes()[1];
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
assertEqual(state.last, db._collection(cn).last(3));
|
|
|
|
assertEqual(state.idx.id, db._collection(cn).getIndexes()[1].id);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test hash index
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testUniqueConstraint : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
c.ensureHashIndex("a", "b");
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "_key" : "test" + i, "a" : parseInt(i / 2), "b" : i });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(1000, state.count);
|
|
|
|
state.idx = c.getIndexes()[1];
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
|
|
var idx = db._collection(cn).getIndexes()[1];
|
|
assertEqual(state.idx.id, idx.id);
|
|
assertEqual("hash", state.idx.type);
|
|
assertFalse(state.idx.unique);
|
|
assertEqual([ "a" ], state.idx.fields);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test unique constraint
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testUniqueConstraint : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
c.ensureUniqueConstraint("a");
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
try {
|
|
c.save({ "_key" : "test" + i, "a" : parseInt(i / 2) });
|
|
}
|
|
catch (err) {
|
|
}
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(500, state.count);
|
|
|
|
state.idx = c.getIndexes()[1];
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
|
|
var idx = db._collection(cn).getIndexes()[1];
|
|
assertEqual(state.idx.id, idx.id);
|
|
assertEqual("hash", state.idx.type);
|
|
assertTrue(state.idx.unique);
|
|
assertEqual([ "a" ], state.idx.fields);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test skiplist
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSkiplist : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
c.ensureSkiplist("a", "b");
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
c.save({ "_key" : "test" + i, "a" : parseInt(i / 2), "b" : i });
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(1000, state.count);
|
|
|
|
state.idx = c.getIndexes()[1];
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
|
|
var idx = db._collection(cn).getIndexes()[1];
|
|
assertEqual(state.idx.id, idx.id);
|
|
assertEqual("skiplist", state.idx.type);
|
|
assertFalse(state.idx.unique);
|
|
assertEqual([ "a", "b" ], state.idx.fields);
|
|
}
|
|
);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test unique skiplist
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testUniqueSkiplist : function () {
|
|
compare(
|
|
function (state) {
|
|
var c = db._create(cn), i;
|
|
c.ensureUniqueSkiplist("a");
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
try {
|
|
c.save({ "_key" : "test" + i, "a" : parseInt(i / 2) });
|
|
}
|
|
catch (err) {
|
|
}
|
|
}
|
|
|
|
state.checksum = collectionChecksum(cn);
|
|
state.count = collectionCount(cn);
|
|
assertEqual(500, state.count);
|
|
|
|
state.idx = c.getIndexes()[1];
|
|
},
|
|
function (state) {
|
|
assertEqual(state.count, collectionCount(cn));
|
|
assertEqual(state.checksum, collectionChecksum(cn));
|
|
|
|
var idx = db._collection(cn).getIndexes()[1];
|
|
assertEqual(state.idx.id, idx.id);
|
|
assertEqual("skiplist", state.idx.type);
|
|
assertTrue(state.idx.unique);
|
|
assertEqual([ "a" ], state.idx.fields);
|
|
}
|
|
);
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- main
|
|
// -----------------------------------------------------------------------------
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief executes the test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
jsunity.run(ReplicationSuite);
|
|
|
|
return jsunity.done();
|
|
|
|
// Local Variables:
|
|
// mode: outline-minor
|
|
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
|
// End:
|