1 #include "utils/Worker.h"
2
3 #include <gtest/gtest.h>
4 #include <hardware/hardware.h>
5
6 #include <chrono>
7
8 using android::Worker;
9
10 struct TestWorker : public Worker {
TestWorkerTestWorker11 TestWorker() : Worker("test-worker", HAL_PRIORITY_URGENT_DISPLAY){};
12
InitTestWorker13 int Init() {
14 return InitWorker();
15 }
16
RoutineTestWorker17 void Routine() override {
18 Lock();
19 if (!enabled_) {
20 int ret = WaitForSignalOrExitLocked();
21 if (ret == -EINTR) {
22 Unlock();
23 return;
24 }
25 // should only reached here if it was enabled
26 if (!enabled_)
27 printf("Shouldn't reach here while disabled %d %d\n", value, ret);
28 }
29 value++;
30 Unlock();
31 }
32
ControlTestWorker33 void Control(bool enable) {
34 bool changed = false;
35 Lock();
36 if (enabled_ != enable) {
37 enabled_ = enable;
38 changed = true;
39 }
40 Unlock();
41
42 if (enable && changed)
43 Signal();
44 }
45
46 // NOLINTNEXTLINE: should not be public
47 int value{};
48
49 private:
50 bool enabled_{};
51 };
52
53 struct WorkerTest : public testing::Test {
54 TestWorker worker;
55
SetUpWorkerTest56 void SetUp() override {
57 worker.Init();
58 }
59
small_delayWorkerTest60 void small_delay() {
61 std::this_thread::sleep_for(std::chrono::milliseconds(20));
62 }
63 };
64
65 // NOLINTNEXTLINE: required by gtest macros
TEST_F(WorkerTest,TestWorker)66 TEST_F(WorkerTest, TestWorker) {
67 // already isInitialized so should succeed
68 ASSERT_TRUE(worker.initialized());
69
70 int val = worker.value;
71 small_delay();
72
73 // value shouldn't change when isInitialized
74 ASSERT_EQ(val, worker.value);
75
76 worker.Control(true);
77 small_delay();
78
79 // while locked, value shouldn't be changing
80 worker.Lock();
81 val = worker.value;
82 small_delay();
83 ASSERT_EQ(val, worker.value);
84 worker.Unlock();
85
86 small_delay();
87 // value should be different now
88 ASSERT_NE(val, worker.value);
89
90 worker.Control(false);
91 worker.Lock();
92 val = worker.value;
93 worker.Unlock();
94 small_delay();
95
96 // value should be same
97 ASSERT_EQ(val, worker.value);
98
99 worker.Exit();
100 ASSERT_FALSE(worker.initialized());
101 }
102
103 // NOLINTNEXTLINE: required by gtest macros
TEST_F(WorkerTest,ExitWhileRunning)104 TEST_F(WorkerTest, ExitWhileRunning) {
105 worker.Control(true);
106
107 std::this_thread::sleep_for(std::chrono::milliseconds(50));
108 worker.Exit();
109 }
110