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 <atomic> 17 #include <chrono> 18 #include <gtest/gtest.h> 19 #include <thread> 20 21 #include "utils/workerQueue.h" 22 23 namespace panda::test { 24 25 class WorkerQueueTest : public ::testing::Test { 26 protected: SetUp()27 void SetUp() override {} TearDown()28 void TearDown() override {} 29 }; 30 31 // Concrete implementation of WorkerQueue for testing 32 class TestWorkerQueue : public WorkerQueue { 33 public: TestWorkerQueue(size_t threadCount)34 explicit TestWorkerQueue(size_t threadCount) : WorkerQueue(threadCount) {} Schedule()35 void Schedule() override {} AddJob(WorkerJob * job)36 void AddJob(WorkerJob *job) 37 { 38 jobs_.push_back(job); 39 jobsCount_++; 40 } 41 }; 42 43 // Test job that counts executions 44 class CountingJob : public WorkerJob { 45 public: CountingJob(std::atomic<int> & counter)46 explicit CountingJob(std::atomic<int>& counter) : counter_(counter) {} Run()47 bool Run() override 48 { 49 counter_++; 50 return true; 51 } 52 private: 53 std::atomic<int>& counter_; 54 }; 55 56 // Test job that waits for signal 57 class WaitingJob : public WorkerJob { 58 public: WaitingJob()59 explicit WaitingJob() {} Run()60 bool Run() override 61 { 62 std::this_thread::sleep_for(std::chrono::milliseconds(1)); 63 return true; 64 } 65 }; 66 67 HWTEST_F(WorkerQueueTest, BasicJobExecution, testing::ext::TestSize.Level0) 68 { 69 std::atomic<int> counter(0); 70 { 71 TestWorkerQueue *queue = new TestWorkerQueue(2); 72 auto* job = new CountingJob(counter); 73 queue->AddJob(job); 74 queue->Consume(); 75 queue->Wait(); 76 } 77 EXPECT_EQ(counter, 1); 78 } 79 80 HWTEST_F(WorkerQueueTest, MultipleJobs, testing::ext::TestSize.Level0) 81 { 82 std::atomic<int> counter(0); 83 { 84 TestWorkerQueue *queue = new TestWorkerQueue(2); 85 for (int i = 0; i < 5; i++) { 86 queue->AddJob(new CountingJob(counter)); 87 } 88 queue->Consume(); 89 queue->Wait(); 90 delete queue; 91 queue = nullptr; 92 } 93 EXPECT_EQ(counter, 5); 94 } 95 96 HWTEST_F(WorkerQueueTest, JobDependencies, testing::ext::TestSize.Level0) 97 { 98 std::atomic<int> counter(0); 99 { 100 TestWorkerQueue *queue = new TestWorkerQueue(2); 101 102 auto* job1 = new CountingJob(counter); 103 auto* job2 = new CountingJob(counter); 104 job2->DependsOn(job1); 105 106 queue->AddJob(job1); 107 queue->AddJob(job2); 108 queue->Consume(); 109 queue->Wait(); 110 delete queue; 111 queue = nullptr; 112 } 113 EXPECT_EQ(counter, 2); 114 } 115 116 HWTEST_F(WorkerQueueTest, JobSignal, testing::ext::TestSize.Level0) 117 { 118 std::atomic<int> counter(0); 119 { 120 TestWorkerQueue *queue = new TestWorkerQueue(1); 121 122 auto* job1 = new CountingJob(counter); 123 auto* job2 = new CountingJob(counter); 124 job2->DependsOn(job1); 125 126 queue->AddJob(job1); 127 queue->AddJob(job2); 128 129 job1->Signal(); 130 queue->Consume(); 131 queue->Wait(); 132 delete queue; 133 queue = nullptr; 134 } 135 EXPECT_EQ(counter, 2); 136 } 137 138 HWTEST_F(WorkerQueueTest, ConcurrentJobs, testing::ext::TestSize.Level0) 139 { 140 std::atomic<int> counter(0); 141 { 142 TestWorkerQueue *queue = new TestWorkerQueue(2); 143 144 // Add a waiting job 145 queue->AddJob(new WaitingJob()); 146 147 // Add some counting jobs 148 for (int i = 0; i < 3; i++) { 149 queue->AddJob(new CountingJob(counter)); 150 } 151 152 queue->Consume(); 153 queue->Wait(); 154 delete queue; 155 queue = nullptr; 156 } 157 EXPECT_EQ(counter, 3); 158 } 159 } // namespace panda::test 160