1
2 /**
3 * Copyright (C) 2018-present MongoDB, Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the Server Side Public License, version 1,
7 * as published by MongoDB, Inc.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * Server Side Public License for more details.
13 *
14 * You should have received a copy of the Server Side Public License
15 * along with this program. If not, see
16 * <http://www.mongodb.com/licensing/server-side-public-license>.
17 *
18 * As a special exception, the copyright holders give permission to link the
19 * code of portions of this program with the OpenSSL library under certain
20 * conditions as described in each individual source file and distribute
21 * linked combinations including the program with the OpenSSL library. You
22 * must comply with the Server Side Public License in all respects for
23 * all of the code used other than as permitted herein. If you modify file(s)
24 * with this exception, you may extend this exception to your version of the
25 * file(s), but you are not obligated to do so. If you do not wish to do so,
26 * delete this exception statement from your version. If you delete this
27 * exception statement from all source files in the program, then also delete
28 * it in the license file.
29 */
30
31 /**
32 * Unit tests of the Initializer type.
33 */
34
35 #include "mongo/base/init.h"
36 #include "mongo/base/initializer.h"
37 #include "mongo/base/initializer_dependency_graph.h"
38 #include "mongo/base/make_string_vector.h"
39 #include "mongo/unittest/unittest.h"
40
41 /*
42 * Unless otherwise specified, all tests herein use the following
43 * dependency graph.
44 *
45 * 0 <- 3 <- 7
46 * ^ / ^ ^
47 * \ v \ \
48 * 2 5 <- 8
49 * / ^ / /
50 * v \ v v
51 * 1 <- 4 <- 6
52 *
53 */
54
55 #define ADD_INITIALIZER(GRAPH, NAME, FN, PREREQS, DEPS) \
56 (GRAPH).addInitializer( \
57 (NAME), (FN), MONGO_MAKE_STRING_VECTOR PREREQS, MONGO_MAKE_STRING_VECTOR DEPS)
58
59 #define ASSERT_ADD_INITIALIZER(GRAPH, NAME, FN, PREREQS, DEPS) \
60 ASSERT_EQUALS(Status::OK(), ADD_INITIALIZER(GRAPH, NAME, FN, PREREQS, DEPS))
61
62
63 #define CONSTRUCT_DEPENDENCY_GRAPH(GRAPH, FN0, FN1, FN2, FN3, FN4, FN5, FN6, FN7, FN8) \
64 do { \
65 InitializerDependencyGraph& _graph_ = (GRAPH); \
66 ASSERT_ADD_INITIALIZER(_graph_, "n0", FN0, MONGO_NO_PREREQUISITES, MONGO_NO_DEPENDENTS); \
67 ASSERT_ADD_INITIALIZER(_graph_, "n1", FN1, MONGO_NO_PREREQUISITES, MONGO_NO_DEPENDENTS); \
68 ASSERT_ADD_INITIALIZER(_graph_, "n2", FN2, ("n0", "n1"), MONGO_NO_DEPENDENTS); \
69 ASSERT_ADD_INITIALIZER(_graph_, "n3", FN3, ("n0", "n2"), MONGO_NO_DEPENDENTS); \
70 ASSERT_ADD_INITIALIZER(_graph_, "n4", FN4, ("n2", "n1"), MONGO_NO_DEPENDENTS); \
71 ASSERT_ADD_INITIALIZER(_graph_, "n5", FN5, ("n3", "n4"), MONGO_NO_DEPENDENTS); \
72 ASSERT_ADD_INITIALIZER(_graph_, "n6", FN6, ("n4"), MONGO_NO_DEPENDENTS); \
73 ASSERT_ADD_INITIALIZER(_graph_, "n7", FN7, ("n3"), MONGO_NO_DEPENDENTS); \
74 ASSERT_ADD_INITIALIZER(_graph_, "n8", FN8, ("n5", "n6", "n7"), MONGO_NO_DEPENDENTS); \
75 } while (false)
76
77 namespace mongo {
78 namespace {
79
80 int globalCounts[9];
81
doNothing(InitializerContext *)82 Status doNothing(InitializerContext*) {
83 return Status::OK();
84 }
85
set0(InitializerContext *)86 Status set0(InitializerContext*) {
87 globalCounts[0] = 1;
88 return Status::OK();
89 }
90
set1(InitializerContext *)91 Status set1(InitializerContext*) {
92 globalCounts[1] = 1;
93 return Status::OK();
94 }
95
set2(InitializerContext *)96 Status set2(InitializerContext*) {
97 if (!globalCounts[0] || !globalCounts[1])
98 return Status(ErrorCodes::UnknownError, "one of 0 or 1 not already set");
99 globalCounts[2] = 1;
100 return Status::OK();
101 }
102
set3(InitializerContext *)103 Status set3(InitializerContext*) {
104 if (!globalCounts[0] || !globalCounts[2])
105 return Status(ErrorCodes::UnknownError, "one of 0 or 2 not already set");
106 globalCounts[3] = 1;
107 return Status::OK();
108 }
109
set4(InitializerContext *)110 Status set4(InitializerContext*) {
111 if (!globalCounts[1] || !globalCounts[2])
112 return Status(ErrorCodes::UnknownError, "one of 1 or 2 not already set");
113 globalCounts[4] = 1;
114 return Status::OK();
115 }
116
set5(InitializerContext *)117 Status set5(InitializerContext*) {
118 if (!globalCounts[3] || !globalCounts[4])
119 return Status(ErrorCodes::UnknownError, "one of 3 or 4 not already set");
120 globalCounts[5] = 1;
121 return Status::OK();
122 }
123
set6(InitializerContext *)124 Status set6(InitializerContext*) {
125 if (!globalCounts[4])
126 return Status(ErrorCodes::UnknownError, "4 not already set");
127 globalCounts[6] = 1;
128 return Status::OK();
129 }
130
set7(InitializerContext *)131 Status set7(InitializerContext*) {
132 if (!globalCounts[3])
133 return Status(ErrorCodes::UnknownError, "3 not already set");
134 globalCounts[7] = 1;
135 return Status::OK();
136 }
137
set8(InitializerContext *)138 Status set8(InitializerContext*) {
139 if (!globalCounts[5] || !globalCounts[6] || !globalCounts[7])
140 return Status(ErrorCodes::UnknownError, "one of 5, 6, 7 not already set");
141 globalCounts[8] = 1;
142 return Status::OK();
143 }
144
clearCounts()145 void clearCounts() {
146 for (size_t i = 0; i < 9; ++i)
147 globalCounts[i] = 0;
148 }
149
TEST(InitializerTest,SuccessfulInitialization)150 TEST(InitializerTest, SuccessfulInitialization) {
151 Initializer initializer;
152 CONSTRUCT_DEPENDENCY_GRAPH(initializer.getInitializerDependencyGraph(),
153 set0,
154 set1,
155 set2,
156 set3,
157 set4,
158 set5,
159 set6,
160 set7,
161 set8);
162 clearCounts();
163 ASSERT_OK(initializer.execute(InitializerContext::ArgumentVector(),
164 InitializerContext::EnvironmentMap()));
165 for (int i = 0; i < 9; ++i)
166 ASSERT_EQUALS(1, globalCounts[i]);
167 }
168
TEST(InitializerTest,Step5Misimplemented)169 TEST(InitializerTest, Step5Misimplemented) {
170 Initializer initializer;
171 CONSTRUCT_DEPENDENCY_GRAPH(initializer.getInitializerDependencyGraph(),
172 set0,
173 set1,
174 set2,
175 set3,
176 set4,
177 doNothing,
178 set6,
179 set7,
180 set8);
181 clearCounts();
182 ASSERT_EQUALS(ErrorCodes::UnknownError,
183 initializer.execute(InitializerContext::ArgumentVector(),
184 InitializerContext::EnvironmentMap()));
185 ASSERT_EQUALS(1, globalCounts[0]);
186 ASSERT_EQUALS(1, globalCounts[1]);
187 ASSERT_EQUALS(1, globalCounts[2]);
188 ASSERT_EQUALS(1, globalCounts[3]);
189 ASSERT_EQUALS(1, globalCounts[4]);
190 ASSERT_EQUALS(0, globalCounts[8]);
191 }
192
193 } // namespace
194 } // namespace mongo
195