summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2016-04-05 16:26:22 -0400
committerAndy Schwerin <schwerin@mongodb.com>2016-04-07 11:29:36 -0400
commit0953a237e58d2af33a55c420d8aefbbb3d4ff88b (patch)
tree1381f6d2715d60797d3237332f1bae038eb594c4
parent82644cc24c2f7a1817741190052704241cfec669 (diff)
downloadmongo-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.yml2
-rw-r--r--jstests/multiVersion/libs/verify_versions.js61
-rw-r--r--jstests/multiVersion/verify_versions_test.js41
-rw-r--r--src/mongo/scripting/mozjs/global.cpp3
-rw-r--r--src/mongo/scripting/utils.cpp10
-rw-r--r--src/mongo/shell/servers.js97
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;