mirror of https://gitee.com/bigwinds/arangodb
2592 lines
79 KiB
JavaScript
2592 lines
79 KiB
JavaScript
/*jshint globalstrict:false, strict:false */
|
|
/*global assertEqual, assertTrue, assertMatch, assertNotEqual
|
|
assertUndefined, assertFalse, fail, REPLICATION_LOGGER_LAST */
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test the replication functions
|
|
///
|
|
/// @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("@arangodb");
|
|
var errors = arangodb.errors;
|
|
var db = arangodb.db;
|
|
var internal = require("internal");
|
|
var replication = require("@arangodb/replication");
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function ReplicationLoggerSuite () {
|
|
'use strict';
|
|
var cn = "UnitTestsReplication";
|
|
var cn2 = "UnitTestsReplication2";
|
|
|
|
var getLastLogTick = function () {
|
|
while (true) {
|
|
var s = replication.logger.state();
|
|
|
|
if (s.state.lastLogTick === s.state.lastUncommittedLogTick) {
|
|
return s.state.lastLogTick;
|
|
}
|
|
internal.wait(0.05, false);
|
|
}
|
|
};
|
|
|
|
var getLogEntries = function (tick, type) {
|
|
var result = [ ];
|
|
getLastLogTick();
|
|
|
|
var exclude = function(name) {
|
|
return (name.substr(0, 11) === '_statistics' ||
|
|
name === '_apps' ||
|
|
name === '_foxxlog' ||
|
|
name === '_jobs' ||
|
|
name === '_queues' ||
|
|
name === '_sessions');
|
|
};
|
|
|
|
var entries = REPLICATION_LOGGER_LAST(tick, "9999999999999999999");
|
|
|
|
if (Array.isArray(type)) {
|
|
entries.forEach(function(e) {
|
|
if ((e.type === 2300 || e.type === 2302) && e.cname && exclude(e.cname)) {
|
|
// exclude statistics markers here
|
|
return;
|
|
}
|
|
if (type.indexOf(e.type) !== -1) {
|
|
result.push(e);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
entries.forEach(function(e) {
|
|
if ((e.type === 2300 || e.type === 2302) && e.cname && exclude(e.cname)) {
|
|
// exclude statistics markers here
|
|
return;
|
|
}
|
|
if (type === undefined || e.type === type) {
|
|
result.push(e);
|
|
}
|
|
});
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
var compareTicks = function (l, r) {
|
|
var i;
|
|
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 waitForTick = function (value) {
|
|
while (true) {
|
|
var state = replication.logger.state().state;
|
|
if (compareTicks(state.lastLogTick, value) > 0) {
|
|
break;
|
|
}
|
|
internal.wait(0.1, false);
|
|
}
|
|
};
|
|
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief set up
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
setUp : function () {
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tear down
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
tearDown : function () {
|
|
db._drop(cn);
|
|
db._drop(cn2);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief get ticks
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testGetLoggerTicks : function () {
|
|
var state, tick;
|
|
|
|
getLastLogTick();
|
|
state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
tick = state.lastLogTick;
|
|
assertTrue(typeof tick === 'string');
|
|
assertMatch(/^\d+$/, state.lastLogTick);
|
|
tick = state.lastUncommittedLogTick;
|
|
assertTrue(typeof tick === 'string');
|
|
assertMatch(/^\d+$/, state.lastLogTick);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief get state
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testGetLoggerState : function () {
|
|
var state, tick, server;
|
|
|
|
getLastLogTick();
|
|
state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
tick = state.lastLogTick;
|
|
assertTrue(typeof tick === 'string');
|
|
assertNotEqual("", state.time);
|
|
assertMatch(/^\d+-\d+-\d+T\d+:\d+:\d+Z$/, state.time);
|
|
|
|
// query the state again
|
|
state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
|
|
if (db._engine().name !== "rocksdb") {
|
|
assertEqual(tick, state.lastLogTick);
|
|
}
|
|
assertTrue(typeof state.lastLogTick === 'string');
|
|
assertMatch(/^\d+$/, state.lastLogTick);
|
|
assertTrue(state.totalEvents >= 0);
|
|
|
|
server = replication.logger.state().server;
|
|
assertEqual(server.version, db._version());
|
|
assertNotEqual("", server.serverId);
|
|
assertMatch(/^\d+$/, server.serverId);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test logging disabled
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDisabledLogger : function () {
|
|
var state, tick, events;
|
|
|
|
state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
tick = state.lastLogTick;
|
|
assertTrue(typeof tick === 'string');
|
|
assertMatch(/^\d+$/, state.lastLogTick);
|
|
events = state.totalEvents;
|
|
assertTrue(state.totalEvents >= 0);
|
|
|
|
// do something that will cause logging (if it was enabled...)
|
|
var c = db._create(cn);
|
|
c.save({ "test" : 1 });
|
|
|
|
waitForTick(tick);
|
|
|
|
state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
assertMatch(/^\d+$/, state.lastLogTick);
|
|
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
|
assertTrue(state.totalEvents > events);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test logging enabled
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testEnabledLogger : function () {
|
|
var state, tick, events;
|
|
|
|
state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
tick = state.lastLogTick;
|
|
assertTrue(typeof tick === 'string');
|
|
assertMatch(/^\d+$/, state.lastLogTick);
|
|
events = state.totalEvents;
|
|
assertTrue(state.totalEvents >= 0);
|
|
|
|
// do something that will cause logging
|
|
var c = db._create(cn);
|
|
c.save({ "test" : 1 });
|
|
|
|
waitForTick(tick);
|
|
|
|
state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
assertMatch(/^\d+$/, state.lastLogTick);
|
|
assertTrue(state.totalEvents >= 1);
|
|
assertNotEqual(tick, state.lastLogTick);
|
|
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
|
assertTrue(state.totalEvents > events);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test first tick
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testFirstTick : function () {
|
|
var state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
var tick = state.lastLogTick;
|
|
assertTrue(typeof tick === 'string');
|
|
assertMatch(/^\d+$/, tick);
|
|
|
|
var firstTick = replication.logger.firstTick();
|
|
assertTrue(typeof firstTick === 'string');
|
|
assertMatch(/^\d+$/, firstTick);
|
|
assertEqual(-1, compareTicks(firstTick, tick));
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test tick ranges
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testTickRanges : function () {
|
|
var state = replication.logger.state().state;
|
|
assertTrue(state.running);
|
|
var tick = state.lastLogTick;
|
|
assertTrue(typeof tick === 'string');
|
|
assertMatch(/^\d+$/, tick);
|
|
|
|
var ranges = replication.logger.tickRanges();
|
|
assertTrue(Array.isArray(ranges));
|
|
assertTrue(ranges.length > 0);
|
|
|
|
for (var i = 0; i < ranges.length; ++i) {
|
|
var df = ranges[i];
|
|
assertTrue(typeof df === 'object');
|
|
assertTrue(df.hasOwnProperty('datafile'));
|
|
assertTrue(df.hasOwnProperty('status'));
|
|
assertTrue(df.hasOwnProperty('tickMin'));
|
|
assertTrue(df.hasOwnProperty('tickMax'));
|
|
|
|
assertTrue(typeof df.datafile === 'string');
|
|
assertTrue(typeof df.status === 'string');
|
|
assertTrue(typeof df.tickMin === 'string');
|
|
assertMatch(/^\d+$/, df.tickMin);
|
|
assertTrue(typeof df.tickMax === 'string');
|
|
assertMatch(/^\d+$/, df.tickMax);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateCollection : function () {
|
|
var tick = getLastLogTick();
|
|
|
|
var c = db._create(cn);
|
|
var entry = getLogEntries(tick, 2000)[0];
|
|
|
|
assertEqual(2000, entry.type);
|
|
assertEqual(2, entry.data.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(c._id, entry.data.cid);
|
|
assertFalse(entry.data.deleted);
|
|
assertEqual(cn, entry.data.name);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerDropCollection : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
db._drop(cn);
|
|
|
|
var entry = getLogEntries(tick, 2001)[0];
|
|
|
|
assertEqual(2001, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerRenameCollection : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
c.rename(cn2);
|
|
|
|
var entry = getLogEntries(tick, 2002)[0];
|
|
|
|
assertEqual(2002, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(cn2, entry.data.name);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerPropertiesCollection : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
c.properties({ waitForSync: true, journalSize: 2097152 });
|
|
|
|
var entry = getLogEntries(tick, 2003)[0];
|
|
|
|
assertEqual(2003, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(c._id, entry.data.cid);
|
|
assertEqual(cn, entry.data.name);
|
|
assertEqual(2, entry.data.type);
|
|
assertEqual(false, entry.data.deleted);
|
|
if (db._engine().name === "mmfiles") {
|
|
assertEqual(2097152, entry.data.journalSize);
|
|
assertEqual(true, entry.data.waitForSync);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerIncludedSystemCollection1 : function () {
|
|
var c = db._collection("_graphs");
|
|
|
|
var tick = getLastLogTick();
|
|
var doc = c.save({ "test": 1 });
|
|
|
|
var entry = getLogEntries(tick, 2300)[0];
|
|
assertEqual(2300, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
|
|
tick = getLastLogTick();
|
|
c.remove(doc._key);
|
|
|
|
entry = getLogEntries(tick, 2302)[0];
|
|
assertEqual(2302, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(doc._key, entry.data._key);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerIncludedSystemCollection2 : function () {
|
|
var c = db._collection("_users");
|
|
|
|
var tick = getLastLogTick();
|
|
var doc = c.save({ "test": 1 });
|
|
|
|
var entry = getLogEntries(tick, 2300)[0];
|
|
assertEqual(2300, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
|
|
tick = getLastLogTick();
|
|
c.remove(doc._key);
|
|
|
|
entry = getLogEntries(tick, 2302)[0];
|
|
assertEqual(2302, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(doc._key, entry.data._key);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerSystemCollection : function () {
|
|
db._drop("_unittests", true);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
var c = db._create("_unittests", { isSystem : true });
|
|
|
|
try {
|
|
var entry = getLogEntries(tick, 2000)[0];
|
|
|
|
assertEqual(2000, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(c.name(), entry.data.name);
|
|
|
|
tick = getLastLogTick();
|
|
c.properties({ waitForSync : true });
|
|
|
|
entry = getLogEntries(tick, 2003)[0];
|
|
assertEqual(2003, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(true, entry.data.waitForSync);
|
|
|
|
tick = getLastLogTick();
|
|
} finally {
|
|
db._drop("_unittests", true);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTruncateCollection1 : function () {
|
|
var c = db._create(cn);
|
|
c.save({ "test": 1, "_key": "abc" });
|
|
|
|
var tick = getLastLogTick();
|
|
c.truncate({ compact: false });
|
|
|
|
var entry = getLogEntries(tick, 2302);
|
|
assertEqual(1, entry.length);
|
|
assertNotEqual("0", entry[0].tid);
|
|
assertEqual(c._id, entry[0].cid);
|
|
assertEqual("abc", entry[0].data._key);
|
|
|
|
c.save({ "test": 1, "_key": "abc" });
|
|
|
|
tick = getLastLogTick();
|
|
c.truncate({ compact: false });
|
|
|
|
entry = getLogEntries(tick, 2302);
|
|
assertNotEqual("0", entry[0].tid);
|
|
assertEqual(c._id, entry[0].cid);
|
|
assertEqual("abc", entry[0].data._key);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTruncateCollection2 : function () {
|
|
var i;
|
|
|
|
var c = db._create(cn);
|
|
for (i = 0; i < 100; ++i) {
|
|
c.save({ "test": 1, "_key": "test" + i });
|
|
}
|
|
|
|
var tick = getLastLogTick();
|
|
c.truncate({ compact: false });
|
|
getLastLogTick();
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2302 ]);
|
|
|
|
assertEqual(102, entry.length);
|
|
// trx start
|
|
assertEqual(2200, entry[0].type);
|
|
assertNotEqual("", entry[0].tid);
|
|
var tid = entry[0].tid;
|
|
|
|
// remove
|
|
var keys = { };
|
|
for (i = 0; i < 100; ++i) {
|
|
assertEqual(2302, entry[i + 1].type);
|
|
assertEqual(tid, entry[i + 1].tid);
|
|
assertEqual(c._id, entry[i + 1].cid);
|
|
keys[entry[i + 1].data._key] = true;
|
|
}
|
|
assertEqual(100, Object.keys(keys).length);
|
|
|
|
// commit
|
|
assertEqual(2201, entry[101].type);
|
|
assertEqual(tid, entry[101].tid);
|
|
},
|
|
|
|
testLoggerTruncateCollectionRocksDB : function () {
|
|
if (db._engine().name !== 'rocksdb') {
|
|
return;
|
|
}
|
|
|
|
let c = db._create(cn);
|
|
let docs = [];
|
|
for (let i = 0; i < 32769; ++i) {
|
|
docs.push({ "_key": "test" + i ,value: i });
|
|
if (docs.length === 5000) {
|
|
c.insert(docs);
|
|
docs = [];
|
|
}
|
|
}
|
|
c.insert(docs);
|
|
|
|
let tick = getLastLogTick();
|
|
c.truncate({ compact: false });
|
|
getLastLogTick();
|
|
let entry = getLogEntries(tick);
|
|
|
|
assertEqual(1, entry.length);
|
|
// truncate marker
|
|
assertEqual(2004, entry[0].type);
|
|
},
|
|
|
|
testLoggerTruncateCollectionAndThenSomeRocksDB : function () {
|
|
if (db._engine().name !== 'rocksdb') {
|
|
return;
|
|
}
|
|
|
|
let c = db._create(cn);
|
|
let docs = [];
|
|
for (let i = 0; i < 32769; ++i) {
|
|
docs.push({ "_key": "test" + i ,value: i });
|
|
if (docs.length === 5000) {
|
|
c.insert(docs);
|
|
docs = [];
|
|
}
|
|
}
|
|
c.insert(docs);
|
|
|
|
let tick = getLastLogTick();
|
|
c.truncate({ compact: false });
|
|
c.insert({ _key: "aha" });
|
|
getLastLogTick();
|
|
let entry = getLogEntries(tick);
|
|
|
|
assertEqual(2, entry.length);
|
|
// truncate marker
|
|
assertEqual(2004, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual("aha", entry[1].data._key);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexHash1 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureUniqueConstraint("a", "b");
|
|
var idx = c.getIndexes()[1];
|
|
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("hash", entry.data.type);
|
|
assertEqual(true, entry.data.unique);
|
|
assertEqual(false, entry.data.sparse);
|
|
assertEqual([ "a", "b" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexHash2 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureHashIndex("a");
|
|
var idx = c.getIndexes()[1];
|
|
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("hash", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(false, entry.data.sparse);
|
|
assertEqual([ "a" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexSparseHash1 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureUniqueConstraint("a", "b", { sparse: true });
|
|
|
|
var idx = c.getIndexes()[1];
|
|
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("hash", entry.data.type);
|
|
assertEqual(true, entry.data.unique);
|
|
assertEqual(true, entry.data.sparse);
|
|
assertEqual([ "a", "b" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexSparseHash2 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureHashIndex("a", { sparse: true });
|
|
|
|
var idx = c.getIndexes()[1];
|
|
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("hash", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(true, entry.data.sparse);
|
|
assertEqual([ "a" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexSkiplist1 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureSkiplist("a", "b", "c");
|
|
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("skiplist", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(false, entry.data.sparse);
|
|
assertEqual([ "a", "b", "c" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexSkiplist2 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureUniqueSkiplist("a");
|
|
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("skiplist", entry.data.type);
|
|
assertEqual(true, entry.data.unique);
|
|
assertEqual(false, entry.data.sparse);
|
|
assertEqual([ "a" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexSparseSkiplist1 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureSkiplist("a", "b", "c", { sparse: true });
|
|
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("skiplist", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(true, entry.data.sparse);
|
|
assertEqual([ "a", "b", "c" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexSparseSkiplist2 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureUniqueSkiplist("a", { sparse: true });
|
|
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("skiplist", entry.data.type);
|
|
assertEqual(true, entry.data.unique);
|
|
assertEqual(true, entry.data.sparse);
|
|
assertEqual([ "a" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexFulltext1 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
c.ensureFulltextIndex("a", 5);
|
|
var idx = c.getIndexes()[1];
|
|
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("fulltext", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(5, entry.data.minLength);
|
|
assertEqual([ "a" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexGeo1 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureGeoIndex("a", "b");
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("geo", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual([ "a", "b" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexGeo2 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureGeoIndex("a", true);
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("geo", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual([ "a" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexGeo3 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureGeoConstraint("a", "b", true);
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("geo", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(true, entry.data.sparse);
|
|
assertEqual([ "a", "b" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexGeo4 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureGeoConstraint("a", "b", false);
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("geo", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(true, entry.data.sparse);
|
|
assertEqual([ "a", "b" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerCreateIndexGeo5 : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.ensureGeoConstraint("a", true);
|
|
var idx = c.getIndexes()[1];
|
|
var entry = getLogEntries(tick, 2100)[0];
|
|
|
|
assertTrue(2100, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
assertEqual("geo", entry.data.type);
|
|
assertEqual(false, entry.data.unique);
|
|
assertEqual(true, entry.data.sparse);
|
|
assertEqual([ "a" ], entry.data.fields);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerDropIndex : function () {
|
|
var c = db._create(cn);
|
|
c.ensureUniqueConstraint("a", "b");
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
// use index at #1 (#0 is primary index)
|
|
var idx = c.getIndexes()[1];
|
|
c.dropIndex(idx);
|
|
var entry = getLogEntries(tick, 2101)[0];
|
|
|
|
assertTrue(2101, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(idx.id.replace(/^.*\//, ''), entry.data.id);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerSaveDocument : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.save({ "test": 1, "_key": "abc" });
|
|
var rev = c.document("abc")._rev;
|
|
var entry = getLogEntries(tick, 2300)[0];
|
|
|
|
assertEqual(2300, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual("abc", entry.data._key);
|
|
assertEqual(rev, entry.data._rev);
|
|
assertEqual(1, entry.data.test);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
c.save({ "test": 2, "foo" : "bar", "_key": "12345" });
|
|
rev = c.document("12345")._rev;
|
|
|
|
entry = getLogEntries(tick, 2300)[0];
|
|
assertEqual(2300, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(c.name(), entry.cname);
|
|
assertEqual("12345", entry.data._key);
|
|
assertEqual(rev, entry.data._rev);
|
|
assertEqual(2, entry.data.test);
|
|
assertEqual("bar", entry.data.foo);
|
|
|
|
try {
|
|
c.save({ "test": 1, "_key": "12345" });
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(1, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerSaveDocuments : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
for (var i = 0; i < 100; ++i) {
|
|
c.save({ "test": 1, "_key": "test" + i });
|
|
}
|
|
|
|
var entry = getLogEntries(tick, 2300);
|
|
assertEqual(100, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerDeleteDocument : function () {
|
|
var c = db._create(cn);
|
|
c.save({ "test": 1, "_key": "abc" });
|
|
c.save({ "test": 1, "_key": "12345" });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
c.remove("abc");
|
|
|
|
var entry = getLogEntries(tick, 2302)[0];
|
|
assertEqual(2302, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(c.name(), entry.cname);
|
|
assertEqual("abc", entry.data._key);
|
|
|
|
tick = getLastLogTick();
|
|
c.remove("12345");
|
|
entry = getLogEntries(tick, 2302)[0];
|
|
|
|
assertEqual(2302, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual("12345", entry.data._key);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
try {
|
|
c.remove("12345");
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2302);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerUpdateDocument : function () {
|
|
var c = db._create(cn);
|
|
var tick = getLastLogTick();
|
|
c.save({ "test": 2, "_key": "abc" });
|
|
c.save({ "test": 1, "_key": "12345" });
|
|
|
|
c.update("abc", { "test" : 2 });
|
|
var entry = getLogEntries(tick, 2300);
|
|
|
|
assertEqual(2300, entry[0].type);
|
|
assertEqual(c._id, entry[0].cid);
|
|
assertEqual(c.name(), entry[0].cname);
|
|
assertEqual("abc", entry[0].data._key);
|
|
assertEqual(2, entry[0].data.test);
|
|
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(c._id, entry[1].cid);
|
|
assertEqual(c.name(), entry[1].cname);
|
|
assertEqual("12345", entry[1].data._key);
|
|
assertEqual(1, entry[1].data.test);
|
|
|
|
|
|
tick = getLastLogTick();
|
|
c.update("abc", { "test" : 3 });
|
|
entry = getLogEntries(tick, 2300)[0];
|
|
|
|
assertEqual(2300, entry.type);
|
|
assertEqual(c._id, entry.cid);
|
|
assertEqual(c.name(), entry.cname);
|
|
assertEqual("abc", entry.data._key);
|
|
assertEqual(3, entry.data.test);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
c.update("abc", { "test" : 3 });
|
|
c.update("12345", { "test" : 2 });
|
|
c.update("abc", { "test" : 4 });
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(3, entry.length);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
try {
|
|
c.update("thefoxx", { });
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerReplaceDocument : function () {
|
|
var c = db._create(cn);
|
|
var tick = getLastLogTick();
|
|
c.save({ "test": 2, "_key": "abc" });
|
|
c.save({ "test": 1, "_key": "12345" });
|
|
|
|
c.replace("abc", { "test" : 2 });
|
|
var entry = getLogEntries(tick, 2300);
|
|
assertEqual(2300, entry[0].type);
|
|
assertEqual(c._id, entry[0].cid);
|
|
assertEqual(c.name(), entry[0].cname);
|
|
assertEqual("abc", entry[0].data._key);
|
|
assertEqual(2, entry[0].data.test);
|
|
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(c._id, entry[1].cid);
|
|
assertEqual(c.name(), entry[1].cname);
|
|
assertEqual("12345", entry[1].data._key);
|
|
assertEqual(1, entry[1].data.test);
|
|
|
|
tick = getLastLogTick();
|
|
c.replace("abc", { "test" : 3 });
|
|
c.replace("abc", { "test" : 3 });
|
|
c.replace("12345", { "test" : 2 });
|
|
c.replace("abc", { "test" : 4 });
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(4, entry.length);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
try {
|
|
c.replace("thefoxx", { });
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerSaveEdge : function () {
|
|
var c = db._create(cn);
|
|
var e = db._createEdgeCollection(cn2);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
e.save(cn + "/test1", cn + "/test2", { "test": 1, "_key": "abc" });
|
|
|
|
var entry = getLogEntries(tick, 2300)[0];
|
|
assertEqual(2300, entry.type);
|
|
assertEqual(e._id, entry.cid);
|
|
assertEqual(e.name(), entry.cname);
|
|
assertEqual("abc", entry.data._key);
|
|
assertEqual(c.name() + "/test1", entry.data._from);
|
|
assertEqual(c.name() + "/test2", entry.data._to);
|
|
assertEqual(1, entry.data.test);
|
|
|
|
tick = getLastLogTick();
|
|
e.save(cn + "/test3", cn + "/test4", { "test": [ 99, false ], "_key": "12345" });
|
|
entry = getLogEntries(tick, 2300)[0];
|
|
|
|
assertEqual(2300, entry.type);
|
|
assertEqual(e._id, entry.cid);
|
|
assertEqual(e.name(), entry.cname);
|
|
assertEqual("12345", entry.data._key);
|
|
assertEqual(c.name() + "/test3", entry.data._from);
|
|
assertEqual(c.name() + "/test4", entry.data._to);
|
|
assertEqual([ 99, false ], entry.data.test);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
try {
|
|
e.save();
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerDeleteEdge : function () {
|
|
db._create(cn);
|
|
var e = db._createEdgeCollection(cn2);
|
|
|
|
e.save(cn + "/test1", cn + "/test2", { "test": 1, "_key": "abc" });
|
|
e.save(cn + "/test3", cn + "/test4", { "test": 1, "_key": "12345" });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
e.remove("abc");
|
|
|
|
var entry = getLogEntries(tick, 2302)[0];
|
|
assertEqual(2302, entry.type);
|
|
assertEqual(e._id, entry.cid);
|
|
assertEqual(e.name(), entry.cname);
|
|
assertEqual("abc", entry.data._key);
|
|
|
|
e.remove("12345");
|
|
|
|
tick = getLastLogTick();
|
|
|
|
try {
|
|
e.remove("12345");
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2302);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerUpdateEdge : function () {
|
|
var c = db._create(cn);
|
|
var e = db._createEdgeCollection(cn2);
|
|
var tick = getLastLogTick();
|
|
e.save(cn + "/test1", cn + "/test2", { "test": 2, "_key": "abc" });
|
|
e.save(cn + "/test3", cn + "/test4", { "test": 1, "_key": "12345" });
|
|
|
|
e.update("abc", { "test" : 2 });
|
|
var entry = getLogEntries(tick, 2300);
|
|
assertEqual(2300, entry[0].type);
|
|
assertEqual(e._id, entry[0].cid);
|
|
assertEqual(e.name(), entry[0].cname);
|
|
assertEqual("abc", entry[0].data._key);
|
|
assertEqual(2, entry[0].data.test);
|
|
assertEqual(c.name() + "/test1", entry[0].data._from);
|
|
assertEqual(c.name() + "/test2", entry[0].data._to);
|
|
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(e._id, entry[1].cid);
|
|
assertEqual(e.name(), entry[1].cname);
|
|
assertEqual("12345", entry[1].data._key);
|
|
assertEqual(1, entry[1].data.test);
|
|
assertEqual(c.name() + "/test3", entry[1].data._from);
|
|
assertEqual(c.name() + "/test4", entry[1].data._to);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
e.update("abc", { "test" : 3 });
|
|
e.update("12345", { "test" : 2 });
|
|
e.update("abc", { "test" : 4 });
|
|
entry = getLogEntries(tick, 2300);
|
|
|
|
assertEqual(3, entry.length);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
try {
|
|
e.update("thefoxx", { });
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerReplaceEdge : function () {
|
|
var c = db._create(cn);
|
|
var e = db._createEdgeCollection(cn2);
|
|
var tick = getLastLogTick();
|
|
|
|
e.save(cn + "/test1", cn + "/test2", { "test": 2, "_key": "abc" });
|
|
e.save(cn + "/test3", cn + "/test4", { "test": 1, "_key": "12345" });
|
|
|
|
e.replace("abc", { _from: c.name() + "/test1", _to: c.name() + "/test2", "test" : 2 });
|
|
var entry = getLogEntries(tick, 2300);
|
|
assertEqual(2300, entry[0].type);
|
|
assertEqual(e._id, entry[0].cid);
|
|
assertEqual(e.name(), entry[0].cname);
|
|
assertEqual("abc", entry[0].data._key);
|
|
assertEqual(2, entry[0].data.test);
|
|
assertEqual(c.name() + "/test1", entry[0].data._from);
|
|
assertEqual(c.name() + "/test2", entry[0].data._to);
|
|
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(e._id, entry[1].cid);
|
|
assertEqual(e.name(), entry[1].cname);
|
|
assertEqual("12345", entry[1].data._key);
|
|
assertEqual(1, entry[1].data.test);
|
|
assertEqual(c.name() + "/test3", entry[1].data._from);
|
|
assertEqual(c.name() + "/test4", entry[1].data._to);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
e.replace("abc", { _from: cn + "/test1", _to: cn + "/test2", "test" : 3 });
|
|
e.replace("abc", { _from: cn + "/test1", _to: cn + "/test2", "test" : 3 });
|
|
e.replace("12345", { _from: cn + "/test3", _to: cn + "/test4", "test" : 2 });
|
|
e.replace("abc", { _from: cn + "/test1", _to: cn + "/test2", "test" : 4 });
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(4, entry.length);
|
|
|
|
tick = getLastLogTick();
|
|
|
|
try {
|
|
e.replace("thefoxx", { });
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
entry = getLogEntries(tick, 2300);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionEmpty : function () {
|
|
db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
var actual = db._executeTransaction({
|
|
collections: {
|
|
},
|
|
action: function () {
|
|
return true;
|
|
}
|
|
});
|
|
assertTrue(actual);
|
|
|
|
var entry = getLogEntries(tick, 2200);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionRead1 : function () {
|
|
var c = db._create(cn);
|
|
c.save({ "test" : 1 });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
var actual = db._executeTransaction({
|
|
collections: {
|
|
read: cn
|
|
},
|
|
action: function () {
|
|
return true;
|
|
}
|
|
});
|
|
assertTrue(actual);
|
|
|
|
var entry = getLogEntries(tick, 2200);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionRead2 : function () {
|
|
var c = db._create(cn);
|
|
c.save({ "test" : 1, "_key": "abc" });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
var actual = db._executeTransaction({
|
|
collections: {
|
|
read: cn
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn);
|
|
|
|
c.document("abc");
|
|
|
|
return true;
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
assertTrue(actual);
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202 ]);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionRead3 : function () {
|
|
db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
try {
|
|
var actual = db._executeTransaction({
|
|
collections: {
|
|
read: cn
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn);
|
|
|
|
c.save({ "foo" : "bar" });
|
|
|
|
return true;
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
actual = true;
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202 ]);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionWrite1 : function () {
|
|
db._create(cn);
|
|
var tick = getLastLogTick();
|
|
|
|
var actual = db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function () {
|
|
return true;
|
|
}
|
|
});
|
|
assertTrue(actual);
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202 ]);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionWrite2 : function () {
|
|
var c = db._create(cn);
|
|
var tick = getLastLogTick();
|
|
|
|
var actual = db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn);
|
|
|
|
c.save({ "test" : 2, "_key": "abc" });
|
|
return true;
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
assertTrue(actual);
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(3, entry.length);
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2201, entry[2].type);
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
|
|
assertEqual(c._id, entry[1].cid);
|
|
assertEqual("abc", entry[1].data._key);
|
|
assertEqual(c._id, entry[1].cid);
|
|
assertEqual(2, entry[1].data.test);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionWrite3 : function () {
|
|
if (db._engine().name === "rocksdb") {
|
|
return;
|
|
}
|
|
db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
try {
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn);
|
|
|
|
c.save({ "test" : 2, "_key": "abc" });
|
|
throw "fail";
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(3, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2202, entry[2].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionWrite4 : function () {
|
|
db._create(cn);
|
|
db._create(cn2);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
try {
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: cn
|
|
},
|
|
action: function (params) {
|
|
var c2 = require("internal").db._collection(params.cn2);
|
|
|
|
// we're using a wrong collection here
|
|
c2.save({ "test" : 2, "_key": "abc" });
|
|
},
|
|
params: {
|
|
cn2: cn2
|
|
}
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
}
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(0, entry.length);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionWrite5 : function () {
|
|
db._create(cn);
|
|
db._create(cn2);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn, cn2 ]
|
|
},
|
|
action: function (params) {
|
|
var c2 = require("internal").db._collection(params.cn);
|
|
|
|
c2.save({ "test" : 1, "_key": "12345" });
|
|
c2.save({ "test" : 2, "_key": "abc" });
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(4, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2300, entry[2].type);
|
|
assertEqual(2201, entry[3].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionWrite6 : function () {
|
|
var c1 = db._create(cn);
|
|
var c2 = db._create(cn2);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
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);
|
|
|
|
c1.save({ "test" : 1, "_key": "12345" });
|
|
c2.save({ "test" : 2, "_key": "abc" });
|
|
},
|
|
params: {
|
|
cn: cn,
|
|
cn2: cn2
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(4, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2300, entry[2].type);
|
|
assertEqual(2201, entry[3].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
assertEqual(c1._id, entry[1].cid);
|
|
assertEqual(c2._id, entry[2].cid);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionUpdate : function () {
|
|
var c1 = db._create(cn);
|
|
|
|
c1.insert({ _key: "foo", value: 1 });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn ]
|
|
},
|
|
action: function (params) {
|
|
var c1 = require("internal").db._collection(params.cn);
|
|
|
|
c1.update("foo", { value: 2 });
|
|
c1.insert({ _key: "foo2", value: 3 });
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(4, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2300, entry[2].type);
|
|
assertEqual(2201, entry[3].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
|
|
assertEqual("UnitTestsReplication", entry[1].cname);
|
|
assertEqual("foo", entry[1].data._key);
|
|
assertEqual(2, entry[1].data.value);
|
|
|
|
assertEqual("UnitTestsReplication", entry[2].cname);
|
|
assertEqual("foo2", entry[2].data._key);
|
|
assertEqual(3, entry[2].data.value);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionReplace : function () {
|
|
var c1 = db._create(cn);
|
|
|
|
c1.insert({ _key: "foo", value: 1 });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn ]
|
|
},
|
|
action: function (params) {
|
|
var c1 = require("internal").db._collection(params.cn);
|
|
|
|
c1.replace("foo", { value2: 2 });
|
|
c1.insert({ _key: "foo2", value2: 3 });
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(4, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2300, entry[2].type);
|
|
assertEqual(2201, entry[3].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
|
|
assertEqual("UnitTestsReplication", entry[1].cname);
|
|
assertEqual("foo", entry[1].data._key);
|
|
assertEqual(2, entry[1].data.value2);
|
|
assertFalse(entry[1].data.hasOwnProperty("value"));
|
|
|
|
assertEqual("UnitTestsReplication", entry[2].cname);
|
|
assertEqual("foo2", entry[2].data._key);
|
|
assertEqual(3, entry[2].data.value2);
|
|
assertFalse(entry[2].data.hasOwnProperty("value"));
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionRemove : function () {
|
|
var c1 = db._create(cn);
|
|
|
|
c1.insert({ _key: "foo", value: 1 });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn ]
|
|
},
|
|
action: function (params) {
|
|
var c1 = require("internal").db._collection(params.cn);
|
|
|
|
c1.replace("foo", { value2: 2 });
|
|
c1.remove("foo");
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300, 2302 ]);
|
|
assertEqual(4, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2302, entry[2].type);
|
|
assertEqual(2201, entry[3].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
|
|
assertEqual("UnitTestsReplication", entry[1].cname);
|
|
assertEqual("foo", entry[1].data._key);
|
|
assertEqual(2, entry[1].data.value2);
|
|
assertFalse(entry[1].data.hasOwnProperty("value"));
|
|
|
|
assertEqual("UnitTestsReplication", entry[2].cname);
|
|
assertEqual("foo", entry[2].data._key);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionMultiRemove : function () {
|
|
var c1 = db._create(cn), i;
|
|
|
|
for (i = 0; i < 100; ++i) {
|
|
c1.insert({ _key: "test" + i, value: i });
|
|
}
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn ]
|
|
},
|
|
action: function (params) {
|
|
var c1 = require("internal").db._collection(params.cn);
|
|
|
|
for (var i = 0; i < 100; ++i) {
|
|
c1.remove("test" + i);
|
|
}
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300, 2302 ]);
|
|
assertEqual(102, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2201, entry[101].type);
|
|
for (i = 1; i < 101; ++i) {
|
|
assertEqual(2302, entry[i].type);
|
|
assertEqual(entry[0].tid, entry[i].tid);
|
|
assertEqual("UnitTestsReplication", entry[i].cname);
|
|
assertEqual("test" + (i - 1), entry[i].data._key);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionMultiCollectionUpdate : function () {
|
|
var c1 = db._create(cn);
|
|
var c2 = db._create(cn2);
|
|
|
|
c1.insert({ _key: "foo", value: 1 });
|
|
c2.insert({ _key: "bar", value: "A" });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
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);
|
|
|
|
c1.replace("foo", { value: 2 });
|
|
c1.insert({ _key: "foo2", value: 3 });
|
|
|
|
c2.replace("bar", { value: "B" });
|
|
c2.insert({ _key: "bar2", value: "C" });
|
|
},
|
|
params: {
|
|
cn: cn,
|
|
cn2: cn2
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(6, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2300, entry[2].type);
|
|
assertEqual(2300, entry[3].type);
|
|
assertEqual(2300, entry[4].type);
|
|
assertEqual(2201, entry[5].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
assertEqual(entry[3].tid, entry[4].tid);
|
|
assertEqual(entry[4].tid, entry[5].tid);
|
|
|
|
assertEqual("UnitTestsReplication", entry[1].cname);
|
|
assertEqual("foo", entry[1].data._key);
|
|
assertEqual(2, entry[1].data.value);
|
|
|
|
assertEqual("UnitTestsReplication", entry[2].cname);
|
|
assertEqual("foo2", entry[2].data._key);
|
|
assertEqual(3, entry[2].data.value);
|
|
|
|
assertEqual("UnitTestsReplication2", entry[3].cname);
|
|
assertEqual("bar", entry[3].data._key);
|
|
assertEqual("B", entry[3].data.value);
|
|
|
|
assertEqual("UnitTestsReplication2", entry[4].cname);
|
|
assertEqual("bar2", entry[4].data._key);
|
|
assertEqual("C", entry[4].data.value);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionMultiCollectionRemove : function () {
|
|
var c1 = db._create(cn);
|
|
var c2 = db._create(cn2);
|
|
|
|
c1.insert({ _key: "foo", value: 1 });
|
|
c2.insert({ _key: "bar", value: "A" });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
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);
|
|
|
|
c1.replace("foo", { value: 2 });
|
|
c1.remove("foo");
|
|
|
|
c2.replace("bar", { value: "B" });
|
|
c2.remove("bar");
|
|
},
|
|
params: {
|
|
cn: cn,
|
|
cn2: cn2
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300, 2302 ]);
|
|
assertEqual(6, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2302, entry[2].type);
|
|
assertEqual(2300, entry[3].type);
|
|
assertEqual(2302, entry[4].type);
|
|
assertEqual(2201, entry[5].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
assertEqual(entry[3].tid, entry[4].tid);
|
|
assertEqual(entry[4].tid, entry[5].tid);
|
|
|
|
assertEqual("UnitTestsReplication", entry[1].cname);
|
|
assertEqual("foo", entry[1].data._key);
|
|
assertEqual(2, entry[1].data.value);
|
|
|
|
assertEqual("UnitTestsReplication", entry[2].cname);
|
|
assertEqual("foo", entry[2].data._key);
|
|
|
|
assertEqual("UnitTestsReplication2", entry[3].cname);
|
|
assertEqual("bar", entry[3].data._key);
|
|
assertEqual("B", entry[3].data.value);
|
|
|
|
assertEqual("UnitTestsReplication2", entry[4].cname);
|
|
assertEqual("bar", entry[4].data._key);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test actions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionMultiCollectionReplace : function () {
|
|
var c1 = db._create(cn);
|
|
var c2 = db._create(cn2);
|
|
|
|
c1.insert({ _key: "foo", value: 1 });
|
|
c2.insert({ _key: "bar", value: "A" });
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
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);
|
|
|
|
c1.update("foo", { value2: 2 });
|
|
c1.insert({ _key: "foo2", value2: 3 });
|
|
|
|
c2.update("bar", { value2: "B" });
|
|
c2.insert({ _key: "bar2", value2: "C" });
|
|
},
|
|
params: {
|
|
cn: cn,
|
|
cn2: cn2
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]);
|
|
assertEqual(6, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2300, entry[2].type);
|
|
assertEqual(2300, entry[3].type);
|
|
assertEqual(2300, entry[4].type);
|
|
assertEqual(2201, entry[5].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(entry[2].tid, entry[3].tid);
|
|
assertEqual(entry[3].tid, entry[4].tid);
|
|
assertEqual(entry[4].tid, entry[5].tid);
|
|
|
|
assertEqual("UnitTestsReplication", entry[1].cname);
|
|
assertEqual("foo", entry[1].data._key);
|
|
assertEqual(1, entry[1].data.value);
|
|
assertEqual(2, entry[1].data.value2);
|
|
|
|
assertEqual("UnitTestsReplication", entry[2].cname);
|
|
assertEqual("foo2", entry[2].data._key);
|
|
assertEqual(3, entry[2].data.value2);
|
|
assertFalse(entry[2].data.hasOwnProperty("value"));
|
|
|
|
assertEqual("UnitTestsReplication2", entry[3].cname);
|
|
assertEqual("bar", entry[3].data._key);
|
|
assertEqual("A", entry[3].data.value);
|
|
assertEqual("B", entry[3].data.value2);
|
|
|
|
assertEqual("UnitTestsReplication2", entry[4].cname);
|
|
assertEqual("bar2", entry[4].data._key);
|
|
assertEqual("C", entry[4].data.value2);
|
|
assertFalse(entry[4].data.hasOwnProperty("value"));
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test collection exclusion
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testLoggerTransactionExcluded : function () {
|
|
var c = db._create(cn);
|
|
|
|
var tick = getLastLogTick();
|
|
|
|
db._executeTransaction({
|
|
collections: {
|
|
write: [ cn, "_users" ]
|
|
},
|
|
action: function (params) {
|
|
var c = require("internal").db._collection(params.cn);
|
|
var users = require("internal").db._collection("_users");
|
|
|
|
c.save({ "test" : 2, "_key": "12345" });
|
|
users.save({ "_key": "unittests1", "foo": false });
|
|
users.remove("unittests1");
|
|
},
|
|
params: {
|
|
cn: cn
|
|
}
|
|
});
|
|
|
|
var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300, 2302 ]);
|
|
assertEqual(5, entry.length);
|
|
|
|
assertEqual(2200, entry[0].type);
|
|
assertEqual(2300, entry[1].type);
|
|
assertEqual(2300, entry[2].type);
|
|
assertEqual(2302, entry[3].type);
|
|
assertEqual(2201, entry[4].type);
|
|
|
|
assertEqual(entry[0].tid, entry[1].tid);
|
|
assertEqual(entry[1].tid, entry[2].tid);
|
|
assertEqual(c._id, entry[1].cid);
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function ReplicationApplierSuite () {
|
|
'use strict';
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief set up
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
setUp : function () {
|
|
replication.applier.stop();
|
|
replication.applier.forget();
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tear down
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
tearDown : function () {
|
|
replication.applier.stop();
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief start applier w/o configuration
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStartApplierNoConfig : function () {
|
|
var state = replication.applier.state();
|
|
|
|
assertFalse(state.state.running);
|
|
|
|
try {
|
|
// start
|
|
replication.applier.start();
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief start applier with configuration
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStartApplierInvalidEndpoint1 : function () {
|
|
var state = replication.applier.state();
|
|
|
|
assertFalse(state.state.running);
|
|
|
|
// configure && start
|
|
replication.applier.properties({
|
|
endpoint: "tcp://127.0.0.1:0", // should not exist
|
|
connectTimeout: 2,
|
|
maxConnectRetries: 0,
|
|
connectionRetryWaitTime: 1
|
|
});
|
|
|
|
replication.applier.start();
|
|
state = replication.applier.state();
|
|
assertEqual(errors.ERROR_NO_ERROR.code, state.state.lastError.errorNum);
|
|
assertTrue(state.state.running);
|
|
|
|
var i = 0, max = 30;
|
|
while (i++ < max) {
|
|
internal.wait(1);
|
|
|
|
state = replication.applier.state();
|
|
if (state.state.running) {
|
|
continue;
|
|
}
|
|
|
|
assertFalse(state.state.running);
|
|
assertTrue(state.state.totalFailedConnects > 0);
|
|
assertTrue(state.state.progress.failedConnects > 0);
|
|
assertTrue(errors.ERROR_REPLICATION_NO_RESPONSE.code, state.state.lastError.errorNum);
|
|
break;
|
|
}
|
|
|
|
if (i >= max) {
|
|
fail();
|
|
}
|
|
|
|
// call start again
|
|
replication.applier.start();
|
|
|
|
state = replication.applier.state();
|
|
assertTrue(state.state.running);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief start applier with configuration
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStartApplierInvalidEndpoint2 : function () {
|
|
var state = replication.applier.state();
|
|
|
|
assertFalse(state.state.running);
|
|
// configure && start
|
|
replication.applier.properties({
|
|
endpoint: "tcp://127.0.0.1:0", // should not exist
|
|
connectTimeout: 2,
|
|
maxConnectRetries: 0,
|
|
connectionRetryWaitTime: 1
|
|
});
|
|
|
|
replication.applier.start();
|
|
state = replication.applier.state();
|
|
assertTrue(state.state.running);
|
|
|
|
var i = 0, max = 30;
|
|
while (i++ < max) {
|
|
internal.wait(1);
|
|
|
|
state = replication.applier.state();
|
|
if (state.state.running) {
|
|
continue;
|
|
}
|
|
|
|
assertFalse(state.state.running);
|
|
assertTrue(state.state.totalFailedConnects > 0);
|
|
assertTrue(state.state.progress.failedConnects > 0);
|
|
assertTrue(state.state.lastError.errorNum === errors.ERROR_REPLICATION_INVALID_RESPONSE.code ||
|
|
state.state.lastError.errorNum === errors.ERROR_REPLICATION_MASTER_ERROR.code ||
|
|
state.state.lastError.errorNum === errors.ERROR_REPLICATION_NO_RESPONSE.code);
|
|
break;
|
|
}
|
|
|
|
if (i >= max) {
|
|
fail();
|
|
}
|
|
|
|
// call start again
|
|
replication.applier.start();
|
|
|
|
state = replication.applier.state();
|
|
assertTrue(state.state.running);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief stop applier
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStopApplier : function () {
|
|
var state = replication.applier.state();
|
|
|
|
assertFalse(state.state.running);
|
|
|
|
// configure && start
|
|
replication.applier.properties({
|
|
endpoint: "tcp://9.9.9.9:9999", // should not exist
|
|
connectTimeout: 2,
|
|
maxConnectRetries: 0,
|
|
connectionRetryWaitTime: 1
|
|
});
|
|
|
|
replication.applier.start();
|
|
state = replication.applier.state();
|
|
assertEqual(errors.ERROR_NO_ERROR.code, state.state.lastError.errorNum);
|
|
assertTrue(state.state.running);
|
|
|
|
// stop
|
|
replication.applier.stop();
|
|
|
|
state = replication.applier.state();
|
|
assertFalse(state.state.running);
|
|
|
|
// stop again
|
|
replication.applier.stop();
|
|
|
|
state = replication.applier.state();
|
|
assertFalse(state.state.running);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief properties
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testApplierProperties : function () {
|
|
var properties = replication.applier.properties();
|
|
|
|
assertEqual(600, properties.requestTimeout);
|
|
assertEqual(10, properties.connectTimeout);
|
|
assertEqual(100, properties.maxConnectRetries);
|
|
assertEqual(0, properties.chunkSize);
|
|
assertFalse(properties.autoStart);
|
|
assertTrue(properties.adaptivePolling);
|
|
assertUndefined(properties.endpoint);
|
|
assertTrue(properties.includeSystem);
|
|
assertEqual("", properties.restrictType);
|
|
assertEqual([ ], properties.restrictCollections);
|
|
assertEqual(15, properties.connectionRetryWaitTime);
|
|
assertEqual(1, properties.idleMinWaitTime);
|
|
assertEqual(2.5, properties.idleMaxWaitTime);
|
|
assertFalse(properties.autoResync);
|
|
assertEqual(2, properties.autoResyncRetries);
|
|
|
|
try {
|
|
replication.applier.properties({ });
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION.code, err.errorNum);
|
|
}
|
|
|
|
replication.applier.properties({
|
|
endpoint: "tcp://9.9.9.9:9999"
|
|
});
|
|
|
|
properties = replication.applier.properties();
|
|
assertEqual(properties.endpoint, "tcp://9.9.9.9:9999");
|
|
assertEqual(600, properties.requestTimeout);
|
|
assertEqual(10, properties.connectTimeout);
|
|
assertEqual(100, properties.maxConnectRetries);
|
|
assertEqual(0, properties.chunkSize);
|
|
assertFalse(properties.autoStart);
|
|
assertTrue(properties.adaptivePolling);
|
|
assertEqual(15, properties.connectionRetryWaitTime);
|
|
assertEqual(1, properties.idleMinWaitTime);
|
|
assertEqual(2.5, properties.idleMaxWaitTime);
|
|
assertFalse(properties.autoResync);
|
|
assertEqual(2, properties.autoResyncRetries);
|
|
|
|
replication.applier.properties({
|
|
endpoint: "tcp://9.9.9.9:9998",
|
|
autoStart: true,
|
|
adaptivePolling: false,
|
|
requestTimeout: 5,
|
|
connectTimeout: 9,
|
|
maxConnectRetries: 4,
|
|
chunkSize: 65536,
|
|
includeSystem: false,
|
|
restrictType: "include",
|
|
restrictCollections: [ "_users" ],
|
|
connectionRetryWaitTime: 60.2,
|
|
idleMinWaitTime: 0.1,
|
|
idleMaxWaitTime: 42.44,
|
|
autoResync: true,
|
|
autoResyncRetries: 13
|
|
});
|
|
|
|
properties = replication.applier.properties();
|
|
assertEqual(properties.endpoint, "tcp://9.9.9.9:9998");
|
|
assertEqual(5, properties.requestTimeout);
|
|
assertEqual(9, properties.connectTimeout);
|
|
assertEqual(4, properties.maxConnectRetries);
|
|
assertEqual(65536, properties.chunkSize);
|
|
assertTrue(properties.autoStart);
|
|
assertFalse(properties.adaptivePolling);
|
|
assertFalse(properties.includeSystem);
|
|
assertEqual("include", properties.restrictType);
|
|
assertEqual([ "_users" ], properties.restrictCollections);
|
|
assertEqual(60.2, properties.connectionRetryWaitTime);
|
|
assertEqual(0.1, properties.idleMinWaitTime);
|
|
assertEqual(42.44, properties.idleMaxWaitTime);
|
|
assertTrue(properties.autoResync);
|
|
assertEqual(13, properties.autoResyncRetries);
|
|
|
|
replication.applier.properties({
|
|
endpoint: "tcp://9.9.9.9:9998",
|
|
autoStart: false,
|
|
maxConnectRetries: 10,
|
|
chunkSize: 128 * 1024,
|
|
includeSystem: true,
|
|
restrictType: "exclude",
|
|
restrictCollections: [ "foo", "bar", "baz" ],
|
|
idleMinWaitTime: 7,
|
|
autoResync: false,
|
|
autoResyncRetries: 22
|
|
});
|
|
|
|
properties = replication.applier.properties();
|
|
assertEqual(properties.endpoint, "tcp://9.9.9.9:9998");
|
|
assertEqual(5, properties.requestTimeout);
|
|
assertEqual(9, properties.connectTimeout);
|
|
assertEqual(10, properties.maxConnectRetries);
|
|
assertEqual(128 * 1024, properties.chunkSize);
|
|
assertFalse(properties.autoStart);
|
|
assertFalse(properties.adaptivePolling);
|
|
assertTrue(properties.includeSystem);
|
|
assertEqual("exclude", properties.restrictType);
|
|
assertEqual([ "bar", "baz", "foo" ], properties.restrictCollections.sort());
|
|
assertEqual(60.2, properties.connectionRetryWaitTime);
|
|
assertEqual(7, properties.idleMinWaitTime);
|
|
assertEqual(42.44, properties.idleMaxWaitTime);
|
|
assertFalse(properties.autoResync);
|
|
assertEqual(22, properties.autoResyncRetries);
|
|
|
|
replication.applier.properties({
|
|
restrictType: "",
|
|
restrictCollections: [ ],
|
|
idleMaxWaitTime: 33,
|
|
autoResyncRetries: 0
|
|
});
|
|
|
|
properties = replication.applier.properties();
|
|
assertEqual("", properties.restrictType);
|
|
assertEqual([ ], properties.restrictCollections);
|
|
assertEqual(60.2, properties.connectionRetryWaitTime);
|
|
assertEqual(7, properties.idleMinWaitTime);
|
|
assertEqual(33, properties.idleMaxWaitTime);
|
|
assertEqual(0, properties.autoResyncRetries);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief start property change while running
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testApplierPropertiesChange : function () {
|
|
replication.applier.properties({
|
|
endpoint: "tcp://9.9.9.9:9999",
|
|
connectTimeout: 2,
|
|
maxConnectRetries: 0,
|
|
connectionRetryWaitTime: 1
|
|
});
|
|
replication.applier.start();
|
|
|
|
var state = replication.applier.state();
|
|
assertTrue(state.state.running);
|
|
|
|
try {
|
|
replication.applier.properties({ endpoint: "tcp://9.9.9.9:9998" });
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_RUNNING.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief applier state
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStateApplier : function () {
|
|
var state = replication.applier.state();
|
|
|
|
assertFalse(state.state.running);
|
|
assertMatch(/^\d+-\d+-\d+T\d+:\d+:\d+Z$/, state.state.time);
|
|
|
|
assertEqual(state.server.version, db._version());
|
|
assertNotEqual("", state.server.serverId);
|
|
assertMatch(/^\d+$/, state.server.serverId);
|
|
|
|
assertUndefined(state.endpoint);
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function ReplicationSyncSuite () {
|
|
'use strict';
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief set up
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
setUp : function () {
|
|
replication.applier.stop();
|
|
replication.applier.forget();
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tear down
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
tearDown : function () {
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief server id
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testServerId : function () {
|
|
var result = replication.serverId();
|
|
|
|
assertTrue(typeof result === 'string');
|
|
assertMatch(/^\d+$/, result);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief no endpoint
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncNoEndpoint : function () {
|
|
try {
|
|
replication.sync();
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_BAD_PARAMETER.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief invalid endpoint
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncNoEndpoint2 : function () {
|
|
try {
|
|
replication.sync({
|
|
endpoint: "tcp://9.9.9.9:9999",
|
|
connectTimeout: 2,
|
|
maxConnectRetries: 0,
|
|
connectionRetryWaitTime: 1,
|
|
verbose: true
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_NO_RESPONSE.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief invalid response
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncInvalidResponse : function () {
|
|
try {
|
|
replication.sync({
|
|
endpoint: "tcp://www.arangodb.com:80",
|
|
connectTimeout: 2,
|
|
maxConnectRetries: 0,
|
|
connectionRetryWaitTime: 1
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertTrue(err.errorNum === errors.ERROR_REPLICATION_INVALID_RESPONSE.code ||
|
|
err.errorNum === errors.ERROR_REPLICATION_MASTER_ERROR.code ||
|
|
err.errorNum === errors.ERROR_REPLICATION_NO_RESPONSE.code);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief invalid restrictType
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncRestrict1 : function () {
|
|
try {
|
|
replication.sync({
|
|
endpoint: "tcp://9.9.9.9:9999",
|
|
restrictType: "foo"
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief invalid restrictCollections
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncRestrict2 : function () {
|
|
try {
|
|
replication.sync({
|
|
endpoint: "tcp://9.9.9.9:9999",
|
|
restrictType: "exclude"
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief invalid restrictCollections
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncRestrict3 : function () {
|
|
try {
|
|
replication.sync({
|
|
endpoint: "tcp://9.9.9.9:9999",
|
|
restrictType: "include"
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief invalid restrictCollections
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncRestrict4 : function () {
|
|
try {
|
|
replication.sync({
|
|
endpoint: "tcp://9.9.9.9:9999",
|
|
restrictCollections: [ "foo" ]
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION.code, err.errorNum);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief invalid restrictCollections
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSyncRestrict5 : function () {
|
|
try {
|
|
replication.sync({
|
|
endpoint: "tcp://9.9.9.9:9999",
|
|
restrictType: "include",
|
|
restrictCollections: "foo"
|
|
});
|
|
fail();
|
|
}
|
|
catch (err) {
|
|
assertEqual(errors.ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION.code, err.errorNum);
|
|
}
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief executes the test suites
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
jsunity.run(ReplicationLoggerSuite);
|
|
jsunity.run(ReplicationApplierSuite);
|
|
jsunity.run(ReplicationSyncSuite);
|
|
|
|
return jsunity.done();
|
|
|