diff options
author | Andy Schwerin <schwerin@mongodb.com> | 2016-04-05 16:26:22 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@mongodb.com> | 2016-04-07 11:29:36 -0400 |
commit | 0953a237e58d2af33a55c420d8aefbbb3d4ff88b (patch) | |
tree | 1381f6d2715d60797d3237332f1bae038eb594c4 | |
parent | 82644cc24c2f7a1817741190052704241cfec669 (diff) | |
download | mongo-0953a237e58d2af33a55c420d8aefbbb3d4ff88b.tar.gz |
SERVER-23547 Make the multiversion concept of "latest" more precise.
This supports multiversion tests involving subversions, like 3.2.1 compared to 3.2 latest.
-rw-r--r-- | etc/evergreen.yml | 2 | ||||
-rw-r--r-- | jstests/multiVersion/libs/verify_versions.js | 61 | ||||
-rw-r--r-- | jstests/multiVersion/verify_versions_test.js | 41 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/global.cpp | 3 | ||||
-rw-r--r-- | src/mongo/scripting/utils.cpp | 10 | ||||
-rw-r--r-- | src/mongo/shell/servers.js | 97 |
6 files changed, 144 insertions, 70 deletions
diff --git a/etc/evergreen.yml b/etc/evergreen.yml index 1c62268301f..23d82f4ca9c 100644 --- a/etc/evergreen.yml +++ b/etc/evergreen.yml @@ -360,7 +360,7 @@ functions: set -o verbose rm -rf /data/install /data/multiversion - ${python|python} buildscripts/setup_multiversion_mongodb.py /data/install /data/multiversion ${multiversion_platform_arch|"Linux/x86_64"} "2.4" "2.6" "3.0" + ${python|python} buildscripts/setup_multiversion_mongodb.py /data/install /data/multiversion ${multiversion_platform_arch|"Linux/x86_64"} "2.4" "2.6" "3.0" "3.2.1" pre: - command: shell.track diff --git a/jstests/multiVersion/libs/verify_versions.js b/jstests/multiVersion/libs/verify_versions.js index f34b28b9ee5..f20da90de80 100644 --- a/jstests/multiVersion/libs/verify_versions.js +++ b/jstests/multiVersion/libs/verify_versions.js @@ -1,37 +1,42 @@ /** - * Helpers for verifying versions of started MongoDB processes + * Helpers for verifying versions of started MongoDB processes. */ -Mongo.prototype.getBinVersion = function() { - var result = this.getDB("admin").runCommand({serverStatus: 1}); - return result.version; -}; +var Mongo, assert; +(function() { + "use strict"; + Mongo.prototype.getBinVersion = function() { + var result = this.getDB("admin").runCommand({serverStatus: 1}); + return result.version; + }; -// Checks that our mongodb process is of a certain version -assert.binVersion = function(mongo, version) { - var currVersion = mongo.getBinVersion(); - assert(MongoRunner.areBinVersionsTheSame(MongoRunner.getBinVersionFor(currVersion), - MongoRunner.getBinVersionFor(version)), - "version " + version + " (" + MongoRunner.getBinVersionFor(version) + ")" + - " is not the same as " + currVersion); -}; + // Checks that our mongodb process is of a certain version + assert.binVersion = function(mongo, version) { + var currVersion = mongo.getBinVersion(); + assert(MongoRunner.areBinVersionsTheSame(MongoRunner.getBinVersionFor(currVersion), + MongoRunner.getBinVersionFor(version)), + "version " + version + " (" + MongoRunner.getBinVersionFor(version) + ")" + + " is not the same as " + MongoRunner.getBinVersionFor(currVersion)); + }; -// Compares an array of desired versions and an array of found versions, -// looking for versions not found -assert.allBinVersions = function(versionsWanted, versionsFound) { + // Compares an array of desired versions and an array of found versions, + // looking for versions not found + assert.allBinVersions = function(versionsWanted, versionsFound) { - for (var i = 0; i < versionsWanted.length; i++) { - var version = versionsWanted[i]; - var found = false; - for (var j = 0; j < versionsFound.length; j++) { - if (MongoRunner.areBinVersionsTheSame(version, versionsFound[j])) { - found = true; - break; + for (var i = 0; i < versionsWanted.length; i++) { + var version = versionsWanted[i]; + var found = false; + for (var j = 0; j < versionsFound.length; j++) { + if (MongoRunner.areBinVersionsTheSame(version, versionsFound[j])) { + found = true; + break; + } } + + assert(found, + "could not find version " + version + " (" + + MongoRunner.getBinVersionFor(version) + ")" + " in " + versionsFound); } + }; - assert(found, - "could not find version " + version + " (" + MongoRunner.getBinVersionFor(version) + - ")" + " in " + versionsFound); - } -}; +}()); diff --git a/jstests/multiVersion/verify_versions_test.js b/jstests/multiVersion/verify_versions_test.js new file mode 100644 index 00000000000..2f21aa67a37 --- /dev/null +++ b/jstests/multiVersion/verify_versions_test.js @@ -0,0 +1,41 @@ +/** + * These tests check the version comparison logic in the multiversion test support code. + * + * In particular, it tests that the shell version (returned by version()) compares equal to + * "latest", not equal to "last-stable", and x.y compares equal to x.y.z, but that x.w does + * not. + */ +(function() { + "use strict"; + + function assertBinVersionsEqual(v1, v2) { + assert(MongoRunner.areBinVersionsTheSame(v1, v2), + "Expected \"" + v1 + "\" to equal \"" + v2 + "\""); + } + + function assertBinVersionsNotEqual(v1, v2) { + assert(!MongoRunner.areBinVersionsTheSame(v1, v2), + "Expected \"" + v1 + "\" not to equal \"" + v2 + "\""); + } + + // The current version is in the 3.2 series. This has to be changed very time we bump + // the major version pair, but it provides a useful test of assumptions. + assertBinVersionsEqual("3.2", version()); + + // "latest" is the same version as the shell, "last-stable" is not. + assertBinVersionsEqual("latest", version()); + assertBinVersionsEqual("", "latest"); + assertBinVersionsEqual("", version()); + assertBinVersionsNotEqual("latest", "last-stable"); + assertBinVersionsNotEqual("last-stable", version()); + + // 3.0 means 3.0.z for any value of z. It does not mean 3.2 or 3.2.w. + assertBinVersionsEqual("3.0", "3.0.4"); + assertBinVersionsEqual("3.0.4", "3.0"); + assertBinVersionsNotEqual("3.2", "3.0"); + assertBinVersionsNotEqual("3.0.9", "3.2.9"); + + // Prohibit versions that don't have at least two components (3 is no good, 3.2 is). + assert.throws(MongoRunner.areBinVersionsTheSame, ["3", "3.2"]); + assert.throws(MongoRunner.areBinVersionsTheSame, ["3.2", "3"]); +}()); diff --git a/src/mongo/scripting/mozjs/global.cpp b/src/mongo/scripting/mozjs/global.cpp index b3bdbec47b0..127dbdc3352 100644 --- a/src/mongo/scripting/mozjs/global.cpp +++ b/src/mongo/scripting/mozjs/global.cpp @@ -38,6 +38,7 @@ #include "mongo/scripting/mozjs/jsstringwrapper.h" #include "mongo/scripting/mozjs/objectwrapper.h" #include "mongo/scripting/mozjs/valuereader.h" +#include "mongo/util/version.h" namespace mongo { namespace mozjs { @@ -83,7 +84,7 @@ void GlobalInfo::Functions::print::call(JSContext* cx, JS::CallArgs args) { } void GlobalInfo::Functions::version::call(JSContext* cx, JS::CallArgs args) { - ValueReader(cx, args.rval()).fromStringData(JS_VersionToString(JS_GetVersion(cx))); + ValueReader(cx, args.rval()).fromStringData(versionString); } void GlobalInfo::Functions::gc::call(JSContext* cx, JS::CallArgs args) { diff --git a/src/mongo/scripting/utils.cpp b/src/mongo/scripting/utils.cpp index e6673460e97..10d8fcfe020 100644 --- a/src/mongo/scripting/utils.cpp +++ b/src/mongo/scripting/utils.cpp @@ -1,4 +1,3 @@ -// utils.cpp /* * Copyright (C) 2010 10gen Inc. * @@ -29,7 +28,6 @@ #include "mongo/scripting/engine.h" #include "mongo/util/md5.hpp" -#include "mongo/util/version.h" namespace mongo { @@ -48,10 +46,6 @@ static BSONObj native_hex_md5(const BSONObj& args, void* data) { return BSON("" << digestToString(d)); } -static BSONObj native_version(const BSONObj& args, void* data) { - return BSON("" << versionString); -} - static BSONObj native_sleep(const mongo::BSONObj& args, void* data) { uassert(16259, "sleep takes a single numeric argument -- sleep(milliseconds)", @@ -69,7 +63,7 @@ static BSONObj native_sleep(const mongo::BSONObj& args, void* data) { void installGlobalUtils(Scope& scope) { scope.injectNative("hex_md5", native_hex_md5); - scope.injectNative("version", native_version); scope.injectNative("sleep", native_sleep); } -} + +} // namespace mongo diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js index a8a33337ff1..0a3aa462549 100644 --- a/src/mongo/shell/servers.js +++ b/src/mongo/shell/servers.js @@ -1,7 +1,11 @@ -// Wrap whole file in a function to avoid polluting the global namespace +var MongoRunner, _startMongod, startMongoProgram, runMongoProgram, startMongoProgramNoConnect, + myPort, connectionURLTheSame; + (function() { - _parsePath = function() { + var shellVersion = version; + + var _parsePath = function() { var dbpath = ""; for (var i = 0; i < arguments.length; ++i) if (arguments[i] == "--dbpath") @@ -13,7 +17,7 @@ return dbpath; }; - _parsePort = function() { + var _parsePort = function() { var port = ""; for (var i = 0; i < arguments.length; ++i) if (arguments[i] == "--port") @@ -71,7 +75,7 @@ assert(connectionURLTheSame("foo/a,b", "foo/b,a")); assert(!connectionURLTheSame("foo/a,b", "bar/a,b")); - createMongoArgs = function(binaryName, args) { + var createMongoArgs = function(binaryName, args) { var fullArgs = [binaryName]; if (args.length == 1 && isObject(args[0])) { @@ -108,24 +112,51 @@ MongoRunner.dataDir = "/data/db"; MongoRunner.dataPath = "/data/db/"; - MongoRunner.VersionSub = function(regex, version) { - this.regex = regex; + MongoRunner.VersionSub = function(pattern, version) { + this.pattern = pattern; this.version = version; }; + /** + * Returns an array of version elements from a version string. + * + * "3.3.4-fade3783" -> ["3", "3", "4-fade3783" ] + * "3.2" -> [ "3", "2" ] + * 3 -> exception: versions must have at least two components. + */ + var convertVersionStringToArray = function(versionString) { + assert("" !== versionString, "Version strings must not be empty"); + var versionArray = versionString.split('.'); + assert.gt(versionArray.length, + 1, + "MongoDB versions must have at least two components to compare, but \"" + + versionString + "\" has " + versionArray.length); + return versionArray; + }; + + /** + * Returns the major version string from a version string. + * + * 3.3.4-fade3783 -> 3.3 + * 3.2 -> 3.2 + * 3 -> exception: versions must have at least two components. + */ + var extractMajorVersionFromVersionString = function(versionString) { + return convertVersionStringToArray(versionString).slice(0, 2).join('.'); + }; + // These patterns allow substituting the binary versions used for each version string to support // the // dev/stable MongoDB release cycle. // // If you add a new version substitution to this list, you should add it to the lists of - // versions - // being checked in '0_test_launching.js' to verify it is susbstituted correctly. + // versions being checked in 'verify_versions_test.js' to verify it is susbstituted correctly. MongoRunner.binVersionSubs = [ - new MongoRunner.VersionSub(/^latest$/, ""), + new MongoRunner.VersionSub("latest", shellVersion()), + new MongoRunner.VersionSub(extractMajorVersionFromVersionString(shellVersion()), + shellVersion()), // To-be-updated when we branch for the next release. - new MongoRunner.VersionSub(/^last-stable$/, "3.0"), - new MongoRunner.VersionSub(/^3\.1(\..*){0,1}/, ""), - new MongoRunner.VersionSub(/^3\.2(\..*){0,1}/, "") + new MongoRunner.VersionSub("last-stable", "3.0") ]; MongoRunner.getBinVersionFor = function(version) { @@ -135,35 +166,42 @@ version = version.toString(); } - // No version set means we use no suffix, this is *different* from "latest" - // since latest may be mapped to a different version. if (version == null) version = ""; version = version.trim(); if (version === "") - return ""; + version = "latest"; // See if this version is affected by version substitutions for (var i = 0; i < MongoRunner.binVersionSubs.length; i++) { var sub = MongoRunner.binVersionSubs[i]; - if (sub.regex.test(version)) { - version = sub.version; + if (sub.pattern == version) { + return sub.version; } } return version; }; + /** + * Returns true if two version strings could represent the same version. This is true + * if, after passing the versions through getBinVersionFor, the the versions have the + * same value for each version component up through the length of the shorter version. + * + * That is, 3.2.4 compares equal to 3.2, but 3.2.4 does not compare equal to 3.2.3. + */ MongoRunner.areBinVersionsTheSame = function(versionA, versionB) { - versionA = MongoRunner.getBinVersionFor(versionA); - versionB = MongoRunner.getBinVersionFor(versionB); + versionA = convertVersionStringToArray(MongoRunner.getBinVersionFor(versionA)); + versionB = convertVersionStringToArray(MongoRunner.getBinVersionFor(versionB)); - if (versionA === "" || versionB === "") { - return versionA === versionB; + var elementsToCompare = Math.min(versionA.length, versionB.length); + for (var i = 0; i < elementsToCompare; ++i) { + if (versionA[i] != versionB[i]) { + return false; + } } - - return versionA.startsWith(versionB) || versionB.startsWith(versionA); + return true; }; MongoRunner.logicalOptions = { @@ -289,7 +327,7 @@ var o = isObject(args) ? args : args[0]; // If we've specified a particular binary version, use that - if (o.binVersion && o.binVersion != "") { + if (o.binVersion && o.binVersion != "" && o.binVersion != shellVersion()) { binaryName += "-" + o.binVersion; } @@ -719,7 +757,7 @@ if (!port) { print("Cannot stop mongo process " + port); - return; + return null; } signal = signal || 15; @@ -773,7 +811,7 @@ // This function's arguments are passed as command line arguments to mongod. // The specified 'dbpath' is cleared if it exists, created if not. // var conn = _startMongodEmpty("--port", 30000, "--dbpath", "asdf"); - _startMongodEmpty = function() { + var _startMongodEmpty = function() { var args = createMongoArgs("mongod", arguments); var dbpath = _parsePath.apply(null, args); @@ -787,11 +825,6 @@ return _startMongodEmpty.apply(null, arguments); }; - _startMongodNoReset = function() { - var args = createMongoArgs("mongod", arguments); - return startMongoProgram.apply(null, args); - }; - /** * Returns a new argArray with any test-specific arguments added. */ @@ -804,7 +837,7 @@ } if (jsTest.options().authMechanism && jsTest.options().authMechanism != "SCRAM-SHA-1") { var hasAuthMechs = false; - for (i in argArray) { + for (var i in argArray) { if (typeof argArray[i] === 'string' && argArray[i].indexOf('authenticationMechanisms') != -1) { hasAuthMechs = true; |