1 /*
2 * Copyright (C) 2025 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 #define LOG_TAG "executor_tests"
18
19 #include <mediautils/SingleThreadExecutor.h>
20 #include <mediautils/TidWrapper.h>
21
22 #include <future>
23
24 #include <gtest/gtest.h>
25
26 using namespace android::mediautils;
27
28 class ExecutorTests : public ::testing::Test {
29 protected:
TearDown()30 void TearDown() override { executor_.shutdown(); }
31 SingleThreadExecutor executor_;
32 };
33
TEST_F(ExecutorTests,TaskEnqueue)34 TEST_F(ExecutorTests, TaskEnqueue) {
35 std::atomic<int> counter = 0;
36 std::packaged_task<int()> task1([&]() {
37 counter++;
38 return 7;
39 });
40
41 auto future1 = task1.get_future();
42 executor_.enqueue(Runnable{std::move(task1)});
43 EXPECT_EQ(future1.get(), 7);
44 EXPECT_EQ(counter, 1);
45 }
46
TEST_F(ExecutorTests,TaskThread)47 TEST_F(ExecutorTests, TaskThread) {
48 std::packaged_task<int()> task1([&]() { return getThreadIdWrapper(); });
49
50 auto future1 = task1.get_future();
51 executor_.enqueue(Runnable{std::move(task1)});
52 EXPECT_NE(future1.get(), getThreadIdWrapper());
53 }
54
TEST_F(ExecutorTests,TaskOrder)55 TEST_F(ExecutorTests, TaskOrder) {
56 std::atomic<int> counter = 0;
57 std::packaged_task<int()> task1([&]() { return counter++; });
58 std::packaged_task<int()> task2([&]() { return counter++; });
59 auto future1 = task1.get_future();
60 auto future2 = task2.get_future();
61
62 executor_.enqueue(Runnable{std::move(task1)});
63 executor_.enqueue(Runnable{std::move(task2)});
64
65 EXPECT_EQ(future1.get(), 0);
66 EXPECT_EQ(future2.get(), 1);
67 EXPECT_EQ(counter, 2);
68 }
69
TEST_F(ExecutorTests,EmptyTask)70 TEST_F(ExecutorTests, EmptyTask) {
71 // does not crash
72 executor_.enqueue(Runnable{});
73 }
74
TEST_F(ExecutorTests,ShutdownTwice)75 TEST_F(ExecutorTests, ShutdownTwice) {
76 executor_.shutdown();
77 executor_.shutdown();
78 }
79