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