• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <gtest/gtest.h>
18 #include "audio_utils.h"
19 
20 using namespace testing::ext;
21 using namespace std;
22 namespace OHOS {
23 namespace AudioStandard {
24 
25 constexpr int32_t SUCCESS = 0;
26 constexpr unsigned int QUEUE_SLOTS = 10;
27 constexpr unsigned int THREAD_NUM = QUEUE_SLOTS + 1;
28 class AudioUtilsUnitTest : public testing::Test {
29 public:
30     static void SetUpTestCase(void);
31     static void TearDownTestCase(void);
32     void SetUp();
33     void TearDown();
34 };
35 
SetUpTestCase(void)36 void AudioUtilsUnitTest::SetUpTestCase(void)
37 {
38     // input testsuit setup step,setup invoked before all testcases
39 }
40 
TearDownTestCase(void)41 void AudioUtilsUnitTest::TearDownTestCase(void)
42 {
43     // input testsuit teardown step,teardown invoked after all testcases
44 }
45 
SetUp(void)46 void AudioUtilsUnitTest::SetUp(void)
47 {
48     // input testcase setup step,setup invoked before each testcases
49 }
50 
TearDown(void)51 void AudioUtilsUnitTest::TearDown(void)
52 {
53     // input testcase teardown step,teardown invoked after each testcases
54 }
55 
56 /**
57 * @tc.name  : Test ClockTime API
58 * @tc.type  : FUNC
59 * @tc.number: ClockTime_001
60 * @tc.desc  : Test ClockTime interface.
61 */
62 HWTEST(AudioUtilsUnitTest, ClockTime_001, TestSize.Level1)
63 {
64     const int64_t CLOCK_TIME = 0;
65     int32_t ret = -1;
66     ret = ClockTime::AbsoluteSleep(CLOCK_TIME);
67     EXPECT_EQ(SUCCESS - 1, ret);
68 
69     int64_t nanoTime = 1000;
70     ret = ClockTime::AbsoluteSleep(nanoTime);
71     EXPECT_EQ(SUCCESS, ret);
72 
73     ret = ClockTime::RelativeSleep(CLOCK_TIME);
74     EXPECT_EQ(SUCCESS - 1, ret);
75 
76     ret = ClockTime::RelativeSleep(nanoTime);
77     EXPECT_EQ(SUCCESS, ret);
78 }
79 
80 /**
81 * @tc.name  : Test Trace API
82 * @tc.type  : FUNC
83 * @tc.number: Trace_001
84 * @tc.desc  : Test Trace interface.
85 */
86 HWTEST(AudioUtilsUnitTest, Trace_001, TestSize.Level1)
87 {
88     std::string value = "Test";
89     std::shared_ptr<Trace> trace = std::make_shared<Trace>(value);
90     trace->End();
91     int64_t count = 1;
92     Trace::Count(value, count);
93 }
94 
95 /**
96 * @tc.name  : Test PermissionUtil API
97 * @tc.type  : FUNC
98 * @tc.number: PermissionUtil_001
99 * @tc.desc  : Test PermissionUtil interface.
100 */
101 HWTEST(AudioUtilsUnitTest, PermissionUtil_001, TestSize.Level1)
102 {
103     bool ret1 = PermissionUtil::VerifyIsSystemApp();
104     EXPECT_EQ(false, ret1);
105     bool ret2 = PermissionUtil::VerifySelfPermission();
106     EXPECT_EQ(true, ret2);
107     bool ret3 = PermissionUtil::VerifySystemPermission();
108     EXPECT_EQ(true, ret3);
109 }
110 
111 /**
112 * @tc.name  : Test AdjustStereoToMonoForPCM API
113 * @tc.type  : FUNC
114 * @tc.number: AdjustStereoToMonoForPCM_001
115 * @tc.desc  : Test AdjustStereoToMonoForPCM interface.
116 */
117 HWTEST(AudioUtilsUnitTest, AdjustStereoToMonoForPCM_001, TestSize.Level1)
118 {
119     uint64_t len = 2;
120 
121     const int8_t BitRET = 1;
122     int8_t arr1[2] = {1, 2};
123     int8_t *data1 = &arr1[0];
124     AdjustStereoToMonoForPCM8Bit(data1, len);
125     EXPECT_EQ(BitRET, data1[0]);
126     EXPECT_EQ(BitRET, data1[1]);
127 
128     len = 4;
129     const int16_t Bit16RET = 1;
130     int16_t arr2[2] = {1, 2};
131     int16_t *data2 = &arr2[0];
132     AdjustStereoToMonoForPCM16Bit(data2, len);
133     EXPECT_EQ(Bit16RET, data2[0]);
134     EXPECT_EQ(Bit16RET, data2[1]);
135 
136     len = 8;
137     const int32_t Bit32RET = 1;
138     int32_t arr4[2] = {1, 2};
139     int32_t *data4 = &arr4[0];
140     AdjustStereoToMonoForPCM32Bit(data4, len);
141     EXPECT_EQ(Bit32RET, data4[0]);
142     EXPECT_EQ(Bit32RET, data4[1]);
143 }
144 
145 /**
146 * @tc.name  : Test AdjustAudioBalanceForPCM API
147 * @tc.type  : FUNC
148 * @tc.number: AdjustAudioBalanceForPCM_001
149 * @tc.desc  : Test AdjustAudioBalanceForPCM interface.
150 */
151 HWTEST(AudioUtilsUnitTest, AdjustAudioBalanceForPCM_001, TestSize.Level1)
152 {
153     float left = 2.0;
154     float right = 2.0;
155     uint64_t len = 2;
156 
157     const int8_t Bit8RET1 = 2;
158     const int8_t Bit8RET2 = 4;
159     int8_t arr1[2] = {1, 2};
160     int8_t *data1 = &arr1[0];
161     AdjustAudioBalanceForPCM8Bit(data1, len, left, right);
162     EXPECT_EQ(Bit8RET1, data1[0]);
163     EXPECT_EQ(Bit8RET2, data1[1]);
164 
165     len = 4;
166     const int16_t Bit16RET1 = 2;
167     const int16_t Bit16RET2 = 4;
168     int16_t arr2[2] = {1, 2};
169     int16_t *data2 = &arr2[0];
170     AdjustAudioBalanceForPCM16Bit(data2, len, left, right);
171     EXPECT_EQ(Bit16RET1, data2[0]);
172     EXPECT_EQ(Bit16RET2, data2[1]);
173 
174     len = 8;
175     const int32_t Bit32RET = 2;
176     int32_t arr4[2] = {1, 2};
177     int32_t *data4 = &arr4[0];
178     AdjustAudioBalanceForPCM32Bit(data4, len, left, right);
179     EXPECT_EQ(Bit32RET, data4[0]);
180     EXPECT_EQ(Bit32RET * 2, data4[1]);
181 }
182 
183 /**
184 * @tc.name  : Test GetSysPara API
185 * @tc.type  : FUNC
186 * @tc.number: GetSysPara_001
187 * @tc.desc  : Test GetSysPara interface.
188 */
189 HWTEST(AudioUtilsUnitTest, GetSysPara_001, TestSize.Level1)
190 {
191     const char *invaildKey = nullptr;
192     int32_t value32 = 2;
193     bool result = GetSysPara(invaildKey, value32);
194     EXPECT_EQ(false, result);
195     const char *key = "debug.audio_service.testmodeon";
196     bool result1 = GetSysPara(key, value32);
197     EXPECT_EQ(true, result1);
198     uint32_t valueU32 = 3;
199     bool result2 = GetSysPara(key, valueU32);
200     EXPECT_EQ(true, result2);
201     int64_t value64 = 0;
202     bool result3 = GetSysPara(key, value64);
203     EXPECT_EQ(true, result3);
204     std::string strValue = "100";
205     bool result4 = GetSysPara(key, strValue);
206     EXPECT_EQ(true, result4);
207 }
208 
209 class DemoThreadData {
210 public:
DemoThreadData()211     DemoThreadData()
212     {
213         putStatus = false;
214         getStatus = false;
215     }
216     bool putStatus;
217     bool getStatus;
218     static AudioSafeBlockQueue<int> shareQueue;
219 
Put(int j)220     void Put(int j)
221     {
222         shareQueue.Push(j);
223         putStatus = true;
224     }
225 
Get()226     void Get()
227     {
228         shareQueue.Pop();
229         getStatus = true;
230     }
231 };
232 
233 AudioSafeBlockQueue<int> DemoThreadData::shareQueue(QUEUE_SLOTS);
234 
PutHandleThreadData(DemoThreadData & q,int i)235 void PutHandleThreadData(DemoThreadData& q, int i)
236 {
237     q.Put(i);
238 }
239 
GetThreadDatePushedStatus(std::array<DemoThreadData,THREAD_NUM> & demoDatas,unsigned int & pushedIn,unsigned int & unpushedIn)240 void GetThreadDatePushedStatus(std::array<DemoThreadData, THREAD_NUM>& demoDatas, unsigned int& pushedIn,
241                                unsigned int& unpushedIn)
242 {
243     pushedIn = 0;
244     unpushedIn = 0;
245     for (auto& t : demoDatas) {
246         if (t.putStatus) {
247             pushedIn++;
248         } else {
249             unpushedIn++;
250         }
251     }
252 }
253 
GetThreadDateGetedStatus(std::array<DemoThreadData,THREAD_NUM> & demoDatas,unsigned int & getedOut,unsigned int & ungetedOut)254 void GetThreadDateGetedStatus(std::array<DemoThreadData, THREAD_NUM>& demoDatas,
255     unsigned int& getedOut, unsigned int& ungetedOut)
256 {
257     getedOut = 0;
258     ungetedOut = 0;
259     for (auto& t : demoDatas) {
260         if (t.getStatus) {
261             getedOut++;
262         } else {
263             ungetedOut++;
264         }
265     }
266 }
267 
PutHandleThreadDataTime(DemoThreadData & q,int i,std::chrono::system_clock::time_point absTime)268 void PutHandleThreadDataTime(DemoThreadData& q, int i, std::chrono::system_clock::time_point absTime)
269 {
270     cout << "thread-" << std::this_thread::get_id() << " run time: "
271         << std::chrono::system_clock::to_time_t(absTime) << endl;
272     std::this_thread::sleep_until(absTime);
273 
274     q.Put(i);
275 }
276 
GetHandleThreadDataTime(DemoThreadData & q,int i,std::chrono::system_clock::time_point absTime)277 void GetHandleThreadDataTime(DemoThreadData& q, int i, std::chrono::system_clock::time_point absTime)
278 {
279     cout << "thread-" << std::this_thread::get_id() << " run time: "
280         << std::chrono::system_clock::to_time_t(absTime) << endl;
281     std::this_thread::sleep_until(absTime);
282 
283     q.Get();
284 }
285 
286 /*
287  * @tc.name: testPut001
288  * @tc.desc: Single-threaded call put and get to determine that the normal scenario
289  */
290 HWTEST(AudioUtilsUnitTest, testPut001, TestSize.Level0)
291 {
292     AudioSafeBlockQueue<int> qi(10);
293     int i = 1;
294     qi.Push(i);
295     EXPECT_EQ(static_cast<unsigned>(1), qi.Size());
296 }
297 
298 /*
299  * @tc.name: testGet001
300  * @tc.desc: Single-threaded call put and get to determine that the normal scenario
301  */
302 HWTEST(AudioUtilsUnitTest, testGet001, TestSize.Level0)
303 {
304     AudioSafeBlockQueue<int> qi(10);
305     for (int i = 0; i < 3; i++) {
306         qi.Push(i);
307     }
308     EXPECT_EQ(static_cast<unsigned>(3), qi.Size());
309     int t = qi.Pop();
310     ASSERT_EQ(t, 0);
311 }
312 
ThreadsJoin(std::thread (& threads)[THREAD_NUM])313 static void ThreadsJoin(std::thread (&threads)[THREAD_NUM])
314 {
315     for (auto& t : threads) {
316         t.join();
317     }
318 }
319 
CheckFullQueueStatus(std::array<DemoThreadData,THREAD_NUM> & demoDatas,unsigned int & pushedIn,unsigned int & unpushedIn,unsigned int & getedOut,unsigned int & ungetedOut)320 static void CheckFullQueueStatus(std::array<DemoThreadData, THREAD_NUM>& demoDatas, unsigned int& pushedIn,
321     unsigned int& unpushedIn, unsigned int& getedOut, unsigned int& ungetedOut)
322 {
323     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
324     GetThreadDatePushedStatus(demoDatas, pushedIn, unpushedIn);
325     GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
326     ASSERT_EQ(pushedIn, THREAD_NUM);
327     ASSERT_EQ(getedOut, THREAD_NUM - QUEUE_SLOTS);
328 }
329 
330 /*
331  * @tc.name: testMutilthreadPutAndBlock001
332  * @tc.desc: Multiple threads put until blocking runs, one thread gets, all threads finish running normally
333  */
334 HWTEST(AudioUtilsUnitTest, testMutilthreadPutAndBlock001, TestSize.Level0)
335 {
336     std::thread threads[THREAD_NUM];
337 
338     std::array<DemoThreadData, THREAD_NUM> demoDatas;
339     demoDatas.fill(DemoThreadData());
340 
341     for (unsigned int i = 0; i < THREAD_NUM; i++) {
342         threads[i] = std::thread(PutHandleThreadData, std::ref(demoDatas[i]), i);
343     }
344 
345     // 1. queue is full and some threads is blocked
346     std::this_thread::sleep_for(std::chrono::seconds(2));
347     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
348 
349     unsigned int pushedIn = 0, unpushedIn = 0, getedOut = 0, ungetedOut = 0;
350     GetThreadDatePushedStatus(demoDatas, pushedIn, unpushedIn);
351 
352     ASSERT_EQ(pushedIn, QUEUE_SLOTS);
353     ASSERT_EQ(unpushedIn, THREAD_NUM - QUEUE_SLOTS);
354 
355     // 2. get one out  and wait some put in
356     for (unsigned int i = 0; i < THREAD_NUM - QUEUE_SLOTS; i++) {
357         demoDatas[0].Get();
358     }
359 
360     std::this_thread::sleep_for(std::chrono::seconds(2));
361     // queue is full and some threads is blocked and is not joined
362     CheckFullQueueStatus(demoDatas, pushedIn, unpushedIn, getedOut, ungetedOut);
363     ThreadsJoin(threads);
364 
365     while (!DemoThreadData::shareQueue.IsEmpty()) {
366         demoDatas[0].Get();
367     }
368 
369     // here means all thread end ok or if some operation blocked and the testcase blocked
370 }
371 
GetTimeAddTwoSeconds()372 static std::time_t GetTimeAddTwoSeconds()
373 {
374     using std::chrono::system_clock;
375     std::time_t timeT = system_clock::to_time_t(system_clock::now());
376     cout << "start time: " << timeT << endl;
377     const int twoSec = 2;
378     timeT += twoSec;
379     return timeT;
380 }
381 
382 /*
383  * @tc.name: testMutilthreadConcurrentPutAndBlockInblankqueue001
384  * @tc.desc: Multi-threaded put() on the empty queue. When n threads are waiting to reach a certain
385  * time-point, everyone puts concurrent to see the status of the queue and the state of the thread.
386  */
387 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentPutAndBlockInblankqueue001, TestSize.Level0)
388 {
389     // 1. prepare
390     std::thread threads[THREAD_NUM];
391     std::array<DemoThreadData, THREAD_NUM> demoDatas;
392     demoDatas.fill(DemoThreadData());
393 
394     using std::chrono::system_clock;
395 
396     std::time_t timeT = GetTimeAddTwoSeconds();
397     // 2. start thread
398     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
399     for (unsigned int i = 0; i < THREAD_NUM; i++) {
400         threads[i] = std::thread(PutHandleThreadDataTime, std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
401     }
402 
403     // 1. queue is full and some threads is blocked
404     std::this_thread::sleep_for(std::chrono::seconds(4));
405     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
406 
407     unsigned int pushedIn = 0;
408     unsigned int unpushedIn = 0;
409     unsigned int getedOut = 0;
410     unsigned int ungetedOut = 0;
411     GetThreadDatePushedStatus(demoDatas, pushedIn, unpushedIn);
412 
413     ASSERT_EQ(pushedIn, QUEUE_SLOTS);
414     ASSERT_EQ(unpushedIn, THREAD_NUM - QUEUE_SLOTS);
415 
416     // 2. get one out  and wait some put in
417     for (unsigned int i = 0; i < THREAD_NUM - QUEUE_SLOTS; i++) {
418         demoDatas[0].Get();
419     }
420 
421     std::this_thread::sleep_for(std::chrono::seconds(2));
422     // queue is full and some threads is blocked and is not joined
423     CheckFullQueueStatus(demoDatas, pushedIn, unpushedIn, getedOut, ungetedOut);
424     ThreadsJoin(threads);
425 
426     while (!DemoThreadData::shareQueue.IsEmpty()) {
427         demoDatas[0].Get();
428     }
429     // here means all thread end ok or if some operation blocked and the testcase blocked
430 }
431 
QueuePushInfull()432 static void QueuePushInfull()
433 {
434     for (unsigned int i = 0; i < QUEUE_SLOTS; i++) {
435         int t = i;
436         DemoThreadData::shareQueue.Push(t);
437     }
438 }
439 
QueuePushInnotfull(const unsigned int remain)440 static void QueuePushInnotfull(const unsigned int remain)
441 {
442     for (unsigned int i = 0; i < QUEUE_SLOTS - remain; i++) {
443         int t = i;
444         DemoThreadData::shareQueue.Push(t);
445     }
446 }
447 
448 /*
449  * @tc.name: testMutilthreadConcurrentPutAndBlockInfullqueue001
450  * @tc.desc: Multi-threaded put() on the full queue. When n threads are waiting to reach a certain
451  * time-point, everyone puts concurrent to see the status of the queue and the state of the thread.
452  */
453 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentPutAndBlockInfullqueue001, TestSize.Level0)
454 {
455     // 1. prepare
456     std::thread threads[THREAD_NUM];
457     std::array<DemoThreadData, THREAD_NUM> demoDatas;
458     demoDatas.fill(DemoThreadData());
459 
460     using std::chrono::system_clock;
461 
462     std::time_t timeT = GetTimeAddTwoSeconds();
463     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
464     QueuePushInfull();
465     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
466 
467     // 2. start thread put in full queue
468     for (unsigned int i = 0; i < THREAD_NUM; i++) {
469         threads[i] = std::thread(PutHandleThreadDataTime, std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
470     }
471 
472     std::this_thread::sleep_for(std::chrono::seconds(3));
473     // 3. now thread is running and all is blocked
474     unsigned int pushedIn = 0;
475     unsigned int unpushedIn = 0;
476     GetThreadDatePushedStatus(demoDatas, pushedIn, unpushedIn);
477     ASSERT_EQ(pushedIn, static_cast<unsigned int>(0));
478     ASSERT_EQ(unpushedIn, THREAD_NUM);
479     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
480     for (unsigned int i = 0; i < THREAD_NUM; i++) {
481         cout << "get out one and then the queue is full" << endl;
482         DemoThreadData::shareQueue.Pop();
483         std::this_thread::sleep_for(std::chrono::seconds(1));
484         ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
485         GetThreadDatePushedStatus(demoDatas, pushedIn, unpushedIn);
486         ASSERT_EQ(pushedIn, i + 1);
487         ASSERT_EQ(unpushedIn, THREAD_NUM - (i + 1));
488     }
489 
490     ThreadsJoin(threads);
491     while (!DemoThreadData::shareQueue.IsEmpty()) {
492         demoDatas[0].Get();
493     }
494 }
495 
496 /*
497  * @tc.name: testMutilthreadConcurrentGetAndBlockInblankqueue001
498  * @tc.desc: Multi-threaded get() on the empty queue. When n threads are waiting to reach a certain
499  * time-point, everyone gets concurrent to see the status of the queue and the state of the thread.
500  */
501 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentGetAndBlockInblankqueue001, TestSize.Level0)
502 {
503     // 1. prepare
504     std::thread threads[THREAD_NUM];
505     std::array<DemoThreadData, THREAD_NUM> demoDatas;
506     demoDatas.fill(DemoThreadData());
507 
508     using std::chrono::system_clock;
509 
510     std::time_t timeT = GetTimeAddTwoSeconds();
511     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
512 
513     // 2. start thread put in empty queue
514     for (unsigned int i = 0; i < THREAD_NUM; i++) {
515         threads[i] = std::thread(GetHandleThreadDataTime,
516             std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
517     }
518     std::this_thread::sleep_for(std::chrono::seconds(3));
519 
520     // 3. now thread is running and all is blocked
521     unsigned int getedOut = 0;
522     unsigned int ungetedOut = 0;
523     GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
524     ASSERT_EQ(getedOut, static_cast<unsigned int>(0));
525     ASSERT_EQ(ungetedOut, THREAD_NUM);
526     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
527 
528     int value = 1;
529 
530     for (unsigned int i = 0; i < THREAD_NUM; i++) {
531         cout << "put in one and then the queue is empty" << endl;
532         DemoThreadData::shareQueue.Push(value);
533         std::this_thread::sleep_for(std::chrono::seconds(1));
534         ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
535         GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
536         ASSERT_EQ(getedOut, i + 1);
537         ASSERT_EQ(ungetedOut, THREAD_NUM - (i + 1));
538     }
539 
540     ThreadsJoin(threads);
541     while (!DemoThreadData::shareQueue.IsEmpty()) {
542         demoDatas[0].Get();
543     }
544 }
545 /*
546  * @tc.name: testMutilthreadConcurrentGetAndBlockInfullqueue001
547  * @tc.desc: Multi-threaded get() on the full queue. When n threads are waiting to reach a certain
548  * time-point, everyone gets concurrent to see the status of the queue and the state of the thread.
549  */
550 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentGetAndBlockInfullqueue001, TestSize.Level0)
551 {
552     // 1. prepare
553     std::thread threads[THREAD_NUM];
554     std::array<DemoThreadData, THREAD_NUM> demoDatas;
555     demoDatas.fill(DemoThreadData());
556 
557     using std::chrono::system_clock;
558 
559     std::time_t timeT = GetTimeAddTwoSeconds();
560     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
561     int t = 1;
562     for (unsigned int i = 0; i < QUEUE_SLOTS; i++) {
563         DemoThreadData::shareQueue.Push(t);
564     }
565     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
566 
567     // 2. start thread put in full queue
568     for (unsigned int i = 0; i < THREAD_NUM; i++) {
569         threads[i] = std::thread(GetHandleThreadDataTime, std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
570     }
571 
572     std::this_thread::sleep_for(std::chrono::seconds(4));
573     // 3. start judge
574     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
575 
576     unsigned int getedOut = 0;
577     unsigned int ungetedOut = 0;
578     GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
579 
580     ASSERT_EQ(getedOut, QUEUE_SLOTS);
581     ASSERT_EQ(ungetedOut, THREAD_NUM - QUEUE_SLOTS);
582 
583     // 2.  put one in  and wait some get out
584     for (unsigned int i = 0; i < THREAD_NUM - QUEUE_SLOTS; i++) {
585         demoDatas[0].Put(t);
586     }
587 
588     std::this_thread::sleep_for(std::chrono::seconds(2));
589     // queue is full and some threads is blocked and is not joined
590     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
591     GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
592     ASSERT_EQ(getedOut, THREAD_NUM);
593     ASSERT_EQ(ungetedOut, static_cast<unsigned int>(0));
594 
595     ThreadsJoin(threads);
596     while (!DemoThreadData::shareQueue.IsEmpty()) {
597         demoDatas[0].Get();
598     }
599 }
600 
601 /*
602  * @tc.name: testMutilthreadConcurrentGetAndBlockInnotfullqueue001
603  * @tc.desc: Multi-threaded get() on the notfull queue. When n threads are waiting to reach a certain
604  * time-point, everyone get concurrent to see the status of the queue and the state of the thread.
605  */
606 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentGetAndBlockInnotfullqueue001, TestSize.Level0)
607 {
608     // 1. prepare
609     std::thread threads[THREAD_NUM];
610     std::array<DemoThreadData, THREAD_NUM> demoDatas;
611     demoDatas.fill(DemoThreadData());
612 
613     using std::chrono::system_clock;
614 
615     const unsigned int REMAIN_SLOTS = 5;
616     std::time_t timeT = GetTimeAddTwoSeconds();
617     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
618     QueuePushInnotfull(REMAIN_SLOTS);
619 
620     // 2. start thread put in not full queue
621     for (unsigned int i = 0; i < THREAD_NUM; i++) {
622         threads[i] = std::thread(GetHandleThreadDataTime,
623             std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
624     }
625 
626     std::this_thread::sleep_for(std::chrono::seconds(3));
627 
628     unsigned int getedOut = 0;
629     unsigned int ungetedOut = 0;
630     GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
631     ASSERT_EQ(getedOut, QUEUE_SLOTS - REMAIN_SLOTS);
632     ASSERT_EQ(ungetedOut, THREAD_NUM - (QUEUE_SLOTS - REMAIN_SLOTS));
633 
634     // 3. put ungetedOut
635     for (unsigned int i = 0; i < ungetedOut; i++) {
636         int t = i;
637         DemoThreadData::shareQueue.Push(t);
638     }
639 
640     std::this_thread::sleep_for(std::chrono::seconds(1));
641     GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
642     ASSERT_EQ(getedOut, THREAD_NUM);
643     ASSERT_EQ(ungetedOut, static_cast<unsigned int>(0));
644 
645     ThreadsJoin(threads);
646     while (!DemoThreadData::shareQueue.IsEmpty()) {
647         demoDatas[0].Get();
648     }
649 }
650 
651 /*
652  * @tc.name: testMutilthreadConcurrentPutAndBlockInnotfullqueue001
653  * @tc.desc: Multi-threaded put() on the not full queue. When n threads are waiting to reach a certain
654  * time-point, everyone puts concurrent to see the status of the queue and the state of the thread.
655  */
656 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentPutAndBlockInnotfullqueue001, TestSize.Level0)
657 {
658     // 1. prepare
659     std::thread threads[THREAD_NUM];
660     std::array<DemoThreadData, THREAD_NUM> demoDatas;
661     demoDatas.fill(DemoThreadData());
662 
663     using std::chrono::system_clock;
664 
665     const unsigned int REMAIN_SLOTS = 5;
666     std::time_t timeT = GetTimeAddTwoSeconds();
667     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
668     QueuePushInnotfull(REMAIN_SLOTS);
669 
670     // 2. start thread put in not full queue
671     for (unsigned int i = 0; i < THREAD_NUM; i++) {
672         threads[i] = std::thread(PutHandleThreadDataTime,
673             std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
674     }
675 
676     std::this_thread::sleep_for(std::chrono::seconds(3));
677 
678     unsigned int putedin = 0;
679     unsigned int unputedin = 0;
680     GetThreadDatePushedStatus(demoDatas, putedin, unputedin);
681     ASSERT_EQ(putedin, REMAIN_SLOTS);
682     ASSERT_EQ(unputedin, THREAD_NUM - REMAIN_SLOTS);
683 
684     // 3. put ungetedOut
685     for (unsigned int i = 0; i < unputedin; i++) {
686         DemoThreadData::shareQueue.Pop();
687     }
688 
689     std::this_thread::sleep_for(std::chrono::seconds(1));
690     GetThreadDatePushedStatus(demoDatas, putedin, unputedin);
691     ASSERT_EQ(putedin, THREAD_NUM);
692     ASSERT_EQ(unputedin, static_cast<unsigned int>(0));
693 
694     ThreadsJoin(threads);
695     while (!DemoThreadData::shareQueue.IsEmpty()) {
696         demoDatas[0].Get();
697     }
698 }
699 
CheckQueueStatus(std::array<DemoThreadData,THREAD_NUM> & demoDatas)700 static void CheckQueueStatus(std::array<DemoThreadData, THREAD_NUM>& demoDatas)
701 {
702     unsigned int getedOut = 0;
703     unsigned int ungetedOut = 0;
704     unsigned int pushedIn = 0;
705     unsigned int unpushedIn = 0;
706     GetThreadDateGetedStatus(demoDatas, getedOut, ungetedOut);
707     GetThreadDatePushedStatus(demoDatas, pushedIn, unpushedIn);
708 
709     ASSERT_EQ(pushedIn, THREAD_NUM);
710     ASSERT_EQ(getedOut, THREAD_NUM);
711 }
712 
713 /*
714  * @tc.name: testMutilthreadConcurrentGetAndPopInblankqueue001
715  * @tc.desc: Multi-threaded put() and Multi-threaded get() on the empty queue. When all threads are waiting to reach
716  * a certain time-point, everyone run concurrently to see the status of the queue and the state of the thread.
717  */
718 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentGetAndPopInblankqueue001, TestSize.Level0)
719 {
720     // 1. prepare
721     std::thread threadsout[THREAD_NUM];
722     std::array<DemoThreadData, THREAD_NUM> demoDatas;
723     demoDatas.fill(DemoThreadData());
724 
725     std::thread threadsin[THREAD_NUM];
726 
727     using std::chrono::system_clock;
728 
729     std::time_t timeT = GetTimeAddTwoSeconds();
730     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
731 
732     // 2. start thread put and get in empty queue
733 
734     for (unsigned int i = 0; i < THREAD_NUM; i++) {
735         threadsout[i] = std::thread(GetHandleThreadDataTime,
736             std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
737     }
738 
739     for (unsigned int i = 0; i < THREAD_NUM; i++) {
740         threadsin[i] = std::thread(PutHandleThreadDataTime,
741             std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
742     }
743 
744     std::this_thread::sleep_for(std::chrono::seconds(3));
745 
746     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
747     CheckQueueStatus(demoDatas);
748 
749     ThreadsJoin(threadsout);
750     ThreadsJoin(threadsin);
751 
752     while (!DemoThreadData::shareQueue.IsEmpty()) {
753         demoDatas[0].Get();
754     }
755 }
756 
757 /*
758  * @tc.name: testMutilthreadConcurrentGetAndPopInfullqueue001
759  * @tc.desc: Multi-threaded put() and Multi-threaded get() on the full queue.
760  * When all threads are waiting to reach a certain
761  * time-point, everyone run concurrently to see the status of the queue and the state of the thread.
762  */
763 HWTEST(AudioUtilsUnitTest, testMutilthreadConcurrentGetAndPopInfullqueue001, TestSize.Level0)
764 {
765     // 1. prepare
766     std::thread threadsout[THREAD_NUM];
767     std::array<DemoThreadData, THREAD_NUM> demoDatas;
768     demoDatas.fill(DemoThreadData());
769 
770     std::thread threadsin[THREAD_NUM];
771 
772     using std::chrono::system_clock;
773 
774     std::time_t timeT = GetTimeAddTwoSeconds();
775     ASSERT_TRUE(DemoThreadData::shareQueue.IsEmpty());
776     int t = 1;
777     for (unsigned int i = 0; i < QUEUE_SLOTS; i++) {
778         DemoThreadData::shareQueue.Push(t);
779     }
780     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
781     // 2. start thread put in not full queue
782     for (unsigned int i = 0; i < THREAD_NUM; i++) {
783         threadsin[i] = std::thread(PutHandleThreadDataTime,
784             std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
785     }
786 
787     for (unsigned int i = 0; i < THREAD_NUM; i++) {
788         threadsout[i] = std::thread(GetHandleThreadDataTime,
789             std::ref(demoDatas[i]), i, system_clock::from_time_t(timeT));
790     }
791 
792     std::this_thread::sleep_for(std::chrono::seconds(3));
793 
794     ASSERT_TRUE(DemoThreadData::shareQueue.IsFull());
795     CheckQueueStatus(demoDatas);
796 
797     ThreadsJoin(threadsout);
798     ThreadsJoin(threadsin);
799 
800     while (!DemoThreadData::shareQueue.IsEmpty()) {
801         demoDatas[0].Get();
802     }
803 }
804 } // namespace AudioStandard
805 } // namespace OHOS