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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/**
* Tests running the delete command on a time-series collection with concurrent modifications to the
* collection.
* @tags: [
* assumes_no_implicit_collection_creation_after_drop,
* does_not_support_stepdowns,
* does_not_support_transactions,
* # $currentOp can't run with a readConcern other than 'local'.
* assumes_read_concern_unchanged,
* # This test only synchronizes deletes on the primary.
* assumes_read_preference_unchanged,
* # Fail points in this test do not exist on mongos.
* assumes_against_mongod_not_mongos,
* uses_parallel_shell,
* ]
*/
(function() {
"use strict";
load("jstests/core/timeseries/libs/timeseries.js");
load("jstests/libs/curop_helpers.js");
load('jstests/libs/parallel_shell_helpers.js');
if (!TimeseriesTest.timeseriesUpdatesAndDeletesEnabled(db.getMongo())) {
jsTestLog("Skipping test because the time-series updates and deletes feature flag is disabled");
return;
}
const timeFieldName = "time";
const metaFieldName = "tag";
const collName = 't';
const dbName = jsTestName();
const testCases = {
DROP_COLLECTION: 0,
REPLACE_COLLECTION: 1,
REPLACE_METAFIELD: 2
};
const validateDeleteIndex =
(docsToInsert, deleteQuery, expectedErrorCode, testCase, newMetaField = null) => {
const testDB = db.getSiblingDB(dbName);
const awaitTestDelete = startParallelShell(funWithArgs(
function(docsToInsert,
deleteQuery,
timeFieldName,
metaFieldName,
collName,
expectedErrorCode,
dbName) {
const testDB = db.getSiblingDB(dbName);
const coll = testDB.getCollection(collName);
assert.commandWorked(testDB.createCollection(
coll.getName(),
{timeseries: {timeField: timeFieldName, metaField: metaFieldName}}));
assert.commandWorked(coll.insert(docsToInsert));
assert.commandWorked(testDB.adminCommand(
{configureFailPoint: "hangDuringBatchRemove", mode: "alwaysOn"}));
assert.commandFailedWithCode(
testDB.runCommand({delete: coll.getName(), deletes: deleteQuery}),
expectedErrorCode);
coll.drop();
},
docsToInsert,
deleteQuery,
timeFieldName,
metaFieldName,
collName,
expectedErrorCode,
dbName));
const coll = testDB.getCollection(collName);
const childOp =
waitForCurOpByFailPoint(testDB, coll.getFullName(), "hangDuringBatchRemove")[0];
// Drop the collection in all test cases.
assert(coll.drop());
switch (testCase) {
case testCases.REPLACE_COLLECTION:
assert.commandWorked(testDB.createCollection(coll.getName()));
break;
case testCases.REPLACE_METAFIELD:
assert.commandWorked(testDB.createCollection(
coll.getName(),
{timeseries: {timeField: timeFieldName, metaField: newMetaField}}));
break;
}
assert.commandWorked(
testDB.adminCommand({configureFailPoint: "hangDuringBatchRemove", mode: "off"}));
// Wait for testDelete to finish.
awaitTestDelete();
};
const objA = {
[timeFieldName]: ISODate(),
"measurement": {"A": "cpu"},
[metaFieldName]: {a: "A"}
};
// Attempt to delete from a collection that has been dropped.
validateDeleteIndex([objA],
[{q: {[metaFieldName]: {a: "A"}}, limit: 0}],
ErrorCodes.NamespaceNotFound,
testCases.DROP_COLLECTION);
// Attempt to delete from a collection that has been replaced with a non-time-series collection.
validateDeleteIndex([objA],
[{q: {[metaFieldName]: {a: "A"}}, limit: 0}],
ErrorCodes.NamespaceNotFound,
testCases.REPLACE_COLLECTION);
// Attempt to delete from a collection that has been replaced with a new time-series collection with
// a different metaField.
validateDeleteIndex([objA],
[{q: {[metaFieldName]: {a: "A"}}, limit: 0}],
ErrorCodes.InvalidOptions,
testCases.REPLACE_METAFIELD,
"meta");
})();
|