From 65be29203b6bcbbdfc2040cbb614d03bfed568a9 Mon Sep 17 00:00:00 2001 From: Binh Vo <146007384+binhvomongodb@users.noreply.github.com> Date: Wed, 6 Aug 2025 17:08:48 -0400 Subject: [PATCH] SERVER-108909 Readd jstests for mixed schema fix (#39732) GitOrigin-RevId: 98494390a6fc09c85e216417054ce7f893168f17 --- ...kports_required_for_multiversion_tests.yml | 4 + .../timeseries_insert_mixed_schema_docs.js | 87 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 jstests/core/timeseries/write/timeseries_insert_mixed_schema_docs.js diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml index 739bbe8cb54..895f997239f 100644 --- a/etc/backports_required_for_multiversion_tests.yml +++ b/etc/backports_required_for_multiversion_tests.yml @@ -466,6 +466,8 @@ last-continuous: ticket: SERVER-105874 - test_file: jstests/sharding/query/lookup/union_with_doubly_nested_lookup.js ticket: SERVER-108341 + - test_file: jstests/core/timeseries/write/timeseries_insert_mixed_schema_docs.js + ticket: SERVER-107361 suites: null last-lts: all: @@ -989,4 +991,6 @@ last-lts: ticket: SERVER-107352 - test_file: jstests/sharding/query/lookup/union_with_doubly_nested_lookup.js ticket: SERVER-108341 + - test_file: jstests/core/timeseries/write/timeseries_insert_mixed_schema_docs.js + ticket: SERVER-107361 suites: null diff --git a/jstests/core/timeseries/write/timeseries_insert_mixed_schema_docs.js b/jstests/core/timeseries/write/timeseries_insert_mixed_schema_docs.js new file mode 100644 index 00000000000..85fd0ecfacf --- /dev/null +++ b/jstests/core/timeseries/write/timeseries_insert_mixed_schema_docs.js @@ -0,0 +1,87 @@ +/** + * Tests directly inserting a time-series bucket with mixed schema. + * + * @tags: [ + * # $listCatalog does not include the tenant prefix in its results. + * command_not_supported_in_serverless, + * requires_timeseries, + * does_not_support_viewless_timeseries_yet, + * ] + */ + +import {TimeseriesTest} from "jstests/core/timeseries/libs/timeseries.js"; +import {getTimeseriesBucketsColl} from "jstests/core/timeseries/libs/viewless_timeseries_util.js"; + +const testDB = db.getSiblingDB(jsTestName()); +const collName = "ts"; + +/** + * Test 1: Basic insert of mixed schema, check bucket counts + */ +(function basicInsertMixedSchemaTest() { + assert.commandWorked(testDB.runCommand({drop: collName})); + assert.commandWorked( + testDB.createCollection(collName, {timeseries: {timeField: "t", metaField: "m"}})); + const coll = testDB[collName]; + + var doc = { + t: ISODate(), + m: "meta", + a: "foo", + }; + assert.commandWorked(coll.insert(doc)); + assert.eq(1, coll.find({"m": "meta"}).toArray().length); + assert.eq(1, getTimeseriesBucketsColl(coll).find({}).toArray().length); + + // new measurement, same bucket + doc.a = "bar"; + assert.commandWorked(coll.insert(doc)); + assert.eq(2, coll.find({"m": "meta"}).toArray().length); + assert.eq(1, getTimeseriesBucketsColl(coll).find({"meta": "meta"}).toArray().length); + + // new measurement, because schema changed, we have a new bucket + doc.a = 1; + assert.commandWorked(coll.insert(doc)); + assert.eq(3, coll.find({"m": "meta"}).toArray().length); + assert.eq(2, getTimeseriesBucketsColl(coll).find({"meta": "meta"}).toArray().length); + + // new measurement, schema changed back, necessitating a third bucket + doc.a = "bam"; + assert.commandWorked(coll.insert(doc)); + assert.eq(4, coll.find({"m": "meta"}).toArray().length); + // New measurement may go into new bucket, or prev bucket (reopened), but should not go into + // the recently created bucket. + assert.eq(1, getTimeseriesBucketsColl(coll).find({"meta": "meta"}).toArray()[1].control.count); +})(); + +/** + * Test 2: Test with very large docs, checks bug discovered in SERVER-107361 + */ +(function largeDocInsertMixedSchemaTest() { + assert.commandWorked(testDB.runCommand({drop: collName})); + assert.commandWorked( + testDB.createCollection(collName, {timeseries: {timeField: "t", metaField: "m"}})); + const coll = testDB[collName]; + + var doc = {t: ISODate(), m: "meta", a: 1, payload: "small"}; + assert.commandWorked(coll.insert(doc)); + assert.eq(1, coll.find({"m": "meta"}).toArray().length); + assert.eq(1, getTimeseriesBucketsColl(coll).find({}).toArray().length); + + // new measurement, because schema changed, we have a new bucket + // previous bug would skip mixed schema check due to handling of large measurements + doc.a = "foo"; + doc.payload = 'A'.repeat(130000); + assert.commandWorked(coll.insert(doc)); + assert.eq(2, coll.find({"m": "meta"}).toArray().length); + assert.eq(2, getTimeseriesBucketsColl(coll).find({"meta": "meta"}).toArray().length); + + // new measurement, schema changed back, necessitating a third bucket + doc.a = 2; + doc.payload = "small"; + assert.commandWorked(coll.insert(doc)); + assert.eq(3, coll.find({"m": "meta"}).toArray().length); + // New measurement may go into new bucket, or prev bucket (reopened), but should not go into + // the recently created bucket. + assert.eq(1, getTimeseriesBucketsColl(coll).find({"meta": "meta"}).toArray()[1].control.count); +})();