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