summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands/mr_test.cpp
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2014-06-28 00:54:54 -0400
committerBenety Goh <benety@mongodb.com>2014-07-01 11:43:45 -0400
commit77f636c4606e01f28c1d8c6bb6606487ede2ffc8 (patch)
treee07ba7c1f175e4d9b665596ccee2329e614d0662 /src/mongo/db/commands/mr_test.cpp
parentef3e85d4f5b67c039668cef805459e29711aa636 (diff)
downloadmongo-77f636c4606e01f28c1d8c6bb6606487ede2ffc8.tar.gz
SERVER-5378 added tests for parsing map reduce output options
Diffstat (limited to 'src/mongo/db/commands/mr_test.cpp')
-rw-r--r--src/mongo/db/commands/mr_test.cpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/mongo/db/commands/mr_test.cpp b/src/mongo/db/commands/mr_test.cpp
new file mode 100644
index 00000000000..aeab70dc4a9
--- /dev/null
+++ b/src/mongo/db/commands/mr_test.cpp
@@ -0,0 +1,145 @@
+/**
+ * Copyright (C) 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+/**
+ * This file contains tests for mongo/db/commands/mr.h
+ */
+
+#include "mongo/db/commands/mr.h"
+
+#include <string>
+
+#include "mongo/db/json.h"
+#include "mongo/unittest/unittest.h"
+
+using namespace mongo;
+
+namespace {
+
+ /**
+ * Tests for mr::Config
+ */
+
+ /**
+ * Helper function to verify field of mr::Config::OutputOptions.
+ */
+ template <typename T> void _compareOutputOptionField(const std::string& dbname,
+ const std::string& cmdObjStr,
+ const std::string& fieldName,
+ const T& actual, const T& expected) {
+ if (actual == expected) return;
+ FAIL(str::stream() << "parseOutputOptions(\"" << dbname << ", " << cmdObjStr << "): "
+ << fieldName << ": Expected: " << expected << ". Actual: " << actual);
+ }
+
+ /**
+ * Returns string representation of mr::Config::OutputType
+ */
+ std::string _getOutTypeString(mr::Config::OutputType outType) {
+ switch (outType) {
+ case mr::Config::REPLACE: return "REPLACE";
+ case mr::Config::MERGE: return "MERGE";
+ case mr::Config::REDUCE: return "REDUCE";
+ case mr::Config::INMEMORY: return "INMEMORY";
+ }
+ invariant(0);
+ }
+
+ /**
+ * Test helper function to check expected result of parseOutputOptions.
+ */
+ void _testConfigParseOutputOptions(const std::string& dbname, const std::string& cmdObjStr,
+ const std::string& expectedOutDb,
+ const std::string& expectedCollectionName,
+ const std::string& expectedFinalNamespace,
+ bool expectedOutNonAtomic,
+ mr::Config::OutputType expectedOutType) {
+ const BSONObj cmdObj = fromjson(cmdObjStr);
+ mr::Config::OutputOptions outputOptions = mr::Config::parseOutputOptions(dbname, cmdObj);
+ _compareOutputOptionField(dbname, cmdObjStr, "outDb", outputOptions.outDB, expectedOutDb);
+ _compareOutputOptionField(dbname, cmdObjStr, "collectionName",
+ outputOptions.collectionName, expectedCollectionName);
+ _compareOutputOptionField(dbname, cmdObjStr, "finalNamespace",
+ outputOptions.finalNamespace, expectedFinalNamespace);
+ _compareOutputOptionField(dbname, cmdObjStr, "outNonAtomic", outputOptions.outNonAtomic,
+ expectedOutNonAtomic);
+ _compareOutputOptionField(dbname, cmdObjStr, "outType",
+ _getOutTypeString(outputOptions.outType),
+ _getOutTypeString(expectedOutType));
+ }
+
+ /**
+ * Tests for mr::Config::parseOutputOptions.
+ */
+ TEST(ConfigOutputOptionsTest, parseOutputOptions) {
+ // Missing 'out' field.
+ ASSERT_THROWS(mr::Config::parseOutputOptions("mydb", fromjson("{}")), UserException);
+ // 'out' must be either string or object.
+ ASSERT_THROWS(mr::Config::parseOutputOptions("mydb", fromjson("{out: 99}")),
+ UserException);
+ // 'out.nonAtomic' is not supported with normal, replace or inline.
+ ASSERT_THROWS(mr::Config::parseOutputOptions(
+ "mydb",
+ fromjson("{out: {normal: 'mycoll', nonAtomic: true}}")),
+ UserException);
+ ASSERT_THROWS(mr::Config::parseOutputOptions(
+ "mydb",
+ fromjson("{out: {replace: 'mycoll', nonAtomic: true}}")),
+ UserException);
+ ASSERT_THROWS(mr::Config::parseOutputOptions(
+ "mydb",
+ fromjson("{out: {inline: 'mycoll', nonAtomic: true}}")),
+ UserException);
+ // Unknown output specifer.
+ ASSERT_THROWS(mr::Config::parseOutputOptions(
+ "mydb",
+ fromjson("{out: {no_such_out_type: 'mycoll'}}")),
+ UserException);
+
+
+ // 'out' is string.
+ _testConfigParseOutputOptions("mydb", "{out: 'mycoll'}",
+ "", "mycoll", "mydb.mycoll", false, mr::Config::REPLACE);
+ // 'out' is object.
+ _testConfigParseOutputOptions("mydb", "{out: {normal: 'mycoll'}}",
+ "", "mycoll", "mydb.mycoll", false, mr::Config::REPLACE);
+ // 'out.db' overrides dbname parameter
+ _testConfigParseOutputOptions("mydb1", "{out: {replace: 'mycoll', db: 'mydb2'}}",
+ "mydb2", "mycoll", "mydb2.mycoll", false,
+ mr::Config::REPLACE);
+ // 'out.nonAtomic' is supported with merge and reduce.
+ _testConfigParseOutputOptions("mydb", "{out: {merge: 'mycoll', nonAtomic: true}}",
+ "", "mycoll", "mydb.mycoll", true, mr::Config::MERGE);
+ _testConfigParseOutputOptions("mydb", "{out: {reduce: 'mycoll', nonAtomic: true}}",
+ "", "mycoll", "mydb.mycoll", true, mr::Config::REDUCE);
+ // inline
+ _testConfigParseOutputOptions("mydb1", "{out: {inline: 'mycoll', db: 'mydb2'}}",
+ "mydb2", "", "", false, mr::Config::INMEMORY);
+ }
+
+} // namespace