summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/noPassthrough/restart_node_with_bridge.js57
-rw-r--r--jstests/replsets/libs/rollback_test.js2
-rw-r--r--jstests/replsets/libs/rollback_test_deluxe.js2
-rw-r--r--src/mongo/shell/bridge.js2
-rw-r--r--src/mongo/shell/replsettest.js24
5 files changed, 71 insertions, 16 deletions
diff --git a/jstests/noPassthrough/restart_node_with_bridge.js b/jstests/noPassthrough/restart_node_with_bridge.js
index 1774ce50167..004b595a208 100644
--- a/jstests/noPassthrough/restart_node_with_bridge.js
+++ b/jstests/noPassthrough/restart_node_with_bridge.js
@@ -1,23 +1,64 @@
/**
- * Tests that a node can be successfully restarted when the bridge is enabled.
+ * Tests that a node can be successfully restarted when the bridge is enabled. Also verifies the
+ * bridge configuration is left intact even after the node is restarted.
+ *
* @tags: [requires_persistence, requires_replication]
*/
(function() {
"use strict";
- const name = "restart_node_with_bridge";
- const rst = new ReplSetTest({name: name, nodes: 1, useBridge: true});
+ load("jstests/replsets/rslib.js"); // for reconnect
+
+ const rst = new ReplSetTest({
+ nodes: [{}, {rsConfig: {priority: 0, votes: 0}}],
+ useBridge: true,
+ });
+
rst.startSet();
rst.initiate();
rst.awaitNodesAgreeOnPrimary();
- let primary = rst.getPrimary();
- assert.commandWorked(primary.getDB("test").getCollection(name).insert({_id: 1}));
+ const primary = rst.getPrimary();
+ const secondary = rst.getSecondary();
+
+ const primaryDB = primary.getDB("test");
+ const primaryColl = primaryDB.getCollection("restart_node_with_bridge");
+
+ function assertWriteReplicates() {
+ assert.commandWorked(primaryColl.update(
+ {_id: 0}, {$inc: {counter: 1}}, {upsert: true, writeConcern: {w: 2}}));
+ }
+
+ function assertWriteFailsToReplicate() {
+ assert.commandFailedWithCode(
+ primaryColl.update(
+ {_id: 0}, {$inc: {counter: 1}}, {writeConcern: {w: 2, wtimeout: 1000}}),
+ ErrorCodes.WriteConcernFailed);
+ }
+ // By default, the primary should be connected to the secondary. Replicating a write should
+ // therefore succeed.
+ assertWriteReplicates();
+
+ // We disconnect the primary from the secondary and verify that replicating a write fails.
+ primary.disconnect(secondary);
+ assertWriteFailsToReplicate();
+
+ // We restart the secondary and verify that replicating a write still fails.
+ rst.restart(secondary);
+ assertWriteFailsToReplicate();
+
+ // We restart the primary and verify that replicating a write still fails.
rst.restart(primary);
- rst.awaitNodesAgreeOnPrimary();
- primary = rst.getPrimary();
- assert.eq(primary.getDB("test").getCollection(name).count({_id: 1}), 1);
+ rst.getPrimary();
+ // Note that we specify 'primaryDB' to avoid having reconnect() send a message directly to the
+ // mongod process rather than going through the mongobridge process as well.
+ reconnect(primaryDB);
+ assertWriteFailsToReplicate();
+
+ // We reconnect the primary to the secondary and verify that replicating a write succeeds.
+ primary.reconnect(secondary);
+ assertWriteReplicates();
rst.stopSet();
}());
diff --git a/jstests/replsets/libs/rollback_test.js b/jstests/replsets/libs/rollback_test.js
index 41717a664cd..a7db988e0e7 100644
--- a/jstests/replsets/libs/rollback_test.js
+++ b/jstests/replsets/libs/rollback_test.js
@@ -396,7 +396,7 @@ function RollbackTest(name = "RollbackTest", replSet) {
}
log(`Stopping node ${hostName} with signal ${signal}`);
- rst.stop(nodeId, signal, opts);
+ rst.stop(nodeId, signal, opts, {forRestart: true});
log(`Restarting node ${hostName}`);
rst.start(nodeId, {}, true /* restart */);
diff --git a/jstests/replsets/libs/rollback_test_deluxe.js b/jstests/replsets/libs/rollback_test_deluxe.js
index 0c4cb988dfc..b3b85de152d 100644
--- a/jstests/replsets/libs/rollback_test_deluxe.js
+++ b/jstests/replsets/libs/rollback_test_deluxe.js
@@ -572,7 +572,7 @@ function RollbackTestDeluxe(name = "FiveNodeDoubleRollbackTest", replSet) {
}
log(`Stopping node ${hostName} with signal ${signal}`);
- rst.stop(nodeId, signal, opts);
+ rst.stop(nodeId, signal, opts, {forRestart: true});
log(`Restarting node ${hostName}`);
const restart = true;
diff --git a/src/mongo/shell/bridge.js b/src/mongo/shell/bridge.js
index 28831ba7a76..e50f9f12c86 100644
--- a/src/mongo/shell/bridge.js
+++ b/src/mongo/shell/bridge.js
@@ -113,7 +113,7 @@ function MongoBridge(options) {
* Terminates the mongobridge process.
*/
this.stop = function stop() {
- _stopMongoProgram(this.port);
+ return _stopMongoProgram(this.port);
};
// Throws an error if 'obj' is not a MongoBridge instance.
diff --git a/src/mongo/shell/replsettest.js b/src/mongo/shell/replsettest.js
index 9efa8ac7f2e..06d72bc54f7 100644
--- a/src/mongo/shell/replsettest.js
+++ b/src/mongo/shell/replsettest.js
@@ -2311,7 +2311,9 @@ var ReplSetTest = function(opts) {
print("ReplSetTest " + (restart ? "(Re)" : "") + "Starting....");
- if (_useBridge) {
+ if (_useBridge && (restart === undefined || !restart)) {
+ // We leave the mongobridge process running when the mongod process is restarted so we
+ // don't need to start a new one.
var bridgeOptions = Object.merge(_bridgeOptions, options.bridgeOptions || {});
bridgeOptions = Object.merge(bridgeOptions, {
hostName: this.host,
@@ -2395,7 +2397,7 @@ var ReplSetTest = function(opts) {
signal = undefined;
}
- this.stop(n, signal, options);
+ this.stop(n, signal, options, {forRestart: true});
var started = this.start(n, options, true, wait);
@@ -2421,11 +2423,18 @@ var ReplSetTest = function(opts) {
/**
* Stops a particular node or nodes, specified by conn or id
*
+ * If _useBridge=true, then the mongobridge process(es) corresponding to the node(s) are also
+ * terminated unless forRestart=true. The mongobridge process(es) are left running across
+ * restarts to ensure their configuration remains intact.
+ *
* @param {number|Mongo} n the index or connection object of the replica set member to stop.
* @param {number} signal the signal number to use for killing
* @param {Object} opts @see MongoRunner.stopMongod
+ * @param {Object} [extraOptions={}]
+ * @param {boolean} [extraOptions.forRestart=false] indicates whether stop() is being called
+ * with the intent to call start() with restart=true for the same node(s) n.
*/
- this.stop = function(n, signal, opts) {
+ this.stop = function(n, signal, opts, {forRestart: forRestart = false} = {}) {
// Flatten array of nodes to stop
if (n.length) {
var nodes = n;
@@ -2453,8 +2462,13 @@ var ReplSetTest = function(opts) {
print('ReplSetTest stop *** Mongod in port ' + conn.port + ' shutdown with code (' + ret +
') ***');
- if (_useBridge) {
- this.nodes[n].stop();
+ if (_useBridge && !forRestart) {
+ // We leave the mongobridge process running when the mongod process is being restarted.
+ const bridge = this.nodes[n];
+ print('ReplSetTest stop *** Shutting down mongobridge on port ' + bridge.port + ' ***');
+ const exitCode = bridge.stop(); // calls MongoBridge#stop()
+ print('ReplSetTest stop *** mongobridge on port ' + bridge.port +
+ ' exited with code (' + exitCode + ') ***');
}
return ret;