diff options
author | Henrik Edin <henrik.edin@mongodb.com> | 2018-08-02 15:23:19 -0400 |
---|---|---|
committer | Henrik Edin <henrik.edin@mongodb.com> | 2018-09-14 11:20:37 -0400 |
commit | 5de2e9361b92fbbc59625636eecbe6bd1f1a78c5 (patch) | |
tree | abbf5b8fed11c7cc75a6094a21b74a1b374d99da | |
parent | 2ea069aa505c750cad6a7ba6ae6d4ac897f396d1 (diff) | |
download | mongo-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.yml | 1 | ||||
-rw-r--r-- | jstests/core/read_after_optime.js | 8 | ||||
-rw-r--r-- | jstests/core_standalone/read_concern.js | 48 | ||||
-rw-r--r-- | jstests/core_standalone/write_concern.js | 18 | ||||
-rw-r--r-- | src/mongo/embedded/replication_coordinator_embedded.cpp | 12 | ||||
-rw-r--r-- | src/mongo/embedded/service_entry_point_embedded.cpp | 38 |
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 {} }; |