Files
mongo/jstests/multiVersion/targetedTestsLastContinuousFeatures/accumulator_fix_last_continuous.js
2022-05-17 02:38:30 +00:00

163 lines
6.0 KiB
JavaScript

/**
* Tests whether $sum accumulator incorrect result bug is fixed when upgrading from the
* last-continuous to the latest.
*
* @tags: [
* requires_sharding,
* ]
*/
(function() {
'use strict';
load('jstests/multiVersion/libs/multi_cluster.js'); // For upgradeCluster()
// TODO SERVER-64227 Remove this test case since this test case is unnecessary after we branch
// for 6.1.
(function testUpgradeFromLastContinuousToLatest() {
const st = new ShardingTest({
shards: 2,
rs: {nodes: 2, binVersion: "last-continuous"},
other: {mongosOptions: {binVersion: "last-continuous"}}
});
let db = st.getDB(jsTestName());
// Makes sure that the test db is sharded.
assert.commandWorked(st.s0.adminCommand({enableSharding: db.getName()}));
let verifyShardedAccumulatorResultsOnBothEngine = (coll, pipeline, verifyThis) => {
const dbs = [
st.rs0.getPrimary().getDB(jsTestName()),
st.rs0.getSecondary().getDB(jsTestName()),
st.rs1.getPrimary().getDB(jsTestName()),
st.rs1.getSecondary().getDB(jsTestName())
];
function setEngine(db, turnOnSBE) {
// Based on which version we are running, set the appropriate parameter which
// controls the execution engine.
const res = db.adminCommand({
getParameter: 1,
internalQueryEnableSlotBasedExecutionEngine: 1,
internalQueryForceClassicEngine: 1
});
if (res.hasOwnProperty("internalQueryEnableSlotBasedExecutionEngine")) {
assert.commandWorked(
db.adminCommand(
{setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: turnOnSBE}),
`at node ${db.getMongo().host}`);
} else {
assert(res.hasOwnProperty("internalQueryForceClassicEngine"));
assert.commandWorked(
db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: !turnOnSBE}),
`at node ${db.getMongo().host}`);
}
}
// Turns to the classic engine at the shards.
dbs.forEach((db) => setEngine(db, false /* turnOnSBE */));
// Verifies that the classic engine's results are same as the expected results.
const classicRes = coll.aggregate(pipeline).toArray();
verifyThis(classicRes);
// Turns to the SBE engine at the shards.
dbs.forEach((db) => setEngine(db, true /* turnOnSBE */));
// Verifies that the SBE engine's results are same as the expected results.
const sbeRes = coll.aggregate(pipeline).toArray();
verifyThis(sbeRes);
};
let shardCollectionByHashing = coll => {
coll.drop();
// Makes sure that the collection is sharded.
assert.commandWorked(
st.s0.adminCommand({shardCollection: coll.getFullName(), key: {_id: "hashed"}}));
return coll;
};
let hashShardedColl = shardCollectionByHashing(db.partial_sum);
for (let i = 0; i < 10; ++i) {
const docs = [
{k: i, n: 1e+34},
{k: i, n: NumberDecimal("0.1")},
{k: i, n: NumberDecimal("0.01")},
{k: i, n: -1e+34}
];
assert.commandWorked(hashShardedColl.insert(docs));
}
const pipelineWithSum = [{$group: {_id: "$k", s: {$sum: "$n"}}}, {$group: {_id: "$s"}}];
const pipelineWithAvg = [{$group: {_id: "$k", s: {$avg: "$n"}}}, {$group: {_id: "$s"}}];
const expectedResSum = [{"_id": NumberDecimal("0.11")}];
verifyShardedAccumulatorResultsOnBothEngine(
hashShardedColl,
pipelineWithSum,
(actualRes) => assert.neq(
actualRes,
expectedResSum,
`Sharded sum for mixed data by which only decimal sum survive on ${version}: \n` +
`${tojson(actualRes)} == ${tojson(expectedResSum)}`));
const expectedResAvg = [{"_id": NumberDecimal("0.0275")}];
verifyShardedAccumulatorResultsOnBothEngine(
hashShardedColl,
pipelineWithAvg,
(actualRes) => assert.neq(
actualRes,
expectedResAvg,
`Sharded avg for mixed data by which only decimal sum survive on ${version}: \n` +
`${tojson(actualRes)} == ${tojson(expectedResAvg)}`));
// Upgrade the cluster to the latest.
st.upgradeCluster(
"latest",
{upgradeShards: true, upgradeConfigs: true, upgradeMongos: true, waitUntilStable: true});
db = st.getDB(jsTestName());
checkFCV(st.rs0.getPrimary().getDB("admin"), lastContinuousFCV);
hashShardedColl = db.partial_sum;
// $sum fix is FCV-gated. So, it's not applied after binary upgrade.
verifyShardedAccumulatorResultsOnBothEngine(
hashShardedColl,
pipelineWithSum,
(actualRes) => assert.neq(
actualRes,
expectedResSum,
"Sharded sum for mixed data by which only decimal sum survive on latest after binary upgrade: \n" +
`${tojson(actualRes)} == ${tojson(expectedResSum)}`));
// On the other hand, $avg fix is not FCV-gated. So, it's applied after binary upgrade.
verifyShardedAccumulatorResultsOnBothEngine(
hashShardedColl,
pipelineWithAvg,
(actualRes) => assert.eq(
actualRes,
expectedResAvg,
"Sharded avg for mixed data by which only decimal sum survive on latest after binary upgrade: \n" +
`${tojson(actualRes)} != ${tojson(expectedResAvg)}`));
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV}));
// The FCV is upgraded to the 'latestFCV' and $sum fix must be applied now.
verifyShardedAccumulatorResultsOnBothEngine(
hashShardedColl,
pipelineWithSum,
(actualRes) => assert.eq(
actualRes,
expectedResSum,
"Sharded sum for mixed data by which only decimal sum survive on latest after FCV upgrade: \n" +
`${tojson(actualRes)} != ${tojson(expectedResSum)}`));
st.stop();
}());
}());