summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2018-08-02 15:23:19 -0400
committerHenrik Edin <henrik.edin@mongodb.com>2018-09-14 11:20:37 -0400
commit5de2e9361b92fbbc59625636eecbe6bd1f1a78c5 (patch)
treeabbf5b8fed11c7cc75a6094a21b74a1b374d99da
parent2ea069aa505c750cad6a7ba6ae6d4ac897f396d1 (diff)
downloadmongo-5de2e9361b92fbbc59625636eecbe6bd1f1a78c5.tar.gz
SERVER-34577 Parse read and write concern for command invocation in embedded. Behave like a standalone mongod.
-rw-r--r--buildscripts/resmokeconfig/suites/core.yml1
-rw-r--r--jstests/core/read_after_optime.js8
-rw-r--r--jstests/core_standalone/read_concern.js48
-rw-r--r--jstests/core_standalone/write_concern.js18
-rw-r--r--src/mongo/embedded/replication_coordinator_embedded.cpp12
-rw-r--r--src/mongo/embedded/service_entry_point_embedded.cpp38
6 files changed, 108 insertions, 17 deletions
diff --git a/buildscripts/resmokeconfig/suites/core.yml b/buildscripts/resmokeconfig/suites/core.yml
index 100211c40e5..45bf1fd5b45 100644
--- a/buildscripts/resmokeconfig/suites/core.yml
+++ b/buildscripts/resmokeconfig/suites/core.yml
@@ -3,6 +3,7 @@ test_kind: js_test
selector:
roots:
- jstests/core/**/*.js
+ - jstests/core_standalone/**/*.js
exclude_files:
# Transactions are not supported on MongoDB standalone nodes, so we do not run these tests in the
# 'core' suite. Instead we run them against a 1-node replica set in the 'core_txns' suite.
diff --git a/jstests/core/read_after_optime.js b/jstests/core/read_after_optime.js
index b5b79757e35..33c5594d742 100644
--- a/jstests/core/read_after_optime.js
+++ b/jstests/core/read_after_optime.js
@@ -1,11 +1,5 @@
// Test that attempting to read after optime fails if replication is not enabled.
-// @tags: [
-// # readConcern code is stripped in embedded and that causes this to succeed.
-// # TODO SERVER-34577
-// incompatible_with_embedded_todo_investigate
-// ]
-
(function() {
"use strict";
@@ -16,5 +10,5 @@
assert.commandFailedWithCode(
db.runCommand(
{find: 'user', filter: {x: 1}, readConcern: {afterOpTime: {ts: futureOpTime, t: 0}}}),
- ErrorCodes.NotAReplicaSet);
+ [ErrorCodes.NotAReplicaSet, ErrorCodes.NotImplemented]);
})();
diff --git a/jstests/core_standalone/read_concern.js b/jstests/core_standalone/read_concern.js
new file mode 100644
index 00000000000..075f5fb7fe5
--- /dev/null
+++ b/jstests/core_standalone/read_concern.js
@@ -0,0 +1,48 @@
+// This test verifies readConcern behavior on a standalone mongod or embedded
+
+(function() {
+ 'use strict';
+
+ // For isWiredTiger.
+ load("jstests/concurrency/fsm_workload_helpers/server_types.js");
+
+ var t = db.read_concern;
+ t.drop();
+
+ assert.commandWorked(t.runCommand({insert: "read_concern", documents: [{x: 1}]}));
+
+ // Local readConcern succeed.
+ assert.commandWorked(t.runCommand({find: "read_concern", readConcern: {level: "local"}}),
+ "expected local readConcern to succeed on standalone mongod");
+
+ // Available readConcern succeed.
+ assert.commandWorked(t.runCommand({find: "read_concern", readConcern: {level: "available"}}),
+ "expected available readConcern to succeed on standalone mongod");
+
+ var majority_result = t.runCommand({find: "read_concern", readConcern: {level: "majority"}});
+ if (isWiredTiger(db) || isEphemeral(db)) {
+ // Majority readConcern succeed.
+ assert.commandWorked(majority_result,
+ "expected majority readConcern to succeed on standalone mongod");
+ } else {
+ // Majority readConcern fail.
+ assert.commandFailedWithCode(
+ majority_result,
+ [ErrorCodes.ReadConcernMajorityNotEnabled, ErrorCodes.NotImplemented],
+ "expected majority readConcern to fail on standalone mongod");
+ }
+
+ // Snapshot readConcern fail.
+ assert.commandFailedWithCode(
+ t.runCommand({find: "read_concern", readConcern: {level: "snapshot"}}),
+ [ErrorCodes.InvalidOptions, ErrorCodes.NotImplemented],
+ "expected snapshot readConcern to fail on standalone mongod");
+
+ // Standalones don't support any operations with clusterTime.
+ assert.commandFailedWithCode(t.runCommand({
+ find: "read_concern",
+ readConcern: {level: "local", afterClusterTime: Timestamp(0, 1)}
+ }),
+ [ErrorCodes.IllegalOperation, ErrorCodes.NotImplemented],
+ "expected afterClusterTime read to fail on standalone mongod");
+})(); \ No newline at end of file
diff --git a/jstests/core_standalone/write_concern.js b/jstests/core_standalone/write_concern.js
new file mode 100644
index 00000000000..fd4036e6925
--- /dev/null
+++ b/jstests/core_standalone/write_concern.js
@@ -0,0 +1,18 @@
+// This test verifies writeConcern behavior on a standalone mongod or embedded mongoed.
+
+(function() {
+ 'use strict';
+
+ var col = db.write_concern;
+ col.drop();
+
+ // Supported writeConcern on standalone
+ assert.commandWorked(col.insert({_id: 0}, {writeConcern: {w: 0}}));
+ assert.commandWorked(col.insert({_id: 1}, {writeConcern: {w: 1}}));
+ assert.commandWorked(col.insert({_id: "majority"}, {writeConcern: {w: "majority"}}));
+
+ // writeConcern: 2 should not work on standalone
+ assert.writeError(col.insert({_id: 2}, {writeConcern: {w: 2}}),
+ "expected writeConcern: 2 to fail");
+
+})(); \ No newline at end of file
diff --git a/src/mongo/embedded/replication_coordinator_embedded.cpp b/src/mongo/embedded/replication_coordinator_embedded.cpp
index f32d93819a2..4c4d02258b1 100644
--- a/src/mongo/embedded/replication_coordinator_embedded.cpp
+++ b/src/mongo/embedded/replication_coordinator_embedded.cpp
@@ -32,6 +32,7 @@
#include "mongo/embedded/replication_coordinator_embedded.h"
+#include "mongo/db/repl/read_concern_args.h"
#include "mongo/db/repl/repl_set_config.h"
#include "mongo/embedded/not_implemented.h"
@@ -208,7 +209,16 @@ OpTime ReplicationCoordinatorEmbedded::getMyLastDurableOpTime() const {
}
Status ReplicationCoordinatorEmbedded::waitUntilOpTimeForRead(OperationContext*,
- const ReadConcernArgs&) {
+ const ReadConcernArgs& readConcern) {
+ // nothing to wait for
+ auto level = readConcern.getLevel();
+ if ((level == ReadConcernLevel::kLocalReadConcern ||
+ level == ReadConcernLevel::kAvailableReadConcern) &&
+ (!readConcern.getArgsAfterClusterTime() && !readConcern.getArgsOpTime() &&
+ !readConcern.getArgsAtClusterTime())) {
+ return Status::OK();
+ }
+
UASSERT_NOT_IMPLEMENTED;
}
diff --git a/src/mongo/embedded/service_entry_point_embedded.cpp b/src/mongo/embedded/service_entry_point_embedded.cpp
index a1f6acc7382..ced60eb8af8 100644
--- a/src/mongo/embedded/service_entry_point_embedded.cpp
+++ b/src/mongo/embedded/service_entry_point_embedded.cpp
@@ -32,6 +32,7 @@
#include "mongo/embedded/service_entry_point_embedded.h"
+#include "mongo/db/read_concern.h"
#include "mongo/db/service_entry_point_common.h"
#include "mongo/embedded/not_implemented.h"
#include "mongo/embedded/periodic_runner_embedded.h"
@@ -44,18 +45,37 @@ public:
return false;
}
- void waitForReadConcern(OperationContext*,
- const CommandInvocation*,
- const OpMsgRequest&) const override {}
+ void waitForReadConcern(OperationContext* opCtx,
+ const CommandInvocation* invocation,
+ const OpMsgRequest& request) const override {
+ auto rcStatus = mongo::waitForReadConcern(
+ opCtx, repl::ReadConcernArgs::get(opCtx), invocation->allowsAfterClusterTime());
+ uassertStatusOK(rcStatus);
+ }
- void waitForWriteConcern(OperationContext*,
- const CommandInvocation*,
- const repl::OpTime&,
- BSONObjBuilder&) const override {}
+ void waitForWriteConcern(OperationContext* opCtx,
+ const CommandInvocation* invocation,
+ const repl::OpTime& lastOpBeforeRun,
+ BSONObjBuilder& commandResponseBuilder) const override {
+ WriteConcernResult res;
+ auto waitForWCStatus =
+ mongo::waitForWriteConcern(opCtx, lastOpBeforeRun, opCtx->getWriteConcern(), &res);
- void waitForLinearizableReadConcern(OperationContext*) const override {}
+ CommandHelpers::appendCommandWCStatus(commandResponseBuilder, waitForWCStatus, res);
+ }
- void uassertCommandDoesNotSpecifyWriteConcern(const BSONObj&) const override {}
+ void waitForLinearizableReadConcern(OperationContext* opCtx) const override {
+ if (repl::ReadConcernArgs::get(opCtx).getLevel() ==
+ repl::ReadConcernLevel::kLinearizableReadConcern) {
+ uassertStatusOK(mongo::waitForLinearizableReadConcern(opCtx));
+ }
+ }
+
+ void uassertCommandDoesNotSpecifyWriteConcern(const BSONObj& cmd) const override {
+ if (commandSpecifiesWriteConcern(cmd)) {
+ uasserted(ErrorCodes::InvalidOptions, "Command does not support writeConcern");
+ }
+ }
void attachCurOpErrInfo(OperationContext*, const BSONObj&) const override {}
};