diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
| commit | 4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch) | |
| tree | 1682a647d4463397c119183369ae6f750d5fdcff /jstests/hooks | |
| parent | aa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff) | |
| parent | 8f0827553e09872941945a093b647a4211a9db7f (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.js | 112 | ||||
| -rw-r--r-- | jstests/hooks/run_dbcheck_background.js | 34 | ||||
| -rw-r--r-- | jstests/hooks/validate_collections.js | 8 |
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}; |
