• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <unistd.h>
18 
19 #include <hwext/gtest-ext.h>
20 #include <hwext/gtest-tag.h>
21 #include "logging.h"
22 #include "profiler_data_repeater.h"
23 
24 using namespace testing::ext;
25 
26 namespace {
27 class ProfilerDataRepeaterTest : public ::testing::Test {
28 protected:
SetUpTestCase()29     static void SetUpTestCase() {}
TearDownTestCase()30     static void TearDownTestCase() {}
31 
SetUp()32     void SetUp() override {}
TearDown()33     void TearDown() override {}
34 };
35 
36 /**
37  * @tc.name: server
38  * @tc.desc: put plugin data.
39  * @tc.type: FUNC
40  */
41 HWTEST_F(ProfilerDataRepeaterTest, PutPluginData, TestSize.Level1)
42 {
43     const int bufferSize = 10;
44     auto dataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
45     ASSERT_NE(dataRepeater, nullptr);
46 
47     for (int i = 0; i < bufferSize; i++) {
48         auto data = std::make_shared<ProfilerPluginData>();
49         dataRepeater->PutPluginData(data);
50         EXPECT_EQ(dataRepeater->Size(), i + 1);
51     }
52 }
53 
54 /**
55  * @tc.name: server
56  * @tc.desc: take plugin data.
57  * @tc.type: FUNC
58  */
59 HWTEST_F(ProfilerDataRepeaterTest, TakePluginData, TestSize.Level1)
60 {
61     const int bufferSize = 10;
62     const int itemCounts = 10000;
63     auto inDataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
64     ASSERT_NE(inDataRepeater, nullptr);
65 
66     auto outDataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
67     ASSERT_NE(outDataRepeater, nullptr);
68 
__anon7a5d0c010202(int x) 69     auto f = [](int x) { return 2 * x + 1; };
70 
__anon7a5d0c010302() 71     std::thread worker([&]() {
72         for (int i = 0; i < itemCounts; i++) {
73             auto itemX = inDataRepeater->TakePluginData();
74 
75             // compute in worker thread
76             int x = itemX ? std::stoi(itemX->data()) : 0;
77             int y = f(x);
78 
79             auto itemY = std::make_shared<ProfilerPluginData>();
80             itemY->set_data(std::to_string(y));
81             outDataRepeater->PutPluginData(itemY);
82         }
83     });
84 
85     for (int i = 0; i < itemCounts; i++) {
86         int x0 = i;
87         auto itemX = std::make_shared<ProfilerPluginData>();
88         itemX->set_data(std::to_string(x0));
89         inDataRepeater->PutPluginData(itemX);
90 
91         auto itemY = outDataRepeater->TakePluginData();
92         int y = itemY ? std::stoi(itemY->data()) : 0;
93 
94         // redo compute in main thread
95         int y0 = f(x0);
96 
97         // check results
98         EXPECT_EQ(y, y0);
99     }
100     worker.join();
101 }
102 
103 /**
104  * @tc.name: server
105  * @tc.desc: take plugin profiler data.
106  * @tc.type: FUNC
107  */
108 HWTEST_F(ProfilerDataRepeaterTest, TakePluginDataVec, TestSize.Level1)
109 {
110     const int itemCounts = 10000;
111     const int bufferSize = itemCounts;
112     auto inDataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
113     ASSERT_NE(inDataRepeater, nullptr);
114 
115     auto outDataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
116     ASSERT_NE(outDataRepeater, nullptr);
117 
__anon7a5d0c010402(int x) 118     auto f = [](int x) { return 2 * x + 1; };
__anon7a5d0c010502() 119     std::thread worker([&]() {
120         for (int i = 0; i < itemCounts; i++) {
121             auto xData = inDataRepeater->TakePluginData();
122 
123             // compute in worker thread
124             int x = xData ? std::stoi(xData->data()) : 0;
125             int y = f(x);
126 
127             auto yData = std::make_shared<ProfilerPluginData>();
128             yData->set_data(std::to_string(y));
129             outDataRepeater->PutPluginData(yData);
130         }
131     });
132 
133     std::vector<int> yVec;
134     for (int i = 0; i < itemCounts; i++) {
135         int x0 = i;
136         auto xData = std::make_shared<ProfilerPluginData>();
137         xData->set_data(std::to_string(x0));
138         inDataRepeater->PutPluginData(xData);
139 
140         int y0 = f(x0);
141         yVec.push_back(y0);
142     }
143     worker.join();
144 
145     std::vector<ProfilerPluginDataPtr> pluginDataVec;
146     auto count = outDataRepeater->TakePluginData(pluginDataVec);
147     EXPECT_EQ(count, yVec.size());
148 
149     for (size_t i = 0; i < pluginDataVec.size(); i++) {
150         auto yData = pluginDataVec[i];
151         int y = yData ? std::stoi(yData->data()) : 0;
152         EXPECT_EQ(y, yVec[i]);
153     }
154 }
155 
156 /**
157  * @tc.name: server
158  * @tc.desc: close plugin profiler data.
159  * @tc.type: FUNC
160  */
161 HWTEST_F(ProfilerDataRepeaterTest, Close, TestSize.Level1)
162 {
163     const int bufferSize = 10;
164     auto dataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
165     ASSERT_NE(dataRepeater, nullptr);
166 
167     dataRepeater->Close();
168 }
169 
170 /**
171  * @tc.name: server
172  * @tc.desc: reset plugin profiler data.
173  * @tc.type: FUNC
174  */
175 HWTEST_F(ProfilerDataRepeaterTest, Reset, TestSize.Level1)
176 {
177     const int bufferSize = 10;
178     auto dataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
179     ASSERT_NE(dataRepeater, nullptr);
180 
181     dataRepeater->Reset();
182 }
183 
184 /**
185  * @tc.name: server
186  * @tc.desc: close plugin profiler data.
187  * @tc.type: FUNC
188  */
189 HWTEST_F(ProfilerDataRepeaterTest, CloseWithFastProducer, TestSize.Level1)
190 {
191     const int bufferSize = 10;
192     const int numProducts = 20;
193     auto dataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
194     ASSERT_NE(dataRepeater, nullptr);
195 
__anon7a5d0c010602() 196     std::thread producer([=]() {
197         for (int i = 0; i < numProducts; i++) {
198             auto data = std::make_shared<ProfilerPluginData>();
199             if (!dataRepeater->PutPluginData(data)) {
200                 HILOG_DEBUG(LOG_CORE, "put data %d FAILED!", i);
201                 break;
202             }
203         }
204     });
205 
206     const int consumeDelayUs = 50 * 1000;
__anon7a5d0c010702() 207     std::thread consumer([=]() {
208         for (int i = 0; i < numProducts; i++) {
209             auto data = dataRepeater->TakePluginData();
210             if (!data) {
211                 HILOG_DEBUG(LOG_CORE, "get data %d FAILED!", i);
212                 break;
213             }
214             usleep(consumeDelayUs);
215         }
216     });
217 
218     usleep(consumeDelayUs * 3);
219     dataRepeater->Close();
220     producer.join();
221     consumer.join();
222 }
223 } // namespace