1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <thread> 17 #include <cinttypes> 18 #include <gtest/gtest.h> 19 #include <gmock/gmock.h> 20 21 #include "audio_service_log.h" 22 #include "audio_errors.h" 23 #include "futex_tool.h" 24 #include "audio_log_utils.h" 25 26 using namespace testing::ext; 27 28 namespace OHOS { 29 namespace AudioStandard { 30 namespace { 31 static constexpr int64_t TIMEOUT_IN_NS = 300000000; // 300ms 32 static constexpr int64_t SHORT_TIMEOUT_IN_NS = 30000000; // 30ms 33 static constexpr uint32_t CYCLES_TIMES = 500; 34 } // namespace 35 36 class FutexToolUnitTest : public testing::Test { 37 public: 38 static void SetUpTestCase(void); 39 static void TearDownTestCase(void); 40 void SetUp(); 41 void TearDown(); 42 }; 43 44 /** 45 * @tc.name : Test FutexTool API 46 * @tc.type : FUNC 47 * @tc.number: FutexTool_001 48 * @tc.desc : Test FutexTool interface. 49 */ 50 HWTEST(FutexToolUnitTest, FutexTool_001, TestSize.Level1) 51 { 52 std::atomic<uint32_t> futexVar = IS_READY; 53 std::atomic<uint32_t> readIndex = 0; 54 std::atomic<uint32_t> writeIndex = 0; 55 __anon5d2bc9ab0202() 56 std::thread threadWrite([&futexVar, &writeIndex] () { 57 writeIndex++; 58 FutexTool::FutexWake(&futexVar, IS_READY); 59 }); 60 __anon5d2bc9ab0302() 61 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 62 return writeIndex > readIndex; 63 }); 64 65 threadWrite.join(); 66 EXPECT_EQ(ret, FUTEX_SUCCESS); 67 } 68 69 /** 70 * @tc.name : Test FutexTool API 71 * @tc.type : FUNC 72 * @tc.number: FutexTool_002 73 * @tc.desc : Test FutexTool interface. 74 */ 75 HWTEST(FutexToolUnitTest, FutexTool_002, TestSize.Level1) 76 { 77 std::atomic<uint32_t> futexVar = IS_NOT_READY; 78 std::atomic<uint32_t> readIndex = 0; 79 std::atomic<uint32_t> writeIndex = 0; 80 __anon5d2bc9ab0402() 81 std::thread threadWrite([&futexVar, &writeIndex] () { 82 writeIndex++; 83 FutexTool::FutexWake(&futexVar, IS_READY); 84 }); 85 __anon5d2bc9ab0502() 86 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 87 return writeIndex > readIndex; 88 }); 89 90 threadWrite.join(); 91 EXPECT_EQ(ret, FUTEX_SUCCESS); 92 } 93 94 /** 95 * @tc.name : Test FutexTool API 96 * @tc.type : FUNC 97 * @tc.number: FutexTool_003 98 * @tc.desc : Test FutexTool interface. 99 */ 100 HWTEST(FutexToolUnitTest, FutexTool_003, TestSize.Level1) 101 { 102 std::atomic<uint32_t> futexVar = IS_READY; 103 std::atomic<uint32_t> writeIndex = 0; 104 __anon5d2bc9ab0602() 105 std::thread threadWrite([&futexVar, &writeIndex] () { 106 while (writeIndex++ < CYCLES_TIMES) {} 107 FutexTool::FutexWake(&futexVar, IS_READY); 108 }); 109 __anon5d2bc9ab0702() 110 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 111 return writeIndex >= CYCLES_TIMES; 112 }); 113 114 threadWrite.join(); 115 EXPECT_EQ(ret, FUTEX_SUCCESS); 116 } 117 118 /** 119 * @tc.name : Test FutexTool API 120 * @tc.type : FUNC 121 * @tc.number: FutexTool_004 122 * @tc.desc : Test FutexTool interface. 123 */ 124 HWTEST(FutexToolUnitTest, FutexTool_004, TestSize.Level1) 125 { 126 std::atomic<uint32_t> futexVar = IS_NOT_READY; 127 std::atomic<uint32_t> writeIndex = 0; 128 __anon5d2bc9ab0802() 129 std::thread threadWrite([&futexVar, &writeIndex] () { 130 while (writeIndex++ < CYCLES_TIMES) {} 131 FutexTool::FutexWake(&futexVar, IS_READY); 132 }); 133 __anon5d2bc9ab0902() 134 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 135 return writeIndex >= CYCLES_TIMES; 136 }); 137 138 threadWrite.join(); 139 EXPECT_EQ(ret, FUTEX_SUCCESS); 140 } 141 142 /** 143 * @tc.name : Test FutexTool API 144 * @tc.type : FUNC 145 * @tc.number: FutexTool_005 146 * @tc.desc : Test FutexTool interface. 147 */ 148 HWTEST(FutexToolUnitTest, FutexTool_005, TestSize.Level1) 149 { 150 std::atomic<uint32_t> futexVar = IS_READY; 151 std::atomic<uint32_t> readIndex = 0; 152 std::atomic<uint32_t> writeIndex = 0; 153 __anon5d2bc9ab0a02() 154 std::thread threadWrite([&futexVar, &writeIndex, &readIndex] () { 155 while (writeIndex++ < CYCLES_TIMES) { 156 if (writeIndex >= readIndex) { 157 FutexTool::FutexWake(&futexVar, IS_READY); 158 } 159 } 160 }); 161 162 while (readIndex++ < CYCLES_TIMES) { __anon5d2bc9ab0b02() 163 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 164 return writeIndex >= readIndex; 165 }); 166 EXPECT_EQ(ret, FUTEX_SUCCESS); 167 } 168 169 threadWrite.join(); 170 } 171 172 /** 173 * @tc.name : Test FutexTool API 174 * @tc.type : FUNC 175 * @tc.number: FutexTool_006 176 * @tc.desc : Test FutexTool interface. 177 */ 178 HWTEST(FutexToolUnitTest, FutexTool_006, TestSize.Level1) 179 { 180 std::atomic<uint32_t> futexVar = IS_NOT_READY; 181 std::atomic<uint32_t> readIndex = 0; 182 std::atomic<uint32_t> writeIndex = 0; 183 __anon5d2bc9ab0c02() 184 std::thread threadWrite([&futexVar, &writeIndex, &readIndex] () { 185 while (writeIndex++ < CYCLES_TIMES) { 186 if (writeIndex >= readIndex) { 187 FutexTool::FutexWake(&futexVar, IS_READY); 188 } 189 } 190 }); 191 192 while (readIndex++ < CYCLES_TIMES) { __anon5d2bc9ab0d02() 193 auto ret = FutexTool::FutexWait(&futexVar, TIMEOUT_IN_NS, [&] () { 194 return writeIndex >= readIndex; 195 }); 196 EXPECT_EQ(ret, FUTEX_SUCCESS); 197 } 198 199 threadWrite.join(); 200 } 201 202 /** 203 * @tc.name : Test FutexTool API 204 * @tc.type : FUNC 205 * @tc.number: FutexTool_007 206 * @tc.desc : Test FutexTool interface. 207 */ 208 HWTEST(FutexToolUnitTest, FutexTool_007, TestSize.Level1) 209 { 210 std::atomic<uint32_t> futexVar = IS_READY; 211 __anon5d2bc9ab0e02() 212 auto ret = FutexTool::FutexWait(&futexVar, SHORT_TIMEOUT_IN_NS, [] () { 213 return false; 214 }); 215 216 EXPECT_EQ(ret, FUTEX_TIMEOUT); 217 } 218 219 /** 220 * @tc.name : Test FutexTool API 221 * @tc.type : FUNC 222 * @tc.number: FutexTool_008 223 * @tc.desc : Test FutexTool interface. 224 */ 225 HWTEST(FutexToolUnitTest, FutexTool_008, TestSize.Level1) 226 { 227 std::atomic<uint32_t> futexVar(100); 228 __anon5d2bc9ab0f02() 229 auto ret = FutexTool::FutexWait(&futexVar, SHORT_TIMEOUT_IN_NS, [] () { 230 return false; 231 }); 232 233 EXPECT_EQ(ret, FUTEX_INVALID_PARAMS); 234 } 235 236 /** 237 * @tc.name : Test ProcessVolumeData API 238 * @tc.type : FUNC 239 * @tc.number: ProcessVolumeData_001 240 * @tc.desc : Test ProcessVolumeData interface. 241 */ 242 HWTEST(FutexToolUnitTest, ProcessVolumeData_001, TestSize.Level1) 243 { 244 AudioLogUtils audioLogUtils; 245 std::string logTag = "test_log_tag"; 246 ChannelVolumes vols; 247 vols.channel = STEREO; 248 vols.volStart[0] = 0; 249 vols.volStart[1] = 0; 250 int64_t count = 10; 251 audioLogUtils.ProcessVolumeData(logTag, vols, count); 252 EXPECT_NE(count, 9); 253 } 254 255 /** 256 * @tc.name : Test ProcessVolumeData API 257 * @tc.type : FUNC 258 * @tc.number: ProcessVolumeData_002 259 * @tc.desc : Test ProcessVolumeData interface. 260 */ 261 HWTEST(FutexToolUnitTest, ProcessVolumeData_002, TestSize.Level1) 262 { 263 AudioLogUtils audioLogUtils; 264 std::string logTag = "test_log_tag"; 265 ChannelVolumes vols; 266 vols.channel = STEREO; 267 vols.volStart[0] = 1; 268 vols.volStart[1] = 1; 269 int64_t count = -10; 270 audioLogUtils.ProcessVolumeData(logTag, vols, count); 271 EXPECT_NE(count, -9); 272 } 273 } // namespace AudioStandard 274 } // namespace OHOS