diff options
author | Adrian Gonzalez <adriangonzalezmontemayor@gmail.com> | 2022-10-07 02:14:09 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-10-07 03:13:43 +0000 |
commit | 0406b63884d9993f0eafd7d6dcd680e0ecdc1a1f (patch) | |
tree | 64af3e807ec0dcf7a65e31ad42f3db054b726e11 /jstests/core/timeseries/bucket_span_and_rounding_seconds.js | |
parent | 84e93642a6d7f52ae2df506cff0df2679f526a2c (diff) | |
download | mongo-0406b63884d9993f0eafd7d6dcd680e0ecdc1a1f.tar.gz |
SERVER-67598 Add support for maxSpanSeconds and roundingSeconds arguments
Diffstat (limited to 'jstests/core/timeseries/bucket_span_and_rounding_seconds.js')
-rw-r--r-- | jstests/core/timeseries/bucket_span_and_rounding_seconds.js | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/jstests/core/timeseries/bucket_span_and_rounding_seconds.js b/jstests/core/timeseries/bucket_span_and_rounding_seconds.js new file mode 100644 index 00000000000..51687928b64 --- /dev/null +++ b/jstests/core/timeseries/bucket_span_and_rounding_seconds.js @@ -0,0 +1,243 @@ +/** + * Tests timeseries collection creation with bucketRoundingSeconds and bucketMaxSpanSeconds + * parameters and checks that we correctly set their value (failing when parameters are + * not added correctly or are missing). + * + * @tags: [ + * # "Overriding safe failed response for :: create" + * does_not_support_stepdowns, + * # We need a timeseries collection. + * requires_timeseries, + * ] + */ +(function() { +'use strict'; + +load("jstests/core/timeseries/libs/timeseries.js"); + +if (!TimeseriesTest.timeseriesScalabilityImprovementsEnabled(db.getMongo())) { + jsTestLog( + "Skipped test as the featureFlagTimeseriesScalabilityImprovements feature flag is not enabled."); + return; +} + +const testDB = db.getSiblingDB(jsTestName()); +assert.commandWorked(testDB.dropDatabase()); + +const timeFieldName = 'time'; +const coll = testDB.t; +const bucketRoundingSecondsTime = 4000; +const bucketMaxSpanSecondsTime = 4000; +const granularitySeconds = "seconds"; +const granularityMinutes = "minutes"; +const granularityHours = "hours"; +const bucketInvalidOptionsError = ErrorCodes.InvalidOptions; + +const granularityTimeOptionsArr = [granularitySeconds, granularityMinutes, granularityHours]; + +const getBucketMaxSpanSecondsFromGranularity = function(granularity) { + switch (granularity) { + case 'seconds': + return 60 * 60; + case 'minutes': + return 60 * 60 * 24; + case 'hours': + return 60 * 60 * 24 * 30; + default: + assert(false, 'Invalid granularity: ' + granularity); + } +}; + +const getBucketRoundingSecondsFromGranularity = function(granularity) { + switch (granularity) { + case 'seconds': + return 60; + case 'minutes': + return 60 * 60; + case 'hours': + return 60 * 60 * 24; + default: + assert(false, 'Invalid granularity: ' + granularity); + } +}; + +const verifyCreateCommandFails = function(secondsOptions = {}, errorCode) { + coll.drop(); + const fullTimeseriesOptions = Object.merge({timeField: timeFieldName}, secondsOptions); + + if (errorCode) { + assert.commandFailedWithCode( + testDB.createCollection(coll.getName(), {timeseries: fullTimeseriesOptions}), + errorCode); + } else { + assert.commandFailed( + testDB.createCollection(coll.getName(), {timeseries: fullTimeseriesOptions})); + } + + const collections = + assert.commandWorked(testDB.runCommand({listCollections: 1})).cursor.firstBatch; + + assert.isnull(collections.find(entry => entry.name === 'system.buckets.' + coll.getName())); + assert.isnull(collections.find(entry => entry.name === coll.getName())); +}; + +(function createTimeseriesCollectionWithBucketSecondsOptions() { + jsTestLog("Create timeseries collection with bucketRoundingSeconds and bucketMaxSpanSeconds."); + // Create a timeseries collection with bucketRoundingSeconds, bucketMaxSpanSeconds and + // custom parameters. ListCollection should show view and bucket collection with the added + // properties. + assert.commandWorked(testDB.createCollection(coll.getName(), { + timeseries: { + timeField: timeFieldName, + bucketRoundingSeconds: bucketRoundingSecondsTime, + bucketMaxSpanSeconds: bucketMaxSpanSecondsTime + } + })); + + let collections = + assert.commandWorked(testDB.runCommand({listCollections: 1})).cursor.firstBatch; + + let collectionEntry = + collections.find(entry => entry.name === 'system.buckets.' + coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, bucketRoundingSecondsTime); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, bucketMaxSpanSecondsTime); + + collectionEntry = collections.find(entry => entry.name === coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, bucketRoundingSecondsTime); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, bucketMaxSpanSecondsTime); + + // Verify the create command succeeds with bucketRoundingSeconds, bucketMaxSpanSeconds set as + // their default granularity values. + for (const granularityTime of granularityTimeOptionsArr) { + coll.drop(); + assert.commandWorked(testDB.createCollection(coll.getName(), { + timeseries: { + timeField: timeFieldName, + granularity: granularityTime, + bucketRoundingSeconds: getBucketRoundingSecondsFromGranularity(granularityTime), + bucketMaxSpanSeconds: getBucketMaxSpanSecondsFromGranularity(granularityTime) + } + })); + collections = + assert.commandWorked(testDB.runCommand({listCollections: 1})).cursor.firstBatch; + + collectionEntry = + collections.find(entry => entry.name === 'system.buckets.' + coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, + getBucketRoundingSecondsFromGranularity(granularityTime)); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, + getBucketMaxSpanSecondsFromGranularity(granularityTime)); + + collectionEntry = collections.find(entry => entry.name === coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, + getBucketRoundingSecondsFromGranularity(granularityTime)); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, + getBucketMaxSpanSecondsFromGranularity(granularityTime)); + } + + // Verify the create command succeeds without setting bucketRoundingSeconds and + // bucketMaxSpanSeconds. This should set their default granularity values. + for (const granularityTime of granularityTimeOptionsArr) { + coll.drop(); + assert.commandWorked(testDB.createCollection(coll.getName(), { + timeseries: { + timeField: timeFieldName, + granularity: granularityTime, + } + })); + collections = + assert.commandWorked(testDB.runCommand({listCollections: 1})).cursor.firstBatch; + + collectionEntry = + collections.find(entry => entry.name === 'system.buckets.' + coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, + getBucketRoundingSecondsFromGranularity(granularityTime)); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, + getBucketMaxSpanSecondsFromGranularity(granularityTime)); + + collectionEntry = collections.find(entry => entry.name === coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, + getBucketRoundingSecondsFromGranularity(granularityTime)); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, + getBucketMaxSpanSecondsFromGranularity(granularityTime)); + } + + // Verify the create command succeeds without setting any field other than timeField, this + // should set granularity as seconds and bucketRoundingSeconds and bucketMaxSpanSeconds with + // their default granularity values. + coll.drop(); + assert.commandWorked(testDB.createCollection(coll.getName(), { + timeseries: { + timeField: timeFieldName, + } + })); + collections = assert.commandWorked(testDB.runCommand({listCollections: 1})).cursor.firstBatch; + + collectionEntry = collections.find(entry => entry.name === 'system.buckets.' + coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, + getBucketRoundingSecondsFromGranularity(granularitySeconds)); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, + getBucketMaxSpanSecondsFromGranularity(granularitySeconds)); + + collectionEntry = collections.find(entry => entry.name === coll.getName()); + assert(collectionEntry); + assert.eq(collectionEntry.options.timeseries.bucketRoundingSeconds, + getBucketRoundingSecondsFromGranularity(granularitySeconds)); + assert.eq(collectionEntry.options.timeseries.bucketMaxSpanSeconds, + getBucketMaxSpanSecondsFromGranularity(granularitySeconds)); +})(); + +(function createTimeseriesCollectionWithInvalidOptions() { + jsTestLog("Create timeseries collection with missing or extra arguments."); + + // Verify the create command fails when the 'bucketRoundingSeconds' option is set but not the + // 'bucketMaxSpanSeconds' option. + verifyCreateCommandFails({bucketRoundingSeconds: bucketRoundingSecondsTime}, + bucketInvalidOptionsError); + + // Verify the create command fails when the 'bucketMaxSpanSeconds' option is set but not the + // 'bucketRoundingSeconds' option. + verifyCreateCommandFails({bucketMaxSpanSeconds: bucketMaxSpanSecondsTime}, + bucketInvalidOptionsError); + + // Verify the create command fails when the 'bucketMaxSpanSeconds' option is set but not the + // 'bucketRoundingSeconds' option (even if set to granularity default seconds value). + verifyCreateCommandFails({bucketMaxSpanSeconds: 3600}, bucketInvalidOptionsError); + + // Verify the create command fails when bucketRoundingSeconds is different than + // bucketMaxSpanSeconds. + verifyCreateCommandFails({bucketRoundingSeconds: 100, bucketMaxSpanSeconds: 50}, + bucketInvalidOptionsError); + + // Verify the create command fails when bucketRoundingSeconds or bucketMaxSpanSeconds is a + // negative value. + verifyCreateCommandFails({bucketRoundingSeconds: -1, bucketMaxSpanSeconds: -1}); + + // Verify the create command fails when granularity is set as minutes alongside + // bucketRoundingSeconds and bucketMaxSpanSeconds and they are not the default granularity + // values. + verifyCreateCommandFails({ + granularity: granularityMinutes, + bucketRoundingSeconds: bucketRoundingSecondsTime, + bucketMaxSpanSeconds: bucketMaxSpanSecondsTime + }, + bucketInvalidOptionsError); + + // Verify the create command fails when granularity is set as hours alongside + // bucketRoundingSeconds and bucketMaxSpanSeconds and they are not the default granularity + // values. + verifyCreateCommandFails({ + granularity: granularityHours, + bucketRoundingSeconds: bucketRoundingSecondsTime, + bucketMaxSpanSeconds: bucketMaxSpanSecondsTime + }, + bucketInvalidOptionsError); +})(); +})(); |