diff options
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/core/apitest_db_profile_level.js | 46 | ||||
-rw-r--r-- | jstests/libs/log.js | 37 |
2 files changed, 74 insertions, 9 deletions
diff --git a/jstests/core/apitest_db_profile_level.js b/jstests/core/apitest_db_profile_level.js index 2172b4ed1cb..20f6ff55df9 100644 --- a/jstests/core/apitest_db_profile_level.js +++ b/jstests/core/apitest_db_profile_level.js @@ -1,11 +1,13 @@ /** * Tests for setting of profile levels - * @tags: [does_not_support_stepdowns, requires_profiling] + * @tags: [does_not_support_stepdowns, requires_profiling, requires_fcv_40] */ (function() { 'use strict'; + load("jstests/libs/log.js"); // For findMatchingLogLine, findMatchingLogLines. + /* * be sure the public collection API is complete */ @@ -16,25 +18,51 @@ // other tests that modify profiler level, when run in parallel. var profileLevelDB = db.getSiblingDB("apitest_db_profile_level"); + // Checks for the log that was expected to be created when profile level changed. + function profilerChangeWasLogged({from, to} = {}) { + const globalLog = assert.commandWorked(profileLevelDB.adminCommand({getLog: 'global'})); + + const fieldMatcher = {msg: "Profiler settings changed"}; + if (from && to) { + const lines = [...findMatchingLogLines(globalLog.log, fieldMatcher)]; + return lines.find(line => line.match(new RegExp(/from:\{ /.source + from.source)) && + line.match(new RegExp(/to:\{ /.source + to.source))); + } else { + return findMatchingLogLine(globalLog.log, fieldMatcher); + } + } + + profileLevelDB.getProfilingLevel(); + assert(!profilerChangeWasLogged({from: /level: 0/, to: /level: -1/}), + "Didn't expect anything to be logged"); + + assert.throws(() => { + profileLevelDB.setProfilingLevel(-1); + }); + profileLevelDB.setProfilingLevel(0); assert(profileLevelDB.getProfilingLevel() == 0, "prof level 0"); + assert(profilerChangeWasLogged({from: /level: 0/, to: /level: 0/}), + "Didn't find expected log line"); profileLevelDB.setProfilingLevel(1); assert(profileLevelDB.getProfilingLevel() == 1, "p1"); + assert(profilerChangeWasLogged({from: /level: 0/, to: /level: 1/}), + "Didn't find expected log line"); profileLevelDB.setProfilingLevel(2); assert(profileLevelDB.getProfilingLevel() == 2, "p2"); + assert(profilerChangeWasLogged({from: /level: 1/, to: /level: 2/}), + "Didn't find expected log line"); profileLevelDB.setProfilingLevel(0); assert(profileLevelDB.getProfilingLevel() == 0, "prof level 0"); + assert(profilerChangeWasLogged({from: /level: 2/, to: /level: 0/}), + "Didn't find expected log line"); - var asserted = false; - try { + assert.throws(() => { profileLevelDB.setProfilingLevel(10); - assert(false); - } catch (e) { - asserted = true; - assert(e.dbSetProfilingException); - } - assert(asserted, "should have asserted"); + }); + // Check that didn't log an invalid profile level change. + assert(!profilerChangeWasLogged({from: /level: 0/, to: /level: 10/}), "Didn't expect log line"); })(); diff --git a/jstests/libs/log.js b/jstests/libs/log.js new file mode 100644 index 00000000000..299a9ab8e0c --- /dev/null +++ b/jstests/libs/log.js @@ -0,0 +1,37 @@ +// Yields every logline that contains the specified fields. The regex escape function used here is +// drawn from the following: +// https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript +// https://github.com/ljharb/regexp.escape +function * findMatchingLogLines(logLines, fields, ignoreFields) { + ignoreFields = ignoreFields || []; + function escapeRegex(input) { + return (typeof input === "string" ? input.replace(/[\^\$\\\.\*\+\?\(\)\[\]\{\}]/g, '\\$&') + : input); + } + function lineMatches(line, fields, ignoreFields) { + const fieldNames = + Object.keys(fields).filter((fieldName) => !ignoreFields.includes(fieldName)); + return fieldNames.every((fieldName) => { + const fieldValue = fields[fieldName]; + let regex = escapeRegex(fieldName) + ":? ?(" + + escapeRegex(checkLog.formatAsLogLine(fieldValue)) + "|" + + escapeRegex(checkLog.formatAsLogLine(fieldValue, true)) + ")"; + const match = line.match(regex); + return match && match[0]; + }); + } + + for (let line of logLines) { + if (lineMatches(line, fields, ignoreFields)) { + yield line; + } + } +} +// Finds and returns a logline containing all the specified fields, or null if no such logline +// was found. +function findMatchingLogLine(logLines, fields, ignoreFields) { + for (let line of findMatchingLogLines(logLines, fields, ignoreFields)) { + return line; + } + return null; +} |