jstests/concurrency/fsm_workload_helpers/check_transaction_server_status_invariants.js
/**
 * Check invariants of transactions metrics reported in 'serverStatus' (server-wide metrics),
 * using the number of given samples.
 *
 * Inside the server, these metrics are tracked individually with atomic counters, but there
 * is no guarantee that two separate counters are updated atomically. There may be a delay
 * between the update of one counter (e.g. 'currentOpen') and another counter (e.g.
 * 'totalAborted'). This means that some invariants may not strictly hold at all times. The
 * assumption is that when these invariants are broken due to these non atomic updates, they
 * are broken for an extremely short period of time, and therefore only appear very rarely
 * when sampling the output of these metrics. We base the testing strategy below on this
 * assumption. Instead of asserting that a particular invariant holds 100% of the time, we
 * assert something slightly weaker i.e. that the invariant holds, for example, 95% percent
 * of the time. The error bounds for this test were determined somewhat empirically, but
 * they were kept very conservative. One goal of these tests is to ensure that if a change
 * was made that broke these metrics significantly, it would be picked up by these tests.
 * This test should not be sensitive to small fluctuations in metrics output.
 */
Check invariants of transactions metrics reported in 'serverStatus' (server-wide metrics),
using the number of given samples.

Inside the server, these metrics are tracked individually with atomic counters, but there
is no guarantee that two separate counters are updated atomically. There may be a delay
between the update of one counter  and another counter . This means that some invariants may not strictly hold at all times. The
assumption is that when these invariants are broken due to these non atomic updates, they
are broken for an extremely short period of time, and therefore only appear very rarely
when sampling the output of these metrics. We base the testing strategy below on this
assumption. Instead of asserting that a particular invariant holds 100% of the time, we
assert something slightly weaker i.e. that the invariant holds, for example, 95% percent
of the time. The error bounds for this test were determined somewhat empirically, but
they were kept very conservative. One goal of these tests is to ensure that if a change
was made that broke these metrics significantly, it would be picked up by these tests.
This test should not be sensitive to small fluctuations in metrics output.
Check invariants of transactions metrics reported in ' serverStatus ' ( server - wide metrics ) using the number of given samples . Inside the server these metrics are tracked individually with atomic counters but there is no guarantee that two separate counters are updated atomically . There may be a delay between the update of one counter and another counter . This means that some invariants may not strictly hold at all times . The assumption is that when these invariants are broken due to these non atomic updates they are broken for an extremely short period of time and therefore only appear very rarely when sampling the output of these metrics . We base the testing strategy below on this assumption . Instead of asserting that a particular invariant holds 100% of the time we assert something slightly weaker i . e . that the invariant holds for example 95% percent of the time . The error bounds for this test were determined somewhat empirically but they were kept very conservative . One goal of these tests is to ensure that if a change was made that broke these metrics significantly it would be picked up by these tests . This test should not be sensitive to small fluctuations in metrics output .
function checkServerStatusInvariants(db, nSamples, isMongos) {
    let samples = [];
    for (let i = 0; i < nSamples; ++i) {
        let txnStats = db.adminCommand({serverStatus: 1}).transactions;
        samples.push(txnStats);
        sleep(50);  
    }
    const maxErrPct = 0.05;
    checkInvariant(samples, activePlusInactiveEqualsOpen, maxErrPct);
    checkInvariant(samples, committedPlusAbortedPlusOpenEqualsStarted, maxErrPct);
    if (!isMongos) {
        checkInvariant(samples,
                       preparedAbortedPlusPreparedCommittedPlusCurrentPreparedEqualsTotalPrepared,
                       maxErrPct);
        checkInvariant(
            samples,
            unpreparedAbortedPlusUnpreparedCommittedPlusUnpreparedOpenEqualsTotalUnprepared,
            maxErrPct);
    } else {
        checkInvariant(samples, totalCommittedEqualsSumOfSuccessfulCommitTypes, maxErrPct);
        checkInvariant(samples, totalAbortedEqualsSumOfAbortCauses, maxErrPct);
    }
    checkInvariant(samples, allCountsNonNegative, 0);
}
function checkServerStatusInvariants ( db , nSamples , isMongos ) { let samples = [ ] ; for ( let i = 0 ; i < nSamples ; ++ i ) { let txnStats = db . adminCommand ( { serverStatus : 1 } ) . transactions ; samples . push ( txnStats ) ; sleep ( 50 ) ; } const maxErrPct = 0.05 ; checkInvariant ( samples , activePlusInactiveEqualsOpen , maxErrPct ) ; checkInvariant ( samples , committedPlusAbortedPlusOpenEqualsStarted , maxErrPct ) ; if ( ! isMongos ) { checkInvariant ( samples , preparedAbortedPlusPreparedCommittedPlusCurrentPreparedEqualsTotalPrepared , maxErrPct ) ; checkInvariant ( samples , unpreparedAbortedPlusUnpreparedCommittedPlusUnpreparedOpenEqualsTotalUnprepared , maxErrPct ) ; } else { checkInvariant ( samples , totalCommittedEqualsSumOfSuccessfulCommitTypes , maxErrPct ) ; checkInvariant ( samples , totalAbortedEqualsSumOfAbortCauses , maxErrPct ) ; } checkInvariant ( samples , allCountsNonNegative , 0 ) ; }
Check invariants of transactions metrics reported in 'serverStatus' (server-wide metrics),
 using the number of given samples.
Check invariants of transactions metrics reported in ' serverStatus ' ( server - wide metrics ) using the number of given samples .
// Sample serverStatus several times, sleeping a bit in between. // milliseconds. // We consider an invariant failure rate of 5% within a large enough sample to be acceptable // For example, in a batch of 100 metrics samples, we would accept <= 5 violations of a // particular invariant. // Check mongod specific stats. // Check mongos specific stats. // allCountsNonNegative() is always expected to succeed.