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 "runnable_tests"
18
19 #include <mediautils/Runnable.h>
20
21 #include <gtest/gtest.h>
22
23 using namespace android::mediautils;
24
25 struct Func {
26 inline static int sMoveCtor = 0;
27 inline static int sDtor = 0;
28 // accumulator for call operator of this object
29 inline static int sSum = 0;
30 static constexpr int VAL1 = 7;
31 static constexpr int VAL2 = 4;
32
FuncFunc33 Func(int v) : value(v) {}
34 Func(const Func&) = delete;
FuncFunc35 Func(Func&& other) : value(other.value) { sMoveCtor++; }
36 Func& operator=(const Func&) = delete;
~FuncFunc37 ~Func() { sDtor++; }
38
operator ()Func39 void operator()() { sSum += value; }
40
41 private:
42 const int value;
43 };
44
45 class RunnableTests : public ::testing::Test {
46 protected:
SetUp()47 void SetUp() override {
48 Func::sMoveCtor = 0;
49 Func::sDtor = 0;
50 Func::sSum = 0;
51 }
52 };
53
TEST_F(RunnableTests,testEmpty)54 TEST_F(RunnableTests, testEmpty) {
55 Runnable r1{};
56 Runnable r2{nullptr};
57 // empty func should do nothing, instead of crash
58 r1();
59 r2();
60 EXPECT_FALSE(r1);
61 EXPECT_FALSE(r2);
62 }
63
foo()64 static int foo() {
65 return 5;
66 }
67
68 struct Copy {
CopyCopy69 Copy() {}
CopyCopy70 Copy(const Copy&) {}
CopyCopy71 Copy(Copy&&) {}
operator ()Copy72 void operator()(){}
73 };
74
TEST_F(RunnableTests,testCompile)75 TEST_F(RunnableTests, testCompile) {
76 const Copy b{};
77 Runnable r1{std::move(b)};
78 Runnable r2{b};
79 Runnable r4{foo};
80 std::unique_ptr<int> ptr;
81 auto move_only = [ptr = std::move(ptr)](){};
82 Runnable r5{std::move(move_only)};
83 auto copyable = [](){};
84 Runnable r6{copyable};
85 }
86
TEST_F(RunnableTests,testBool)87 TEST_F(RunnableTests, testBool) {
88 Runnable r1{[]() {}};
89 EXPECT_TRUE(r1);
90 }
91
TEST_F(RunnableTests,testCall)92 TEST_F(RunnableTests, testCall) {
93 Runnable r1{Func{Func::VAL1}};
94 EXPECT_TRUE(r1);
95 r1();
96 EXPECT_EQ(Func::sSum, Func::VAL1);
97 }
98
TEST_F(RunnableTests,testDtor)99 TEST_F(RunnableTests, testDtor) {
100 {
101 Runnable r1{Func{Func::VAL1}};
102 }
103 EXPECT_EQ(Func::sDtor, 2);
104 }
105
TEST_F(RunnableTests,testMoveCtor)106 TEST_F(RunnableTests, testMoveCtor) {
107 {
108 Runnable moved_from{Func{Func::VAL1}};
109 EXPECT_EQ(Func::sMoveCtor, 1);
110 EXPECT_EQ(Func::sDtor, 1);
111 Runnable r1{std::move(moved_from)};
112 EXPECT_EQ(Func::sDtor, 2); // impl detail that we destroy internal obj after move
113 EXPECT_EQ(Func::sMoveCtor, 2);
114 EXPECT_TRUE(r1);
115 EXPECT_FALSE(moved_from);
116 r1();
117 EXPECT_EQ(Func::sSum, Func::VAL1);
118 }
119 EXPECT_EQ(Func::sDtor, 3);
120 }
121
TEST_F(RunnableTests,testMoveAssign)122 TEST_F(RunnableTests, testMoveAssign) {
123 {
124 Runnable r1{Func{Func::VAL2}};
125 Runnable moved_from{Func{Func::VAL1}};
126 EXPECT_EQ(Func::sMoveCtor, 2);
127 EXPECT_EQ(Func::sDtor, 2);
128 r1();
129 EXPECT_EQ(Func::sSum, 4);
130 r1 = std::move(moved_from);
131 EXPECT_EQ(Func::sDtor, 4); // impl detail that we destroy internal obj after move
132 EXPECT_EQ(Func::sMoveCtor, 3);
133 EXPECT_TRUE(r1);
134 EXPECT_FALSE(moved_from);
135 r1(); // value should now hold Func::VAL1
136 EXPECT_EQ(Func::sSum, Func::VAL2 + Func::VAL1);
137 }
138 EXPECT_EQ(Func::sDtor, 5);
139 }
140