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