blob: ac0c5fcebbe1ef089aa3077e9524c8936b964d3a [file] [log] [blame]
Roman Stratiienko13cc3662020-08-29 21:35:39 +03001#include "utils/Worker.h"
Roman Stratiienkoaa3cd542020-08-29 11:26:16 +03002
Adrian Salidofa37f672017-02-16 10:29:46 -08003#include <gtest/gtest.h>
4#include <hardware/hardware.h>
5
6#include <chrono>
7
Adrian Salidofa37f672017-02-16 10:29:46 -08008using android::Worker;
9
10struct TestWorker : public Worker {
Roman Stratiienkod21071f2021-03-09 21:56:50 +020011 TestWorker() : Worker("test-worker", HAL_PRIORITY_URGENT_DISPLAY){};
Adrian Salidofa37f672017-02-16 10:29:46 -080012
13 int Init() {
14 return InitWorker();
15 }
16
Roman Stratiienkod21071f2021-03-09 21:56:50 +020017 void Routine() override {
Adrian Salidofa37f672017-02-16 10:29:46 -080018 Lock();
19 if (!enabled_) {
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030020 auto ret = WaitForSignalOrExitLocked();
Adrian Salidofa37f672017-02-16 10:29:46 -080021 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
33 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
Roman Stratiienkod21071f2021-03-09 21:56:50 +020046 // NOLINTNEXTLINE: should not be public
47 int value{};
Adrian Salidofa37f672017-02-16 10:29:46 -080048
49 private:
Roman Stratiienkod21071f2021-03-09 21:56:50 +020050 bool enabled_{};
Adrian Salidofa37f672017-02-16 10:29:46 -080051};
52
53struct WorkerTest : public testing::Test {
54 TestWorker worker;
55
Roman Stratiienkod21071f2021-03-09 21:56:50 +020056 void SetUp() override {
Adrian Salidofa37f672017-02-16 10:29:46 -080057 worker.Init();
58 }
59
60 void small_delay() {
61 std::this_thread::sleep_for(std::chrono::milliseconds(20));
62 }
63};
64
Roman Stratiienkod21071f2021-03-09 21:56:50 +020065// NOLINTNEXTLINE: required by gtest macros
66TEST_F(WorkerTest, TestWorker) {
Rhys Kiddc7a6d272018-02-26 01:17:42 -050067 // already isInitialized so should succeed
Adrian Salidofa37f672017-02-16 10:29:46 -080068 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
Roman Stratiienkod21071f2021-03-09 21:56:50 +0200103// NOLINTNEXTLINE: required by gtest macros
104TEST_F(WorkerTest, ExitWhileRunning) {
Adrian Salidofa37f672017-02-16 10:29:46 -0800105 worker.Control(true);
106
107 std::this_thread::sleep_for(std::chrono::milliseconds(50));
108 worker.Exit();
109}