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