diff options
Diffstat (limited to 'broadcastradio/common/tests/WorkerThread_test.cpp')
-rw-r--r-- | broadcastradio/common/tests/WorkerThread_test.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/broadcastradio/common/tests/WorkerThread_test.cpp b/broadcastradio/common/tests/WorkerThread_test.cpp new file mode 100644 index 00000000..ed36de3e --- /dev/null +++ b/broadcastradio/common/tests/WorkerThread_test.cpp | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <broadcastradio-utils/WorkerThread.h> | ||
18 | #include <gtest/gtest.h> | ||
19 | |||
20 | namespace { | ||
21 | |||
22 | using namespace std::chrono_literals; | ||
23 | |||
24 | using android::WorkerThread; | ||
25 | |||
26 | using std::atomic; | ||
27 | using std::chrono::time_point; | ||
28 | using std::chrono::steady_clock; | ||
29 | using std::is_sorted; | ||
30 | using std::lock_guard; | ||
31 | using std::mutex; | ||
32 | using std::this_thread::sleep_for; | ||
33 | using std::vector; | ||
34 | |||
35 | #define ASSERT_EQ_WITH_TOLERANCE(val1, val2, tolerance) \ | ||
36 | ASSERT_LE((val1) - (tolerance), (val2)); \ | ||
37 | ASSERT_GE((val1) + (tolerance), (val2)); | ||
38 | |||
39 | TEST(WorkerThreadTest, oneTask) { | ||
40 | atomic<bool> executed(false); | ||
41 | atomic<time_point<steady_clock>> stop; | ||
42 | WorkerThread thread; | ||
43 | |||
44 | auto start = steady_clock::now(); | ||
45 | thread.schedule( | ||
46 | [&]() { | ||
47 | stop = steady_clock::now(); | ||
48 | executed = true; | ||
49 | }, | ||
50 | 100ms); | ||
51 | |||
52 | sleep_for(150ms); | ||
53 | |||
54 | ASSERT_TRUE(executed); | ||
55 | auto delta = stop.load() - start; | ||
56 | ASSERT_EQ_WITH_TOLERANCE(delta, 100ms, 50ms); | ||
57 | } | ||
58 | |||
59 | TEST(WorkerThreadTest, cancelSecond) { | ||
60 | atomic<bool> executed1(false); | ||
61 | atomic<bool> executed2(false); | ||
62 | WorkerThread thread; | ||
63 | |||
64 | thread.schedule([&]() { executed2 = true; }, 100ms); | ||
65 | thread.schedule([&]() { executed1 = true; }, 25ms); | ||
66 | |||
67 | sleep_for(50ms); | ||
68 | thread.cancelAll(); | ||
69 | sleep_for(100ms); | ||
70 | |||
71 | ASSERT_TRUE(executed1); | ||
72 | ASSERT_FALSE(executed2); | ||
73 | } | ||
74 | |||
75 | TEST(WorkerThreadTest, executeInOrder) { | ||
76 | mutex mut; | ||
77 | vector<int> order; | ||
78 | WorkerThread thread; | ||
79 | |||
80 | thread.schedule( | ||
81 | [&]() { | ||
82 | lock_guard<mutex> lk(mut); | ||
83 | order.push_back(0); | ||
84 | }, | ||
85 | 50ms); | ||
86 | |||
87 | thread.schedule( | ||
88 | [&]() { | ||
89 | lock_guard<mutex> lk(mut); | ||
90 | order.push_back(4); | ||
91 | }, | ||
92 | 400ms); | ||
93 | |||
94 | thread.schedule( | ||
95 | [&]() { | ||
96 | lock_guard<mutex> lk(mut); | ||
97 | order.push_back(1); | ||
98 | }, | ||
99 | 100ms); | ||
100 | |||
101 | thread.schedule( | ||
102 | [&]() { | ||
103 | lock_guard<mutex> lk(mut); | ||
104 | order.push_back(3); | ||
105 | }, | ||
106 | 300ms); | ||
107 | |||
108 | thread.schedule( | ||
109 | [&]() { | ||
110 | lock_guard<mutex> lk(mut); | ||
111 | order.push_back(2); | ||
112 | }, | ||
113 | 200ms); | ||
114 | |||
115 | sleep_for(500ms); | ||
116 | |||
117 | ASSERT_EQ(5u, order.size()); | ||
118 | ASSERT_TRUE(is_sorted(order.begin(), order.end())); | ||
119 | } | ||
120 | |||
121 | TEST(WorkerThreadTest, dontExecuteAfterDestruction) { | ||
122 | atomic<bool> executed1(false); | ||
123 | atomic<bool> executed2(false); | ||
124 | { | ||
125 | WorkerThread thread; | ||
126 | |||
127 | thread.schedule([&]() { executed2 = true; }, 100ms); | ||
128 | thread.schedule([&]() { executed1 = true; }, 25ms); | ||
129 | |||
130 | sleep_for(50ms); | ||
131 | } | ||
132 | sleep_for(100ms); | ||
133 | |||
134 | ASSERT_TRUE(executed1); | ||
135 | ASSERT_FALSE(executed2); | ||
136 | } | ||
137 | |||
138 | } // anonymous namespace | ||