summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/db/write_concern_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/db/write_concern_test.go')
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/db/write_concern_test.go267
1 files changed, 267 insertions, 0 deletions
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/db/write_concern_test.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/db/write_concern_test.go
new file mode 100644
index 00000000000..94573bb2005
--- /dev/null
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/db/write_concern_test.go
@@ -0,0 +1,267 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package db
+
+import (
+ "github.com/mongodb/mongo-tools/common/connstring"
+ . "github.com/smartystreets/goconvey/convey"
+
+ "fmt"
+ "testing"
+ "time"
+)
+
+func TestBuildWriteConcern(t *testing.T) {
+ Convey("When building write concern object", t, func() {
+ Convey("and given a write concern string value, and a boolean indicating if the "+
+ "write concern is to be used on a replica set, on calling BuildWriteConcern...", func() {
+ Convey("no error should be returned if the write concern is valid", func() {
+ writeConcern, err := BuildWriteConcern(`{w:34}`, ReplSet, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 34)
+ writeConcern, err = BuildWriteConcern(`{w:"majority"}`, ReplSet, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.WMode, ShouldEqual, "majority")
+ writeConcern, err = BuildWriteConcern(`majority`, ReplSet, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.WMode, ShouldEqual, "majority")
+ writeConcern, err = BuildWriteConcern(`tagset`, ReplSet, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.WMode, ShouldEqual, "tagset")
+ })
+ Convey("on replica sets, only a write concern of 1 or 0 should be returned", func() {
+ writeConcern, err := BuildWriteConcern(`{w:34}`, Standalone, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 1)
+ writeConcern, err = BuildWriteConcern(`{w:"majority"}`, Standalone, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 1)
+ writeConcern, err = BuildWriteConcern(`tagset`, Standalone, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 1)
+ })
+ Convey("with a w value of 0, without j set, a nil write concern should be returned", func() {
+ writeConcern, err := BuildWriteConcern(`{w:0}`, Standalone, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern, ShouldBeNil)
+ })
+ Convey("with a negative w value, an error should be returned", func() {
+ _, err := BuildWriteConcern(`{w:-1}`, ReplSet, nil)
+ So(err, ShouldNotBeNil)
+ _, err = BuildWriteConcern(`{w:-2}`, ReplSet, nil)
+ So(err, ShouldNotBeNil)
+ })
+ Convey("with a w value of 0, with j set, a non-nil write concern should be returned", func() {
+ writeConcern, err := BuildWriteConcern(`{w:0, j:true}`, Standalone, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.J, ShouldBeTrue)
+ })
+ // Regression test for TOOLS-1741
+ Convey("When passing an empty writeConcern and empty URI"+
+ "then write concern should default to being majority", func() {
+ writeConcern, err := BuildWriteConcern("", ReplSet, nil)
+ So(err, ShouldBeNil)
+ So(writeConcern.WMode, ShouldEqual, "majority")
+ })
+ })
+ Convey("and given a connection string", func() {
+ Convey("with a w value of 0, without j set, a nil write concern should be returned", func() {
+ writeConcern, err := BuildWriteConcern(``, Standalone, &connstring.ConnString{W: "0"})
+ So(err, ShouldBeNil)
+ So(writeConcern, ShouldBeNil)
+ })
+ Convey("with a negative w value, an error should be returned", func() {
+ _, err := BuildWriteConcern(``, ReplSet, &connstring.ConnString{W: "-1"})
+ So(err, ShouldNotBeNil)
+ _, err = BuildWriteConcern(``, ReplSet, &connstring.ConnString{W: "-2"})
+ So(err, ShouldNotBeNil)
+ })
+ Convey("on replica sets, only a write concern of 1 or 0 should be returned", func() {
+ writeConcern, err := BuildWriteConcern(``, Standalone, &connstring.ConnString{W: "34"})
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 1)
+ writeConcern, err = BuildWriteConcern(``, Standalone, &connstring.ConnString{W: "majority"})
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 1)
+ writeConcern, err = BuildWriteConcern(``, Standalone, &connstring.ConnString{W: "tagset"})
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 1)
+ })
+ })
+ Convey("and given both, should error", func() {
+ _, err := BuildWriteConcern(`ab`, ReplSet, &connstring.ConnString{W: "-1"})
+ So(err, ShouldNotBeNil)
+ })
+ })
+}
+
+func TestConstructWCObject(t *testing.T) {
+ Convey("Given a write concern string value, on calling constructWCObject...", t, func() {
+
+ Convey("non-JSON string values should be assigned to the 'WMode' "+
+ "field in their entirety", func() {
+ writeConcernString := "majority"
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.WMode, ShouldEqual, writeConcernString)
+ })
+
+ Convey("non-JSON int values should be assigned to the 'w' field "+
+ "in their entirety", func() {
+ writeConcernString := `{w: 4}`
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 4)
+ })
+
+ Convey("JSON strings with valid j, wtimeout, fsync and w, should be "+
+ "assigned accordingly", func() {
+ writeConcernString := `{w: 3, j: true, fsync: false, wtimeout: 43}`
+ expectedW := 3
+ expectedWTimeout := 43
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, expectedW)
+ So(writeConcern.J, ShouldBeTrue)
+ So(writeConcern.FSync, ShouldBeFalse)
+ So(writeConcern.WTimeout, ShouldEqual, expectedWTimeout)
+ })
+
+ Convey("JSON strings with an argument for j that is not false should set j true", func() {
+ writeConcernString := `{w: 3, j: "rue"}`
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 3)
+ So(writeConcern.J, ShouldBeTrue)
+ })
+
+ Convey("JSON strings with an argument for fsync that is not false should set fsync true", func() {
+ writeConcernString := `{w: 3, fsync: "rue"}`
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 3)
+ So(writeConcern.FSync, ShouldBeTrue)
+ })
+
+ Convey("JSON strings with an invalid wtimeout argument should error out", func() {
+ writeConcernString := `{w: 3, wtimeout: "rue"}`
+ _, err := constructWCObject(writeConcernString)
+ So(err, ShouldNotBeNil)
+ writeConcernString = `{w: 3, wtimeout: "43"}`
+ _, err = constructWCObject(writeConcernString)
+ So(err, ShouldNotBeNil)
+ })
+
+ Convey("JSON strings with any non-false j argument should not error out", func() {
+ writeConcernString := `{w: 3, j: "t"}`
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.J, ShouldBeTrue)
+ writeConcernString = `{w: 3, j: "f"}`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.J, ShouldBeTrue)
+ writeConcernString = `{w: 3, j: false}`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.J, ShouldBeFalse)
+ writeConcernString = `{w: 3, j: 0}`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.J, ShouldBeFalse)
+ })
+
+ Convey("JSON strings with a shorthand fsync argument should not error out", func() {
+ writeConcernString := `{w: 3, fsync: "t"}`
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.FSync, ShouldBeTrue)
+ writeConcernString = `{w: "3", fsync: "f"}`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.FSync, ShouldBeTrue)
+ writeConcernString = `{w: "3", fsync: false}`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.FSync, ShouldBeFalse)
+ writeConcernString = `{w: "3", fsync: 0}`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern.FSync, ShouldBeFalse)
+ })
+
+ Convey("Unacknowledge write concern strings should return a nil object "+
+ "if journaling is not required", func() {
+ writeConcernString := `{w: 0}`
+ writeConcern, err := constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern, ShouldBeNil)
+ writeConcernString = `{w: 0}`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern, ShouldBeNil)
+ writeConcernString = `0`
+ writeConcern, err = constructWCObject(writeConcernString)
+ So(err, ShouldBeNil)
+ So(writeConcern, ShouldBeNil)
+ })
+ })
+}
+
+func TestConstructSafetyFromConnString(t *testing.T) {
+ Convey("Given a parsed &connstring, on calling constructSafetyFromConnString...", t, func() {
+
+ Convey("non string values should be assigned to the 'WMode' "+
+ "field in their entirety", func() {
+ writeConcernString := "majority"
+ cs := &connstring.ConnString{
+ W: writeConcernString,
+ }
+ writeConcern, err := constructSafetyFromConnString(cs)
+ So(err, ShouldBeNil)
+ So(writeConcern.WMode, ShouldEqual, writeConcernString)
+ })
+
+ Convey("Int values should be assigned to the 'w' field ", func() {
+ cs := &connstring.ConnString{
+ W: "4",
+ }
+ writeConcern, err := constructSafetyFromConnString(cs)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, 4)
+ })
+
+ Convey("&connstrings with valid j, wtimeout, fsync and w, should be "+
+ "assigned accordingly", func() {
+ expectedW := 3
+ expectedWTimeout := 43
+ cs := &connstring.ConnString{
+ W: "3",
+ Journal: true,
+ FSync: false,
+ WTimeout: time.Second * 43,
+ }
+ writeConcern, err := constructSafetyFromConnString(cs)
+ So(err, ShouldBeNil)
+ So(writeConcern.W, ShouldEqual, expectedW)
+ So(writeConcern.J, ShouldBeTrue)
+ So(writeConcern.FSync, ShouldBeFalse)
+ So(writeConcern.WTimeout, ShouldEqual, expectedWTimeout)
+ })
+
+ Convey("Unacknowledge write concern strings should return a nil object "+
+ "if journaling is not required", func() {
+ cs := &connstring.ConnString{
+ W: "0",
+ }
+ writeConcern, err := constructSafetyFromConnString(cs)
+ fmt.Println(writeConcern)
+ So(err, ShouldBeNil)
+ So(writeConcern, ShouldBeNil)
+ })
+ })
+}