diff options
author | David Bradford <david.bradford@mongodb.com> | 2018-02-15 15:23:13 -0500 |
---|---|---|
committer | David Bradford <david.bradford@mongodb.com> | 2018-02-15 15:23:13 -0500 |
commit | aa8388487e3bea0737237b48a06e6b20b243e791 (patch) | |
tree | c0773560c7d6acb2b45c8ccb6f1e38e2cff7f605 /jstests | |
parent | caf6f27ec26a5b0d325e2fcbad39d0239f798a43 (diff) | |
download | mongo-aa8388487e3bea0737237b48a06e6b20b243e791.tar.gz |
SERVER-33034: Update jstest asserts to accept a function for messages
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/auth/killop_own_ops.js | 12 | ||||
-rw-r--r-- | jstests/noPassthrough/shell_assertions.js | 527 | ||||
-rw-r--r-- | jstests/noPassthrough/shell_cmd_assertions.js | 38 | ||||
-rw-r--r-- | jstests/noPassthrough/shell_write_assertions.js | 89 | ||||
-rw-r--r-- | jstests/noPassthroughWithMongod/connections_opened.js | 12 |
5 files changed, 663 insertions, 15 deletions
diff --git a/jstests/auth/killop_own_ops.js b/jstests/auth/killop_own_ops.js index 6ebfc99d28d..c128e7f0ba0 100644 --- a/jstests/auth/killop_own_ops.js +++ b/jstests/auth/killop_own_ops.js @@ -71,10 +71,8 @@ o = ops(); return o.length == 1; }, - { - toString: function() { - return tojson(db.currentOp().inprog); - } + () => { + return tojson(db.currentOp().inprog); }, 60000); @@ -117,10 +115,8 @@ o2 = ops(); return o2.length == 1; }, - { - toString: function() { - return tojson(db.currentOp().inprog); - } + () => { + return tojson(db.currentOp().inprog); }, 60000); diff --git a/jstests/noPassthrough/shell_assertions.js b/jstests/noPassthrough/shell_assertions.js new file mode 100644 index 00000000000..299dbc00d53 --- /dev/null +++ b/jstests/noPassthrough/shell_assertions.js @@ -0,0 +1,527 @@ +/** + * Tests for the assertion functions in mongo/shell/assert.js. + */ +(() => { + "use strict"; + + const tests = []; + + const kDefaultTimeoutMS = 10 * 1000; + const kSmallTimeoutMS = 200; + const kSmallRetryIntervalMS = 1; + const kDefaultRetryAttempts = 5; + + /* doassert tests */ + + tests.push(function callingDoAssertWithStringThrowsException() { + const expectedError = 'hello world'; + const actualError = assert.throws(() => { + doassert(expectedError); + }); + + assert.eq('Error: ' + expectedError, + actualError, + 'doAssert should throw passed msg as exception'); + }); + + tests.push(function callingDoAssertWithObjectThrowsException() { + const expectedError = {err: 'hello world'}; + const actualError = assert.throws(() => { + doassert(expectedError); + }); + + assert.eq('Error: ' + tojson(expectedError), + actualError, + 'doAssert should throw passed object as exception'); + }); + + tests.push(function callingDoAssertWithStringPassedAsFunctionThrowsException() { + const expectedError = 'hello world'; + const actualError = assert.throws(() => { + doassert(() => { + return expectedError; + }); + }); + + assert.eq('Error: ' + expectedError, + actualError, + 'doAssert should throw passed msg as exception'); + }); + + tests.push(function callingDoAssertWithObjectAsFunctionThrowsException() { + const expectedError = {err: 'hello world'}; + const actualError = assert.throws(() => { + doassert(() => { + return expectedError; + }); + }); + + assert.eq('Error: ' + tojson(expectedError), + actualError, + 'doAssert should throw passed object as exception'); + }); + + /* assert tests */ + + tests.push(function assertShouldFailForMoreThan2Args() { + const err = assert.throws(() => { + assert(1, 2, 3); + }); + assert.neq(-1, + err.message.indexOf('Too many parameters'), + 'Too many params message should be displayed'); + }); + + tests.push(function assertShouldNotThrowExceptionForTrue() { + assert.doesNotThrow(() => { + assert(true, 'message'); + }); + }); + + tests.push(function assertShouldThrowExceptionForFalse() { + const expectedMessage = 'message'; + const err = assert.throws(() => { + assert(false, expectedMessage); + }); + + assert.neq( + -1, err.message.indexOf(expectedMessage), 'assert message should be thrown on error'); + }); + + tests.push(function assertShouldThrowExceptionForFalseWithDefaultMessage() { + const defaultMessage = 'assert failed'; + const err = assert.throws(() => { + assert(false); + }); + + assert.eq(defaultMessage, err.message, 'assert message should be thrown on error'); + }); + + tests.push(function assertShouldThrowExceptionForFalseWithDefaultMessagePrefix() { + const prefix = 'assert failed'; + const message = 'the assertion failed'; + const err = assert.throws(() => { + assert(false, message); + }); + + assert.neq(-1, err.message.indexOf(prefix), 'assert message should should contain prefix'); + assert.neq(-1, + err.message.indexOf(message), + 'assert message should should contain original message'); + }); + + tests.push(function assertShouldNotCallMsgFunctionsOnSuccess() { + var called = false; + + assert(true, () => { + called = true; + }); + + assert.eq(false, called, 'called should not have been udpated'); + }); + + tests.push(function assertShouldCallMsgFunctionsOnFailure() { + var called = false; + + assert.throws(() => { + assert(false, () => { + called = true; + return 'error message'; + }); + }); + + assert.eq(true, called, 'called should not have been udpated'); + }); + + /* assert.automsg tests */ + + tests.push(function automsgShouldPassToAssert() { + const defaultMessage = '1 === 2'; + const err = assert.throws(() => { + assert.automsg(defaultMessage); + }); + + assert.neq(-1, err.message.indexOf(defaultMessage), 'default message should be returned'); + }); + + /* assert.eq tests */ + + tests.push(function eqShouldPassOnEquality() { + assert.doesNotThrow(() => { + assert.eq(3, 3); + }); + }); + + tests.push(function eqShouldFailWhenNotEqual() { + assert.throws(() => { + assert.eq(2, 3); + }); + }); + + tests.push(function eqShouldNotCallMsgFunctionOnSuccess() { + var called = false; + + assert.doesNotThrow(() => { + assert.eq(3, 3, () => { + called = true; + }); + }); + + assert.eq(false, called, 'msg function should not have been called'); + }); + + tests.push(function eqShouldCallMsgFunctionOnFailure() { + var called = false; + + assert.throws(() => { + assert.eq(1, 3, () => { + called = true; + }); + }); + + assert.eq(true, called, 'msg function should have been called'); + }); + + /* assert.eq.automsg tests */ + + tests.push(function eqAutomsgShouldCreateMessage() { + const defaultMessage = '[1] != [2]'; + const err = assert.throws(() => { + assert.eq.automsg(1, 2); + }); + + assert.neq(-1, err.message.indexOf(defaultMessage), 'default message should be returned'); + }); + + /* assert.neq tests */ + + tests.push(function neqShouldFailOnEquality() { + assert.throws(() => { + assert.neq(3, 3); + }); + }); + + tests.push(function neqShouldPassWhenNotEqual() { + assert.doesNotThrow(() => { + assert.neq(2, 3); + }); + }); + + /* assert.hasFields tests */ + + tests.push(function hasFieldsRequiresAnArrayOfFields() { + const object = {field1: 1, field2: 1, field3: 1}; + + assert.throws(() => { + assert.hasFields(object, 'field1'); + }); + }); + + tests.push(function hasFieldsShouldPassWhenObjectHasField() { + const object = {field1: 1, field2: 1, field3: 1}; + + assert.doesNotThrow(() => { + assert.hasFields(object, ['field1']); + }); + }); + + tests.push(function hasFieldsShouldFailWhenObjectDoesNotHaveField() { + const object = {field1: 1, field2: 1, field3: 1}; + + assert.throws(() => { + assert.hasFields(object, ['fieldDoesNotExist']); + }); + }); + + /* assert.contains tests */ + + tests.push(function containsShouldOnlyWorkOnArrays() { + assert.throws(() => { + assert.contains(42, 5); + }); + }); + + tests.push(function containsShouldPassIfArrayContainsValue() { + const array = [1, 2, 3]; + + assert.doesNotThrow(() => { + assert.contains(2, array); + }); + }); + + tests.push(function containsShouldFailIfArrayDoesNotContainValue() { + const array = [1, 2, 3]; + + assert.throws(() => { + assert.contains(42, array); + }); + }); + + /* assert.soon tests */ + + tests.push(function soonPassesWhenFunctionPasses() { + assert.doesNotThrow(() => { + assert.soon(() => { + return true; + }); + }); + }); + + tests.push(function soonFailsIfMethodNeverPasses() { + assert.throws(() => { + assert.soon(() => { + return false; + }, 'assert message', kSmallTimeoutMS, kSmallRetryIntervalMS); + }); + }); + + tests.push(function soonPassesIfMethodEventuallyPasses() { + var count = 0; + assert.doesNotThrow(() => { + assert.soon(() => { + count += 1; + return count === 3; + }, 'assert message', kDefaultTimeoutMS, kSmallRetryIntervalMS); + }); + }); + + /* assert.soonNoExcept tests */ + + tests.push(function soonNoExceptEventuallyPassesEvenWithExceptions() { + var count = 0; + assert.doesNotThrow(() => { + assert.soonNoExcept(() => { + count += 1; + if (count < 3) { + throw new Error('failed'); + } + return true; + }, 'assert message', kDefaultTimeoutMS, kSmallRetryIntervalMS); + }); + }); + + tests.push(function soonNoExceptFailsIfExceptionAlwaysThrown() { + var count = 0; + assert.throws(() => { + assert.soonNoExcept(() => { + throw new Error('failed'); + }, 'assert message', kSmallTimeoutMS, kSmallRetryIntervalMS); + }); + }); + + /* assert.retry tests */ + + tests.push(function retryPassesAfterAFewAttempts() { + var count = 0; + + assert.doesNotThrow(() => { + assert.retry(() => { + count += 1; + return count === 3; + }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); + }); + }); + + tests.push(function retryFailsAfterMaxAttempts() { + assert.throws(() => { + assert.retry(() => { + return false; + }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); + }); + }); + + /* assert.retryNoExcept tests */ + + tests.push(function retryNoExceptPassesAfterAFewAttempts() { + var count = 0; + + assert.doesNotThrow(() => { + assert.retryNoExcept(() => { + count += 1; + if (count < 3) { + throw new Error('failed'); + } + return count === 3; + }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); + }); + }); + + tests.push(function retryNoExceptFailsAfterMaxAttempts() { + assert.throws(() => { + assert.retryNoExcept(() => { + throw new Error('failed'); + }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); + }); + }); + + /* assert.time tests */ + + tests.push(function timeIsSuccessfulIfFuncExecutesInTime() { + assert.doesNotThrow(() => { + assert.time(() => { + return true; + }, 'assert message', kDefaultTimeoutMS); + }); + }); + + tests.push(function timeFailsIfFuncDoesNotFinishInTime() { + assert.throws(() => { + assert.time(() => { + return true; + }, 'assert message', -5 * 60 * 1000); + }); + }); + + /* assert.isnull tests */ + + tests.push(function isnullPassesOnNull() { + assert.doesNotThrow(() => { + assert.isnull(null); + }); + }); + + tests.push(function isnullPassesOnUndefined() { + assert.doesNotThrow(() => { + assert.isnull(undefined); + }); + }); + + tests.push(function isnullFailsOnNotNull() { + assert.throws(() => { + assert.isnull('hello world'); + }); + }); + + /* assert.lt tests */ + + tests.push(function ltPassesWhenLessThan() { + assert.doesNotThrow(() => { + assert.lt(3, 5); + }); + }); + + tests.push(function ltFailsWhenNotLessThan() { + assert.throws(() => { + assert.lt(5, 3); + }); + }); + + tests.push(function ltFailsWhenEqual() { + assert.throws(() => { + assert.lt(5, 5); + }); + }); + + /* assert.gt tests */ + + tests.push(function gtPassesWhenGreaterThan() { + assert.doesNotThrow(() => { + assert.gt(5, 3); + }); + }); + + tests.push(function gtFailsWhenNotGreaterThan() { + assert.throws(() => { + assert.gt(3, 5); + }); + }); + + tests.push(function gtFailsWhenEqual() { + assert.throws(() => { + assert.gt(5, 5); + }); + }); + + /* assert.lte tests */ + + tests.push(function ltePassesWhenLessThan() { + assert.doesNotThrow(() => { + assert.lte(3, 5); + }); + }); + + tests.push(function lteFailsWhenNotLessThan() { + assert.throws(() => { + assert.lte(5, 3); + }); + }); + + tests.push(function ltePassesWhenEqual() { + assert.doesNotThrow(() => { + assert.lte(5, 5); + }); + }); + + /* assert.gte tests */ + + tests.push(function gtePassesWhenGreaterThan() { + assert.doesNotThrow(() => { + assert.gte(5, 3); + }); + }); + + tests.push(function gteFailsWhenNotGreaterThan() { + assert.throws(() => { + assert.gte(3, 5); + }); + }); + + tests.push(function gtePassesWhenEqual() { + assert.doesNotThrow(() => { + assert.gte(5, 5); + }); + }); + + /* assert.betweenIn tests */ + + tests.push(function betweenInPassWhenNumberIsBetween() { + assert.doesNotThrow(() => { + assert.betweenIn(3, 4, 5); + }); + }); + + tests.push(function betweenInFailsWhenNumberIsNotBetween() { + assert.throws(() => { + assert.betweenIn(3, 5, 4); + }); + }); + + tests.push(function betweenInPassWhenNumbersEqual() { + assert.doesNotThrow(() => { + assert.betweenIn(3, 3, 5); + }); + assert.doesNotThrow(() => { + assert.betweenIn(3, 5, 5); + }); + }); + + /* assert.betweenEx tests */ + + tests.push(function betweenExPassWhenNumberIsBetween() { + assert.doesNotThrow(() => { + assert.betweenEx(3, 4, 5); + }); + }); + + tests.push(function betweenExFailsWhenNumberIsNotBetween() { + assert.throws(() => { + assert.betweenEx(3, 5, 4); + }); + }); + + tests.push(function betweenExFailsWhenNumbersEqual() { + assert.throws(() => { + assert.betweenEx(3, 3, 5); + }); + assert.throws(() => { + assert.betweenEx(3, 5, 5); + }); + }); + + /* main */ + + tests.forEach((test) => { + jsTest.log(`Starting tests '${test.name}'`); + test(); + }); +})(); diff --git a/jstests/noPassthrough/shell_cmd_assertions.js b/jstests/noPassthrough/shell_cmd_assertions.js index d0a5dbaeaff..669b442a37d 100644 --- a/jstests/noPassthrough/shell_cmd_assertions.js +++ b/jstests/noPassthrough/shell_cmd_assertions.js @@ -1,3 +1,6 @@ +/** + * Tests for the command assertion functions in mongo/shell/assert.js. + */ (function() { "use strict"; const conn = MongoRunner.runMongod(); @@ -19,6 +22,40 @@ assert.throws(() => assert.commandFailedWithCode(res, 0)); }); + function _assertMsgFunctionExecution( + assertFunc, assertParameter, {expectException: expectException = false} = {}) { + var msgFunctionCalled = false; + var expectedAssert = assert.doesNotThrow; + + if (expectException) { + expectedAssert = assert.throws; + } + + expectedAssert(() => { + assertFunc(assertParameter, () => { + msgFunctionCalled = true; + }); + }); + + assert.eq( + expectException, msgFunctionCalled, "msg function execution should match assertion"); + } + + tests.push(function msgFunctionOnlyCalledOnFailure() { + const res = db.runCommand({"ping": 1}); + + _assertMsgFunctionExecution(assert.commandWorked, res, {expectException: false}); + _assertMsgFunctionExecution( + assert.commandWorkedIgnoringWriteErrors, res, {expectException: false}); + _assertMsgFunctionExecution(assert.commandFailed, res, {expectException: true}); + + var msgFunctionCalled = false; + assert.throws(() => assert.commandFailedWithCode(res, 0, () => { + msgFunctionCalled = true; + })); + assert.eq(true, msgFunctionCalled, "msg function execution should match assertion"); + }); + tests.push(function rawCommandErr() { const res = db.runCommand({"IHopeNobodyEverMakesThisACommand": 1}); assert.throws(() => assert.commandWorked(res)); @@ -252,5 +289,6 @@ test(); }); + /* cleanup */ MongoRunner.stopMongod(conn); })(); diff --git a/jstests/noPassthrough/shell_write_assertions.js b/jstests/noPassthrough/shell_write_assertions.js new file mode 100644 index 00000000000..e3473bd445e --- /dev/null +++ b/jstests/noPassthrough/shell_write_assertions.js @@ -0,0 +1,89 @@ +/** + * Tests for the write assertion functions in mongo/shell/assert.js. + */ +(() => { + "use strict"; + const conn = MongoRunner.runMongod(); + const db = conn.getDB("writeAssertions"); + assert.neq(null, conn, "mongodb was unable to start up"); + const tests = []; + + function setup() { + db.coll.drop(); + } + + function _doFailedWrite(collection) { + const duplicateId = 42; + + const res = collection.insert({_id: duplicateId}); + assert.writeOK(res, "write to collection should have been successful"); + const failedRes = collection.insert({_id: duplicateId}); + assert.writeError(failedRes, "duplicate key write should have failed"); + return failedRes; + } + + /* writeOK tests */ + tests.push(function writeOKSuccessfulWriteDoesNotCallMsgFunction() { + var msgFunctionCalled = false; + + const result = db.coll.insert({data: "hello world"}); + assert.doesNotThrow(() => { + assert.writeOK(result, () => { + msgFunctionCalled = true; + }); + }); + + assert.eq(false, msgFunctionCalled, "message function should not have been called"); + }); + + tests.push(function writeOKUnsuccessfulWriteDoesCallMsgFunction() { + var msgFunctionCalled = false; + + const failedResult = _doFailedWrite(db.coll); + assert.throws(() => { + assert.writeOK(failedResult, () => { + msgFunctionCalled = true; + }); + }); + + assert.eq(true, msgFunctionCalled, "message function should have been called"); + }); + + /* writeError tests */ + tests.push(function writeErrorSuccessfulWriteDoesCallMsgFunction() { + var msgFunctionCalled = false; + + const result = db.coll.insert({data: "hello world"}); + assert.throws(() => { + assert.writeError(result, () => { + msgFunctionCalled = true; + }); + }); + + assert.eq(true, msgFunctionCalled, "message function should have been called"); + }); + + tests.push(function writeErrorUnsuccessfulWriteDoesNotCallMsgFunction() { + var msgFunctionCalled = false; + + const failedResult = _doFailedWrite(db.coll); + assert.doesNotThrow(() => { + assert.writeError(failedResult, () => { + msgFunctionCalled = true; + }); + }); + + assert.eq(false, msgFunctionCalled, "message function should not have been called"); + }); + + /* main */ + + tests.forEach((test) => { + jsTest.log(`Starting tests '${test.name}'`); + setup(); + test(); + }); + + /* cleanup */ + MongoRunner.stopMongod(conn); +})(); diff --git a/jstests/noPassthroughWithMongod/connections_opened.js b/jstests/noPassthroughWithMongod/connections_opened.js index d3d141ab5a1..ecd2076f2af 100644 --- a/jstests/noPassthroughWithMongod/connections_opened.js +++ b/jstests/noPassthroughWithMongod/connections_opened.js @@ -47,13 +47,11 @@ function waitForConnections(expectedCurrentConnections, expectedTotalConnections return (expectedCurrentConnections == currentConnInfo.current) && (expectedTotalConnections, currentConnInfo.totalCreated); }, - { - toString: function() { - return "Incorrect connection numbers. Expected " + expectedCurrentConnections + - " current connections and " + expectedTotalConnections + " total" + - " connections. Connection info from serverStatus: " + - tojson(db.serverStatus().connections); - } + () => { + return "Incorrect connection numbers. Expected " + expectedCurrentConnections + + " current connections and " + expectedTotalConnections + " total" + + " connections. Connection info from serverStatus: " + + tojson(db.serverStatus().connections); }, 5 * 60000); } |