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 <cstdlib>
6
7 #include "test-registry.h"
8
9 #include <fbl/function.h>
10 #include <zxtest/base/event-broadcaster.h>
11 #include <zxtest/base/observer.h>
12 #include <zxtest/base/test-case.h>
13 #include <zxtest/base/test-info.h>
14 #include <zxtest/base/types.h>
15
16 // Defines a FakeObserver class which tracks call to OnTestCaseEvent methods.
17 #define TESTCASE_EVENT_OBSERVER(Event) \
18 class FakeObserver : public LifecycleObserver { \
19 public: \
20 void OnTestCase##Event(const TestCase& test_case) final { \
21 on_notify(test_case); \
22 called = true; \
23 } \
24 \
25 fbl::Function<void(const TestCase& test_case)> on_notify; \
26 bool called = false; \
27 }
28
29 // Defines a FakeObserver class which tracks call to OnTestEvent methods.
30 #define TEST_EVENT_OBSERVER(Event) \
31 class FakeObserver : public LifecycleObserver { \
32 public: \
33 void OnTest##Event(const TestCase& test_case, const TestInfo& info) final { \
34 on_notify(test_case, info); \
35 called = true; \
36 } \
37 \
38 fbl::Function<void(const TestCase& test_case, const TestInfo& info)> on_notify; \
39 bool called = false; \
40 }
41
42 // Fills ObserverList with |kNumObservers| instances of |FakeObserver|, which should be defined
43 // for the scope. And sets on_notify of each observer to on_notify_def and registers them
44 // with |event_broadcaster|.
45 #define REGISTER_OBSERVERS(observer_list, event_broadcaster, on_notify_def) \
46 for (int i = 0; i < kNumObservers; ++i) { \
47 observer_list.push_back({}); \
48 auto& observer = observer_list[observer_list.size() - 1]; \
49 observer.on_notify = on_notify_def; \
50 event_broadcaster.Subscribe(&observer); \
51 }
52
53 namespace zxtest {
54 namespace test {
55 namespace {
56
57 constexpr char kTestCaseName[] = "TestCase";
58 constexpr char kTestName[] = "Test";
59
60 constexpr int kNumObservers = 100;
61
62 const SourceLocation kLocation = {.filename = "filename", .line_number = 20};
63
Stub()64 void Stub() {}
65
66 template <typename T>
ValidateAllObserversNotified(const T & observers)67 void ValidateAllObserversNotified(const T& observers) {
68 for (auto& observer : observers) {
69 ZX_ASSERT_MSG(observer.called, "EventBroadcaster failed to propagate event.\n");
70 }
71 }
72
73 } // namespace
74
EventBroadcasterOnTestCaseStart()75 void EventBroadcasterOnTestCaseStart() {
76 TESTCASE_EVENT_OBSERVER(Start);
77
78 TestCase test_case(kTestCaseName, &Stub, &Stub);
79 internal::EventBroadcaster event_broadcaster;
80 fbl::Vector<FakeObserver> observers;
81 observers.reserve(kNumObservers);
82
83 REGISTER_OBSERVERS(observers, event_broadcaster, [&test_case](const TestCase& actual) {
84 ZX_ASSERT_MSG(&actual == &test_case,
85 "EventBroadcaster::OnTestCaseStart propagated the wrong test case\n");
86 });
87
88 event_broadcaster.OnTestCaseStart(test_case);
89
90 ValidateAllObserversNotified(observers);
91 }
92
EventBroadcasterOnTestStart()93 void EventBroadcasterOnTestStart() {
94 TEST_EVENT_OBSERVER(Start);
95
96 TestCase test_case(kTestCaseName, &Stub, &Stub);
97 TestInfo test_info(kTestName, kLocation, nullptr);
98 internal::EventBroadcaster event_broadcaster;
99 fbl::Vector<FakeObserver> observers;
100 observers.reserve(kNumObservers);
101
102 REGISTER_OBSERVERS(
103 observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
104 ZX_ASSERT_MSG(&actual == &test_case,
105 "EventBroadcaster::OnTestStart propagated the wrong test case\n");
106 ZX_ASSERT_MSG(&actual_info == &test_info,
107 "EventBroadcaster::OnTestStart propagated the wrong test info\n");
108 });
109
110 event_broadcaster.OnTestStart(test_case, test_info);
111
112 ValidateAllObserversNotified(observers);
113 }
114
EventBroadcasterOnTestSkip()115 void EventBroadcasterOnTestSkip() {
116 TEST_EVENT_OBSERVER(Skip);
117
118 TestCase test_case(kTestCaseName, &Stub, &Stub);
119 TestInfo test_info(kTestName, kLocation, nullptr);
120 internal::EventBroadcaster event_broadcaster;
121 fbl::Vector<FakeObserver> observers;
122 observers.reserve(kNumObservers);
123
124 REGISTER_OBSERVERS(
125 observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
126 ZX_ASSERT_MSG(&actual == &test_case,
127 "EventBroadcaster::OnTestSkip propagated the wrong test case\n");
128 ZX_ASSERT_MSG(&actual_info == &test_info,
129 "EventBroadcaster::OnTestSkip propagated the wrong test info\n");
130 });
131
132 event_broadcaster.OnTestSkip(test_case, test_info);
133
134 ValidateAllObserversNotified(observers);
135 }
136
EventBroadcasterOnTestSuccess()137 void EventBroadcasterOnTestSuccess() {
138 TEST_EVENT_OBSERVER(Success);
139
140 TestCase test_case(kTestCaseName, &Stub, &Stub);
141 TestInfo test_info(kTestName, kLocation, nullptr);
142 internal::EventBroadcaster event_broadcaster;
143 fbl::Vector<FakeObserver> observers;
144 observers.reserve(kNumObservers);
145
146 REGISTER_OBSERVERS(
147 observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
148 ZX_ASSERT_MSG(&actual == &test_case,
149 "EventBroadcaster::OnTestSuccess propagated the wrong test case\n");
150 ZX_ASSERT_MSG(&actual_info == &test_info,
151 "EventBroadcaster::OnTestSuccess propagated the wrong test info\n");
152 });
153
154 event_broadcaster.OnTestSuccess(test_case, test_info);
155
156 ValidateAllObserversNotified(observers);
157 }
158
EventBroadcasterOnTestFailure()159 void EventBroadcasterOnTestFailure() {
160 TEST_EVENT_OBSERVER(Failure);
161
162 TestCase test_case(kTestCaseName, &Stub, &Stub);
163 TestInfo test_info(kTestName, kLocation, nullptr);
164 internal::EventBroadcaster event_broadcaster;
165 fbl::Vector<FakeObserver> observers;
166 observers.reserve(kNumObservers);
167
168 REGISTER_OBSERVERS(
169 observers, event_broadcaster, [&](const TestCase& actual, const TestInfo& actual_info) {
170 ZX_ASSERT_MSG(&actual == &test_case,
171 "EventBroadcaster::OnTestFailure propagated the wrong test case\n");
172 ZX_ASSERT_MSG(&actual_info == &test_info,
173 "EventBroadcaster::OnTestFailure propagated the wrong test info\n");
174 });
175
176 event_broadcaster.OnTestFailure(test_case, test_info);
177
178 ValidateAllObserversNotified(observers);
179 }
180
EventBroadcasterOnTestCaseEnd()181 void EventBroadcasterOnTestCaseEnd() {
182 TESTCASE_EVENT_OBSERVER(End);
183
184 TestCase test_case(kTestCaseName, &Stub, &Stub);
185 internal::EventBroadcaster event_broadcaster;
186 fbl::Vector<FakeObserver> observers;
187 observers.reserve(kNumObservers);
188
189 REGISTER_OBSERVERS(observers, event_broadcaster, [&test_case](const TestCase& actual) {
190 ZX_ASSERT_MSG(&actual == &test_case,
191 "EventBroadcaster::OnTestCaseEnd propagated the wrong test case\n");
192 });
193
194 event_broadcaster.OnTestCaseEnd(test_case);
195
196 ValidateAllObserversNotified(observers);
197 }
198
199 } // namespace test
200 } // namespace zxtest
201