summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/log_and_profile_query_hash.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/noPassthrough/log_and_profile_query_hash.js')
-rw-r--r--jstests/noPassthrough/log_and_profile_query_hash.js288
1 files changed, 147 insertions, 141 deletions
diff --git a/jstests/noPassthrough/log_and_profile_query_hash.js b/jstests/noPassthrough/log_and_profile_query_hash.js
index 2a0757689a6..50395061e54 100644
--- a/jstests/noPassthrough/log_and_profile_query_hash.js
+++ b/jstests/noPassthrough/log_and_profile_query_hash.js
@@ -2,155 +2,161 @@
//
// Confirms that profiled find queries and corresponding logs have matching queryHashes.
(function() {
- "use strict";
-
- // For getLatestProfilerEntry().
- load("jstests/libs/profiler.js");
-
- // Prevent the mongo shell from gossiping its cluster time, since this will increase the amount
- // of data logged for each op. For some of the testcases below, including the cluster time would
- // cause them to be truncated at the 512-byte RamLog limit, and some of the fields we need to
- // check would be lost.
- TestData.skipGossipingClusterTime = true;
-
- const conn = MongoRunner.runMongod();
- assert.neq(null, conn, "mongod was unable to start up");
- const testDB = conn.getDB("jstests_query_shape_hash");
- const coll = testDB.test;
-
- const profileEntryFilter = {op: "query"};
-
- assert.commandWorked(testDB.setProfilingLevel(2, {"slowms": 0}));
- assert.commandWorked(testDB.setLogLevel(0, "query"));
-
- // Parses the logLine and profileEntry into similar string representations with no white spaces.
- // Returns true if the logLine command components correspond to the profile entry. This is
- // sufficient for the purpose of testing query hashes.
- function logMatchesEntry(logLine, profileEntry) {
- if (logLine.indexOf("command: find { find: \"test\"") >= 0 &&
- logLine.indexOf(profileEntry["command"]["comment"]) >= 0) {
- return true;
- }
- return false;
- }
-
- // Fetch the log line that corresponds to the profile entry. If there is no such line, return
- // null.
- function retrieveLogLine(log, profileEntry) {
- const logLine = log.reduce((acc, line) => {
- if (logMatchesEntry(line, profileEntry)) {
- // Assert that the matching does not pick up more than one line corresponding to
- // the entry.
- assert.eq(acc, null);
- return line;
- }
- return acc;
- }, null);
- return logLine;
+"use strict";
+
+// For getLatestProfilerEntry().
+load("jstests/libs/profiler.js");
+
+// Prevent the mongo shell from gossiping its cluster time, since this will increase the amount
+// of data logged for each op. For some of the testcases below, including the cluster time would
+// cause them to be truncated at the 512-byte RamLog limit, and some of the fields we need to
+// check would be lost.
+TestData.skipGossipingClusterTime = true;
+
+const conn = MongoRunner.runMongod();
+assert.neq(null, conn, "mongod was unable to start up");
+const testDB = conn.getDB("jstests_query_shape_hash");
+const coll = testDB.test;
+
+const profileEntryFilter = {
+ op: "query"
+};
+
+assert.commandWorked(testDB.setProfilingLevel(2, {"slowms": 0}));
+assert.commandWorked(testDB.setLogLevel(0, "query"));
+
+// Parses the logLine and profileEntry into similar string representations with no white spaces.
+// Returns true if the logLine command components correspond to the profile entry. This is
+// sufficient for the purpose of testing query hashes.
+function logMatchesEntry(logLine, profileEntry) {
+ if (logLine.indexOf("command: find { find: \"test\"") >= 0 &&
+ logLine.indexOf(profileEntry["command"]["comment"]) >= 0) {
+ return true;
}
-
- // Run the find command, retrieve the corresponding profile object and log line, then ensure
- // that both the profile object and log line have matching stable query hashes (if any).
- function runTestsAndGetHashes(db, {comment, test, hasQueryHash}) {
- assert.commandWorked(db.adminCommand({clearLog: "global"}));
- assert.doesNotThrow(() => test(db, comment));
- const log = assert.commandWorked(db.adminCommand({getLog: "global"})).log;
- const profileEntry =
- getLatestProfilerEntry(testDB, {op: "query", "command.comment": comment});
- // Parse the profile entry to retrieve the corresponding log entry.
- const logLine = retrieveLogLine(log, profileEntry);
- assert.neq(logLine, null);
-
- // Confirm that the query hashes either exist or don't exist in both log and profile
- // entries. If the queryHash and planCacheKey exist, ensure that the hashes from the
- // profile entry match the log line.
- assert.eq(hasQueryHash, profileEntry.hasOwnProperty("queryHash"));
- assert.eq(hasQueryHash, profileEntry.hasOwnProperty("planCacheKey"));
- assert.eq(hasQueryHash, (logLine.indexOf(profileEntry["queryHash"]) >= 0));
- assert.eq(hasQueryHash, (logLine.indexOf(profileEntry["planCacheKey"]) >= 0));
- if (hasQueryHash) {
- return {
- queryHash: profileEntry["queryHash"],
- planCacheKey: profileEntry["planCacheKey"]
- };
+ return false;
+}
+
+// Fetch the log line that corresponds to the profile entry. If there is no such line, return
+// null.
+function retrieveLogLine(log, profileEntry) {
+ const logLine = log.reduce((acc, line) => {
+ if (logMatchesEntry(line, profileEntry)) {
+ // Assert that the matching does not pick up more than one line corresponding to
+ // the entry.
+ assert.eq(acc, null);
+ return line;
}
- return null;
+ return acc;
+ }, null);
+ return logLine;
+}
+
+// Run the find command, retrieve the corresponding profile object and log line, then ensure
+// that both the profile object and log line have matching stable query hashes (if any).
+function runTestsAndGetHashes(db, {comment, test, hasQueryHash}) {
+ assert.commandWorked(db.adminCommand({clearLog: "global"}));
+ assert.doesNotThrow(() => test(db, comment));
+ const log = assert.commandWorked(db.adminCommand({getLog: "global"})).log;
+ const profileEntry = getLatestProfilerEntry(testDB, {op: "query", "command.comment": comment});
+ // Parse the profile entry to retrieve the corresponding log entry.
+ const logLine = retrieveLogLine(log, profileEntry);
+ assert.neq(logLine, null);
+
+ // Confirm that the query hashes either exist or don't exist in both log and profile
+ // entries. If the queryHash and planCacheKey exist, ensure that the hashes from the
+ // profile entry match the log line.
+ assert.eq(hasQueryHash, profileEntry.hasOwnProperty("queryHash"));
+ assert.eq(hasQueryHash, profileEntry.hasOwnProperty("planCacheKey"));
+ assert.eq(hasQueryHash, (logLine.indexOf(profileEntry["queryHash"]) >= 0));
+ assert.eq(hasQueryHash, (logLine.indexOf(profileEntry["planCacheKey"]) >= 0));
+ if (hasQueryHash) {
+ return {queryHash: profileEntry["queryHash"], planCacheKey: profileEntry["planCacheKey"]};
}
-
- // Add data and indices.
- const nDocs = 200;
- for (let i = 0; i < nDocs; i++) {
- assert.commandWorked(coll.insert({a: i, b: -1, c: 1}));
- }
- assert.commandWorked(coll.createIndex({a: 1}));
- assert.commandWorked(coll.createIndex({b: 1}));
-
- const queryA = {a: {$gte: 3}, b: 32};
- const queryB = {a: {$gte: 199}, b: -1};
- const projectionB = {_id: 0, b: 1};
- const sortC = {c: -1};
-
- const testList = [
- {
- comment: "Test0 find query",
- test: function(db, comment) {
- assert.eq(200, db.test.find().comment(comment).itcount());
- },
- hasQueryHash: false
+ return null;
+}
+
+// Add data and indices.
+const nDocs = 200;
+for (let i = 0; i < nDocs; i++) {
+ assert.commandWorked(coll.insert({a: i, b: -1, c: 1}));
+}
+assert.commandWorked(coll.createIndex({a: 1}));
+assert.commandWorked(coll.createIndex({b: 1}));
+
+const queryA = {
+ a: {$gte: 3},
+ b: 32
+};
+const queryB = {
+ a: {$gte: 199},
+ b: -1
+};
+const projectionB = {
+ _id: 0,
+ b: 1
+};
+const sortC = {
+ c: -1
+};
+
+const testList = [
+ {
+ comment: "Test0 find query",
+ test: function(db, comment) {
+ assert.eq(200, db.test.find().comment(comment).itcount());
},
- {
- comment: "Test1 find query",
- test: function(db, comment) {
- assert.eq(1,
- db.test.find(queryB, projectionB).sort(sortC).comment(comment).itcount(),
- 'unexpected document count');
- },
- hasQueryHash: true
+ hasQueryHash: false
+ },
+ {
+ comment: "Test1 find query",
+ test: function(db, comment) {
+ assert.eq(1,
+ db.test.find(queryB, projectionB).sort(sortC).comment(comment).itcount(),
+ 'unexpected document count');
},
- {
- comment: "Test2 find query",
- test: function(db, comment) {
- assert.eq(0,
- db.test.find(queryA, projectionB).sort(sortC).comment(comment).itcount(),
- 'unexpected document count');
- },
- hasQueryHash: true
- }
- ];
-
- const hashValues = testList.map((testCase) => runTestsAndGetHashes(testDB, testCase));
-
- // Confirm that the same shape of query has the same hashes.
- assert.neq(hashValues[0], hashValues[1]);
- assert.eq(hashValues[1], hashValues[2]);
-
- // Test that the expected 'planCacheKey' and 'queryHash' are included in the transitional
- // log lines when an inactive cache entry is created.
- assert.commandWorked(testDB.setLogLevel(1, "query"));
- const testInactiveCreationLog = {
- comment: "Test Creating inactive entry.",
+ hasQueryHash: true
+ },
+ {
+ comment: "Test2 find query",
test: function(db, comment) {
assert.eq(0,
- db.test.find({b: {$lt: 12}, a: {$eq: 500}})
- .sort({a: -1})
- .comment(comment)
- .itcount(),
+ db.test.find(queryA, projectionB).sort(sortC).comment(comment).itcount(),
'unexpected document count');
},
hasQueryHash: true
-
- };
- const onCreationHashes = runTestsAndGetHashes(testDB, testInactiveCreationLog);
- const log = assert.commandWorked(testDB.adminCommand({getLog: "global"})).log;
-
- // Fetch the line that logs when an inactive cache entry is created for the query with
- // 'planCacheKey' and 'queryHash'. Confirm only one line does this.
- const creationLogList = log.filter(
- logLine =>
- (logLine.indexOf("Creating inactive cache entry for query shape query") != -1 &&
- logLine.indexOf("planCacheKey " + String(onCreationHashes.planCacheKey)) != -1 &&
- logLine.indexOf("queryHash " + String(onCreationHashes.queryHash)) != -1));
- assert.eq(1, creationLogList.length);
-
- MongoRunner.stopMongod(conn);
+ }
+];
+
+const hashValues = testList.map((testCase) => runTestsAndGetHashes(testDB, testCase));
+
+// Confirm that the same shape of query has the same hashes.
+assert.neq(hashValues[0], hashValues[1]);
+assert.eq(hashValues[1], hashValues[2]);
+
+// Test that the expected 'planCacheKey' and 'queryHash' are included in the transitional
+// log lines when an inactive cache entry is created.
+assert.commandWorked(testDB.setLogLevel(1, "query"));
+const testInactiveCreationLog = {
+ comment: "Test Creating inactive entry.",
+ test: function(db, comment) {
+ assert.eq(
+ 0,
+ db.test.find({b: {$lt: 12}, a: {$eq: 500}}).sort({a: -1}).comment(comment).itcount(),
+ 'unexpected document count');
+ },
+ hasQueryHash: true
+
+};
+const onCreationHashes = runTestsAndGetHashes(testDB, testInactiveCreationLog);
+const log = assert.commandWorked(testDB.adminCommand({getLog: "global"})).log;
+
+// Fetch the line that logs when an inactive cache entry is created for the query with
+// 'planCacheKey' and 'queryHash'. Confirm only one line does this.
+const creationLogList = log.filter(
+ logLine => (logLine.indexOf("Creating inactive cache entry for query shape query") != -1 &&
+ logLine.indexOf("planCacheKey " + String(onCreationHashes.planCacheKey)) != -1 &&
+ logLine.indexOf("queryHash " + String(onCreationHashes.queryHash)) != -1));
+assert.eq(1, creationLogList.length);
+
+MongoRunner.stopMongod(conn);
})();