mirror of https://github.com/mongodb/mongo
SERVER-101755 Add string substitution to assertion messages (#34437)
GitOrigin-RevId: 344c864a3ad16675ce9190e47ebfba143c741660
This commit is contained in:
parent
e3315cf7d7
commit
a918fa85ba
|
|
@ -576,7 +576,7 @@ class TestExceptionExtraction(unittest.TestCase):
|
||||||
]
|
]
|
||||||
output = execute_resmoke(resmoke_args).stdout
|
output = execute_resmoke(resmoke_args).stdout
|
||||||
|
|
||||||
expected = "The following tests failed (with exit code):\n buildscripts/tests/resmoke_end2end/failtestfiles/js_failure.js (253 Failure executing JS file)\n uncaught exception: Error: [true] != [false] are not equal"
|
expected = "The following tests failed (with exit code):\n buildscripts/tests/resmoke_end2end/failtestfiles/js_failure.js (253 Failure executing JS file)\n uncaught exception: Error: [true] and [false] are not equal"
|
||||||
assert expected in output
|
assert expected in output
|
||||||
|
|
||||||
def test_resmoke_fixture_error(self):
|
def test_resmoke_fixture_error(self):
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ export default [
|
||||||
assert: true,
|
assert: true,
|
||||||
doassert: true,
|
doassert: true,
|
||||||
sortDoc: true,
|
sortDoc: true,
|
||||||
|
formatErrorMsg: true,
|
||||||
|
|
||||||
// src/mongo/shell/bridge.d.ts
|
// src/mongo/shell/bridge.d.ts
|
||||||
MongoBridge: true,
|
MongoBridge: true,
|
||||||
|
|
@ -189,7 +190,6 @@ export default [
|
||||||
isString: true,
|
isString: true,
|
||||||
printjson: true,
|
printjson: true,
|
||||||
printjsononeline: true,
|
printjsononeline: true,
|
||||||
stringifyErrorMessageAndAttributes: true,
|
|
||||||
toJsonForLog: true,
|
toJsonForLog: true,
|
||||||
tojson: true,
|
tojson: true,
|
||||||
tojsonObject: true,
|
tojsonObject: true,
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ export const $config = (function() {
|
||||||
// become refined. Retrying swapping the zone range will allow us to target the
|
// become refined. Retrying swapping the zone range will allow us to target the
|
||||||
// shard key in its refined state.
|
// shard key in its refined state.
|
||||||
const newShardKeyField = this.newShardKeyFields[1];
|
const newShardKeyField = this.newShardKeyFields[1];
|
||||||
const errorMsg = stringifyErrorMessageAndAttributes(e);
|
const errorMsg = formatErrorMsg(e.message, e.extraAttr);
|
||||||
if ((errorMsg.includes(newShardKeyField) && errorMsg.includes('are not equal')) ||
|
if ((errorMsg.includes(newShardKeyField) && errorMsg.includes('are not equal')) ||
|
||||||
(errorMsg.includes(newShardKeyField) &&
|
(errorMsg.includes(newShardKeyField) &&
|
||||||
errorMsg.includes('assert.eq() failed'))) {
|
errorMsg.includes('assert.eq() failed'))) {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ export const $config = extendWorkload($baseConfig, function($config, $super) {
|
||||||
// migrated back in. The particular error code is replaced with a more generic one, so this is
|
// migrated back in. The particular error code is replaced with a more generic one, so this is
|
||||||
// identified by the failed migration's error message.
|
// identified by the failed migration's error message.
|
||||||
$config.data.isMoveChunkErrorAcceptable = (err) => {
|
$config.data.isMoveChunkErrorAcceptable = (err) => {
|
||||||
const errorMsg = stringifyErrorMessageAndAttributes(err);
|
const errorMsg = formatErrorMsg(err.message, err.extraAttr);
|
||||||
return (errorMsg.includes("CommandFailed") ||
|
return (errorMsg.includes("CommandFailed") ||
|
||||||
errorMsg.includes("Documents in target range may still be in use") ||
|
errorMsg.includes("Documents in target range may still be in use") ||
|
||||||
// This error can occur when the test updates the shard key value of a document
|
// This error can occur when the test updates the shard key value of a document
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ const expectedGlobalVars = [
|
||||||
"escape",
|
"escape",
|
||||||
"eval",
|
"eval",
|
||||||
"eventResumeTokenType",
|
"eventResumeTokenType",
|
||||||
|
"formatErrorMsg",
|
||||||
"gc",
|
"gc",
|
||||||
"getJSHeapLimitMB",
|
"getJSHeapLimitMB",
|
||||||
"globalThis",
|
"globalThis",
|
||||||
|
|
@ -110,7 +111,6 @@ const expectedGlobalVars = [
|
||||||
"isNumber",
|
"isNumber",
|
||||||
"isObject",
|
"isObject",
|
||||||
"isString",
|
"isString",
|
||||||
"stringifyErrorMessageAndAttributes",
|
|
||||||
"parseFloat",
|
"parseFloat",
|
||||||
"parseInt",
|
"parseInt",
|
||||||
"print",
|
"print",
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ ShardingTest.prototype.checkUUIDsConsistentAcrossCluster = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (stringifyErrorMessageAndAttributes(e).indexOf("Unauthorized") < 0) {
|
if (formatErrorMsg(e.message, e.extraAttr).indexOf("Unauthorized") < 0) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
jsTest.log.info("ignoring exception while checking UUID consistency across cluster",
|
jsTest.log.info("ignoring exception while checking UUID consistency across cluster",
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,9 @@ for (let config of invalidMixedVersionsToCheck) {
|
||||||
() => new ShardingTest({shouldFailInit: true, shards: config.shards, other: config.other}));
|
() => new ShardingTest({shouldFailInit: true, shards: config.shards, other: config.other}));
|
||||||
assert.eq(
|
assert.eq(
|
||||||
true,
|
true,
|
||||||
err.message.includes(
|
formatErrorMsg(err.message, err.extraAttr)
|
||||||
"Can only specify one of 'last-lts' and 'last-continuous' in binVersion, not both."),
|
.includes(
|
||||||
|
"Can only specify one of 'last-lts' and 'last-continuous' in binVersion, not both."),
|
||||||
"Unexpected Error");
|
"Unexpected Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -793,17 +793,18 @@ tests.push(function assertJsonFormat() {
|
||||||
tests.push(function assertEqJsonFormat() {
|
tests.push(function assertEqJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.eq(5, 2 + 2, "lorem ipsum");
|
assert.eq(5, 2 + 2, "lorem ipsum");
|
||||||
}, {msg: "assert.eq() failed : lorem ipsum", attr: {a: 5, b: 4}});
|
}, {msg: "[{a}] and [{b}] are not equal : lorem ipsum", attr: {a: 5, b: 4}});
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.eq(5, 2 + 2, "lorem ipsum", kAttr);
|
assert.eq(5, 2 + 2, "lorem ipsum", kAttr);
|
||||||
}, {msg: "assert.eq() failed : lorem ipsum", attr: {a: 5, b: 4, ...kAttr}});
|
}, {msg: "[{a}] and [{b}] are not equal : lorem ipsum", attr: {a: 5, b: 4, ...kAttr}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertDocEqJsonFormat() {
|
tests.push(function assertDocEqJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.docEq({msg: "hello"}, {msg: "goodbye"}, "lorem ipsum", kAttr);
|
assert.docEq({msg: "hello"}, {msg: "goodbye"}, "lorem ipsum", kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.docEq() failed : lorem ipsum",
|
msg:
|
||||||
|
"expected document {expectedDoc} and actual document {actualDoc} are not equal : lorem ipsum",
|
||||||
attr: {expectedDoc: {msg: "hello"}, actualDoc: {msg: "goodbye"}, ...kAttr}
|
attr: {expectedDoc: {msg: "hello"}, actualDoc: {msg: "goodbye"}, ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -812,7 +813,7 @@ tests.push(function assertSetEqJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.setEq(new Set([1, 2, 3]), new Set([4, 5]), "lorem ipsum", kAttr);
|
assert.setEq(new Set([1, 2, 3]), new Set([4, 5]), "lorem ipsum", kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.setEq() failed : lorem ipsum",
|
msg: "expected set {expectedSet} and actual set {actualSet} are not equal : lorem ipsum",
|
||||||
attr: {expectedSet: [1, 2, 3], actualSet: [4, 5], ...kAttr}
|
attr: {expectedSet: [1, 2, 3], actualSet: [4, 5], ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -821,7 +822,7 @@ tests.push(function assertSameMembersJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.sameMembers([1, 2], [1], "Oops!", assert._isDocEq, kAttr);
|
assert.sameMembers([1, 2], [1], "Oops!", assert._isDocEq, kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.sameMembers() failed : Oops!",
|
msg: "{aArr} != {bArr} : Oops!",
|
||||||
attr: {aArr: [1, 2], bArr: [1], compareFn: "_isDocEq", ...kAttr}
|
attr: {aArr: [1, 2], bArr: [1], compareFn: "_isDocEq", ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -830,7 +831,7 @@ tests.push(function assertFuzzySameMembersJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.fuzzySameMembers([{soccer: 42}], [{score: 42000}], ["score"], "Oops!", 4, kAttr);
|
assert.fuzzySameMembers([{soccer: 42}], [{score: 42000}], ["score"], "Oops!", 4, kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.sameMembers() failed : Oops!",
|
msg: "{aArr} != {bArr} : Oops!",
|
||||||
attr: {aArr: [{soccer: 42}], bArr: [{score: 42000}], compareFn: "fuzzyCompare", ...kAttr}
|
attr: {aArr: [{soccer: 42}], bArr: [{score: 42000}], compareFn: "fuzzyCompare", ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -838,14 +839,14 @@ tests.push(function assertFuzzySameMembersJsonFormat() {
|
||||||
tests.push(function assertNeqJsonFormat() {
|
tests.push(function assertNeqJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.neq(42, 42, "Oops!", kAttr);
|
assert.neq(42, 42, "Oops!", kAttr);
|
||||||
}, {msg: "assert.neq() failed : Oops!", attr: {a: 42, b: 42, ...kAttr}});
|
}, {msg: "[{a}] and [{b}] are equal : Oops!", attr: {a: 42, b: 42, ...kAttr}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertHasFieldsJsonFormat() {
|
tests.push(function assertHasFieldsJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.hasFields({hello: "world"}, ["goodbye"], "Oops!", kAttr);
|
assert.hasFields({hello: "world"}, ["goodbye"], "Oops!", kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.hasFields() failed : Oops!",
|
msg: "Not all of the values from {arr} were in {result} : Oops!",
|
||||||
attr: {result: {hello: "world"}, arr: ["goodbye"], ...kAttr}
|
attr: {result: {hello: "world"}, arr: ["goodbye"], ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -853,20 +854,23 @@ tests.push(function assertHasFieldsJsonFormat() {
|
||||||
tests.push(function assertContainsJsonFormat() {
|
tests.push(function assertContainsJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.contains(3, [14, 15, 926], "Oops!", kAttr);
|
assert.contains(3, [14, 15, 926], "Oops!", kAttr);
|
||||||
}, {msg: "assert.contains() failed : Oops!", attr: {element: 3, arr: [14, 15, 926], ...kAttr}});
|
}, {
|
||||||
|
msg: "{element} was not in {arr} : Oops!",
|
||||||
|
attr: {element: 3, arr: [14, 15, 926], ...kAttr}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertDoesNotContainJsonFormat() {
|
tests.push(function assertDoesNotContainJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.doesNotContain(3, [3, 23], "Oops!", kAttr);
|
assert.doesNotContain(3, [3, 23], "Oops!", kAttr);
|
||||||
}, {msg: "assert.doesNotContain() failed : Oops!", attr: {element: 3, arr: [3, 23], ...kAttr}});
|
}, {msg: "{element} is in {arr} : Oops!", attr: {element: 3, arr: [3, 23], ...kAttr}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertContainsPrefixJsonFormat() {
|
tests.push(function assertContainsPrefixJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.containsPrefix("hello", ["hell", "help"], "Oops!", kAttr);
|
assert.containsPrefix("hello", ["hell", "help"], "Oops!", kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.containsPrefix() failed : Oops!",
|
msg: "{prefix} was not a prefix in {arr} : Oops!",
|
||||||
attr: {prefix: "hello", arr: ["hell", "help"], ...kAttr}
|
attr: {prefix: "hello", arr: ["hell", "help"], ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -888,7 +892,7 @@ tests.push(function assertSoonNoExceptJsonFormat() {
|
||||||
tests.push(function assertRetryJsonFormat() {
|
tests.push(function assertRetryJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.retry(() => false, "Oops!", 2, 10, {runHangAnalyzer: false}, kAttr);
|
assert.retry(() => false, "Oops!", 2, 10, {runHangAnalyzer: false}, kAttr);
|
||||||
}, {msg: "assert.retry() failed : Oops!", attr: {...kAttr}});
|
}, {msg: "Oops!", attr: {...kAttr}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertRetryNoExceptJsonFormat() {
|
tests.push(function assertRetryNoExceptJsonFormat() {
|
||||||
|
|
@ -896,7 +900,7 @@ tests.push(function assertRetryNoExceptJsonFormat() {
|
||||||
assert.retryNoExcept(() => {
|
assert.retryNoExcept(() => {
|
||||||
throw Error("disaster");
|
throw Error("disaster");
|
||||||
}, "Oops!", 2, 10, {runHangAnalyzer: false}, kAttr);
|
}, "Oops!", 2, 10, {runHangAnalyzer: false}, kAttr);
|
||||||
}, {msg: "assert.retry() failed : Oops!", attr: {...kAttr}});
|
}, {msg: "Oops!", attr: {...kAttr}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertTimeJsonFormat() {
|
tests.push(function assertTimeJsonFormat() {
|
||||||
|
|
@ -908,11 +912,16 @@ tests.push(function assertTimeJsonFormat() {
|
||||||
try {
|
try {
|
||||||
assert.time(f, "Oops!", timeoutMS, {runHangAnalyzer: false}, kAttr);
|
assert.time(f, "Oops!", timeoutMS, {runHangAnalyzer: false}, kAttr);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Override the 'timeMS' to make the test deterministic.
|
// Override 'timeMS' to make the test deterministic.
|
||||||
e.extraAttr.timeMS = sleepTimeMS;
|
e.extraAttr.timeMS = sleepTimeMS;
|
||||||
|
// Override 'diff' to make the test deterministic.
|
||||||
|
e.extraAttr.diff = sleepTimeMS;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}, {msg: "assert.time() failed : Oops!", attr: {timeMS: sleepTimeMS, timeoutMS, ...kAttr}});
|
}, {
|
||||||
|
msg: "assert.time failed : Oops!",
|
||||||
|
attr: {timeMS: sleepTimeMS, timeoutMS, function: f, diff: sleepTimeMS, ...kAttr}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertThrowsJsonFormat() {
|
tests.push(function assertThrowsJsonFormat() {
|
||||||
|
|
@ -929,7 +938,7 @@ tests.push(function assertThrowsWithCodeJsonFormat() {
|
||||||
throw err;
|
throw err;
|
||||||
}, 42, [], "Oops!", kAttr);
|
}, 42, [], "Oops!", kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.throwsWithCode() failed : Oops!",
|
msg: "[{code}] and [{expectedCode}] are not equal : Oops!",
|
||||||
attr: {code: 24, expectedCode: [42], ...kAttr}
|
attr: {code: 24, expectedCode: [42], ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -941,7 +950,7 @@ tests.push(function assertDoesNotThrowJsonFormat() {
|
||||||
throw err;
|
throw err;
|
||||||
}, [], "Oops!", kAttr);
|
}, [], "Oops!", kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.doesNotThrow() failed : Oops!",
|
msg: "threw unexpected exception: {error} : Oops!",
|
||||||
attr: {error: {message: "disaster"}, ...kAttr}
|
attr: {error: {message: "disaster"}, ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -950,8 +959,8 @@ tests.push(function assertCommandWorkedWrongArgumentTypeJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.commandWorked("cmd", "Oops!");
|
assert.commandWorked("cmd", "Oops!");
|
||||||
}, {
|
}, {
|
||||||
msg: "expected result type 'object'" +
|
msg:
|
||||||
" : unexpected result type given to assert.commandWorked()",
|
"expected result type 'object', got '{resultType}', res='{result}' : unexpected result type given to assert.commandWorked()",
|
||||||
attr: {result: "cmd", resultType: "string"}
|
attr: {result: "cmd", resultType: "string"}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -968,7 +977,8 @@ tests.push(function assertCommandWorkedJsonFormat() {
|
||||||
};
|
};
|
||||||
assert.commandWorked(res, "Oops!");
|
assert.commandWorked(res, "Oops!");
|
||||||
}, {
|
}, {
|
||||||
msg: "command failed: unexpected error : Oops!",
|
msg:
|
||||||
|
"command failed: {res} with original command request: {originalCommand} with errmsg: unexpected error : Oops!",
|
||||||
attr: {
|
attr: {
|
||||||
res: {
|
res: {
|
||||||
ok: 0,
|
ok: 0,
|
||||||
|
|
@ -989,7 +999,7 @@ tests.push(function assertCommandFailedJsonFormat() {
|
||||||
const res = {ok: 1, _mongo: "connection to localhost:20000", _commandObj: {hello: 1}};
|
const res = {ok: 1, _mongo: "connection to localhost:20000", _commandObj: {hello: 1}};
|
||||||
assert.commandFailed(res, "Oops!");
|
assert.commandFailed(res, "Oops!");
|
||||||
}, {
|
}, {
|
||||||
msg: "command worked when it should have failed : Oops!",
|
msg: "command worked when it should have failed: {res} : Oops!",
|
||||||
attr: {
|
attr: {
|
||||||
res: {
|
res: {
|
||||||
ok: 1,
|
ok: 1,
|
||||||
|
|
@ -1007,7 +1017,7 @@ tests.push(function assertCommandFailedWithCodeJsonFormat() {
|
||||||
const res = {ok: 1, _mongo: "connection to localhost:20000", _commandObj: {hello: 1}};
|
const res = {ok: 1, _mongo: "connection to localhost:20000", _commandObj: {hello: 1}};
|
||||||
assert.commandFailedWithCode(res, ErrorCodes.BadValue, "Oops!");
|
assert.commandFailedWithCode(res, ErrorCodes.BadValue, "Oops!");
|
||||||
}, {
|
}, {
|
||||||
msg: "command worked when it should have failed : Oops!",
|
msg: "command worked when it should have failed: {res} : Oops!",
|
||||||
attr: {
|
attr: {
|
||||||
res: {
|
res: {
|
||||||
ok: 1,
|
ok: 1,
|
||||||
|
|
@ -1032,7 +1042,8 @@ tests.push(function assertCommandFailedWithWrongCodeJsonFormat() {
|
||||||
};
|
};
|
||||||
assert.commandFailedWithCode(res, ErrorCodes.NetworkTimeout, "Oops!");
|
assert.commandFailedWithCode(res, ErrorCodes.NetworkTimeout, "Oops!");
|
||||||
}, {
|
}, {
|
||||||
msg: "command did not fail with any of the following codes [ 89 ] unexpected error : Oops!",
|
msg:
|
||||||
|
"command did not fail with any of the following codes {expectedCode} {res}. errmsg: unexpected error : Oops!",
|
||||||
attr: {
|
attr: {
|
||||||
res: {
|
res: {
|
||||||
ok: 0,
|
ok: 0,
|
||||||
|
|
@ -1053,7 +1064,7 @@ tests.push(function assertWriteOKJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
const res = {ok: 0};
|
const res = {ok: 0};
|
||||||
assert.writeOK(res, "Oops!");
|
assert.writeOK(res, "Oops!");
|
||||||
}, {msg: "unknown type of write result, cannot check ok : Oops!", attr: {res: {ok: 0}}});
|
}, {msg: "unknown type of write result, cannot check ok: {res} : Oops!", attr: {res: {ok: 0}}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertWriteErrorJsonFormat() {
|
tests.push(function assertWriteErrorJsonFormat() {
|
||||||
|
|
@ -1062,7 +1073,7 @@ tests.push(function assertWriteErrorJsonFormat() {
|
||||||
new WriteResult({nRemoved: 0, writeErrors: [], upserted: []}, 3, {w: "majority"});
|
new WriteResult({nRemoved: 0, writeErrors: [], upserted: []}, 3, {w: "majority"});
|
||||||
assert.writeError(res, "Oops!");
|
assert.writeError(res, "Oops!");
|
||||||
}, {
|
}, {
|
||||||
msg: "no write error : Oops!",
|
msg: "no write error: {res} : Oops!",
|
||||||
attr: {
|
attr: {
|
||||||
res: {
|
res: {
|
||||||
ok: {"$undefined": true},
|
ok: {"$undefined": true},
|
||||||
|
|
@ -1083,7 +1094,8 @@ tests.push(function assertWriteErrorWithCodeJsonFormat() {
|
||||||
{nRemoved: 0, writeErrors: [writeError], upserted: []}, 3, {w: "majority"});
|
{nRemoved: 0, writeErrors: [writeError], upserted: []}, 3, {w: "majority"});
|
||||||
assert.writeErrorWithCode(res, ErrorCodes.BadValue, "Oops!");
|
assert.writeErrorWithCode(res, ErrorCodes.BadValue, "Oops!");
|
||||||
}, {
|
}, {
|
||||||
msg: "found code(s) does not match any of the expected codes : Oops!",
|
msg:
|
||||||
|
"found code(s) {writeErrorCodes} does not match any of the expected codes {expectedCode}. Original command response: {res} : Oops!",
|
||||||
attr: {
|
attr: {
|
||||||
res: {
|
res: {
|
||||||
ok: {"$undefined": true},
|
ok: {"$undefined": true},
|
||||||
|
|
@ -1102,20 +1114,20 @@ tests.push(function assertWriteErrorWithCodeJsonFormat() {
|
||||||
tests.push(function assertIsNullJsonFormat() {
|
tests.push(function assertIsNullJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.isnull({ok: 1}, "Oops!", kAttr);
|
assert.isnull({ok: 1}, "Oops!", kAttr);
|
||||||
}, {msg: "assert.isnull() failed : Oops!", attr: {value: {ok: 1}, ...kAttr}});
|
}, {msg: "supposed to be null, was: {value} : Oops!", attr: {value: {ok: 1}, ...kAttr}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertLTJsonFormat() {
|
tests.push(function assertLTJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.lt(41, 18, "Oops!", kAttr);
|
assert.lt(41, 18, "Oops!", kAttr);
|
||||||
}, {msg: "assert less than failed : Oops!", attr: {a: 41, b: 18, ...kAttr}});
|
}, {msg: "{a} is not less than {b} : Oops!", attr: {a: 41, b: 18, ...kAttr}});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertBetweenJsonFormat() {
|
tests.push(function assertBetweenJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.between(1, 15, 10, "Oops!", true, kAttr);
|
assert.between(1, 15, 10, "Oops!", true, kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.between() failed : Oops!",
|
msg: "{b} is not between {a} and {c} : Oops!",
|
||||||
attr: {a: 1, b: 15, c: 10, inclusive: true, ...kAttr}
|
attr: {a: 1, b: 15, c: 10, inclusive: true, ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -1123,18 +1135,20 @@ tests.push(function assertBetweenJsonFormat() {
|
||||||
tests.push(function assertCloseJsonFormat() {
|
tests.push(function assertCloseJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.close(123.4567, 123.4678, "Oops!");
|
assert.close(123.4567, 123.4678, "Oops!");
|
||||||
}, {msg: "assert.close() failed : Oops!", attr: {a: 123.4567, b: 123.4678, places: 4}});
|
}, {
|
||||||
|
msg:
|
||||||
|
"123.4567 is not equal to 123.4678 within 4 places, absolute error: 0.011099999999999, relative error: 0.00008990198254118888 : Oops!"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.push(function assertCloseWithinMSJsonFormat() {
|
tests.push(function assertCloseWithinMSJsonFormat() {
|
||||||
const dateForLog = (arg) => JSON.parse(JSON.stringify(arg));
|
const dateForLog = (arg) => JSON.parse(JSON.stringify(arg));
|
||||||
const date1 = new Date();
|
const date1 = Date.UTC(1970, 0, 1, 23, 59, 59, 999);
|
||||||
sleep(10);
|
const date2 = date1 + 10;
|
||||||
const date2 = new Date();
|
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.closeWithinMS(date1, date2, "Oops!", 1, kAttr);
|
assert.closeWithinMS(date1, date2, "Oops!", 1, kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.closeWithinMS() failed : Oops!",
|
msg: "86399999 is not equal to 86400009 within 1 millis, actual delta: 10 millis : Oops!",
|
||||||
attr: {a: dateForLog(date1), b: dateForLog(date2), deltaMS: 1, ...kAttr}
|
attr: {a: dateForLog(date1), b: dateForLog(date2), deltaMS: 1, ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -1143,7 +1157,7 @@ tests.push(function assertIncludesJsonFormat() {
|
||||||
assertThrowsErrorWithJson(() => {
|
assertThrowsErrorWithJson(() => {
|
||||||
assert.includes("farmacy", "ace", "Oops!", kAttr);
|
assert.includes("farmacy", "ace", "Oops!", kAttr);
|
||||||
}, {
|
}, {
|
||||||
msg: "assert.includes() failed : Oops!",
|
msg: "string [{haystack}] does not include [{needle}] : Oops!",
|
||||||
attr: {haystack: "farmacy", needle: "ace", ...kAttr}
|
attr: {haystack: "farmacy", needle: "ace", ...kAttr}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ tests.push(function invalidResponsesAttemptToProvideInformationToCommandWorks()
|
||||||
const error = assert.throws(() => {
|
const error = assert.throws(() => {
|
||||||
assert.commandWorked(invalidRes);
|
assert.commandWorked(invalidRes);
|
||||||
});
|
});
|
||||||
const errorMsg = stringifyErrorMessageAndAttributes(error);
|
const errorMsg = formatErrorMsg(error.message, error.extraAttr);
|
||||||
assert.gte(errorMsg.indexOf(invalidRes), 0);
|
assert.gte(errorMsg.indexOf(invalidRes), 0);
|
||||||
assert.gte(errorMsg.indexOf(typeof invalidRes), 0);
|
assert.gte(errorMsg.indexOf(typeof invalidRes), 0);
|
||||||
});
|
});
|
||||||
|
|
@ -310,7 +310,7 @@ tests.push(function invalidResponsesAttemptToProvideInformationCommandFailed() {
|
||||||
const error = assert.throws(() => {
|
const error = assert.throws(() => {
|
||||||
assert.commandFailed(invalidRes);
|
assert.commandFailed(invalidRes);
|
||||||
});
|
});
|
||||||
const errorMsg = stringifyErrorMessageAndAttributes(error);
|
const errorMsg = formatErrorMsg(error.message, error.extraAttr);
|
||||||
assert.gte(errorMsg.indexOf(invalidRes), 0);
|
assert.gte(errorMsg.indexOf(invalidRes), 0);
|
||||||
assert.gte(errorMsg.indexOf(typeof invalidRes), 0);
|
assert.gte(errorMsg.indexOf(typeof invalidRes), 0);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -45,5 +45,5 @@ const err = assert.throws(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
assert(/ResumableRangeDeleterDisabled/.test(stringifyErrorMessageAndAttributes(err)), err);
|
assert(/ResumableRangeDeleterDisabled/.test(formatErrorMsg(err.message, err.extraAttr)), err);
|
||||||
reshardingTest.teardown();
|
reshardingTest.teardown();
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ function runStandaloneTest(stageRegex, pipeline, expectedCommand) {
|
||||||
|
|
||||||
const result = assert.throws(() => coll.aggregate(pipeline, {cursor: {batchSize: 2}}));
|
const result = assert.throws(() => coll.aggregate(pipeline, {cursor: {batchSize: 2}}));
|
||||||
assert(isNetworkError(result));
|
assert(isNetworkError(result));
|
||||||
assert(stageRegex.test(stringifyErrorMessageAndAttributes(result)),
|
assert(stageRegex.test(formatErrorMsg(result.message, result.extraAttr)),
|
||||||
`Error wasn't due to stage failing: ${result}`);
|
`Error wasn't due to stage failing: ${result}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,17 @@ declare function assert(value: boolean | any, msg?: string | function | object,
|
||||||
*/
|
*/
|
||||||
declare function sortDoc(doc: object): any
|
declare function sortDoc(doc: object): any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format error message by replacing occurrences of '{key}'s in 'msg' with 'value' in [key, value] pairs from 'attr'.
|
||||||
|
*
|
||||||
|
* @param msg Failure message.
|
||||||
|
* @param attr Additional attributes to be included in failure messages.
|
||||||
|
* @param serializeFn Additional function to serialize 'value' in [key, value] pairs from 'attr'.
|
||||||
|
*
|
||||||
|
* @returns Failure message.
|
||||||
|
*/
|
||||||
|
declare function formatErrorMsg(msg: string, attr?: object, serializeFn?: function): string
|
||||||
|
|
||||||
declare module assert {
|
declare module assert {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,13 @@ function _convertExceptionToReturnStatus(func, excMsg) {
|
||||||
return safeFunc;
|
return safeFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatErrorMsg(msg, attr = {}, serializeFn = tojson) {
|
||||||
|
for (const [key, value] of Object.entries(attr)) {
|
||||||
|
msg = msg.replaceAll(`{${key}}`, serializeFn(value));
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
assert = (function() {
|
assert = (function() {
|
||||||
// Wrapping the helper function in an IIFE to avoid polluting the global namespace.
|
// Wrapping the helper function in an IIFE to avoid polluting the global namespace.
|
||||||
|
|
||||||
|
|
@ -104,7 +111,7 @@ assert = (function() {
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _doassert(msg, prefix, attr, prefixOverride) {
|
function _doassert(msg, prefix, attr) {
|
||||||
if (TestData?.logFormat === "json") {
|
if (TestData?.logFormat === "json") {
|
||||||
if (attr?.res) {
|
if (attr?.res) {
|
||||||
// Special handling for command reply a.k.a. 'res' parameters, as it might contain
|
// Special handling for command reply a.k.a. 'res' parameters, as it might contain
|
||||||
|
|
@ -115,9 +122,9 @@ assert = (function() {
|
||||||
...(attr.res._mongo && {connection: attr.res._mongo})
|
...(attr.res._mongo && {connection: attr.res._mongo})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
doassert(_buildAssertionMessage(msg, prefixOverride ?? prefix), attr);
|
doassert(_buildAssertionMessage(msg, prefix), attr);
|
||||||
}
|
}
|
||||||
doassert(_buildAssertionMessage(msg, prefix), attr?.res);
|
doassert(_buildAssertionMessage(msg, formatErrorMsg(prefix, attr, tojson)), attr?.res);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _validateAssertionMessage(msg, attr) {
|
function _validateAssertionMessage(msg, attr) {
|
||||||
|
|
@ -189,10 +196,7 @@ assert = (function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg, `[{a}] and [{b}] are not equal`, {a, b, ...attr});
|
||||||
`[${tojson(a)}] != [${tojson(b)}] are not equal`,
|
|
||||||
{a, b, ...attr},
|
|
||||||
"assert.eq() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function _isDocEq(a, b) {
|
function _isDocEq(a, b) {
|
||||||
|
|
@ -212,10 +216,8 @@ assert = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg,
|
||||||
"expected document " + tojson(expectedDoc) + " and actual document " +
|
"expected document {expectedDoc} and actual document {actualDoc} are not equal",
|
||||||
tojson(actualDoc) + " are not equal",
|
{expectedDoc, actualDoc, ...attr});
|
||||||
{expectedDoc, actualDoc, ...attr},
|
|
||||||
"assert.docEq() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -228,10 +230,8 @@ assert = (function() {
|
||||||
const failAssertion = function() {
|
const failAssertion = function() {
|
||||||
_doassert(
|
_doassert(
|
||||||
msg,
|
msg,
|
||||||
"expected set " + tojson(expectedSet) + " and actual set " + tojson(actualSet) +
|
"expected set {expectedSet} and actual set {actualSet} are not equal",
|
||||||
" are not equal",
|
{expectedSet: Array.from(expectedSet), actualSet: Array.from(actualSet), ...attr});
|
||||||
{expectedSet: Array.from(expectedSet), actualSet: Array.from(actualSet), ...attr},
|
|
||||||
"assert.setEq() failed");
|
|
||||||
};
|
};
|
||||||
if (expectedSet.size !== actualSet.size) {
|
if (expectedSet.size !== actualSet.size) {
|
||||||
failAssertion();
|
failAssertion();
|
||||||
|
|
@ -253,10 +253,7 @@ assert = (function() {
|
||||||
_validateAssertionMessage(msg, attr);
|
_validateAssertionMessage(msg, attr);
|
||||||
|
|
||||||
const failAssertion = function() {
|
const failAssertion = function() {
|
||||||
_doassert(msg,
|
_doassert(msg, "{aArr} != {bArr}", {aArr, bArr, compareFn: compareFn.name, ...attr});
|
||||||
tojson(aArr) + " != " + tojson(bArr),
|
|
||||||
{aArr, bArr, compareFn: compareFn.name, ...attr},
|
|
||||||
"assert.sameMembers() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (aArr.length !== bArr.length) {
|
if (aArr.length !== bArr.length) {
|
||||||
|
|
@ -299,10 +296,7 @@ assert = (function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg, "[{a}] and [{b}] are equal", {a, b, ...attr});
|
||||||
`[${tojson(a)}] == [${tojson(b)}] are equal`,
|
|
||||||
{a, b, ...attr},
|
|
||||||
"assert.neq() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.hasFields = function(result, arr, msg, attr) {
|
assert.hasFields = function(result, arr, msg, attr) {
|
||||||
|
|
@ -318,10 +312,8 @@ assert = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count != arr.length) {
|
if (count != arr.length) {
|
||||||
_doassert(msg,
|
_doassert(
|
||||||
"Not all of the values from " + tojson(arr) + " were in " + tojson(result),
|
msg, "Not all of the values from {arr} were in {result}", {result, arr, ...attr});
|
||||||
{result, arr, ...attr},
|
|
||||||
"assert.hasFields() failed");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -339,10 +331,7 @@ assert = (function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg, "{element} was not in {arr}", {element, arr, ...attr});
|
||||||
tojson(element) + " was not in " + tojson(arr),
|
|
||||||
{element, arr, ...attr},
|
|
||||||
"assert.contains() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.doesNotContain = function(element, arr, msg, attr) {
|
assert.doesNotContain = function(element, arr, msg, attr) {
|
||||||
|
|
@ -355,10 +344,7 @@ assert = (function() {
|
||||||
const match = comp == element ||
|
const match = comp == element ||
|
||||||
((comp != null && element != null) && friendlyEqual(comp, element));
|
((comp != null && element != null) && friendlyEqual(comp, element));
|
||||||
if (match) {
|
if (match) {
|
||||||
_doassert(msg,
|
_doassert(msg, "{element} is in {arr}", {element, arr, ...attr});
|
||||||
tojson(element) + " is in " + tojson(arr),
|
|
||||||
{element, arr, ...attr},
|
|
||||||
"assert.doesNotContain() failed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -382,10 +368,7 @@ assert = (function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg, "{prefix} was not a prefix in {arr}", {prefix, arr, ...attr});
|
||||||
tojson(prefix) + " was not a prefix in " + tojson(arr),
|
|
||||||
{prefix, arr, ...attr},
|
|
||||||
"assert.containsPrefix() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -500,7 +483,7 @@ assert = (function() {
|
||||||
print(msg + " Running hang analyzer from assert.retry.");
|
print(msg + " Running hang analyzer from assert.retry.");
|
||||||
MongoRunner.runHangAnalyzer();
|
MongoRunner.runHangAnalyzer();
|
||||||
}
|
}
|
||||||
_doassert(msg, null, attr, "assert.retry() failed");
|
_doassert(msg, null, attr);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -556,8 +539,7 @@ assert = (function() {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const msgPrefix =
|
const msgPrefix = "assert.time failed";
|
||||||
"assert.time failed timeout " + timeout + "ms took " + diff + "ms : " + f + ", msg";
|
|
||||||
msg = _buildAssertionMessage(msg);
|
msg = _buildAssertionMessage(msg);
|
||||||
if (runHangAnalyzer) {
|
if (runHangAnalyzer) {
|
||||||
msg = msg + " The hang analyzer is automatically called in assert.time functions. " +
|
msg = msg + " The hang analyzer is automatically called in assert.time functions. " +
|
||||||
|
|
@ -567,8 +549,7 @@ assert = (function() {
|
||||||
print(msg + " Running hang analyzer from assert.time.");
|
print(msg + " Running hang analyzer from assert.time.");
|
||||||
MongoRunner.runHangAnalyzer();
|
MongoRunner.runHangAnalyzer();
|
||||||
}
|
}
|
||||||
_doassert(
|
_doassert(msg, msgPrefix, {timeMS: diff, timeoutMS: timeout, function: f, diff, ...attr});
|
||||||
msg, msgPrefix, {timeMS: diff, timeoutMS: timeout, ...attr}, "assert.time() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function assertThrowsHelper(func, params) {
|
function assertThrowsHelper(func, params) {
|
||||||
|
|
@ -649,9 +630,8 @@ assert = (function() {
|
||||||
}
|
}
|
||||||
if (!expectedCode.some((ec) => error.code == ec)) {
|
if (!expectedCode.some((ec) => error.code == ec)) {
|
||||||
_doassert(msg,
|
_doassert(msg,
|
||||||
`[${tojson(error.code)}] != [${tojson(expectedCode)}] are not equal`,
|
`[{code}] and [{expectedCode}] are not equal`,
|
||||||
{code: error.code, expectedCode, ...attr},
|
{code: error.code, expectedCode, ...attr});
|
||||||
"assert.throwsWithCode() failed");
|
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
};
|
};
|
||||||
|
|
@ -666,9 +646,8 @@ assert = (function() {
|
||||||
if (error) {
|
if (error) {
|
||||||
const {code, message} = error;
|
const {code, message} = error;
|
||||||
_doassert(msg,
|
_doassert(msg,
|
||||||
"threw unexpected exception: " + error,
|
"threw unexpected exception: {error}",
|
||||||
{error: {...(code && {code}), ...(message && {message})}, ...attr},
|
{error: {...(code && {code}), ...(message && {message})}, ...attr});
|
||||||
"assert.doesNotThrow() failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -722,9 +701,8 @@ assert = (function() {
|
||||||
function _validateCommandResponse(res, assertionName) {
|
function _validateCommandResponse(res, assertionName) {
|
||||||
if (typeof res !== "object") {
|
if (typeof res !== "object") {
|
||||||
_doassert(`unexpected result type given to assert.${assertionName}()`,
|
_doassert(`unexpected result type given to assert.${assertionName}()`,
|
||||||
`expected result type 'object', got '${typeof res}', res='${res}'`,
|
`expected result type 'object', got '{resultType}', res='{result}'`,
|
||||||
{result: res, resultType: typeof res},
|
{result: res, resultType: typeof res});
|
||||||
"expected result type 'object'");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -776,21 +754,18 @@ assert = (function() {
|
||||||
|
|
||||||
// Keep this as a function so we don't call tojson if not necessary.
|
// Keep this as a function so we don't call tojson if not necessary.
|
||||||
const makeFailPrefix = (res) => {
|
const makeFailPrefix = (res) => {
|
||||||
let prefix = "command failed: " + tojson(res);
|
let prefix = "command failed: {res}";
|
||||||
if (typeof res._commandObj === "object" && res._commandObj !== null) {
|
if (typeof res._commandObj === "object" && res._commandObj !== null) {
|
||||||
prefix += " with original command request: " + tojson(res._commandObj);
|
prefix += " with original command request: {originalCommand}";
|
||||||
}
|
}
|
||||||
if (typeof res._mongo === "object" && res._mongo !== null) {
|
if (typeof res._mongo === "object" && res._mongo !== null) {
|
||||||
prefix += " on connection: " + res._mongo;
|
prefix += " on connection: {connection}";
|
||||||
|
}
|
||||||
|
if (res.hasOwnProperty("errmsg")) {
|
||||||
|
prefix += ` with errmsg: ${res.errmsg}`;
|
||||||
}
|
}
|
||||||
return prefix;
|
return prefix;
|
||||||
};
|
};
|
||||||
const makeFailPrefixOverride = (res) => {
|
|
||||||
if (res.hasOwnProperty("errmsg")) {
|
|
||||||
return `command failed: ${res.errmsg}`;
|
|
||||||
}
|
|
||||||
return "command failed";
|
|
||||||
};
|
|
||||||
|
|
||||||
if (_isWriteResultType(res)) {
|
if (_isWriteResultType(res)) {
|
||||||
// These can only contain write errors, not command errors.
|
// These can only contain write errors, not command errors.
|
||||||
|
|
@ -801,7 +776,9 @@ assert = (function() {
|
||||||
// A WriteCommandError implies ok:0.
|
// A WriteCommandError implies ok:0.
|
||||||
// Error objects may have a `code` property added (e.g.
|
// Error objects may have a `code` property added (e.g.
|
||||||
// DBCollection.prototype.mapReduce) without a `ok` property.
|
// DBCollection.prototype.mapReduce) without a `ok` property.
|
||||||
_doassert(msg, makeFailPrefix(res), {res}, makeFailPrefixOverride(res));
|
_doassert(msg,
|
||||||
|
makeFailPrefix(res),
|
||||||
|
{res, originalCommand: res._commandObj, connection: res._mongo});
|
||||||
} else if (res.hasOwnProperty("ok")) {
|
} else if (res.hasOwnProperty("ok")) {
|
||||||
// Handle raw command responses or cases like MapReduceResult which extend command
|
// Handle raw command responses or cases like MapReduceResult which extend command
|
||||||
// response.
|
// response.
|
||||||
|
|
@ -810,16 +787,15 @@ assert = (function() {
|
||||||
ignoreWriteConcernErrors: ignoreWriteConcernErrors
|
ignoreWriteConcernErrors: ignoreWriteConcernErrors
|
||||||
})) {
|
})) {
|
||||||
_runHangAnalyzerForSpecificFailureTypes(res);
|
_runHangAnalyzerForSpecificFailureTypes(res);
|
||||||
_doassert(msg, makeFailPrefix(res), {res}, makeFailPrefixOverride(res));
|
_doassert(msg,
|
||||||
|
makeFailPrefix(res),
|
||||||
|
{res, originalCommand: res._commandObj, connection: res._mongo});
|
||||||
}
|
}
|
||||||
} else if (res.hasOwnProperty("acknowledged")) {
|
} else if (res.hasOwnProperty("acknowledged")) {
|
||||||
// CRUD api functions return plain js objects with an acknowledged property.
|
// CRUD api functions return plain js objects with an acknowledged property.
|
||||||
// no-op.
|
// no-op.
|
||||||
} else {
|
} else {
|
||||||
_doassert(msg,
|
_doassert(msg, "unknown type of result, cannot check ok: {res}", {res});
|
||||||
"unknown type of result, cannot check ok: " + tojson(res),
|
|
||||||
{res},
|
|
||||||
"unknown type of result");
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -836,30 +812,21 @@ assert = (function() {
|
||||||
|
|
||||||
// Keep this as a function so we don't call tojson if not necessary.
|
// Keep this as a function so we don't call tojson if not necessary.
|
||||||
const makeFailPrefix = (res) => {
|
const makeFailPrefix = (res) => {
|
||||||
return "command worked when it should have failed: " + tojson(res);
|
|
||||||
};
|
|
||||||
const makeFailPrefixOverride = (res) => {
|
|
||||||
if (res.hasOwnProperty("errmsg")) {
|
if (res.hasOwnProperty("errmsg")) {
|
||||||
return `command worked when it should have failed: ${res.errmsg}`;
|
return `command worked when it should have failed: {res}. errmsg: ${res.errMsg}`;
|
||||||
}
|
}
|
||||||
return "command worked when it should have failed";
|
return "command worked when it should have failed: {res}";
|
||||||
};
|
};
|
||||||
|
|
||||||
const makeFailCodePrefix = (res, expectedCode) => {
|
const makeFailCodePrefix = (res, expectedCode) => {
|
||||||
return (expectedCode !== assert._kAnyErrorCode)
|
|
||||||
? "command did not fail with any of the following codes " + tojson(expectedCode) +
|
|
||||||
" " + tojson(res)
|
|
||||||
: null;
|
|
||||||
};
|
|
||||||
const makeFailCodePrefixOverride = (res, expectedCode) => {
|
|
||||||
if (res.hasOwnProperty("errmsg")) {
|
if (res.hasOwnProperty("errmsg")) {
|
||||||
return (expectedCode !== assert._kAnyErrorCode)
|
return (expectedCode !== assert._kAnyErrorCode)
|
||||||
? "command did not fail with any of the following codes " +
|
? `command did not fail with any of the following codes {expectedCode} {res}. errmsg: ${
|
||||||
tojson(expectedCode) + " " + res.errmsg
|
res.errmsg}`
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
return (expectedCode !== assert._kAnyErrorCode)
|
return (expectedCode !== assert._kAnyErrorCode)
|
||||||
? "command did not fail with any of the following codes " + tojson(expectedCode)
|
? "command did not fail with any of the following codes {expectedCode} {res}"
|
||||||
: null;
|
: null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -872,20 +839,14 @@ assert = (function() {
|
||||||
// DBCollection.prototype.mapReduce) without a `ok` property.
|
// DBCollection.prototype.mapReduce) without a `ok` property.
|
||||||
if (expectedCode !== assert._kAnyErrorCode) {
|
if (expectedCode !== assert._kAnyErrorCode) {
|
||||||
if (!res.hasOwnProperty("code") || !expectedCode.includes(res.code)) {
|
if (!res.hasOwnProperty("code") || !expectedCode.includes(res.code)) {
|
||||||
_doassert(msg,
|
_doassert(msg, makeFailCodePrefix(res, expectedCode), {res, expectedCode});
|
||||||
makeFailCodePrefix(res, expectedCode),
|
|
||||||
{res, expectedCode},
|
|
||||||
makeFailCodePrefixOverride(res, expectedCode));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (res.hasOwnProperty("ok")) {
|
} else if (res.hasOwnProperty("ok")) {
|
||||||
// Handle raw command responses or cases like MapReduceResult which extend command
|
// Handle raw command responses or cases like MapReduceResult which extend command
|
||||||
// response.
|
// response.
|
||||||
if (_rawReplyOkAndNoWriteErrors(res)) {
|
if (_rawReplyOkAndNoWriteErrors(res)) {
|
||||||
_doassert(msg,
|
_doassert(msg, makeFailPrefix(res), {res});
|
||||||
makeFailPrefix(res, expectedCode),
|
|
||||||
{res},
|
|
||||||
makeFailPrefixOverride(res, expectedCode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedCode !== assert._kAnyErrorCode) {
|
if (expectedCode !== assert._kAnyErrorCode) {
|
||||||
|
|
@ -900,23 +861,14 @@ assert = (function() {
|
||||||
|
|
||||||
if (!foundCode) {
|
if (!foundCode) {
|
||||||
_runHangAnalyzerForSpecificFailureTypes(res);
|
_runHangAnalyzerForSpecificFailureTypes(res);
|
||||||
_doassert(msg,
|
_doassert(msg, makeFailCodePrefix(res, expectedCode), {res, expectedCode});
|
||||||
makeFailCodePrefix(res, expectedCode),
|
|
||||||
{res, expectedCode},
|
|
||||||
makeFailCodePrefixOverride(res, expectedCode));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (res.hasOwnProperty("acknowledged")) {
|
} else if (res.hasOwnProperty("acknowledged")) {
|
||||||
// CRUD api functions return plain js objects with an acknowledged property.
|
// CRUD api functions return plain js objects with an acknowledged property.
|
||||||
_doassert(msg,
|
_doassert(msg, makeFailPrefix(res), {res});
|
||||||
makeFailPrefix(res, expectedCode),
|
|
||||||
{res},
|
|
||||||
makeFailPrefixOverride(res, expectedCode));
|
|
||||||
} else {
|
} else {
|
||||||
_doassert(msg,
|
_doassert(msg, "unknown type of result, cannot check error: {res}", {res});
|
||||||
"unknown type of result, cannot check error: " + tojson(res),
|
|
||||||
{res},
|
|
||||||
"unknown type of result");
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -996,7 +948,7 @@ assert = (function() {
|
||||||
|
|
||||||
if (errMsg) {
|
if (errMsg) {
|
||||||
_runHangAnalyzerForSpecificFailureTypes(res);
|
_runHangAnalyzerForSpecificFailureTypes(res);
|
||||||
_doassert(msg, errMsg + ": " + tojson(res), {res}, errMsg);
|
_doassert(msg, errMsg + ": {res}", {res}, errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -1047,7 +999,7 @@ assert = (function() {
|
||||||
|
|
||||||
if (errMsg) {
|
if (errMsg) {
|
||||||
_runHangAnalyzerForSpecificFailureTypes(res);
|
_runHangAnalyzerForSpecificFailureTypes(res);
|
||||||
_doassert(msg, errMsg + ": " + tojson(res), {res}, errMsg);
|
_doassert(msg, errMsg + ": {res}", {res});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedCode !== assert._kAnyErrorCode) {
|
if (expectedCode !== assert._kAnyErrorCode) {
|
||||||
|
|
@ -1056,14 +1008,11 @@ assert = (function() {
|
||||||
}
|
}
|
||||||
const found = expectedCode.some((ec) => writeErrorCodes.has(ec));
|
const found = expectedCode.some((ec) => writeErrorCodes.has(ec));
|
||||||
if (!found) {
|
if (!found) {
|
||||||
errMsg = "found code(s) " + tojson(Array.from(writeErrorCodes)) +
|
errMsg =
|
||||||
" does not match any of the expected codes " + tojson(expectedCode) +
|
"found code(s) {writeErrorCodes} does not match any of the expected codes {expectedCode}. Original command response: {res}";
|
||||||
". Original command response: " + tojson(res);
|
|
||||||
_runHangAnalyzerForSpecificFailureTypes(res);
|
_runHangAnalyzerForSpecificFailureTypes(res);
|
||||||
_doassert(msg,
|
_doassert(
|
||||||
errMsg,
|
msg, errMsg, {res, expectedCode, writeErrorCodes: Array.from(writeErrorCodes)});
|
||||||
{res, expectedCode, writeErrorCodes: Array.from(writeErrorCodes)},
|
|
||||||
"found code(s) does not match any of the expected codes");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1077,10 +1026,7 @@ assert = (function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg, "supposed to be null, was: {value}", {value, ...attr});
|
||||||
"supposed to be null, was: " + tojson(value),
|
|
||||||
{value, ...attr},
|
|
||||||
"assert.isnull() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function _shouldUseBsonWoCompare(a, b) {
|
function _shouldUseBsonWoCompare(a, b) {
|
||||||
|
|
@ -1117,10 +1063,7 @@ assert = (function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg, "{a} is not " + description + " {b}", {a, b, ...attr});
|
||||||
a + " is not " + description + " " + b,
|
|
||||||
{a, b, ...attr},
|
|
||||||
`assert ${description} failed`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.lt = function(a, b, msg, attr) {
|
assert.lt = function(a, b, msg, attr) {
|
||||||
|
|
@ -1158,10 +1101,7 @@ assert = (function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_doassert(msg,
|
_doassert(msg, "{b} is not between {a} and {c}", {a, b, c, inclusive, ...attr});
|
||||||
b + " is not between " + a + " and " + c,
|
|
||||||
{a, b, c, inclusive, ...attr},
|
|
||||||
"assert.between() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.betweenIn = function(a, b, c, msg, attr) {
|
assert.betweenIn = function(a, b, c, msg, attr) {
|
||||||
|
|
@ -1193,7 +1133,7 @@ assert = (function() {
|
||||||
assert.close = function(a, b, msg, places = 4) {
|
assert.close = function(a, b, msg, places = 4) {
|
||||||
const [isClose, errMsg] = _isClose(a, b, places);
|
const [isClose, errMsg] = _isClose(a, b, places);
|
||||||
if (!isClose) {
|
if (!isClose) {
|
||||||
_doassert(msg, errMsg, {a, b, places}, "assert.close() failed");
|
_doassert(msg, errMsg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1240,10 +1180,7 @@ assert = (function() {
|
||||||
"actual delta: " + actualDelta + " millis";
|
"actual delta: " + actualDelta + " millis";
|
||||||
|
|
||||||
const forLog = (arg) => arg instanceof Date ? JSON.parse(JSON.stringify(arg)) : arg;
|
const forLog = (arg) => arg instanceof Date ? JSON.parse(JSON.stringify(arg)) : arg;
|
||||||
_doassert(msg,
|
_doassert(msg, msgPrefix, {a: forLog(a), b: forLog(b), deltaMS, ...attr});
|
||||||
msgPrefix,
|
|
||||||
{a: forLog(a), b: forLog(b), deltaMS, ...attr},
|
|
||||||
"assert.closeWithinMS() failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.includes = function(haystack, needle, msg, attr) {
|
assert.includes = function(haystack, needle, msg, attr) {
|
||||||
|
|
@ -1251,8 +1188,8 @@ assert = (function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefix = `string [${haystack}] does not include [${needle}]`;
|
const prefix = "string [{haystack}] does not include [{needle}]";
|
||||||
_doassert(msg, prefix, {haystack, needle, ...attr}, "assert.includes() failed");
|
_doassert(msg, prefix, {haystack, needle, ...attr});
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.noAPIParams = function(cmdOptions) {
|
assert.noAPIParams = function(cmdOptions) {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ declare function isObject()
|
||||||
declare function isString()
|
declare function isString()
|
||||||
declare function printjson()
|
declare function printjson()
|
||||||
declare function printjsononeline()
|
declare function printjsononeline()
|
||||||
declare function stringifyErrorMessageAndAttributes()
|
|
||||||
declare function toJsonForLog()
|
declare function toJsonForLog()
|
||||||
declare function tojson()
|
declare function tojson()
|
||||||
declare function tojsonObject()
|
declare function tojsonObject()
|
||||||
|
|
|
||||||
|
|
@ -925,11 +925,3 @@ isNumber = function(x) {
|
||||||
isObject = function(x) {
|
isObject = function(x) {
|
||||||
return typeof (x) == "object";
|
return typeof (x) == "object";
|
||||||
};
|
};
|
||||||
|
|
||||||
stringifyErrorMessageAndAttributes = function(e) {
|
|
||||||
const escapedMsg = JSON.stringify(e.message);
|
|
||||||
if (!e.extraAttr) {
|
|
||||||
return escapedMsg;
|
|
||||||
}
|
|
||||||
return `${escapedMsg}: ${tojson(e.extraAttr)}`;
|
|
||||||
};
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue