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