1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "test-registry.h"
6
7 #include <fbl/function.h>
8 #include <zircon/assert.h>
9 #include <zxtest/base/observer.h>
10 #include <zxtest/base/test-case.h>
11 #include <zxtest/base/test-driver.h>
12 #include <zxtest/base/test.h>
13
14 namespace zxtest {
15 using internal::TestDriver;
16 namespace test {
17 namespace {
18
19 constexpr char kTestCaseName[] = "TestCase";
20
Stub()21 void Stub() {}
22
23 class FakeTest : public zxtest::Test {
24 public:
25 fbl::Function<void()> body = &Stub;
26
27 private:
TestBody()28 void TestBody() final { body(); }
29 };
30
31 // Lifecycle observer that verifies that callbacks are executed correctly within
32 // zxtest::TestCase.
33 class FakeLifecycleObserver : public LifecycleObserver {
34 public:
~FakeLifecycleObserver()35 ~FakeLifecycleObserver() final {}
36
37 // Reports before every TestCase is set up.
OnTestCaseStart(const TestCase & test_case)38 void OnTestCaseStart(const TestCase& test_case) final {
39 ZX_ASSERT_MSG(
40 test_case_++ == 0 && test_ == 0,
41 "LifecycleObserver::TestCaseStart was not called before any test execution.\n");
42 }
43
44 // Reports before every test starts.
OnTestStart(const TestCase & test_case,const TestInfo & test)45 void OnTestStart(const TestCase& test_case, const TestInfo& test) final {
46 ZX_ASSERT_MSG(test_++ == 0, "LifecycleObserver::TestStart was not called second.\n");
47 }
48
49 // Reports before every test starts.
OnTestSkip(const TestCase & test_case,const TestInfo & test)50 void OnTestSkip(const TestCase& test_case, const TestInfo& test) final {
51 ZX_ASSERT_MSG(test_ == 1, "LifecycleObserver::TestSkip was not called third.\n");
52 test_ = 0;
53 }
54
55 // Reports before every TestCase is set up.
OnTestFailure(const TestCase & test_case,const TestInfo & test)56 void OnTestFailure(const TestCase& test_case, const TestInfo& test) final {
57 ZX_ASSERT_MSG(test_ == 1, "LifecycleObserver::TestFailure was not called third.\n");
58 test_ = 0;
59 }
60
61 // Reports before every TestCase is set up.
OnTestSuccess(const TestCase & test_case,const TestInfo & test)62 void OnTestSuccess(const TestCase& test_case, const TestInfo& test) final {
63 ZX_ASSERT_MSG(test_ == 1, "LifecycleObserver::TestSuccess was not called third.\n");
64 test_ = 0;
65 }
66
67 // Reports before every TestCase is torn down.
OnTestCaseEnd(const TestCase & test_case)68 void OnTestCaseEnd(const TestCase& test_case) final {
69 ZX_ASSERT_MSG(test_case_ == 1 && test_ == 0,
70 "LifecycleObserver::TestCaseEnd was not called after all tests.\n");
71 test_case_ = 0;
72 }
73
74 private:
75 size_t test_case_ = 0;
76 size_t test_ = 0;
77 };
78
79 } // namespace
80
TestCaseDefault()81 void TestCaseDefault() {
82 TestCase test_case(kTestCaseName, &Stub, &Stub);
83
84 ZX_ASSERT_MSG(test_case.name() == kTestCaseName, "TestCase name do no match.");
85 ZX_ASSERT_MSG(test_case.TestCount() == 0, "TestCase is not initialized with 0 tests.");
86 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 0,
87 "TestCase is not initialized with 0 matching tests.");
88 }
89
TestCaseRegisterTest()90 void TestCaseRegisterTest() {
91 TestCase test_case(kTestCaseName, &Stub, &Stub);
92 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
93 const fbl::String kTestName = "TestName";
94
95 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation, &Test::Create<FakeTest>),
96 "TestCase failed to register a test.");
97
98 ZX_ASSERT_MSG(test_case.TestCount() == 1, "TestCase matching count does not match.");
99 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 1, "TestCase .");
100 }
101
TestCaseRun()102 void TestCaseRun() {
103 TestDriverStub driver;
104 int order = 0;
105 int set_up;
106 int tear_down;
107 int test;
108 TestCase test_case(
109 kTestCaseName, [&order, &set_up]() { set_up = order++; },
110 [&order, &tear_down]() { tear_down = order++; });
111 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
112 const fbl::String kTestName = "TestName";
113
114 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation,
115 [&order, &test](TestDriver* driver) {
116 auto test_ptr = Test::Create<FakeTest>(driver);
117 test_ptr->body = [&order, &test]() { test = order++; };
118 return test_ptr;
119 }),
120 "TestCase failed to register a test.");
121 FakeLifecycleObserver observer;
122 test_case.Run(&observer, &driver);
123
124 ZX_ASSERT_MSG(set_up < test, "Test executed before Test::SetUpTestCase\n");
125 ZX_ASSERT_MSG(test < tear_down, "Test::TearDownTestCase executed before Test/\n ");
126 }
127
TestCaseRegisterDuplicatedTestFails()128 void TestCaseRegisterDuplicatedTestFails() {
129 TestCase test_case(kTestCaseName, &Stub, &Stub);
130 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
131 const fbl::String kTestName = "TestName";
132
133 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation, &Test::Create<FakeTest>),
134 "TestCase failed to register a test.");
135 // Registering a test with the same name, will fail.
136 ZX_ASSERT_MSG(!test_case.RegisterTest(kTestName, kLocation, &Test::Create<FakeTest>),
137 "TestCase failed to detect duplicated test.");
138
139 ZX_ASSERT_MSG(test_case.TestCount() == 1, "TestCase::TestCount does not match expected value.");
140 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 1,
141 "TestCase::MatchingTestCount does not match expected value.");
142 }
143
TestCaseFilter()144 void TestCaseFilter() {
145 TestCase test_case(kTestCaseName, &Stub, &Stub);
146 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
147 const fbl::String kTestName = "TestName";
148
149 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation, &Test::Create<FakeTest>),
150 "TestCase failed to register a test.");
151
152 ZX_ASSERT_MSG(test_case.RegisterTest("TestName2", kLocation, &Test::Create<FakeTest>),
153 "TestCase failed to register second test.");
154
155 test_case.Filter([&kTestName](const fbl::String& test_case, const fbl::String& test) {
156 return test == kTestName;
157 });
158
159 ZX_ASSERT_MSG(test_case.TestCount() == 2, "TestCase::TestCount does not match expected value.");
160 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 1,
161 "TestCase::MatchingTestCount does not match expected value.");
162 }
163
TestCaseFilterNoMatches()164 void TestCaseFilterNoMatches() {
165 TestCase test_case(kTestCaseName, &Stub, &Stub);
166 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
167 const fbl::String kTestName = "TestName";
168
169 ZX_ASSERT_MSG(
170 test_case.RegisterTest(kTestName, kLocation,
171 [](TestDriver* driver) { return std::make_unique<FakeTest>(); }),
172 "TestCase failed to register a test.");
173
174 test_case.Filter([](const fbl::String& test_case, const fbl::String& test) { return false; });
175
176 ZX_ASSERT_MSG(test_case.TestCount() == 1, "TestCase::TestCount does not match expected value.");
177 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 0,
178 "TestCase::MatchingTestCount does not match expected value.");
179 }
180
TestCaseFilterAllMatching()181 void TestCaseFilterAllMatching() {
182 TestCase test_case(kTestCaseName, &Stub, &Stub);
183 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
184 const fbl::String kTestName = "TestName";
185
186 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation, &Test::Create<FakeTest>),
187 "TestCase failed to register a test.");
188
189 ZX_ASSERT_MSG(test_case.RegisterTest("TestName2", kLocation, &Test::Create<FakeTest>),
190 "TestCase failed to register a test.");
191
192 test_case.Filter([](const fbl::String& test_case, const fbl::String& test) { return true; });
193
194 ZX_ASSERT_MSG(test_case.TestCount() == 2, "TestCase::TestCount does not match expected value.");
195 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 2,
196 "TestCase::MatchingTestCount does not match expected value.");
197 }
198
TestCaseFilterNullMatchesAll()199 void TestCaseFilterNullMatchesAll() {
200 TestCase test_case(kTestCaseName, &Stub, &Stub);
201 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
202 const fbl::String kTestName = "TestName";
203
204 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation, &Test::Create<FakeTest>),
205 "TestCase failed to register a test.");
206
207 ZX_ASSERT_MSG(test_case.RegisterTest("TestName2", kLocation, &Test::Create<FakeTest>),
208 "TestCase failed to register a test.");
209
210 test_case.Filter(nullptr);
211
212 ZX_ASSERT_MSG(test_case.TestCount() == 2, "TestCase::TestCount does not match expected value.");
213 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 2,
214 "TestCase::MatchingTestCount does not match expected value.");
215 }
216
TestCaseFilterDoNotAccumulate()217 void TestCaseFilterDoNotAccumulate() {
218 TestCase test_case(kTestCaseName, &Stub, &Stub);
219 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
220 const fbl::String kTestName = "TestName";
221
222 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation, &Test::Create<FakeTest>),
223 "TestCase failed to register a test.");
224
225 test_case.Filter([](const fbl::String& test_case, const fbl::String& test) { return false; });
226 test_case.Filter([](const fbl::String& test_case, const fbl::String& test) { return true; });
227
228 ZX_ASSERT_MSG(test_case.TestCount() == 1, "TestCase::TestCount does not match expected value.");
229 ZX_ASSERT_MSG(test_case.MatchingTestCount() == 1,
230 "TestCase::MatchingTestCount does not match expected value.");
231 }
232
TestCaseShuffle()233 void TestCaseShuffle() {
234 TestDriverStub driver;
235 TestCase test_case(kTestCaseName, &Stub, &Stub);
236 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
237 const fbl::String kTestName = "TestName";
238 fbl::Vector<int> run_order;
239
240 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation,
241 [&run_order](TestDriver* driver) {
242 auto test = Test::Create<FakeTest>(driver);
243 test->body = [&run_order]() {
244 run_order.push_back(1);
245 };
246 return test;
247 }),
248 "TestCase failed to register a test.");
249
250 ZX_ASSERT_MSG(test_case.RegisterTest("TestName2", kLocation,
251 [&run_order](TestDriver* driver) {
252 auto test = Test::Create<FakeTest>(driver);
253 test->body = [&run_order]() {
254 run_order.push_back(2);
255 };
256 return test;
257 }),
258 "TestCase failed to register a test.");
259
260 ZX_ASSERT_MSG(test_case.RegisterTest("TestName3", kLocation,
261 [&run_order](TestDriver* driver) {
262 auto test = Test::Create<FakeTest>(driver);
263 test->body = [&run_order]() {
264 run_order.push_back(3);
265 };
266 return test;
267 }),
268 "TestCase failed to register a test.");
269
270 // With seed = 0 and 3 tests, using musl implementation of random , we get 2 3 1 run order.
271 LifecycleObserver observer;
272 test_case.Shuffle(0);
273 test_case.Run(&observer, &driver);
274
275 ZX_ASSERT_MSG(run_order[0] == 2, "Shuffle failed.");
276 ZX_ASSERT_MSG(run_order[1] == 3, "Shuffle failed.");
277 ZX_ASSERT_MSG(run_order[2] == 1, "Shuffle failed.");
278 }
279
TestCaseUnShuffle()280 void TestCaseUnShuffle() {
281 TestDriverStub driver;
282 TestCase test_case(kTestCaseName, &Stub, &Stub);
283 const SourceLocation kLocation = {.filename = "test.cpp", .line_number = 1};
284 const fbl::String kTestName = "TestName";
285 fbl::Vector<int> run_order;
286
287 ZX_ASSERT_MSG(test_case.RegisterTest(kTestName, kLocation,
288 [&run_order](TestDriver* driver) {
289 auto test = Test::Create<FakeTest>(driver);
290 test->body = [&run_order]() {
291 run_order.push_back(1);
292 };
293 return test;
294 }),
295 "TestCase failed to register a test.");
296
297 ZX_ASSERT_MSG(test_case.RegisterTest("TestName2", kLocation,
298 [&run_order](TestDriver* driver) {
299 auto test = Test::Create<FakeTest>(driver);
300 test->body = [&run_order]() {
301 run_order.push_back(2);
302 };
303 return test;
304 }),
305 "TestCase failed to register a test.");
306
307 ZX_ASSERT_MSG(test_case.RegisterTest("TestName3", kLocation,
308 [&run_order](TestDriver* driver) {
309 auto test = Test::Create<FakeTest>(driver);
310 test->body = [&run_order]() {
311 run_order.push_back(3);
312 };
313 return test;
314 }),
315 "TestCase failed to register a test.");
316
317 LifecycleObserver observer;
318 test_case.Shuffle(0);
319 test_case.UnShuffle();
320 test_case.Run(&observer, &driver);
321
322 ZX_ASSERT_MSG(run_order[0] == 1, "UnShuffle failed.");
323 ZX_ASSERT_MSG(run_order[1] == 2, "UnShuffle failed.");
324 ZX_ASSERT_MSG(run_order[2] == 3, "UNShuffle failed.");
325 }
326
327 } // namespace test
328 } // namespace zxtest
329