summaryrefslogtreecommitdiff
path: root/jstests/core/list_catalog.js
blob: 163e312cef09019cf2758c7558fc261221c82e4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
 * Basic tests for the $listCatalog aggregation stage.
 *
 * @tags: [
 *     # Asserts on number of indexes.
 *     assumes_no_implicit_index_creation,
 *     # Time-series collection inserts are not supported in multi-document transactions.
 *     does_not_support_transactions,
 *     requires_fcv_60,
 *     # $listCatalog result can be large and may be returned in multiple batches.
 *     requires_getmore,
 * ]
 */
(function() {
'use strict';

load('jstests/libs/fixture_helpers.js');

const testDB = db.getSiblingDB(jsTestName());
assert.commandWorked(testDB.dropDatabase());

// Simple collection with one secondary index.
const collSimple = testDB.simple;
assert.commandWorked(collSimple.createIndex({a: 1}));
assert.commandWorked(collSimple.insert({_id: 0, a: 0}));

// Simple view.
const viewSimpleName = 'simple_view';
assert.commandWorked(testDB.createView(viewSimpleName, collSimple.getName(), [{$project: {a: 0}}]));

// Time-series collection.
assert.commandWorked(testDB.createCollection('ts', {timeseries: {timeField: 'tt'}}));
const collTimeseries = testDB.ts;
assert.commandWorked(collTimeseries.insert({_id: 1, tt: ISODate(), x: 123}));

// Collection with clustered index.
assert.commandWorked(
    testDB.createCollection('clustered', {clusteredIndex: {key: {_id: 1}, unique: true}}));
const collClustered = testDB.clustered;
assert.commandWorked(collClustered.insert({_id: 2, y: 'abc'}));

const numIndexes = function(coll, entry, numSecondaryIndexes) {
    let numIndexes = numSecondaryIndexes + 1;
    if (entry.md.options.clusteredIndex) {
        --numIndexes;
    }
    if (FixtureHelpers.isSharded(coll)) {
        ++numIndexes;
    }
    return numIndexes;
};

const checkEntries = function(collName, entries, type, {numSecondaryIndexes, viewOn}) {
    const ns = testDB.getName() + '.' + collName;
    assert(entries.some((entry) => entry.ns === ns));
    for (const entry of entries) {
        if (entry.ns !== ns) {
            continue;
        }

        assert.eq(entry.db, testDB.getName());
        assert.eq(entry.name, collName);
        assert.eq(entry.type, type);
        if (FixtureHelpers.isMongos(testDB)) {
            assert(entry.shard);
        }
        if (type === 'collection') {
            assert.eq(entry.md.indexes.length,
                      numIndexes(testDB[collName], entry, numSecondaryIndexes));
        }
        if (type === 'view' || type === 'timeseries') {
            assert.eq(entry.viewOn, viewOn);
        }
    }
};

let result = collSimple.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collSimple.getFullName() + ' $listCatalog: ' + tojson(result));
checkEntries(collSimple.getName(), result, 'collection', {numSecondaryIndexes: 1});

result = collClustered.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collClustered.getFullName() + ' $listCatalog: ' + tojson(result));
checkEntries(collClustered.getName(), result, 'collection', {numSecondaryIndexes: 0});

assert.commandFailedWithCode(
    testDB.runCommand({aggregate: viewSimpleName, pipeline: [{$listCatalog: {}}], cursor: {}}),
    40602);

assert.commandFailedWithCode(
    testDB.runCommand(
        {aggregate: collTimeseries.getName(), pipeline: [{$listCatalog: {}}], cursor: {}}),
    40602);

assert.commandFailedWithCode(
    testDB.runCommand({aggregate: 1, pipeline: [{$listCatalog: {}}], cursor: {}}),
    ErrorCodes.InvalidNamespace);

const adminDB = testDB.getSiblingDB('admin');
result = adminDB.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog('Collectionless $listCatalog: ' + tojson(result));

checkEntries(collSimple.getName(), result, 'collection', {numSecondaryIndexes: 1});
checkEntries(collClustered.getName(), result, 'collection', {numSecondaryIndexes: 0});
checkEntries(viewSimpleName, result, 'view', {viewOn: collSimple.getName()});
checkEntries(collTimeseries.getName(), result, 'timeseries', {
    viewOn: 'system.buckets.' + collTimeseries.getName()
});
})();