summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Golden <xdg@xdg.me>2019-07-15 16:07:34 -0400
committerDavid Golden <xdg@xdg.me>2019-07-16 10:05:28 -0400
commitfef7f169653b788c00f61fed26d0237a24b897f3 (patch)
tree680e519598b3f98ac5577465a3b3269c0833acc0
parentd37eef2f8a1f3ef0f7d10d1cde016bb366df37a0 (diff)
downloadmongo-fef7f169653b788c00f61fed26d0237a24b897f3.tar.gz
Import tools: f6fdd97dbea59639732068720558c83b88947e15 from branch v4.1
ref: 4eba41d830..f6fdd97dbe for: 4.2.0 TOOLS-2174 mongodump and mongoexport fail to dump autoIndexId false capped collection due to invalid hint TOOLS-2276 dump/export/files query should use extJSON v2 and ordered BSON TOOLS-2302 Update supported build platforms to match server 4.2 TOOLS-2332 oplog_replay_local_rs.js fails on server latest
-rw-r--r--jstests/tool/dumprestore7.js9
-rw-r--r--jstests/tool/exportimport4.js14
-rw-r--r--jstests/tool/exportimport5.js50
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/common-pvt.yml46
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/common.yml58
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/import.data2
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go28
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump_test.go100
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/options.go4
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport.go13
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport_test.go97
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles.go26
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles_test.go4
13 files changed, 369 insertions, 82 deletions
diff --git a/jstests/tool/dumprestore7.js b/jstests/tool/dumprestore7.js
index 9b561f7f010..8078a7ab595 100644
--- a/jstests/tool/dumprestore7.js
+++ b/jstests/tool/dumprestore7.js
@@ -56,8 +56,11 @@
var data = MongoRunner.dataDir + "/dumprestore7-dump1/";
var query = {ts: {$gt: time}};
- print("mongodump query: " + tojson(query));
-
+ var queryJSON = '{"ts":{"$gt":{"$timestamp":{"t":' + time.t + ',"i":' + time.i + '}}}}';
+ print("mongodump query: " + queryJSON);
+ if (_isWindows()) {
+ queryJSON = '"' + queryJSON.replace(/"/g, '\\"') + '"';
+ }
var testQueryCount =
replTest.getPrimary().getDB("local").getCollection("oplog.rs").find(query).itcount();
assert.eq(testQueryCount, 20, "the query should match 20 documents");
@@ -66,7 +69,7 @@
host: "127.0.0.1:" + replTest.ports[0],
db: "local",
collection: "oplog.rs",
- query: tojson(query),
+ query: queryJSON,
out: data,
});
assert.eq(0, exitCode, "monogdump failed to dump the oplog");
diff --git a/jstests/tool/exportimport4.js b/jstests/tool/exportimport4.js
index 9c6f6d70b0a..e1937e5fc44 100644
--- a/jstests/tool/exportimport4.js
+++ b/jstests/tool/exportimport4.js
@@ -19,9 +19,11 @@ install_test_data = function() {
// attempt to export fields without NaN
install_test_data();
-
-t.runTool(
- "export", "--out", t.extFile, "-d", t.baseName, "-c", "foo", "-q", "{a:{\"$nin\":[NaN]}}");
+var queryJSON = '{"a":{"$nin":[{"$numberDouble":"NaN"}]}}';
+if (_isWindows()) {
+ queryJSON = '"' + queryJSON.replace(/"/g, '\\"') + '"';
+}
+t.runTool("export", "--out", t.extFile, "-d", t.baseName, "-c", "foo", "-q", queryJSON);
c.drop();
assert.eq(0, c.count(), "after drop", "-d", t.baseName, "-c", "foo");
@@ -33,7 +35,11 @@ assert.eq(2, c.count(), "after restore 1");
// attempt to export fields with NaN
install_test_data();
-t.runTool("export", "--out", t.extFile, "-d", t.baseName, "-c", "foo", "-q", "{a:NaN}");
+queryJSON = '{"a":{"$numberDouble":"NaN"}}';
+if (_isWindows()) {
+ queryJSON = '"' + queryJSON.replace(/"/g, '\\"') + '"';
+}
+t.runTool("export", "--out", t.extFile, "-d", t.baseName, "-c", "foo", "-q", queryJSON);
c.drop();
assert.eq(0, c.count(), "after drop", "-d", t.baseName, "-c", "foo");
diff --git a/jstests/tool/exportimport5.js b/jstests/tool/exportimport5.js
index 380e9391118..65368203998 100644
--- a/jstests/tool/exportimport5.js
+++ b/jstests/tool/exportimport5.js
@@ -21,8 +21,19 @@ install_test_data = function() {
// attempt to export fields without Infinity
install_test_data();
-t.runTool(
- "export", "--out", t.extFile, "-d", t.baseName, "-c", "foo", "-q", "{a:{\"$nin\":[Infinity]}}");
+var queryJSON = '{"a":{"$nin":[{"$numberDouble":"Infinity"}]}}';
+if (_isWindows()) {
+ queryJSON = '"' + queryJSON.replace(/"/g, '\\"') + '"';
+}
+t.runTool("export",
+ "--out",
+ t.extFile,
+ "-d",
+ t.baseName,
+ "-c",
+ "foo",
+ "-q",
+ queryJSON);
c.drop();
assert.eq(0, c.count(), "after drop", "-d", t.baseName, "-c", "foo");
@@ -33,8 +44,19 @@ assert.eq(3, c.count(), "after restore 1");
// attempt to export fields with Infinity
install_test_data();
-
-t.runTool("export", "--out", t.extFile, "-d", t.baseName, "-c", "foo", "-q", "{a:Infinity}");
+queryJSON = '{"a":{"$numberDouble":"Infinity"}}';
+if (_isWindows()) {
+ queryJSON = '"' + queryJSON.replace(/"/g, '\\"') + '"';
+}
+t.runTool("export",
+ "--out",
+ t.extFile,
+ "-d",
+ t.baseName,
+ "-c",
+ "foo",
+ "-q",
+ queryJSON);
c.drop();
assert.eq(0, c.count(), "after drop", "-d", t.baseName, "-c", "foo");
@@ -46,6 +68,10 @@ assert.eq(3, c.count(), "after restore 2");
// attempt to export fields without -Infinity
install_test_data();
+queryJSON = '{"a":{"$nin":[{"$numberDouble":"-Infinity"}]}}';
+if (_isWindows()) {
+ queryJSON = '"' + queryJSON.replace(/"/g, '\\"') + '"';
+}
t.runTool("export",
"--out",
t.extFile,
@@ -54,7 +80,7 @@ t.runTool("export",
"-c",
"foo",
"-q",
- "{a:{\"$nin\":[-Infinity]}}");
+ queryJSON);
c.drop();
assert.eq(0, c.count(), "after drop", "-d", t.baseName, "-c", "foo");
@@ -66,7 +92,19 @@ assert.eq(4, c.count(), "after restore 3");
// attempt to export fields with -Infinity
install_test_data();
-t.runTool("export", "--out", t.extFile, "-d", t.baseName, "-c", "foo", "-q", "{a:-Infinity}");
+queryJSON = '{"a":{"$numberDouble":"-Infinity"}}';
+if (_isWindows()) {
+ queryJSON = '"' + queryJSON.replace(/"/g, '\\"') + '"';
+}
+t.runTool("export",
+ "--out",
+ t.extFile,
+ "-d",
+ t.baseName,
+ "-c",
+ "foo",
+ "-q",
+ queryJSON);
c.drop();
assert.eq(0, c.count(), "after drop", "-d", t.baseName, "-c", "foo");
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common-pvt.yml b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common-pvt.yml
index 1d625e37019..479b422f873 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common-pvt.yml
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common-pvt.yml
@@ -196,7 +196,7 @@ buildvariants:
- name: amazonlinux64-enterprise
display_name: Amazon Linux 64 Enterprise
run_on:
- - linux-64-amzn-test
+ - amazon1-2018-test
expansions:
build_tags: "sasl gssapi ssl"
tasks: *atlas_live_tasks
@@ -248,7 +248,7 @@ buildvariants:
- name: rhel62-enterprise
display_name: RHEL 6.2 Enterprise
run_on:
- - rhel62-test
+ - rhel62-small
expansions:
build_tags: "sasl gssapi ssl"
tasks: *atlas_live_tasks
@@ -256,7 +256,7 @@ buildvariants:
- name: rhel70-enterprise
display_name: RHEL 7.0 Enterprise
run_on:
- - rhel70
+ - rhel70-small
expansions:
build_tags: "sasl gssapi ssl"
tasks: *atlas_live_tasks
@@ -293,6 +293,14 @@ buildvariants:
build_tags: "sasl gssapi ssl"
tasks: *atlas_live_tasks
+- name: ubuntu1804-enterprise
+ display_name: Ubuntu 18.04 Enterprise
+ run_on:
+ - ubuntu1804-test
+ expansions:
+ build_tags: "sasl gssapi ssl"
+ tasks: *atlas_live_tasks
+
#######################################
# Windows Buildvariants #
#######################################
@@ -300,7 +308,7 @@ buildvariants:
- name: windows-64-ssl
display_name: Windows 64-bit SSL
run_on:
- - windows-64-vs2013-compile
+ - windows-64-vs2017-test
expansions:
build_tags: "ssl"
tasks: *atlas_live_tasks
@@ -319,6 +327,16 @@ buildvariants:
build_tags: "ssl"
tasks: *atlas_live_tasks
+- name: ubuntu1804-arm64-ssl
+ display_name: ZAP ARM64 Ubuntu 18.04 SSL
+ run_on:
+ - ubuntu1804-arm64-small
+ stepback: false
+ batchtime: 10080 # weekly
+ expansions:
+ build_tags: "ssl"
+ tasks: *atlas_live_tasks
+
#######################################
# Power Buildvariants #
#######################################
@@ -343,6 +361,16 @@ buildvariants:
build_tags: 'ssl sasl gssapi'
tasks: *atlas_live_tasks
+- name: ubuntu1804-ppc64le-enterprise
+ display_name: ZAP PPC64LE Ubuntu 18.04 Enterprise
+ run_on:
+ - ubuntu1804-power8-test
+ stepback: false
+ batchtime: 10080 # weekly
+ expansions:
+ build_tags: 'ssl sasl gssapi'
+ tasks: *atlas_live_tasks
+
#######################################
# Z (s390x) Buildvariants #
#######################################
@@ -357,6 +385,16 @@ buildvariants:
build_tags: "sasl gssapi ssl"
tasks: *atlas_live_tasks
+- name: rhel72-s390x-enterprise
+ display_name: ZAP s390x RHEL 7.2 Enterprise
+ run_on:
+ - rhel72-zseries-test
+ stepback: false
+ batchtime: 10080 # weekly
+ expansions:
+ build_tags: "sasl gssapi ssl"
+ tasks: *atlas_live_tasks
+
- name: ubuntu1604-s390x-enterprise
display_name: ZAP s390x Ubuntu 16.04 Enterprise
run_on:
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common.yml b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common.yml
index b756c2f19ce..db5fc62a185 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common.yml
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common.yml
@@ -182,28 +182,28 @@ mongo_tools_variables:
- name: integration-4.2
- name: integration-4.2-auth
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-3.2
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-3.4
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-3.6
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-4.0
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-4.2
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-dump-restore-with-archiving-current
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-dump-restore-with-gzip-current
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-unstable
- name: unit
windows_64_ssl_task_list: &windows_64_ssl_tasks
@@ -225,25 +225,25 @@ mongo_tools_variables:
- name: integration-4.2-auth
- name: kerberos
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-3.2
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-3.4
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-3.6
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-4.0
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-4.2
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: qa-tests-unstable
distros:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
- name: unit
- name: native-cert-ssl-current
rhel71_ppc64le_enterprise_task_list: &rhel71_ppc64le_enterprise_tasks
@@ -1836,7 +1836,7 @@ buildvariants:
- name: rhel62
display_name: RHEL 6.2
run_on:
- - rhel62-test
+ - rhel62-small
expansions:
<<: *mongod_default_startup_args
<<: *mongo_default_startup_args
@@ -1851,7 +1851,7 @@ buildvariants:
- name: rhel62-ssl
display_name: RHEL 6.2 SSL
run_on:
- - rhel62-test
+ - rhel62-small
expansions:
<<: *mongod_ssl_startup_args
<<: *mongo_ssl_startup_args
@@ -1871,7 +1871,7 @@ buildvariants:
- name: rhel62-enterprise
display_name: RHEL 6.2 Enterprise
run_on:
- - rhel62-test
+ - rhel62-small
expansions:
<<: *mongod_default_startup_args
<<: *mongo_default_startup_args
@@ -1890,7 +1890,7 @@ buildvariants:
- name: rhel70
display_name: RHEL 7.0
run_on:
- - rhel70
+ - rhel70-small
expansions:
build_tags: ""
tasks:
@@ -1900,7 +1900,7 @@ buildvariants:
- name: rhel70-enterprise
display_name: RHEL 7.0 Enterprise
run_on:
- - rhel70
+ - rhel70-small
expansions:
build_tags: "sasl gssapi ssl"
tasks:
@@ -2035,7 +2035,7 @@ buildvariants:
- name: windows-64
display_name: Windows 64-bit
run_on:
- - windows-64-vs2013-test
+ - windows-64-vs2017-test
expansions:
<<: *mongod_default_startup_args
<<: *mongo_default_startup_args
@@ -2052,7 +2052,7 @@ buildvariants:
- name: windows-64-ssl
display_name: Windows 64-bit SSL
run_on:
- - windows-64-vs2013-compile
+ - windows-64-vs2017-compile
expansions:
<<: *mongod_ssl_startup_args
<<: *mongo_ssl_startup_args
@@ -2074,7 +2074,7 @@ buildvariants:
- name: windows-64-enterprise
display_name: Windows 64-bit Enterprise
run_on:
- - windows-64-vs2013-compile
+ - windows-64-vs2017-compile
expansions:
<<: *mongod_default_startup_args
<<: *mongo_default_startup_args
@@ -2221,6 +2221,18 @@ buildvariants:
integration_test_args: integration
tasks: *rhel67_s390x_enterprise_tasks
+- name: rhel72-s390x-enterprise
+ display_name: ZAP s390x RHEL 7.2 Enterprise
+ run_on:
+ - rhel72-zseries-test
+ stepback: false
+ batchtime: 10080 # weekly
+ expansions:
+ build_tags: "sasl gssapi ssl"
+ tasks:
+ - name: dist
+ - name: replay-dist
+
- name: ubuntu1604-s390x-enterprise
display_name: ZAP s390x Ubuntu 16.04 Enterprise
run_on:
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/import.data b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/import.data
index 8126e685de1..c991b271e9c 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/import.data
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/import.data
@@ -1,5 +1,5 @@
{
- "commit": "4eba41d830a94075202cd6eed6e3669ced4f9579",
+ "commit": "f6fdd97dbea59639732068720558c83b88947e15",
"github": "mongodb/mongo-tools.git",
"vendor": "tools",
"branch": "v4.1"
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go
index 3db90063c55..4c956895542 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go
@@ -12,11 +12,9 @@ import (
"github.com/mongodb/mongo-tools-common/archive"
"github.com/mongodb/mongo-tools-common/auth"
- "github.com/mongodb/mongo-tools-common/bsonutil"
"github.com/mongodb/mongo-tools-common/db"
"github.com/mongodb/mongo-tools-common/failpoint"
"github.com/mongodb/mongo-tools-common/intents"
- "github.com/mongodb/mongo-tools-common/json"
"github.com/mongodb/mongo-tools-common/log"
"github.com/mongodb/mongo-tools-common/options"
"github.com/mongodb/mongo-tools-common/progress"
@@ -54,7 +52,7 @@ type MongoDump struct {
// useful internals that we don't directly expose as options
SessionProvider *db.SessionProvider
manager *intents.Manager
- query bson.M
+ query bson.D
oplogCollection string
oplogStart primitive.Timestamp
oplogEnd primitive.Timestamp
@@ -197,26 +195,16 @@ func (dump *MongoDump) Dump() (err error) {
dump.shutdownIntentsNotifier = newNotifier()
if dump.InputOptions.HasQuery() {
- // parse JSON then convert extended JSON values
- var asJSON interface{}
content, err := dump.InputOptions.GetQuery()
if err != nil {
return err
}
- err = json.Unmarshal(content, &asJSON)
+ var query bson.D
+ err = bson.UnmarshalExtJSON(content, false, &query)
if err != nil {
- return fmt.Errorf("error parsing query as json: %v", err)
+ return fmt.Errorf("error parsing query as Extended JSON: %v", err)
}
- convertedJSON, err := bsonutil.ConvertLegacyExtJSONValueToBSON(asJSON)
- if err != nil {
- return fmt.Errorf("error converting query to bson: %v", err)
- }
- asMap, ok := convertedJSON.(map[string]interface{})
- if !ok {
- // unlikely to be reached
- return fmt.Errorf("query is not in proper format")
- }
- dump.query = bson.M(asMap)
+ dump.query = query
}
if !dump.SkipUsersAndRoles && dump.OutputOptions.DumpDBUsersAndRoles {
@@ -533,7 +521,11 @@ func (dump *MongoDump) DumpIntent(intent *intents.Intent, buffer resettableOutpu
// Views have an implied aggregation which does not support snapshot.
// These are all a no-op.
default:
- findQuery.Hint = bson.D{{"_id", 1}}
+ // Don't hint autoIndexId:false collections
+ autoIndexId, found := intent.Options["autoIndexId"]
+ if !found || autoIndexId == true {
+ findQuery.Hint = bson.D{{"_id", 1}}
+ }
}
var dumpCount int64
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump_test.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump_test.go
index d08a89ec00a..1de256efa52 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump_test.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump_test.go
@@ -214,7 +214,7 @@ func readBSONIntoDatabase(dir, restoreDBName string) error {
bsonSource := db.NewDecodedBSONSource(db.NewBSONSource(file))
defer bsonSource.Close()
- var result bson.M
+ var result bson.D
for bsonSource.Next(&result) {
_, err = collection.InsertOne(nil, result)
if err != nil {
@@ -239,7 +239,7 @@ func setUpMongoDumpTestData() error {
coll := session.Database(testDB).Collection(collectionName)
for j := 0; j < 10*(i+1); j++ {
- _, err = coll.InsertOne(nil, bson.M{"collectionName": collectionName, "age": j})
+ _, err = coll.InsertOne(nil, bson.M{"collectionName": collectionName, "age": j, "coords": bson.D{{"x", i}, {"y", j}}})
if err != nil {
return err
}
@@ -407,7 +407,7 @@ func testDumpOneCollection(md *MongoDump, dumpDir string) {
iter, err := collOriginal.Find(nil, bson.D{})
So(err, ShouldBeNil)
- var result bson.M
+ var result bson.D
for iter.Next(nil) {
iter.Decode(&result)
restoredCount, err := collRestore.CountDocuments(nil, result)
@@ -832,3 +832,97 @@ func TestMongoDumpOplog(t *testing.T) {
})
}
+
+// Test dumping a collection with autoIndexId:false. As of MongoDB 4.0,
+// this is only allowed on the 'local' database.
+func TestMongoDumpTOOLS2174(t *testing.T) {
+ testtype.SkipUnlessTestType(t, testtype.IntegrationTestType)
+ log.SetWriter(ioutil.Discard)
+
+ sessionProvider, _, err := testutil.GetBareSessionProvider()
+ if err != nil {
+ t.Fatalf("No cluster available: %v", err)
+ }
+
+ collName := "tools-2174"
+ dbName := "local"
+
+ var r1 bson.M
+ sessionProvider.Run(bson.D{{"drop", collName}}, &r1, dbName)
+
+ createCmd := bson.D{
+ {"create", collName},
+ {"autoIndexId", false},
+ }
+ var r2 bson.M
+ err = sessionProvider.Run(createCmd, &r2, dbName)
+ if err != nil {
+ t.Fatalf("Error creating capped, no-autoIndexId collection: %v", err)
+ }
+
+ Convey("testing dumping a capped, autoIndexId:false collection", t, func() {
+ md := simpleMongoDumpInstance()
+ md.ToolOptions.Namespace.Collection = collName
+ md.ToolOptions.Namespace.DB = dbName
+ md.OutputOptions.Out = "dump"
+ err = md.Init()
+ So(err, ShouldBeNil)
+ err = md.Dump()
+ So(err, ShouldBeNil)
+ })
+}
+
+func TestMongoDumpOrderedQuery(t *testing.T) {
+ testtype.SkipUnlessTestType(t, testtype.IntegrationTestType)
+ log.SetWriter(ioutil.Discard)
+
+ Convey("With a MongoDump instance", t, func() {
+ err := setUpMongoDumpTestData()
+ So(err, ShouldBeNil)
+ path, err := os.Getwd()
+ So(err, ShouldBeNil)
+ dumpDir := util.ToUniversalPath(filepath.Join(path, "dump"))
+
+ Convey("testing that --query is order-preserving", func() {
+ // If order is not preserved, probabalistically, some of these
+ // loops will fail.
+ for i := 0; i < 100; i++ {
+ So(os.RemoveAll(dumpDir), ShouldBeNil)
+
+ md := simpleMongoDumpInstance()
+ md.InputOptions.Query = `{"coords":{"x":0,"y":1}}`
+ md.ToolOptions.Namespace.Collection = testCollectionNames[0]
+ md.ToolOptions.Namespace.DB = testDB
+ md.OutputOptions.Out = "dump"
+ err = md.Init()
+ So(err, ShouldBeNil)
+ err = md.Dump()
+ So(err, ShouldBeNil)
+
+ dumpBSON := util.ToUniversalPath(filepath.Join(dumpDir, testDB, testCollectionNames[0]+".bson"))
+
+ file, err := os.Open(dumpBSON)
+ So(err, ShouldBeNil)
+
+ bsonSource := db.NewDecodedBSONSource(db.NewBSONSource(file))
+
+ var count int
+ var result bson.M
+ for bsonSource.Next(&result) {
+ count++
+ }
+ So(bsonSource.Err(), ShouldBeNil)
+
+ So(count, ShouldEqual, 1)
+
+ bsonSource.Close()
+ file.Close()
+ }
+ })
+
+ Reset(func() {
+ So(os.RemoveAll(dumpDir), ShouldBeNil)
+ So(tearDownMongoDumpTestData(), ShouldBeNil)
+ })
+ })
+}
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/options.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/options.go
index 599fc21d910..0de15aad972 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/options.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/options.go
@@ -21,8 +21,8 @@ See http://docs.mongodb.org/manual/reference/program/mongodump/ for more informa
// InputOptions defines the set of options to use in retrieving data from the server.
type InputOptions struct {
- Query string `long:"query" short:"q" description:"query filter, as a JSON string, e.g., '{x:{$gt:1}}'"`
- QueryFile string `long:"queryFile" description:"path to a file containing a query filter (JSON)"`
+ Query string `long:"query" short:"q" description:"query filter, as a v2 Extended JSON string, e.g., '{\"x\":{\"$gt\":1}}'"`
+ QueryFile string `long:"queryFile" description:"path to a file containing a query filter (v2 Extended JSON)"`
ReadPreference string `long:"readPreference" value-name:"<string>|<json>" description:"specify either a preference mode (e.g. 'nearest') or a preference json object (e.g. '{mode: \"nearest\", tagSets: [{a: \"b\"}], maxStalenessSeconds: 123}')"`
TableScan bool `long:"forceTableScan" description:"force a table scan"`
}
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport.go
index bd2adee4a8d..5ba2ffaf36a 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport.go
@@ -305,16 +305,16 @@ func (exp *MongoExport) getCursor() (*mongo.Cursor, error) {
findOpts.SetSort(sortD)
}
- query := map[string]interface{}{}
+ query := bson.D{}
if exp.InputOpts != nil && exp.InputOpts.HasQuery() {
var err error
content, err := exp.InputOpts.GetQuery()
if err != nil {
return nil, err
}
- query, err = getObjectFromByteArg(content)
+ err = bson.UnmarshalExtJSON(content, false, &query)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("error parsing query as Extended JSON: %v", err)
}
}
@@ -329,8 +329,11 @@ func (exp *MongoExport) getCursor() (*mongo.Cursor, error) {
if !exp.InputOpts.ForceTableScan && len(query) == 0 && exp.InputOpts != nil && exp.InputOpts.Sort == "" &&
!exp.collInfo.IsView() && !exp.collInfo.IsSystemCollection() {
- // Use a hint on the _id index instead of the deprecated snapshot option
- findOpts.SetHint(bson.D{{"_id", 1}})
+ // Don't hint autoIndexId:false collections
+ autoIndexId, found := exp.collInfo.Options["autoIndexId"]
+ if !found || autoIndexId == true {
+ findOpts.SetHint(bson.D{{"_id", 1}})
+ }
}
if exp.InputOpts != nil {
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport_test.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport_test.go
index 716724ef503..842d895cbc7 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport_test.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongoexport/mongoexport_test.go
@@ -7,17 +7,73 @@
package mongoexport
import (
+ "bytes"
"encoding/json"
+ "io/ioutil"
"os"
"testing"
"github.com/mongodb/mongo-tools-common/bsonutil"
+ "github.com/mongodb/mongo-tools-common/db"
+ "github.com/mongodb/mongo-tools-common/log"
+ "github.com/mongodb/mongo-tools-common/options"
"github.com/mongodb/mongo-tools-common/testtype"
+ "github.com/mongodb/mongo-tools-common/testutil"
. "github.com/smartystreets/goconvey/convey"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
+var (
+ // database with test data
+ testDB = "mongoexport_test_db"
+ testCollectionName = "coll1"
+)
+
+func simpleMongoExportOpts() Options {
+ var toolOptions *options.ToolOptions
+
+ // get ToolOptions from URI or defaults
+ if uri := os.Getenv("MONGOD"); uri != "" {
+ fakeArgs := []string{"--uri=" + uri}
+ toolOptions = options.New("mongoexport", "", "", "", options.EnabledOptions{URI: true})
+ toolOptions.URI.AddKnownURIParameters(options.KnownURIOptionsReadPreference)
+ _, err := toolOptions.ParseArgs(fakeArgs)
+ if err != nil {
+ panic("Could not parse MONGOD environment variable")
+ }
+ } else {
+ ssl := testutil.GetSSLOptions()
+ auth := testutil.GetAuthOptions()
+ connection := &options.Connection{
+ Host: "localhost",
+ Port: db.DefaultTestPort,
+ }
+ toolOptions = &options.ToolOptions{
+ SSL: &ssl,
+ Connection: connection,
+ Auth: &auth,
+ Verbosity: &options.Verbosity{},
+ URI: &options.URI{},
+ }
+ }
+
+ // Limit ToolOptions to test database
+ toolOptions.Namespace = &options.Namespace{DB: testDB, Collection: testCollectionName}
+
+ opts := Options{
+ ToolOptions: toolOptions,
+ OutputFormatOptions: &OutputFormatOptions{
+ Type: "json",
+ JSONFormat: "canonical",
+ },
+ InputOptions: &InputOptions{},
+ }
+
+ log.SetVerbosity(toolOptions.Verbosity)
+ return opts
+}
+
func TestExtendedJSON(t *testing.T) {
testtype.SkipUnlessTestType(t, testtype.UnitTestType)
@@ -50,3 +106,44 @@ func TestFieldSelect(t *testing.T) {
So(makeFieldSelector("x,foo.baz"), ShouldResemble, bson.M{"_id": 1, "foo": 1, "x": 1})
})
}
+
+// Test exporting a collection with autoIndexId:false. As of MongoDB 4.0,
+// this is only allowed on the 'local' database.
+func TestMongoExportTOOLS2174(t *testing.T) {
+ testtype.SkipUnlessTestType(t, testtype.IntegrationTestType)
+ log.SetWriter(ioutil.Discard)
+
+ sessionProvider, _, err := testutil.GetBareSessionProvider()
+ if err != nil {
+ t.Fatalf("No cluster available: %v", err)
+ }
+
+ collName := "tools-2174"
+ dbName := "local"
+
+ var r1 bson.M
+ sessionProvider.Run(bson.D{{"drop", collName}}, &r1, dbName)
+
+ createCmd := bson.D{
+ {"create", collName},
+ {"autoIndexId", false},
+ }
+ var r2 bson.M
+ err = sessionProvider.Run(createCmd, &r2, dbName)
+ if err != nil {
+ t.Fatalf("Error creating capped, no-autoIndexId collection: %v", err)
+ }
+
+ Convey("testing dumping a capped, autoIndexId:false collection", t, func() {
+ opts := simpleMongoExportOpts()
+ opts.Collection = collName
+ opts.DB = dbName
+
+ me, err := New(opts)
+ So(err, ShouldBeNil)
+ defer me.Close()
+ out := &bytes.Buffer{}
+ _, err = me.Export(out)
+ So(err, ShouldBeNil)
+ })
+}
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles.go
index 5c15124cf74..e6786182ad1 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles.go
@@ -13,10 +13,9 @@ import (
"io"
"os"
"regexp"
+ "strings"
- "github.com/mongodb/mongo-tools-common/bsonutil"
"github.com/mongodb/mongo-tools-common/db"
- "github.com/mongodb/mongo-tools-common/json"
"github.com/mongodb/mongo-tools-common/log"
"github.com/mongodb/mongo-tools-common/options"
"github.com/mongodb/mongo-tools-common/util"
@@ -287,22 +286,27 @@ func (mf *MongoFiles) handleDeleteID() error {
// parse and convert input extended JSON _id. Generates a new ObjectID if no _id provided.
func (mf *MongoFiles) parseOrCreateID() (interface{}, error) {
- if mf.Id == "" {
+ trimmed := strings.Trim(mf.Id, " ")
+
+ if trimmed == "" {
return primitive.NewObjectID(), nil
}
- var asJSON interface{}
- if err := json.Unmarshal([]byte(mf.Id), &asJSON); err != nil {
- return nil, fmt.Errorf("error parsing provided extJSON: %v", err)
+ // Wrap JSON bytes into a document for unmarshaling, then pick out the value after.
+ var wrapped string
+ switch trimmed[0] {
+ case '{':
+ wrapped = fmt.Sprintf(`{"_id":%s}`, trimmed)
+ default:
+ wrapped = fmt.Sprintf(`{"_id":"%s"}`, trimmed)
}
-
- // legacy extJSON parser
- id, err := bsonutil.ConvertLegacyExtJSONValueToBSON(asJSON)
+ var idDoc bson.D
+ err := bson.UnmarshalExtJSON([]byte(wrapped), false, &idDoc)
if err != nil {
- return nil, fmt.Errorf("error converting extJSON vlaue to bson: %v", err)
+ return nil, fmt.Errorf("error parsing id as Extended JSON: %v", err)
}
- return id, nil
+ return idDoc[0].Value, nil
}
// writeGFSFileToLocal writes a file from gridFS to stdout or the filesystem.
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles_test.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles_test.go
index bf14d399cee..ae5303c22c4 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles_test.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongofiles/mongofiles_test.go
@@ -198,7 +198,7 @@ func fileContentsCompare(file1, file2 *os.File, t *testing.T) (bool, error) {
// get an id of an existing file, for _id access
func idOfFile(filename string) string {
- return fmt.Sprintf("ObjectId('%v')", testFiles[filename].Hex())
+ return fmt.Sprintf(`{"$oid":"%s"}`, testFiles[filename].Hex())
}
// test output needs some cleaning
@@ -540,7 +540,7 @@ func TestMongoFilesCommands(t *testing.T) {
})
Convey("Testing the 'put_id' command by putting some lorem ipsum file with 287613 bytes with different ids should succeed", func() {
- for _, idToTest := range []string{"'test_id'", "'{a:\"b\"}'", "'{$numberlong:9999999999999999999999}'", "'{a:{b:{c:{}}}}'"} {
+ for _, idToTest := range []string{`test_id`, `{"a":"b"}`, `{"$numberLong":"999999999999999"}`, `{"a":{"b":{"c":{}}}}`} {
runPutIDTestCase(idToTest, t)
}
})