summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/auth/lib/commands_lib.js1
-rw-r--r--jstests/noPassthrough/aggregate_operation_metrics.js17
-rw-r--r--jstests/noPassthrough/index_build_operation_metrics.js18
-rw-r--r--jstests/noPassthrough/ttl_operation_metrics.js8
-rw-r--r--src/mongo/db/pipeline/document_source_operation_metrics.cpp5
5 files changed, 35 insertions, 14 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js
index 5d333e9188b..268c2640fe0 100644
--- a/jstests/auth/lib/commands_lib.js
+++ b/jstests/auth/lib/commands_lib.js
@@ -5989,6 +5989,7 @@ var authCommandsLib = {
privileges: [
{resource: {cluster: true}, actions: ["operationMetrics"]},
],
+ expectFail: true,
},
]
},
diff --git a/jstests/noPassthrough/aggregate_operation_metrics.js b/jstests/noPassthrough/aggregate_operation_metrics.js
index 62533397cf7..61095041c86 100644
--- a/jstests/noPassthrough/aggregate_operation_metrics.js
+++ b/jstests/noPassthrough/aggregate_operation_metrics.js
@@ -63,9 +63,24 @@ let getServerStatusMetrics = (db) => {
return ss.resourceConsumption;
};
+const primary = rst.getPrimary();
+
+// $operationMetrics may only be run against the admin database and in a 'collectionless' form.
+assert.commandFailedWithCode(primary.getDB('invalid').runCommand({
+ aggregate: 1,
+ pipeline: [{$operationMetrics: {}}],
+ cursor: {},
+}),
+ ErrorCodes.InvalidNamespace);
+assert.commandFailedWithCode(primary.getDB('admin').runCommand({
+ aggregate: 'test',
+ pipeline: [{$operationMetrics: {}}],
+ cursor: {},
+}),
+ ErrorCodes.InvalidNamespace);
+
// Perform very basic reads and writes on two different databases.
const db1Name = 'db1';
-const primary = rst.getPrimary();
const db1 = primary.getDB(db1Name);
assert.commandWorked(db1.coll1.insert({a: 1}));
assert.commandWorked(db1.coll2.insert({a: 1}));
diff --git a/jstests/noPassthrough/index_build_operation_metrics.js b/jstests/noPassthrough/index_build_operation_metrics.js
index e15e2f1bd45..6a13dbc4fd8 100644
--- a/jstests/noPassthrough/index_build_operation_metrics.js
+++ b/jstests/noPassthrough/index_build_operation_metrics.js
@@ -26,8 +26,8 @@ const secondaryDB = secondary.getDB(dbName);
const nDocs = 100;
-const clearMetrics = (db) => {
- db.aggregate([{$operationMetrics: {clearMetrics: true}}]);
+const clearMetrics = (conn) => {
+ conn.getDB('admin').aggregate([{$operationMetrics: {clearMetrics: true}}]);
};
// Get aggregated metrics keyed by database name.
@@ -60,7 +60,7 @@ assert.commandWorked(primaryDB.createCollection(collName));
* primary node.
*/
(function loadCollection() {
- clearMetrics(primaryDB);
+ clearMetrics(primary);
let bulk = primaryDB[collName].initializeUnorderedBulkOp();
for (let i = 0; i < nDocs; i++) {
@@ -92,7 +92,7 @@ assert.commandWorked(primaryDB.createCollection(collName));
* Build an index. Expect that metrics are reasonable and only reported on the primary node.
*/
(function buildIndex() {
- clearMetrics(primaryDB);
+ clearMetrics(primary);
assert.commandWorked(primaryDB[collName].createIndex({a: 1}));
assertMetrics(primary, (metrics) => {
@@ -134,7 +134,7 @@ assert.commandWorked(primaryDB[collName].dropIndex({a: 1}));
* Build an index. Expect that metrics are reasonable and only reported on the primary node.
*/
(function buildUniqueIndex() {
- clearMetrics(primaryDB);
+ clearMetrics(primary);
assert.commandWorked(primaryDB[collName].createIndex({a: 1}, {unique: true}));
assertMetrics(primary, (metrics) => {
@@ -180,7 +180,7 @@ assert.commandWorked(primaryDB[collName].dropIndex({a: 1}));
// Insert a document at the end that makes the index non-unique.
assert.commandWorked(primaryDB[collName].insert({a: (nDocs - 1)}));
- clearMetrics(primaryDB);
+ clearMetrics(primary);
assert.commandFailedWithCode(primaryDB[collName].createIndex({a: 1}, {unique: true}),
ErrorCodes.DuplicateKey);
@@ -222,7 +222,7 @@ assert.commandWorked(primaryDB[collName].dropIndex({a: 1}));
* and reports read metrics.
*/
(function buildIndexInterrupt() {
- clearMetrics(primaryDB);
+ clearMetrics(primary);
// Hang the index build after kicking off the build on the primary, but before scanning the
// collection.
@@ -298,8 +298,8 @@ assert.commandWorked(primaryDB[collName].dropIndex({a: 1}));
* The the stepped-down node should not collect anything.
*/
(function buildIndexWithStepDown() {
- clearMetrics(primaryDB);
- clearMetrics(secondaryDB);
+ clearMetrics(primary);
+ clearMetrics(secondary);
// Hang the index build after kicking off the build on the secondary, but before scanning the
// collection.
diff --git a/jstests/noPassthrough/ttl_operation_metrics.js b/jstests/noPassthrough/ttl_operation_metrics.js
index 42de17ff0ed..4b57fe9481f 100644
--- a/jstests/noPassthrough/ttl_operation_metrics.js
+++ b/jstests/noPassthrough/ttl_operation_metrics.js
@@ -31,8 +31,8 @@ const secondary = rst.getSecondary();
const primaryDB = primary.getDB(dbName);
const secondaryDB = secondary.getDB(dbName);
-const clearMetrics = (db) => {
- db.aggregate([{$operationMetrics: {clearMetrics: true}}]);
+const clearMetrics = (conn) => {
+ conn.getDB('admin').aggregate([{$operationMetrics: {clearMetrics: true}}]);
};
// Get aggregated metrics keyed by database name.
@@ -73,7 +73,7 @@ assert.commandWorked(primaryDB[collName].createIndex({x: 1}, {expireAfterSeconds
let pauseTtl = configureFailPoint(primary, 'hangTTLMonitorWithLock');
pauseTtl.wait();
-clearMetrics(primaryDB);
+clearMetrics(primary);
let now = new Date();
let later = new Date(now.getTime() + 1000 * 60 * 60);
@@ -90,7 +90,7 @@ assertMetrics(primary, (metrics) => {
});
// Clear metrics and wait for a TTL pass to delete the documents.
-clearMetrics(primaryDB);
+clearMetrics(primary);
pauseTtl.off();
waitForTtlPass(primaryDB);
diff --git a/src/mongo/db/pipeline/document_source_operation_metrics.cpp b/src/mongo/db/pipeline/document_source_operation_metrics.cpp
index d694b651f16..c2037bc2e12 100644
--- a/src/mongo/db/pipeline/document_source_operation_metrics.cpp
+++ b/src/mongo/db/pipeline/document_source_operation_metrics.cpp
@@ -88,6 +88,11 @@ intrusive_ptr<DocumentSource> DocumentSourceOperationMetrics::createFromBson(
"The aggregateOperationResourceConsumption server parameter is not set");
}
+ const NamespaceString& nss = pExpCtx->ns;
+ uassert(ErrorCodes::InvalidNamespace,
+ "$operationMetrics must be run against the 'admin' database with {aggregate: 1}",
+ nss.db() == NamespaceString::kAdminDb && nss.isCollectionlessAggregateNS());
+
uassert(ErrorCodes::BadValue,
"The $operationMetrics stage specification must be an object",
elem.type() == Object);