103 lines
3.5 KiB
JavaScript
103 lines
3.5 KiB
JavaScript
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
|
|
import {runWithRetries} from "jstests/libs/run_with_retries.js";
|
|
|
|
// Helper function to retry a test.
|
|
// This is useful because the spilling stats are global and can be affected by spuriously
|
|
// running background/system queries that are not part of the actual test.
|
|
// In case the returned global spilling stats are modified by outside queries and are not as
|
|
// expected by the test, we simply retry a few times to wait out the effects of the background
|
|
// activity on the spilling stats.
|
|
// This is not a perfect solution, but helps to reduce test flakiness.
|
|
export function runReleaseMemoryTestWithRetries(fn) {
|
|
return runWithRetries(
|
|
fn,
|
|
(e) => {
|
|
jsTest.log.info("caught exception and will retry", e);
|
|
return true;
|
|
},
|
|
3 /* numRetries */,
|
|
500 /* initialBackoffMs */,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Asserts that releaseMemory command failed for a given cursor with the appropriate code.
|
|
*/
|
|
export function assertReleaseMemoryFailedWithCode(result, cursorId, codes) {
|
|
if (!Array.isArray(codes)) {
|
|
codes = [codes];
|
|
}
|
|
if (!result.hasOwnProperty("cursorsWithErrors")) {
|
|
doassert("Command result does not contain 'cursorsWithErrors' field: " + tojson(result));
|
|
}
|
|
for (const releaseMemoryError of result.cursorsWithErrors) {
|
|
if (releaseMemoryError.cursorId.compare(cursorId) === 0) {
|
|
assert.contains(
|
|
releaseMemoryError.status.code,
|
|
codes,
|
|
"the following release memory error contains an unexpected error code: " + tojson(releaseMemoryError),
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
doassert(
|
|
"Cursor " +
|
|
tojsononeline(cursorId) +
|
|
" did not fail during release memory. Full command result: " +
|
|
tojson(result),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Asserts that releaseMemory command worked for a given cursor.
|
|
*/
|
|
export function assertReleaseMemoryWorked(result, cursorId) {
|
|
if (!result.hasOwnProperty("cursorsReleased")) {
|
|
doassert("Command result does not contain 'cursorsReleased' field: " + tojson(result));
|
|
}
|
|
for (const releaseMemoryOk of result.cursorsReleased) {
|
|
if (releaseMemoryOk.compare(cursorId) === 0) {
|
|
return;
|
|
}
|
|
}
|
|
doassert(
|
|
"Releasing memory from cursor " +
|
|
tojsononeline(cursorId) +
|
|
" did not succeed during release memory. Full command result: " +
|
|
tojson(result),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Accumulate metric from a server status
|
|
*/
|
|
export function accumulateServerStatusMetric(db, metricGetter) {
|
|
return retryOnRetryableError(
|
|
() => {
|
|
let total = 0;
|
|
FixtureHelpers.mapOnEachShardNode({
|
|
db: db,
|
|
func: (db) => {
|
|
const serverStatus = db.serverStatus();
|
|
if (!serverStatus.hasOwnProperty("metrics")) {
|
|
return;
|
|
}
|
|
total += metricGetter(serverStatus.metrics);
|
|
},
|
|
});
|
|
return total;
|
|
},
|
|
10,
|
|
100,
|
|
[ErrorCodes.InterruptedDueToStorageChange],
|
|
);
|
|
}
|
|
|
|
// Sets the mode of the simulateAvailableDiskSpace failpoint.
|
|
export function setAvailableDiskSpaceMode(db, mode, bytes = 450 * 1024 * 1024) {
|
|
FixtureHelpers.runCommandOnEachPrimary({
|
|
db: db,
|
|
cmdObj: {configureFailPoint: "simulateAvailableDiskSpace", mode, "data": {bytes: bytes}},
|
|
});
|
|
}
|