summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaddie Zechar <mez2113@columbia.edu>2023-03-21 15:12:28 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-03-21 15:38:45 +0000
commit4a20978382e1d521edc7654bde022f6849285749 (patch)
tree94f0e729017da0070b81708a633dbd4ae754fc5a
parenteb23c1b873bc57b84af44973395af0d67ffe5863 (diff)
downloadmongo-v6.2.tar.gz
SERVER-73735 Fail more gracefully if telemetry store configuration is attempted and telemetry store is disabledv6.2
-rw-r--r--jstests/noPassthroughWithMongod/telemetry_configuration.js32
-rw-r--r--jstests/telemetry/feature_flag_off_sampling_rate_on.js49
-rw-r--r--jstests/telemetry/telemetry_feature_flag.js27
-rw-r--r--jstests/telemetry/telemetry_sampling_rate.js41
-rw-r--r--src/mongo/db/query/telemetry.cpp2
-rw-r--r--src/mongo/db/query/telemetry_util.h13
6 files changed, 164 insertions, 0 deletions
diff --git a/jstests/noPassthroughWithMongod/telemetry_configuration.js b/jstests/noPassthroughWithMongod/telemetry_configuration.js
new file mode 100644
index 00000000000..8d0b6ed68b5
--- /dev/null
+++ b/jstests/noPassthroughWithMongod/telemetry_configuration.js
@@ -0,0 +1,32 @@
+/**
+ * Tests that the telemetry store can be resized if it is configured, and cannot be resized if it is
+ * disabled.
+ */
+(function() {
+"use strict";
+
+load("jstests/libs/feature_flag_util.js");
+
+if (FeatureFlagUtil.isEnabled(db, "Telemetry")) {
+ // The feature flag is enabled - make sure the telemetry store can be configured.
+ const original = assert.commandWorked(
+ db.adminCommand({getParameter: 1, internalQueryConfigureTelemetryCacheSize: 1}));
+ assert(original.hasOwnProperty("internalQueryConfigureTelemetryCacheSize"), original);
+ const originalValue = original.internalQueryConfigureTelemetryCacheSize;
+ try {
+ assert.doesNotThrow(
+ () => db.adminCommand(
+ {setParameter: 1, internalQueryConfigureTelemetryCacheSize: '2MB'}));
+ // Other tests verify that resizing actually affects the data structure size.
+ } finally {
+ assert.doesNotThrow(
+ () => db.adminCommand(
+ {setParameter: 1, internalQueryConfigureTelemetryCacheSize: originalValue}));
+ }
+} else {
+ // The feature flag is disabled - make sure the telemetry store *cannot* be configured.
+ assert.commandFailedWithCode(
+ db.adminCommand({setParameter: 1, internalQueryConfigureTelemetryCacheSize: '2MB'}),
+ 7373500);
+}
+}());
diff --git a/jstests/telemetry/feature_flag_off_sampling_rate_on.js b/jstests/telemetry/feature_flag_off_sampling_rate_on.js
new file mode 100644
index 00000000000..59a13b4b679
--- /dev/null
+++ b/jstests/telemetry/feature_flag_off_sampling_rate_on.js
@@ -0,0 +1,49 @@
+/**
+ * Test that calls to read from telemetry store fail when feature flag is turned off and sampling
+ * rate > 0.
+ */
+load('jstests/libs/analyze_plan.js');
+load("jstests/libs/feature_flag_util.js");
+
+(function() {
+"use strict";
+
+// This test specifically tests error handling when the feature flag is not on.
+if (FeatureFlagUtil.isEnabled(db, "Telemetry")) {
+ return;
+}
+
+// Set sampling rate to MAX_INT.
+let options = {
+ setParameter: {internalQueryConfigureTelemetrySamplingRate: 2147483647},
+};
+
+const conn = MongoRunner.runMongod(options);
+const testdb = conn.getDB('test');
+var coll = testdb[jsTestName()];
+coll.drop();
+
+// Bulk insert documents to reduces roundtrips and make timeout on a slow machine less likely.
+const bulk = coll.initializeUnorderedBulkOp();
+for (let i = 1; i <= 20; i++) {
+ bulk.insert({foo: 0, bar: Math.floor(Math.random() * 3)});
+}
+assert.commandWorked(bulk.execute());
+
+// Pipeline to read telemetry store should fail without feature flag turned on even though sampling
+// rate is > 0.
+assert.commandFailedWithCode(
+ db.adminCommand({aggregate: 1, pipeline: [{$telemetry: {}}], cursor: {}}),
+ ErrorCodes.QueryFeatureNotAllowed);
+
+// Pipeline, with a filter, to read telemetry store fails without feature flag turned on even though
+// sampling rate is > 0.
+assert.commandFailedWithCode(db.adminCommand({
+ aggregate: 1,
+ pipeline: [{$telemetry: {}}, {$match: {"key.find.find": {$eq: "###"}}}],
+ cursor: {}
+}),
+ ErrorCodes.QueryFeatureNotAllowed);
+
+MongoRunner.stopMongod(conn);
+}());
diff --git a/jstests/telemetry/telemetry_feature_flag.js b/jstests/telemetry/telemetry_feature_flag.js
new file mode 100644
index 00000000000..03aa33d19f2
--- /dev/null
+++ b/jstests/telemetry/telemetry_feature_flag.js
@@ -0,0 +1,27 @@
+/**
+ * Test that calls to read from telemetry store fail when feature flag is turned off.
+ */
+load('jstests/libs/analyze_plan.js');
+load("jstests/libs/feature_flag_util.js");
+
+(function() {
+"use strict";
+
+// This test specifically tests error handling when the feature flag is not on.
+if (FeatureFlagUtil.isEnabled(db, "Telemetry")) {
+ return;
+}
+
+// Pipeline to read telemetry store should fail without feature flag turned on.
+assert.commandFailedWithCode(
+ db.adminCommand({aggregate: 1, pipeline: [{$telemetry: {}}], cursor: {}}),
+ ErrorCodes.QueryFeatureNotAllowed);
+
+// Pipeline, with a filter, to read telemetry store fails without feature flag turned on.
+assert.commandFailedWithCode(db.adminCommand({
+ aggregate: 1,
+ pipeline: [{$telemetry: {}}, {$match: {"key.find.find": {$eq: "###"}}}],
+ cursor: {}
+}),
+ ErrorCodes.QueryFeatureNotAllowed);
+}());
diff --git a/jstests/telemetry/telemetry_sampling_rate.js b/jstests/telemetry/telemetry_sampling_rate.js
new file mode 100644
index 00000000000..3789e044ea6
--- /dev/null
+++ b/jstests/telemetry/telemetry_sampling_rate.js
@@ -0,0 +1,41 @@
+/**
+ * Test that calls to read from telemetry store fail when sampling rate is not greater than 0 even
+ * if feature flag is on.
+ */
+load('jstests/libs/analyze_plan.js');
+load("jstests/libs/feature_flag_util.js");
+
+(function() {
+"use strict";
+
+if (!FeatureFlagUtil.isEnabled(db, "Telemetry")) {
+ return;
+}
+
+let options = {
+ setParameter: {internalQueryConfigureTelemetrySamplingRate: 0},
+};
+
+const conn = MongoRunner.runMongod(options);
+const testdb = conn.getDB('test');
+var coll = testdb[jsTestName()];
+coll.drop();
+for (var i = 0; i < 20; i++) {
+ coll.insert({foo: 0, bar: Math.floor(Math.random() * 3)});
+}
+
+coll.aggregate([{$match: {foo: 1}}], {cursor: {batchSize: 2}});
+
+// Reading telemetry store with a sampling rate of 0 should return 0 documents.
+let telStore = testdb.adminCommand({aggregate: 1, pipeline: [{$telemetry: {}}], cursor: {}});
+assert.eq(telStore.cursor.firstBatch.length, 0);
+
+// TODO SERVER-71531 enable below test.
+// Reading telemetry store should work now with a sampling rate of greater than 0.
+// assert.commandWorked(testdb.adminCommand({setParameter: 1,
+// internalQueryConfigureTelemetrySamplingRate: 2147483647})); coll.aggregate([{$match: {foo: 1}}],
+// {cursor: {batchSize: 2}}); assert.commandWorked(testdb.adminCommand({aggregate: 1, pipeline:
+// [{$telemetry: {}}], cursor: {}}));
+
+MongoRunner.stopMongod(conn);
+}());
diff --git a/src/mongo/db/query/telemetry.cpp b/src/mongo/db/query/telemetry.cpp
index 90e7da76ddb..a41428abea0 100644
--- a/src/mongo/db/query/telemetry.cpp
+++ b/src/mongo/db/query/telemetry.cpp
@@ -146,6 +146,8 @@ ServiceContext::ConstructorActionRegisterer telemetryStoreManagerRegisterer{
// featureFlags are not allowed to be changed at runtime. Therefore it's not an issue
// to not create a telemetry store in ConstructorActionRegisterer at start up with the
// flag off - because the flag can not be turned on at any point afterwards.
+ telemetry_util::telemetryStoreOnParamChangeUpdater(serviceCtx) =
+ std::make_unique<telemetry_util::NoChangesAllowedTelemetryParamUpdater>();
return;
}
diff --git a/src/mongo/db/query/telemetry_util.h b/src/mongo/db/query/telemetry_util.h
index 0aedd95e26e..133d45f1338 100644
--- a/src/mongo/db/query/telemetry_util.h
+++ b/src/mongo/db/query/telemetry_util.h
@@ -60,6 +60,19 @@ public:
};
/**
+ * A stub implementation that does not allow changing any parameters - to be used if the telemetry
+ * store is disabled and cannot be re-enabled without restarting, as with a feature flag.
+ */
+class NoChangesAllowedTelemetryParamUpdater : public OnParamChangeUpdater {
+public:
+ void updateCacheSize(ServiceContext* serviceCtx, memory_util::MemorySize memSize) final {
+ uasserted(7373500,
+ "Cannot configure telemetry store - it is currently disabled and a restart is "
+ "required to activate.");
+ }
+};
+
+/**
* Decorated accessor to the 'OnParamChangeUpdater' stored in 'ServiceContext'.
*/
extern const Decorable<ServiceContext>::Decoration<std::unique_ptr<OnParamChangeUpdater>>