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