diff options
Diffstat (limited to 'jstests/core/timeseries')
-rw-r--r-- | jstests/core/timeseries/libs/timeseries.js | 29 | ||||
-rw-r--r-- | jstests/core/timeseries/timeseries_graph_lookup.js | 157 |
2 files changed, 172 insertions, 14 deletions
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); +})(); |