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
|
"use strict";
/**
* Repeatedly creates a collection and a view with the same namespace. Validates that we never
* manage to have both a Collection and View created on the same namespace at the same time.
*
* @tags: [catches_command_failures]
*/
var $config = (function() {
const prefix = "create_collection_and_view";
// We'll use a single unique collection for all operations executed by this test. The
// convention is that each FSM workload is given a unique 'collName' as input to increase
// separation between different tests running in parallel. Otherwise we could just use a fixed
// name, but we want to play nice.
const getCollectionName = (collName) => {
return prefix + "_" + collName;
};
const getBaseCollectionName = (collName) => {
return prefix + "_" + collName + "_base";
};
const setup = (db, collName) => {
assertAlways.commandWorked(db.createCollection(getBaseCollectionName(collName)));
};
const teardown = (db, collName) => {
db.getCollection(getCollectionName(collName)).drop();
db.getCollection(getBaseCollectionName(collName)).drop();
};
const states = {
init: (db, collName) => {},
createView: (db, collName) => {
// In a sharded collection, we may sometimes get a NamespaceNotFound error, as we
// attempt to to do some additional validation on the creation options after we get back
// the NamespaceExists error, and the namespace may have been dropped in the meantime.
assertAlways.commandWorkedOrFailedWithCode(
db.createCollection(
getCollectionName(collName),
{viewOn: getBaseCollectionName(collName), pipeline: [{$match: {}}]}),
[ErrorCodes.NamespaceExists, ErrorCodes.NamespaceNotFound]);
},
createCollection: (db, collName) => {
// In a sharded collection, we may sometimes get a NamespaceNotFound error. See above.
assertAlways.commandWorkedOrFailedWithCode(
db.createCollection(getCollectionName(collName)),
[ErrorCodes.NamespaceExists, ErrorCodes.NamespaceNotFound]);
},
verifyNoDuplicates: (db, collName) => {
// Check how many collections/views match our namespace.
const res =
db.runCommand("listCollections", {filter: {name: getCollectionName(collName)}});
assertAlways.commandWorked(res);
// We expect that we only ever find 0 or 1. If we find 2 or more, then we managed to
// create a view and collection on the same namespace simultaneously, which is a bug.
assertAlways.lte(res.cursor.firstBatch.length, 1);
},
dropNamespace: (db, collName) => {
db.getCollection(getCollectionName(collName)).drop();
},
};
const transitions = {
init: {createCollection: 0.5, createView: 0.5},
// Always verify after creation because there's no point in creating an invalid situation
// (view and collection simultaneously on the same namespace) if we don't observe it.
createCollection: {verifyNoDuplicates: 1.0},
createView: {verifyNoDuplicates: 1.0},
verifyNoDuplicates: {dropNamespace: 1.0},
dropNamespace: {createCollection: 0.5, createView: 0.5}
};
return {
threadCount: 10,
iterations: 200,
setup,
states,
teardown,
transitions,
};
})();
|