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
|
// Tests the parsing of the timeZoneInfo parameter and file use.
(function() {
// Test that a bad file causes startup to fail.
assert.throws(
() => MongoRunner.runMongod({timeZoneInfo: "jstests/libs/config_files/bad_timezone_info"}),
[],
"expected launching mongod with bad timezone rules to fail");
assert.neq(-1, rawMongoProgramOutput().search(/Fatal assertion.*40475/));
// Test that a non-existent directory causes startup to fail.
assert.throws(
() => MongoRunner.runMongod({timeZoneInfo: "jstests/libs/config_files/missing_directory"}),
[],
"expected launching mongod with bad timezone rules to fail");
// Look for either old or new error message
assert(rawMongoProgramOutput().includes("Error creating service context") ||
rawMongoProgramOutput().includes("Failed to create service context"));
function testWithGoodTimeZoneDir(tz_good_path) {
let conn = MongoRunner.runMongod({timeZoneInfo: tz_good_path});
assert.neq(conn, null, "expected launching mongod with good timezone rules to succeed");
// Test that can use file-provided timezones in an expression.
const testDB = conn.getDB("test");
const coll = testDB.parse_zone_info;
assert.commandWorked(coll.insert({x: new Date()}));
assert.doesNotThrow(
() => coll.aggregate([{$set: {x_parts: {$dateToParts: {date: "$x", timezone: "GMT"}}}}]));
assert.doesNotThrow(
() => coll.aggregate(
[{$set: {x_parts: {$dateToParts: {date: "$x", timezone: "America/Sao_Paulo"}}}}]));
// Confirm that attempt to use a non-existent timezone in an expression fails.
const err =
assert.throws(() => coll.aggregate(
[{$set: {x_parts: {$dateToParts: {date: "$x", timezone: "Unknown"}}}}]));
assert.eq(err.code, 40485);
// Test some dates which specifically exercise slim-format timezone files. The test-case below
// produced incorrect output using `$dateToParts` on `timelib-2018.01` with slim timezone format
// and the "America/New York" timezone, since timelib was unable to correctly extrapolate DST
// changes from the slim-format files. This was fixed in the timelib 2021 series.
const corner_coll = testDB.parse_zone_info_corner_cases;
let test_dates = [
{
test_date: "2020-10-20T19:49:47.634Z",
test_date_parts: {
"year": 2020,
"month": 10,
"day": 20,
"hour": 15,
"minute": 49,
"second": 47,
"millisecond": 634
}
},
{
test_date: "2020-12-14T12:00:00Z",
test_date_parts: {
"year": 2020,
"month": 12,
"day": 14,
"hour": 7,
"minute": 0,
"second": 0,
"millisecond": 0
}
}
];
for (let i = 0; i < test_dates.length; ++i) {
assert.commandWorked(corner_coll.insert({_id: i, x: new ISODate(test_dates[i].test_date)}));
}
let res = corner_coll
.aggregate([
{$set: {x_parts: {$dateToParts: {date: "$x", timezone: "America/New_York"}}}},
{$sort: {_id: 1}}
])
.toArray();
for (let i = 0; i < test_dates.length; ++i) {
assert.eq(res[i].x_parts, test_dates[i].test_date_parts);
}
MongoRunner.stopMongod(conn);
}
// Test that startup can succeed with a good file.
testWithGoodTimeZoneDir("jstests/libs/config_files/good_timezone_info_fat");
testWithGoodTimeZoneDir("jstests/libs/config_files/good_timezone_info_slim");
}());
|