0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-28100 moved common test code for all 3 tags.js tests into a test library under replsets/libs/

This commit is contained in:
Benety Goh 2017-05-15 11:39:27 -04:00
parent 6ad4b7d448
commit bcf3d946e6
4 changed files with 297 additions and 719 deletions

View File

@ -1,8 +1,7 @@
(function() {
'use strict';
load("jstests/replsets/rslib.js");
load("jstests/replsets/libs/tags.js");
var oldVersion = "last-stable";
var newVersion = "latest";
@ -13,248 +12,5 @@
{binVersion: oldVersion},
{binVersion: newVersion}
];
var host = getHostName();
var name = 'tags';
var replTest = new ReplSetTest({name: name, nodes: {n0: nodes[0]}, useBridge: true});
replTest.startSet();
replTest.initiate();
for (let i = 1; i < nodes.length; ++i) {
replTest.add(nodes[i]);
}
const conns = replTest.nodes;
nodes = replTest.nodeList();
var port = replTest.ports;
var nextVersion = replTest.getReplSetConfigFromNode().version + 1;
const replSetConfig = {
_id: name,
members: [
{
_id: 0,
host: nodes[0],
tags: {
server: '0',
dc: 'ny',
ny: '1',
rack: 'ny.rk1',
},
},
{
_id: 1,
host: nodes[1],
priority: 2,
tags: {
server: '1',
dc: 'ny',
ny: '2',
rack: 'ny.rk1',
},
},
{
_id: 2,
host: nodes[2],
priority: 3,
tags: {
server: '2',
dc: 'ny',
ny: '3',
rack: 'ny.rk2', 2: 'this',
},
},
{
_id: 3,
host: nodes[3],
tags: {
server: '3',
dc: 'sf',
sf: '1',
rack: 'sf.rk1',
},
},
{
_id: 4,
host: nodes[4],
tags: {
server: '4',
dc: 'sf',
sf: '2',
rack: 'sf.rk2',
},
},
],
settings: {
getLastErrorModes: {
'2 dc and 3 server': {
dc: 2,
server: 3,
},
'1 and 2': {
2: 1,
server: 1,
},
'2': {
2: 1,
},
'3 and 4': {
sf: 2,
},
'3 or 4': {
sf: 1,
},
},
},
version: nextVersion,
};
reconfig(replTest, replSetConfig);
replTest.waitForState(replTest.nodes[2], ReplSetTest.State.PRIMARY, 60 * 1000);
replTest.awaitReplication();
// Create collection to guard against timeouts due to file allocation.
assert.commandWorked(replTest.getPrimary().getDB('foo').createCollection('bar'));
replTest.awaitReplication();
var ensurePrimary = function(nodeId, expectedWritableNodes) {
jsTestLog('Node ' + nodeId + ' (' + replTest.nodes[nodeId].host + ') should be primary.');
replTest.waitForState(replTest.nodes[nodeId], ReplSetTest.State.PRIMARY, 60 * 1000);
primary = replTest.getPrimary();
primary.forceWriteMode('commands');
var writeConcern = {writeConcern: {w: expectedWritableNodes, wtimeout: 30 * 1000}};
assert.writeOK(primary.getDB('foo').bar.insert({x: 100}, writeConcern));
return primary;
};
// 2 should eventually stage a priority takeover from the primary.
var primary = ensurePrimary(2, 3);
jsTestLog('primary is now 2');
var config = assert.commandWorked(primary.adminCommand({replSetGetConfig: 1})).config;
jsTestLog('test configuration = ' + tojson(config));
jsTestLog('Setting up partitions: [0-1-2] [3] [4]');
conns[0].disconnect(conns[3]);
conns[0].disconnect(conns[4]);
conns[1].disconnect(conns[3]);
conns[1].disconnect(conns[4]);
conns[2].disconnect(conns[3]);
conns[2].disconnect(conns[4]);
conns[3].disconnect(conns[4]);
jsTestLog('Done setting up partitions');
jsTestLog('partitions: nodes with each set of brackets [N1, N2, N3] form a complete network.');
jsTestLog('partitions: [0-1-2] [3] [4] (only nodes 0 and 1 can replicate from primary node 2');
var doc = {x: 1};
// This timeout should be shorter in duration than the server parameter maxSyncSourceLagSecs.
// Some writes are expected to block for this 'timeout' duration before failing.
// Depending on the order of heartbeats (containing last committed op time) received
// by a node, it might hang up on its sync source. This may cause some of the write concern
// tests to fail.
var timeout = 20 * 1000;
jsTestLog('test1');
primary = ensurePrimary(2, 3);
jsTestLog('Non-existent write concern should be rejected.');
options = {writeConcern: {w: 'blahblah', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
var result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert.eq(ErrorCodes.UnknownReplWriteConcern,
result.getWriteConcernError().code,
tojson(result.getWriteConcernError()));
jsTestLog('Write concern "3 or 4" should fail - 3 and 4 are not connected to the primary.');
var options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = primary.getDB('foo').bar.insert(doc, options);
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
conns[1].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3] ' +
'(all nodes besides node 3 can replicate from primary node 2)');
primary = ensurePrimary(2, 4);
jsTestLog('Write concern "3 or 4" should work - 4 is now connected to the primary ' +
primary.host + ' via node 1 ' + replTest.nodes[1].host);
options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "3 and 4" should fail - 3 is not connected to the primary.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout, tojson(result.getWriteConcernError()));
conns[3].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3-4] ' +
'(all secondaries can replicate from primary node 2)');
primary = ensurePrimary(2, 5);
jsTestLog('31004 should sync from 31001 (31026)');
jsTestLog('31003 should sync from 31004 (31024)');
jsTestLog('Write concern "3 and 4" should work - ' +
'nodes 3 and 4 are connected to primary via node 1.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" - writes to primary only.');
options = {writeConcern: {w: '2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "1 and 2"');
options = {writeConcern: {w: '1 and 2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2 dc and 3 server"');
primary = ensurePrimary(2, 5);
options = {writeConcern: {w: '2 dc and 3 server', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Bringing down current primary node 2 ' + primary.host +
' to allow next higher priority node 1 ' + replTest.nodes[1].host +
' to become primary.');
// Is this necessary since 3 will be connected to the new primary via node 4?
conns[1].reconnect(conns[3]);
conns[2].disconnect(conns[0]);
conns[2].disconnect(conns[1]);
// Is this necessary when we partition node 2 off from the rest of the nodes?
replTest.stop(2);
jsTestLog('partitions: [0-1] [2] [1-3-4] ' +
'(all secondaries except down node 2 can replicate from new primary node 1)');
// Node 1 with slightly higher priority will take over.
jsTestLog('1 must become primary here because otherwise the other members will take too ' +
'long timing out their old sync threads');
primary = ensurePrimary(1, 4);
jsTestLog('Write concern "3 and 4" should still work with new primary node 1 ' + primary.host);
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" should fail because node 2 ' + replTest.nodes[2].host +
' is down.');
options = {writeConcern: {w: '2', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
replTest.stopSet();
jsTestLog('tags.js SUCCESS');
new TagsTest({nodes: nodes, forceWriteMode: 'commands'}).run();
}());

View File

@ -1,247 +1,16 @@
(function() {
'use strict';
load("jstests/replsets/libs/tags.js");
var oldVersion = "last-stable";
var newVersion = "latest";
var nodes = {
n1: {binVersion: oldVersion},
n2: {binVersion: newVersion},
n3: {binVersion: oldVersion},
n4: {binVersion: newVersion},
n5: {binVersion: oldVersion}
};
var host = getHostName();
var name = 'tags';
var replTest = new ReplSetTest({name: name, nodes: nodes, useBridge: true});
var nodes = replTest.nodeList();
var conns = replTest.startSet();
var port = replTest.ports;
replTest.initiate({
_id: name,
members: [
{
_id: 0,
host: nodes[0],
tags: {
server: '0',
dc: 'ny',
ny: '1',
rack: 'ny.rk1',
},
},
{
_id: 1,
host: nodes[1],
priority: 2,
tags: {
server: '1',
dc: 'ny',
ny: '2',
rack: 'ny.rk1',
},
},
{
_id: 2,
host: nodes[2],
priority: 3,
tags: {
server: '2',
dc: 'ny',
ny: '3',
rack: 'ny.rk2', 2: 'this',
},
},
{
_id: 3,
host: nodes[3],
tags: {
server: '3',
dc: 'sf',
sf: '1',
rack: 'sf.rk1',
},
},
{
_id: 4,
host: nodes[4],
tags: {
server: '4',
dc: 'sf',
sf: '2',
rack: 'sf.rk2',
},
},
],
settings: {
getLastErrorModes: {
'2 dc and 3 server': {
dc: 2,
server: 3,
},
'1 and 2': {
2: 1,
server: 1,
},
'2': {
2: 1,
},
'3 and 4': {
sf: 2,
},
'3 or 4': {
sf: 1,
},
},
},
});
replTest.waitForState(replTest.nodes[2], ReplSetTest.State.PRIMARY, 60 * 1000);
replTest.awaitReplication();
// Create collection to guard against timeouts due to file allocation.
assert.commandWorked(replTest.getPrimary().getDB('foo').createCollection('bar'));
replTest.awaitReplication();
var ensurePrimary = function(nodeId, expectedWritableNodes) {
jsTestLog('Node ' + nodeId + ' (' + replTest.nodes[nodeId].host + ') should be primary.');
replTest.waitForState(replTest.nodes[nodeId], ReplSetTest.State.PRIMARY, 60 * 1000);
primary = replTest.getPrimary();
primary.forceWriteMode('commands');
var writeConcern = {writeConcern: {w: expectedWritableNodes, wtimeout: 30 * 1000}};
assert.writeOK(primary.getDB('foo').bar.insert({x: 100}, writeConcern));
return primary;
};
// 2 should eventually stage a priority takeover from the primary.
var primary = ensurePrimary(2, 3);
jsTestLog('primary is now 2');
var config = assert.commandWorked(primary.adminCommand({replSetGetConfig: 1})).config;
jsTestLog('test configuration = ' + tojson(config));
jsTestLog('Setting up partitions: [0-1-2] [3] [4]');
conns[0].disconnect(conns[3]);
conns[0].disconnect(conns[4]);
conns[1].disconnect(conns[3]);
conns[1].disconnect(conns[4]);
conns[2].disconnect(conns[3]);
conns[2].disconnect(conns[4]);
conns[3].disconnect(conns[4]);
jsTestLog('Done setting up partitions');
jsTestLog('partitions: nodes with each set of brackets [N1, N2, N3] form a complete network.');
jsTestLog('partitions: [0-1-2] [3] [4] (only nodes 0 and 1 can replicate from primary node 2');
var doc = {x: 1};
// This timeout should be shorter in duration than the server parameter maxSyncSourceLagSecs.
// Some writes are expected to block for this 'timeout' duration before failing.
// Depending on the order of heartbeats (containing last committed op time) received
// by a node, it might hang up on its sync source. This may cause some of the write concern
// tests to fail.
var timeout = 20 * 1000;
jsTestLog('test1');
primary = ensurePrimary(2, 3);
jsTestLog('Non-existent write concern should be rejected.');
options = {writeConcern: {w: 'blahblah', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
var result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert.eq(ErrorCodes.UnknownReplWriteConcern,
result.getWriteConcernError().code,
tojson(result.getWriteConcernError()));
jsTestLog('Write concern "3 or 4" should fail - 3 and 4 are not connected to the primary.');
var options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = primary.getDB('foo').bar.insert(doc, options);
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
conns[1].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3] ' +
'(all nodes besides node 3 can replicate from primary node 2)');
primary = ensurePrimary(2, 4);
jsTestLog('Write concern "3 or 4" should work - 4 is now connected to the primary ' +
primary.host + ' via node 1 ' + replTest.nodes[1].host);
options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "3 and 4" should fail - 3 is not connected to the primary.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout, tojson(result.getWriteConcernError()));
conns[3].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3-4] ' +
'(all secondaries can replicate from primary node 2)');
primary = ensurePrimary(2, 5);
jsTestLog('31004 should sync from 31001 (31026)');
jsTestLog('31003 should sync from 31004 (31024)');
jsTestLog('Write concern "3 and 4" should work - ' +
'nodes 3 and 4 are connected to primary via node 1.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" - writes to primary only.');
options = {writeConcern: {w: '2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "1 and 2"');
options = {writeConcern: {w: '1 and 2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2 dc and 3 server"');
primary = ensurePrimary(2, 5);
options = {writeConcern: {w: '2 dc and 3 server', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Bringing down current primary node 2 ' + primary.host +
' to allow next higher priority node 1 ' + replTest.nodes[1].host +
' to become primary.');
// Is this necessary since 3 will be connected to the new primary via node 4?
conns[1].reconnect(conns[3]);
conns[2].disconnect(conns[0]);
conns[2].disconnect(conns[1]);
// Is this necessary when we partition node 2 off from the rest of the nodes?
replTest.stop(2);
jsTestLog('partitions: [0-1] [2] [1-3-4] ' +
'(all secondaries except down node 2 can replicate from new primary node 1)');
// Node 1 with slightly higher priority will take over.
jsTestLog('1 must become primary here because otherwise the other members will take too ' +
'long timing out their old sync threads');
primary = ensurePrimary(1, 4);
jsTestLog('Write concern "3 and 4" should still work with new primary node 1 ' + primary.host);
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" should fail because node 2 ' + replTest.nodes[2].host +
' is down.');
options = {writeConcern: {w: '2', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
replTest.stopSet();
jsTestLog('tags.js SUCCESS');
let nodes = [
{binVersion: oldVersion},
{binVersion: newVersion},
{binVersion: oldVersion},
{binVersion: newVersion},
{binVersion: oldVersion}
];
new TagsTest({nodes: nodes, forceWriteMode: 'commands'}).run();
}());

View File

@ -0,0 +1,282 @@
/**
* Sets up a test for replica set tags sets.
*
* https://docs.mongodb.com/v3.0/tutorial/configure-replica-set-tag-sets/
*/
var TagsTest = function(options) {
'use strict';
if (!(this instanceof TagsTest)) {
return new TagsTest(options);
}
// Capture the 'this' reference
var self = this;
self.options = options;
/**
* Runs the test.
*/
this.run = function() {
var options = this.options;
load('jstests/replsets/rslib.js');
let nodes = options.nodes;
var host = getHostName();
var name = 'tags';
var replTest = new ReplSetTest({name: name, nodes: {n0: nodes[0]}, useBridge: true});
replTest.startSet();
replTest.initiate();
// If provided in 'options', we set the featureCompatibilityVersion. We do this prior to
// adding any other members to the replica set. This effectively allows us to emulate
// upgrading some of our nodes to the latest version while performing write operations under
// different network partition scenarios.
if (options.setFeatureCompatibilityVersion) {
assert.commandWorked(replTest.getPrimary().adminCommand(
{setFeatureCompatibilityVersion: options.setFeatureCompatibilityVersion}));
}
for (let i = 1; i < nodes.length; ++i) {
replTest.add(nodes[i]);
}
const conns = replTest.nodes;
nodes = replTest.nodeList();
var port = replTest.ports;
var nextVersion = replTest.getReplSetConfigFromNode().version + 1;
const replSetConfig = {
_id: name,
members: [
{
_id: 0,
host: nodes[0],
tags: {
server: '0',
dc: 'ny',
ny: '1',
rack: 'ny.rk1',
},
},
{
_id: 1,
host: nodes[1],
priority: 2,
tags: {
server: '1',
dc: 'ny',
ny: '2',
rack: 'ny.rk1',
},
},
{
_id: 2,
host: nodes[2],
priority: 3,
tags: {
server: '2',
dc: 'ny',
ny: '3',
rack: 'ny.rk2', 2: 'this',
},
},
{
_id: 3,
host: nodes[3],
tags: {
server: '3',
dc: 'sf',
sf: '1',
rack: 'sf.rk1',
},
},
{
_id: 4,
host: nodes[4],
tags: {
server: '4',
dc: 'sf',
sf: '2',
rack: 'sf.rk2',
},
},
],
settings: {
getLastErrorModes: {
'2 dc and 3 server': {
dc: 2,
server: 3,
},
'1 and 2': {
2: 1,
server: 1,
},
'2': {
2: 1,
},
'3 and 4': {
sf: 2,
},
'3 or 4': {
sf: 1,
},
},
},
version: nextVersion,
};
reconfig(replTest, replSetConfig);
replTest.waitForState(replTest.nodes[2], ReplSetTest.State.PRIMARY);
replTest.awaitReplication();
// Create collection to guard against timeouts due to file allocation.
assert.commandWorked(replTest.getPrimary().getDB('foo').createCollection('bar'));
replTest.awaitReplication();
var ensurePrimary = function(nodeId, expectedWritableNodes) {
jsTestLog('Node ' + nodeId + ' (' + replTest.nodes[nodeId].host +
') should be primary.');
replTest.waitForState(replTest.nodes[nodeId], ReplSetTest.State.PRIMARY, 60 * 1000);
primary = replTest.getPrimary();
if (options.forceWriteMode) {
primary.forceWriteMode(options.forceWriteMode);
}
var writeConcern = {writeConcern: {w: expectedWritableNodes, wtimeout: 30 * 1000}};
assert.writeOK(primary.getDB('foo').bar.insert({x: 100}, writeConcern));
return primary;
};
// 2 should eventually stage a priority takeover from the primary.
var primary = ensurePrimary(2, 3);
jsTestLog('primary is now 2');
var config = assert.commandWorked(primary.adminCommand({replSetGetConfig: 1})).config;
jsTestLog('test configuration = ' + tojson(config));
jsTestLog('Setting up partitions: [0-1-2] [3] [4]');
conns[0].disconnect(conns[3]);
conns[0].disconnect(conns[4]);
conns[1].disconnect(conns[3]);
conns[1].disconnect(conns[4]);
conns[2].disconnect(conns[3]);
conns[2].disconnect(conns[4]);
conns[3].disconnect(conns[4]);
jsTestLog('Done setting up partitions');
jsTestLog(
'partitions: nodes with each set of brackets [N1, N2, N3] form a complete network.');
jsTestLog(
'partitions: [0-1-2] [3] [4] (only nodes 0 and 1 can replicate from primary node 2');
var doc = {x: 1};
// This timeout should be shorter in duration than the server parameter
// maxSyncSourceLagSecs.
// Some writes are expected to block for this 'timeout' duration before failing.
// Depending on the order of heartbeats (containing last committed op time) received
// by a node, it might hang up on its sync source. This may cause some of the write concern
// tests to fail.
var timeout = 20 * 1000;
jsTestLog('test1');
primary = ensurePrimary(2, 3);
jsTestLog('Non-existent write concern should be rejected.');
options = {writeConcern: {w: 'blahblah', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
var result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert.eq(ErrorCodes.UnknownReplWriteConcern,
result.getWriteConcernError().code,
tojson(result.getWriteConcernError()));
jsTestLog('Write concern "3 or 4" should fail - 3 and 4 are not connected to the primary.');
var options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = primary.getDB('foo').bar.insert(doc, options);
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
conns[1].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3] ' +
'(all nodes besides node 3 can replicate from primary node 2)');
primary = ensurePrimary(2, 4);
jsTestLog('Write concern "3 or 4" should work - 4 is now connected to the primary ' +
primary.host + ' via node 1 ' + replTest.nodes[1].host);
options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "3 and 4" should fail - 3 is not connected to the primary.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout,
tojson(result.getWriteConcernError()));
conns[3].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3-4] ' +
'(all secondaries can replicate from primary node 2)');
primary = ensurePrimary(2, 5);
jsTestLog('Write concern "3 and 4" should work - ' +
'nodes 3 and 4 are connected to primary via node 1.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" - writes to primary only.');
options = {writeConcern: {w: '2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "1 and 2"');
options = {writeConcern: {w: '1 and 2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2 dc and 3 server"');
primary = ensurePrimary(2, 5);
options = {writeConcern: {w: '2 dc and 3 server', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Bringing down current primary node 2 ' + primary.host +
' to allow next higher priority node 1 ' + replTest.nodes[1].host +
' to become primary.');
conns[1].reconnect(conns[3]);
conns[2].disconnect(conns[0]);
conns[2].disconnect(conns[1]);
jsTestLog('partitions: [0-1] [2] [1-3-4] ' +
'(all secondaries except down node 2 can replicate from new primary node 1)');
// Node 1 with slightly higher priority will take over.
jsTestLog('1 must become primary here because otherwise the other members will take too ' +
'long timing out their old sync threads');
primary = ensurePrimary(1, 4);
jsTestLog('Write concern "3 and 4" should still work with new primary node 1 ' +
primary.host);
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" should fail because node 2 ' + replTest.nodes[2].host +
' is down.');
options = {writeConcern: {w: '2', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
replTest.stopSet();
};
};

View File

@ -1,237 +1,8 @@
(function() {
'use strict';
var num = 5;
var host = getHostName();
var name = 'tags';
load("jstests/replsets/libs/tags.js");
var replTest = new ReplSetTest({name: name, nodes: num, useBridge: true});
var nodes = replTest.nodeList();
var conns = replTest.startSet();
var port = replTest.ports;
replTest.initiate({
_id: name,
members: [
{
_id: 0,
host: nodes[0],
tags: {
server: '0',
dc: 'ny',
ny: '1',
rack: 'ny.rk1',
},
},
{
_id: 1,
host: nodes[1],
priority: 2,
tags: {
server: '1',
dc: 'ny',
ny: '2',
rack: 'ny.rk1',
},
},
{
_id: 2,
host: nodes[2],
priority: 3,
tags: {
server: '2',
dc: 'ny',
ny: '3',
rack: 'ny.rk2', 2: 'this',
},
},
{
_id: 3,
host: nodes[3],
tags: {
server: '3',
dc: 'sf',
sf: '1',
rack: 'sf.rk1',
},
},
{
_id: 4,
host: nodes[4],
tags: {
server: '4',
dc: 'sf',
sf: '2',
rack: 'sf.rk2',
},
},
],
settings: {
getLastErrorModes: {
'2 dc and 3 server': {
dc: 2,
server: 3,
},
'1 and 2': {
2: 1,
server: 1,
},
'2': {
2: 1,
},
'3 and 4': {
sf: 2,
},
'3 or 4': {
sf: 1,
},
},
},
});
replTest.waitForState(replTest.nodes[2], ReplSetTest.State.PRIMARY);
replTest.awaitReplication();
// Create collection to guard against timeouts due to file allocation.
assert.commandWorked(replTest.getPrimary().getDB('foo').createCollection('bar'));
replTest.awaitReplication();
var ensurePrimary = function(nodeId, expectedWritableNodes) {
jsTestLog('Node ' + nodeId + ' (' + replTest.nodes[nodeId].host + ') should be primary.');
replTest.waitForState(replTest.nodes[nodeId], ReplSetTest.State.PRIMARY, 60 * 1000);
primary = replTest.getPrimary();
var writeConcern = {writeConcern: {w: expectedWritableNodes, wtimeout: 30 * 1000}};
assert.writeOK(primary.getDB('foo').bar.insert({x: 100}, writeConcern));
return primary;
};
// 2 should eventually stage a priority takeover from the primary.
var primary = ensurePrimary(2, 3);
jsTestLog('primary is now 2');
var config = assert.commandWorked(primary.adminCommand({replSetGetConfig: 1})).config;
jsTestLog('test configuration = ' + tojson(config));
jsTestLog('Setting up partitions: [0-1-2] [3] [4]');
conns[0].disconnect(conns[3]);
conns[0].disconnect(conns[4]);
conns[1].disconnect(conns[3]);
conns[1].disconnect(conns[4]);
conns[2].disconnect(conns[3]);
conns[2].disconnect(conns[4]);
conns[3].disconnect(conns[4]);
jsTestLog('Done setting up partitions');
jsTestLog('partitions: nodes with each set of brackets [N1, N2, N3] form a complete network.');
jsTestLog('partitions: [0-1-2] [3] [4] (only nodes 0 and 1 can replicate from primary node 2');
var doc = {x: 1};
// This timeout should be shorter in duration than the server parameter maxSyncSourceLagSecs.
// Some writes are expected to block for this 'timeout' duration before failing.
// Depending on the order of heartbeats (containing last committed op time) received
// by a node, it might hang up on its sync source. This may cause some of the write concern
// tests to fail.
var timeout = 20 * 1000;
jsTestLog('test1');
primary = ensurePrimary(2, 3);
jsTestLog('Non-existent write concern should be rejected.');
options = {writeConcern: {w: 'blahblah', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
var result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert.eq(ErrorCodes.UnknownReplWriteConcern,
result.getWriteConcernError().code,
tojson(result.getWriteConcernError()));
jsTestLog('Write concern "3 or 4" should fail - 3 and 4 are not connected to the primary.');
var options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = primary.getDB('foo').bar.insert(doc, options);
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
conns[1].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3] ' +
'(all nodes besides node 3 can replicate from primary node 2)');
primary = ensurePrimary(2, 4);
jsTestLog('Write concern "3 or 4" should work - 4 is now connected to the primary ' +
primary.host + ' via node 1 ' + replTest.nodes[1].host);
options = {writeConcern: {w: '3 or 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "3 and 4" should fail - 3 is not connected to the primary.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout, tojson(result.getWriteConcernError()));
conns[3].reconnect(conns[4]);
jsTestLog('partitions: [0-1-2] [1-4] [3-4] ' +
'(all secondaries can replicate from primary node 2)');
primary = ensurePrimary(2, 5);
jsTestLog('31004 should sync from 31001 (31026)');
jsTestLog('31003 should sync from 31004 (31024)');
jsTestLog('Write concern "3 and 4" should work - ' +
'nodes 3 and 4 are connected to primary via node 1.');
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" - writes to primary only.');
options = {writeConcern: {w: '2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "1 and 2"');
options = {writeConcern: {w: '1 and 2', wtimeout: 0}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2 dc and 3 server"');
primary = ensurePrimary(2, 5);
options = {writeConcern: {w: '2 dc and 3 server', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Bringing down current primary node 2 ' + primary.host +
' to allow next higher priority node 1 ' + replTest.nodes[1].host +
' to become primary.');
// Is this necessary since 3 will be connected to the new primary via node 4?
conns[1].reconnect(conns[3]);
conns[2].disconnect(conns[0]);
conns[2].disconnect(conns[1]);
// Is this necessary when we partition node 2 off from the rest of the nodes?
replTest.stop(2);
jsTestLog('partitions: [0-1] [2] [1-3-4] ' +
'(all secondaries except down node 2 can replicate from new primary node 1)');
// Node 1 with slightly higher priority will take over.
jsTestLog('1 must become primary here because otherwise the other members will take too ' +
'long timing out their old sync threads');
primary = ensurePrimary(1, 4);
jsTestLog('Write concern "3 and 4" should still work with new primary node 1 ' + primary.host);
options = {writeConcern: {w: '3 and 4', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
assert.writeOK(primary.getDB('foo').bar.insert(doc, options));
jsTestLog('Write concern "2" should fail because node 2 ' + replTest.nodes[2].host +
' is down.');
options = {writeConcern: {w: '2', wtimeout: timeout}};
assert.writeOK(primary.getDB('foo').bar.insert(doc));
result = assert.writeError(primary.getDB('foo').bar.insert(doc, options));
assert.neq(null, result.getWriteConcernError());
assert(result.getWriteConcernError().errInfo.wtimeout);
replTest.stopSet();
jsTestLog('tags.js SUCCESS');
let nodes = [{}, {}, {}, {}, {}];
new TagsTest({nodes: nodes}).run();
}());