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
|
//
// This test ensures that the hello command and its aliases, ismaster and isMaster,
// are all accepted.
//
// @tags: [
// # Assert on the isWritablePrimary field of a hello response. If a primary steps down after
// # accepting a hello command and returns before its connection is closed, the response can
// # contain isWritablePrimary: false.
// does_not_support_stepdowns,
// ]
(function() {
"use strict";
function checkResponseFields(command, commandType) {
var res = db.runCommand(command);
// check that the fields that should be there are there and have proper values
assert(res.maxBsonObjectSize && isNumber(res.maxBsonObjectSize) && res.maxBsonObjectSize > 0,
"maxBsonObjectSize possibly missing:" + tojson(res));
assert(
res.maxMessageSizeBytes && isNumber(res.maxMessageSizeBytes) && res.maxBsonObjectSize > 0,
"maxMessageSizeBytes possibly missing:" + tojson(res));
assert(res.maxWriteBatchSize && isNumber(res.maxWriteBatchSize) && res.maxWriteBatchSize > 0,
"maxWriteBatchSize possibly missing:" + tojson(res));
if (commandType === "hello") {
assert.eq("boolean",
typeof res.isWritablePrimary,
"isWritablePrimary field is not a boolean" + tojson(res));
assert(res.isWritablePrimary === true, "isWritablePrimary field is false" + tojson(res));
} else {
assert.eq("boolean", typeof res.ismaster, "ismaster field is not a boolean" + tojson(res));
assert(res.ismaster === true, "ismaster field is false" + tojson(res));
}
assert(res.localTime, "localTime possibly missing:" + tojson(res));
assert(res.connectionId, "connectionId missing or false" + tojson(res));
if (!testingReplication) {
var badFields = [];
var unwantedReplSetFields = [
"setName",
"setVersion",
"secondary",
"hosts",
"passives",
"arbiters",
"primary",
"arbiterOnly",
"passive",
"slaveDelay",
"secondaryDelaySecs",
"hidden",
"tags",
"buildIndexes",
"me"
];
var field;
// check that the fields that shouldn't be there are not there
for (field in res) {
if (!res.hasOwnProperty(field)) {
continue;
}
if (Array.contains(unwantedReplSetFields, field)) {
badFields.push(field);
}
}
assert(
badFields.length === 0,
"\nthe result:\n" + tojson(res) + "\ncontained fields it shouldn't have: " + badFields);
}
}
checkResponseFields("hello", "hello");
checkResponseFields("ismaster", "ismaster");
checkResponseFields("isMaster", "isMaster");
checkResponseFields({hello: 1, unknownField: 1}, "hello");
checkResponseFields({ismaster: 1, unknownField: 1}, "ismaster");
checkResponseFields({isMaster: 1, unknownField: 1}, "isMaster");
// As operations happen concurrently, the response objects may have different timestamps. To compare
// response objects returned from calling commands directly and shell helpers below, we must remove
// the timestamps.
function removeTimestamps(cmdResponse) {
delete cmdResponse.localTime;
delete cmdResponse.operationTime;
delete cmdResponse.$clusterTime;
if (cmdResponse.lastWrite) {
delete cmdResponse.lastWrite.opTime;
delete cmdResponse.lastWrite.majorityOpTime;
}
}
// We also test the db.hello() and db.isMaster() helpers to ensure that they return
// the same response objects as from running the commands directly.
let cmdResponse1 = removeTimestamps(db.runCommand("hello"));
let cmdResponse2 = removeTimestamps(db.hello());
assert.eq(cmdResponse1, cmdResponse2);
cmdResponse1 = removeTimestamps(db.runCommand("isMaster"));
cmdResponse2 = removeTimestamps(db.isMaster());
assert.eq(cmdResponse1, cmdResponse2);
})();
|