summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoonsoo Kim <yoonsoo.kim@mongodb.com>2021-03-18 15:59:31 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-19 23:55:43 +0000
commit388ce132e9edd64cbfdf677a87ac5044ca3a79ed (patch)
tree167aad4c6c5b6616e1ccb37fd2d585ef85c22edb
parent534cd73dab035bf8a72852f24dd21c9c84669365 (diff)
downloadmongo-SERVER-54990-refactor-TODO.tar.gz
SERVER-54069 Added $graphLookup test suite for timeseriesSERVER-54990-refactor-TODO
-rw-r--r--etc/evergreen.yml2
-rw-r--r--jstests/core/timeseries/libs/timeseries.js29
-rw-r--r--jstests/core/timeseries/timeseries_graph_lookup.js157
3 files changed, 173 insertions, 15 deletions
diff --git a/etc/evergreen.yml b/etc/evergreen.yml
index 24966083b47..a63b854eb9c 100644
--- a/etc/evergreen.yml
+++ b/etc/evergreen.yml
@@ -5761,7 +5761,7 @@ tasks:
- func: "do setup"
- func: "run tests"
vars:
- resmoke_args: --suites=core --shellReadMode=legacy --shellWriteMode=compatibility --storageEngine=wiredTiger --excludeWithAnyTags=requires_find_command
+ resmoke_args: --suites=core --shellReadMode=legacy --shellWriteMode=compatibility --storageEngine=wiredTiger --excludeWithAnyTags=requires_find_command,requires_timeseries
- <<: *task_template
name: jsCore_auth
diff --git a/jstests/core/timeseries/libs/timeseries.js b/jstests/core/timeseries/libs/timeseries.js
index f1f4d3eb917..df52c18749a 100644
--- a/jstests/core/timeseries/libs/timeseries.js
+++ b/jstests/core/timeseries/libs/timeseries.js
@@ -29,6 +29,10 @@ var TimeseriesTest = class {
return arr[Random.randInt(arr.length)];
}
+ static getRandomUsage() {
+ return Random.randInt(101);
+ }
+
/**
* Generates time-series data based on the TSBS document-per-event format.
*
@@ -38,10 +42,6 @@ var TimeseriesTest = class {
static generateHosts(numHosts) {
const hosts = new Array(numHosts);
- const getRandomUsage = function() {
- return Random.randInt(101);
- };
-
const regions = [
"ap-northeast-1",
"ap-southeast-1",
@@ -102,21 +102,22 @@ var TimeseriesTest = class {
const regionIndex = Random.randInt(regions.length);
hosts[i] = {
fields: {
- usage_guest: getRandomUsage(),
- usage_guest_nice: getRandomUsage(),
- usage_idle: getRandomUsage(),
- usage_iowait: getRandomUsage(),
- usage_irq: getRandomUsage(),
- usage_nice: getRandomUsage(),
- usage_softirq: getRandomUsage(),
- usage_steal: getRandomUsage(),
- usage_system: getRandomUsage(),
- usage_user: getRandomUsage(),
+ usage_guest: TimeseriesTest.getRandomUsage(),
+ usage_guest_nice: TimeseriesTest.getRandomUsage(),
+ usage_idle: TimeseriesTest.getRandomUsage(),
+ usage_iowait: TimeseriesTest.getRandomUsage(),
+ usage_irq: TimeseriesTest.getRandomUsage(),
+ usage_nice: TimeseriesTest.getRandomUsage(),
+ usage_softirq: TimeseriesTest.getRandomUsage(),
+ usage_steal: TimeseriesTest.getRandomUsage(),
+ usage_system: TimeseriesTest.getRandomUsage(),
+ usage_user: TimeseriesTest.getRandomUsage(),
},
tags: {
arch: TimeseriesTest.getRandomElem(["x64", "x86"]),
datacenter: TimeseriesTest.getRandomElem(dataCenters[regionIndex]),
hostname: "host_" + i,
+ hostid: i,
os: TimeseriesTest.getRandomElem(
["Ubuntu15.10", "Ubuntu16.10", "Ubuntu16.04LTS"]),
rack: Random.randInt(100).toString(),
diff --git a/jstests/core/timeseries/timeseries_graph_lookup.js b/jstests/core/timeseries/timeseries_graph_lookup.js
new file mode 100644
index 00000000000..29786acb8fb
--- /dev/null
+++ b/jstests/core/timeseries/timeseries_graph_lookup.js
@@ -0,0 +1,157 @@
+/**
+ * Verifies that time-series bucket collections work as expected with $graphLookup.
+ *
+ *
+ * @tags: [
+ * assumes_unsharded_collection,
+ * assumes_against_mongod_not_mongos,
+ * requires_timeseries,
+ * requires_fcv_49,
+ * sbe_incompatible,
+ * ]
+ */
+(function() {
+"use strict";
+
+load("jstests/core/timeseries/libs/timeseries.js");
+
+if (!TimeseriesTest.timeseriesCollectionsEnabled(db.getMongo())) {
+ jsTestLog("Skipping test because the time-series collection feature flag is disabled");
+ return;
+}
+
+const testDB = db.getSiblingDB(jsTestName());
+assert.commandWorked(testDB.dropDatabase());
+const timeFieldName = "time";
+const hostIdFieldName = "hostid";
+const nonTimeseriesCollOption = null;
+const timeseriesCollOption = {
+ timeseries: {timeField: timeFieldName, metaField: hostIdFieldName}
+};
+const numHosts = 10;
+const numDocs = 200;
+
+Random.setRandomSeed();
+const hosts = TimeseriesTest.generateHosts(numHosts);
+
+let testFunc = function(collAOption, collBOption) {
+ // Prepares two collections. Each collection can be either a time-series or a non time-series
+ // collection, depending on collAOption/collBOption.
+ const collA = testDB.getCollection("a");
+ const collB = testDB.getCollection("b");
+ collA.drop();
+ collB.drop();
+ assert.commandWorked(testDB.createCollection(collA.getName(), collAOption));
+ assert.commandWorked(testDB.createCollection(collB.getName(), collBOption));
+ let entryCountPerHost = new Array(numHosts).fill(0);
+ let entryCountOver80AndExistsIdlePerHost = new Array(numHosts).fill(0);
+
+ // Inserts into collA, one entry per host.
+ for (let i = 0; i < numHosts; i++) {
+ let host = hosts[i];
+ assert.commandWorked(collA.insert({time: ISODate(), hostid: host.tags.hostid}));
+ }
+
+ // Inserts some random documents to collB. The 'idle' measurement is inserted only when usage is
+ // odd.
+ for (let i = 0; i < numDocs; i++) {
+ let host = TimeseriesTest.getRandomElem(hosts);
+ let usage = TimeseriesTest.getRandomUsage();
+ if (usage % 2) {
+ assert.commandWorked(collB.insert(
+ {time: ISODate(), hostid: host.tags.hostid, cpu: usage, idle: 100 - usage}));
+ } else {
+ assert.commandWorked(
+ collB.insert({time: ISODate(), hostid: host.tags.hostid, cpu: usage}));
+ }
+
+ // These counts are to test metaField match.
+ entryCountPerHost[host.tags.hostid]++;
+
+ // These counts are to test measurement fields match which are specified by $graphLookup's
+ // restrictSearchWithMatch.
+ if (usage > 80 && usage % 2) {
+ entryCountOver80AndExistsIdlePerHost[host.tags.hostid]++;
+ }
+ }
+
+ // Verifies that a meta field "hostid" works with $graphLookup.
+ let results = collA.aggregate([
+ {
+ $graphLookup: {
+ from: collB.getName(),
+ startWith: "$hostid",
+ connectFromField: "hostid",
+ connectToField: "hostid",
+ as: "matchedB",
+ maxDepth: 0
+ }
+ }, {
+ $project: {
+ _id: 0,
+ hostid: 1,
+ matchedB: {
+ $size: "$matchedB"
+ }
+ }
+ },
+ {$sort: {hostid: 1}}
+ ]).toArray();
+
+ assert.eq(numHosts, results.length, results);
+
+ for (let i = 0; i < numHosts; i++) {
+ assert.eq({hostid: i, matchedB: entryCountPerHost[i]}, results[i], results);
+ }
+
+ // Verifies that measurement fields "cpu" and "idle" work with $graphLookup as expected.
+ results = collA.aggregate([
+ {
+ $graphLookup: {
+ from: collB.getName(),
+ startWith: "$hostid",
+ connectFromField: "hostid",
+ connectToField: "hostid",
+ as: "matchedB",
+ maxDepth: 0,
+ restrictSearchWithMatch: {
+ cpu: {$gt: 80}, // Tests measurement "cpu".
+ idle: {$exists: true} // Tests the existence of measurement "idle".
+ }
+ }
+ }, {
+ $project: {
+ _id: 0,
+ hostid: 1,
+ matchedB: {
+ $size: "$matchedB"
+ }
+ }
+ },
+ {$sort: {hostid: 1}}
+ ]).toArray();
+
+ assert.eq(numHosts, results.length, results);
+
+ for (let i = 0; i < numHosts; i++) {
+ let expectedCount = entryCountOver80AndExistsIdlePerHost[i];
+ assert.eq(
+ {hostid: i, matchedB: expectedCount}, results[i], entryCountOver80AndExistsIdlePerHost);
+ }
+};
+
+// Tests case #1: collA: non time-series, collB: time-series
+var collAOption = nonTimeseriesCollOption;
+var collBOption = timeseriesCollOption;
+testFunc(collAOption, collBOption);
+
+// Tests case #2: collA: time-series, collB: non time-series
+collAOption = timeseriesCollOption;
+collBOption = nonTimeseriesCollOption;
+testFunc(collAOption, collBOption);
+
+// Tests case #3: collA: time-series, collB: time-series
+collAOption = timeseriesCollOption;
+collBOption = timeseriesCollOption;
+testFunc(collAOption, collBOption);
+})();