summaryrefslogtreecommitdiff
path: root/jstests/hooks
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /jstests/hooks
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (diff)
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0' with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'jstests/hooks')
-rw-r--r--jstests/hooks/run_aggregate_metrics_background.js112
-rw-r--r--jstests/hooks/run_dbcheck_background.js34
-rw-r--r--jstests/hooks/validate_collections.js8
3 files changed, 121 insertions, 33 deletions
diff --git a/jstests/hooks/run_aggregate_metrics_background.js b/jstests/hooks/run_aggregate_metrics_background.js
new file mode 100644
index 00000000000..32335852fcd
--- /dev/null
+++ b/jstests/hooks/run_aggregate_metrics_background.js
@@ -0,0 +1,112 @@
+/**
+ * Runs the $operationMetrics stage and ensures that all the expected fields are present.
+ */
+
+'use strict';
+
+(function() {
+load('jstests/libs/discover_topology.js'); // For Topology and DiscoverTopology.
+
+if (typeof db === 'undefined') {
+ throw new Error(
+ "Expected mongo shell to be connected a server, but global 'db' object isn't defined");
+}
+
+// Disable implicit sessions so FSM workloads that kill random sessions won't interrupt the
+// operations in this test that aren't resilient to interruptions.
+TestData.disableImplicitSessions = true;
+
+const topology = DiscoverTopology.findConnectedNodes(db.getMongo());
+
+const aggregateMetricsBackground = function(host) {
+ function verifyFields(doc) {
+ const kTopLevelFields = [
+ "docBytesWritten",
+ "docUnitsWritten",
+ "idxEntryBytesWritten",
+ "idxEntryUnitsWritten",
+ "totalUnitsWritten",
+ "cpuNanos",
+ "db",
+ "primaryMetrics",
+ "secondaryMetrics"
+ ];
+ const kReadFields = [
+ "docBytesRead",
+ "docUnitsRead",
+ "idxEntryBytesRead",
+ "idxEntryUnitsRead",
+ "keysSorted",
+ "docUnitsReturned"
+ ];
+
+ for (let key of kTopLevelFields) {
+ assert(doc.hasOwnProperty(key), "The metrics output is missing the property: " + key);
+ }
+ let primaryMetrics = doc.primaryMetrics;
+ for (let key of kReadFields) {
+ assert(primaryMetrics.hasOwnProperty(key),
+ "The metrics output is missing the property: primaryMetrics." + key);
+ }
+ let secondaryMetrics = doc.secondaryMetrics;
+ for (let key of kReadFields) {
+ assert(secondaryMetrics.hasOwnProperty(key),
+ "The metrics output is missing the property: secondaryMetrics." + key);
+ }
+ }
+
+ let conn = new Mongo(host);
+ conn.setSecondaryOk();
+
+ assert.neq(
+ null, conn, "Failed to connect to host '" + host + "' for background metrics collection");
+
+ // Filter out arbiters.
+ if (conn.adminCommand({isMaster: 1}).arbiterOnly) {
+ print("Skipping background aggregation against test node: " + host +
+ " because it is an arbiter and has no data.");
+ return;
+ }
+
+ let db = conn.getDB("admin");
+ let clearMetrics = Math.random() < 0.9 ? false : true;
+ print("Running $operationMetrics with {clearMetrics: " + clearMetrics + "} on host: " + host);
+ const cursor = db.aggregate([{$operationMetrics: {clearMetrics: clearMetrics}}]);
+ while (cursor.hasNext()) {
+ let doc = cursor.next();
+ try {
+ verifyFields(doc);
+ } catch (e) {
+ print("caught exception while verifying that all expected fields are in the metrics " +
+ "output: " + tojson(doc));
+ throw (e);
+ }
+ }
+};
+
+// This file is run continuously and is very fast so we want to impose some kind of rate limiting
+// which is why we sleep for 1 second here. This sleep is here rather than in
+// aggregate_metrics_background.py because the background job that file uses is designed to be run
+// continuously so it is easier and cleaner to just sleep here.
+sleep(1000);
+if (topology.type === Topology.kStandalone) {
+ try {
+ aggregateMetricsBackground(topology.mongod);
+ } catch (e) {
+ print("background aggregate metrics against the standalone failed");
+ throw e;
+ }
+} else if (topology.type === Topology.kReplicaSet) {
+ for (let replicaMember of topology.nodes) {
+ try {
+ aggregateMetricsBackground(replicaMember);
+ } catch (e) {
+ print("background aggregate metrics was not successful against all replica set " +
+ "members");
+ throw e;
+ }
+ }
+} else {
+ throw new Error("Unsupported topology configuration: " + tojson(topology));
+}
+})();
diff --git a/jstests/hooks/run_dbcheck_background.js b/jstests/hooks/run_dbcheck_background.js
index bb4a67d85af..9a62ad58dd3 100644
--- a/jstests/hooks/run_dbcheck_background.js
+++ b/jstests/hooks/run_dbcheck_background.js
@@ -97,32 +97,16 @@ const exceptionFilteredBackgroundDbCheck = function(hosts) {
const healthlog = node.getDB('local').system.healthlog;
// Regex matching strings that start without "SnapshotTooOld"
const regexStringWithoutSnapTooOld = /^((?!^SnapshotTooOld).)*$/;
-
- // healthlog is a capped collection, truncation during scan might cause cursor
- // invalidation. Truncated data is most likely from previous tests in the fixture, so we
- // should still be able to catch errors by retrying.
- assert.soon(() => {
- try {
- let errs = healthlog.find(
- {"severity": "error", "data.error": regexStringWithoutSnapTooOld});
- if (errs.hasNext()) {
- const err = "dbCheck found inconsistency on " + node.host;
- jsTestLog(err + ". Errors: ");
- for (let count = 0; errs.hasNext() && count < 20; count++) {
- jsTestLog(tojson(errs.next()));
- }
- assert(false, err);
- }
- return true;
- } catch (e) {
- if (e.code !== ErrorCodes.CappedPositionLost) {
- throw e;
- }
- jsTestLog(`Retrying on CappedPositionLost error: ${tojson(e)}`);
- return false;
+ let errs =
+ healthlog.find({"severity": "error", "data.error": regexStringWithoutSnapTooOld});
+ if (errs.hasNext()) {
+ const err = "dbCheck found inconsistency on " + node.host;
+ jsTestLog(err + ". Errors: ");
+ for (let count = 0; errs.hasNext() && count < 20; count++) {
+ jsTestLog(tojson(errs.next()));
}
- }, "healthlog scan could not complete.", 60000);
-
+ assert(false, err);
+ }
jsTestLog("Checked health log on " + node.host);
});
diff --git a/jstests/hooks/validate_collections.js b/jstests/hooks/validate_collections.js
index 1c673d33839..1ef1a9a761a 100644
--- a/jstests/hooks/validate_collections.js
+++ b/jstests/hooks/validate_collections.js
@@ -70,13 +70,6 @@ function CollectionValidator() {
print('Skipping collection validation for ' + coll.getFullName() +
' since collection was not found');
continue;
- } else if (res.codeName === "CommandNotSupportedOnView") {
- // Even though we pass a filter to getCollectionInfos() to only fetch
- // collections, nothing is preventing the collection from being dropped and
- // recreated as a view.
- print('Skipping collection validation for ' + coll.getFullName() +
- ' as it is a view');
- continue;
}
const host = db.getMongo().host;
print('Collection validation failed on host ' + host +
@@ -124,7 +117,6 @@ function CollectionValidator() {
// accurate.
enforceFastCount:
!TestData.skipEnforceFastCountOnValidate && !TestData.allowUncleanShutdowns,
- warnOnSchemaValidation: true
});
if (validateRes.ok !== 1) {
return {ok: 0, host: host, validateRes: validateRes};