• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. 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 <gtest/gtest.h>
17 #include <dlfcn.h>
18 #include <fstream>
19 #include "gpu_data_plugin.h"
20 #include "plugin_module_api.h"
21 
22 using namespace testing::ext;
23 
24 namespace {
25 const std::string DEFAULT_TEST_PATH = "/data/local/tmp/resource";
26 const std::string SO_PATH = "libgpudataplugin.z.so";
27 const std::string DEFAULT_BIN_PATH("/data/local/tmp/gpudataplugintest");
28 
29 std::string g_path;
30 std::string g_testPath;
31 
32 #if defined(__LP64__)
33 const unsigned long long EXPECT_VAL = 12;
34 const unsigned long long SLEEP_TIME = 2;
35 constexpr uint32_t BUF_SIZE = 4 * 1024 * 1024;
36 #endif
37 
38 struct TestVmstat {
39     int64_t pgpgin;
40     int64_t pgpgout;
41 };
42 
43 class GpuDataPluginTest : public ::testing::Test {
44 public:
SetUpTestCase()45     static void SetUpTestCase() {}
46 
TearDownTestCase()47     static void TearDownTestCase()
48     {
49         if (access(g_testPath.c_str(), F_OK) == 0) {
50             std::string str = "rm -rf " + g_testPath;
51             system(str.c_str());
52         }
53     }
54 };
55 
Getexepath()56 string Getexepath()
57 {
58     char buf[PATH_MAX] = "";
59     std::string path = "/proc/self/exe";
60     size_t rslt = readlink(path.c_str(), buf, sizeof(buf));
61     if (rslt < 0 || (rslt >= sizeof(buf))) {
62         return "";
63     }
64     buf[rslt] = '\0';
65     for (int i = rslt; i >= 0; i--) {
66         if (buf[i] == '/') {
67             buf[i + 1] = '\0';
68             break;
69         }
70     }
71     return buf;
72 }
73 
GetFullPath(std::string path)74 std::string GetFullPath(std::string path)
75 {
76     if (path.size() > 0 && path[0] != '/') {
77         return Getexepath() + path;
78     }
79     return path;
80 }
81 
WriteFunc(WriterStruct * writer,const void * data,size_t size)82 long WriteFunc(WriterStruct* writer, const void* data, size_t size)
83 {
84     if (writer == nullptr || data == nullptr || size <= 0) {
85         return -1;
86     }
87 
88     return 0;
89 }
90 
FlushFunc(WriterStruct * writer)91 bool FlushFunc(WriterStruct* writer)
92 {
93     if (writer == nullptr) {
94         return false;
95     }
96     return true;
97 }
98 
StartReportFunc(WriterStruct * writer)99 RandomWriteCtx* StartReportFunc(WriterStruct* writer)
100 {
101     return nullptr;
102 }
103 
FinishReportFunc(WriterStruct * writer,int32_t size)104 void FinishReportFunc(WriterStruct* writer, int32_t size)
105 {
106     return;
107 }
108 
109 #if defined(__LP64__)
PluginGpuInfoStub(GpuDataPlugin & gpuPlugin,WriterStruct * writer)110 bool PluginGpuInfoStub(GpuDataPlugin& gpuPlugin, WriterStruct *writer)
111 {
112     GpuConfig protoConfig;
113     std::vector<uint8_t> configData(protoConfig.ByteSizeLong());
114     int ret = protoConfig.SerializeToArray(configData.data(), configData.size());
115     if (ret < 0) {
116         return false;
117     }
118     gpuPlugin.SetWriter(writer);
119     // start
120     ret = gpuPlugin.Start(configData.data(), configData.size());
121     if (ret < 0) {
122         return false;
123     }
124     return true;
125 }
126 #endif
127 
128 /**
129  * @tc.name: gpu plugin
130  * @tc.desc: Test whether the path exists.
131  * @tc.type: FUNC
132  */
133 HWTEST_F(GpuDataPluginTest, TestPath, TestSize.Level1)
134 {
135     g_path = GetFullPath(DEFAULT_TEST_PATH);
136     g_testPath = g_path;
137     EXPECT_NE("", g_path);
138     g_path += "/gpustat1.txt";
139 }
140 
141 /**
142  * @tc.name: gpu plugin
143  * @tc.desc: gpu information test for specific path.
144  * @tc.type: FUNC
145  */
146 HWTEST_F(GpuDataPluginTest, TestPlugin, TestSize.Level1)
147 {
148 #if defined(__LP64__)
149     GpuDataPlugin gpuPlugin;
150     WriterStruct writer = {WriteFunc, FlushFunc, StartReportFunc, FinishReportFunc};
151     EXPECT_TRUE(PluginGpuInfoStub(gpuPlugin, &writer));
152     sleep(SLEEP_TIME);
153     EXPECT_EQ(gpuPlugin.Stop(), 0);
154     std::vector<std::pair<uint64_t, int>> gpuDataVect = {{1000, 32}, {1001, 43}, {1002, 50}};
155     gpuPlugin.resultWriter_->isProtobufSerialize = true;
156     gpuPlugin.FlushGpuData(gpuDataVect);
157     EXPECT_GT(gpuPlugin.buffer_.size(), 0);
158     gpuPlugin.resultWriter_->isProtobufSerialize = false;
159     gpuPlugin.FlushGpuData(gpuDataVect);
160     EXPECT_GT(gpuPlugin.GetBootTime(), 0);
161 #endif
162 }
163 
164 /**
165  * @tc.name: gpu plugin
166  * @tc.desc: gpu information test read gpu data
167  * @tc.type: FUNC
168  */
169 HWTEST_F(GpuDataPluginTest, TestReadGpuData, TestSize.Level1)
170 {
171 #if defined(__LP64__)
172     GpuDataPlugin gpuPlugin;
173     WriterStruct writer = {WriteFunc, FlushFunc};
174     gpuPlugin.SetWriter(&writer);
175     gpuPlugin.running_ = true;
176     gpuPlugin.resultWriter_->isProtobufSerialize = true;
177     gpuPlugin.file_.open(g_path);
178     EXPECT_EQ(gpuPlugin.ReadFile(), EXPECT_VAL);
179     gpuPlugin.file_.close();
180     EXPECT_TRUE(PluginGpuInfoStub(gpuPlugin, &writer));
181     sleep(SLEEP_TIME);
182     EXPECT_GT(gpuPlugin.buffer_.size(), 0);
183     EXPECT_EQ(gpuPlugin.Stop(), 0);
184 #endif
185 }
186 
187 /**
188  * @tc.name: gpu plugin
189  * @tc.desc: gpu plugin registration test.
190  * @tc.type: FUNC
191  */
192 HWTEST_F(GpuDataPluginTest, TestPluginRegister, TestSize.Level1)
193 {
194 #if defined(__LP64__)
195     void* handle = dlopen(SO_PATH.c_str(), RTLD_LAZY);
196     ASSERT_NE(handle, nullptr);
197     PluginModuleStruct* gpuPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
198     ASSERT_NE(gpuPlugin, nullptr);
199     EXPECT_STREQ(gpuPlugin->name, "gpu-plugin");
200     EXPECT_EQ(gpuPlugin->resultBufferSizeHint, BUF_SIZE);
201 
202     // Serialize config
203     GpuConfig protoConfig;
204     int configLength = protoConfig.ByteSizeLong();
205     ASSERT_EQ(configLength, 0);
206     std::vector<uint8_t> configBuffer(configLength);
207     EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer.data(), configLength));
208     // run plugin
209     WriterStruct writer = {WriteFunc, FlushFunc};
210     std::vector<uint8_t> dataBuffer(gpuPlugin->resultBufferSizeHint);
211     EXPECT_EQ(gpuPlugin->callbacks->onRegisterWriterStruct(&writer), 0);
212     EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength), RET_SUCC);
213     EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStop(), RET_SUCC);
214 
215     // 反序列化失败导致的start失败
216     configLength++;
217     std::vector<uint8_t> configBuffer2(configLength);
218     EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer2.data(), configLength));
219     EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStart(configBuffer2.data(), configLength+1), RET_FAIL);
220 #endif
221 }
222 
223 /**
224  * @tc.name: gpu plugin
225  * @tc.desc: test gpu plugin read array data
226  * @tc.type: FUNC
227  */
228 HWTEST_F(GpuDataPluginTest, TestPluginReadArrayData, TestSize.Level1)
229 {
230 #if defined(__LP64__)
231     void* handle = dlopen(SO_PATH.c_str(), RTLD_LAZY);
232     ASSERT_NE(handle, nullptr);
233     PluginModuleStruct* gpuPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
234     ASSERT_NE(gpuPlugin, nullptr);
235     EXPECT_STREQ(gpuPlugin->name, "gpu-plugin");
236     EXPECT_EQ(gpuPlugin->resultBufferSizeHint, BUF_SIZE);
237 
238     // Serialize config
239     GpuConfig protoConfig;
240     protoConfig.set_pid(11001);
241     protoConfig.set_report_gpu_data_array(true);
242     int configLength = protoConfig.ByteSizeLong();
243     ASSERT_NE(configLength, 0);
244     std::vector<uint8_t> configBuffer(configLength);
245     EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer.data(), configLength));
246     // run plugin
247     WriterStruct writer = {WriteFunc, FlushFunc};
248     std::vector<uint8_t> dataBuffer(gpuPlugin->resultBufferSizeHint);
249     EXPECT_EQ(gpuPlugin->callbacks->onRegisterWriterStruct(&writer), 0);
250     EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength), RET_SUCC);
251     EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStop(), RET_SUCC);
252 #endif
253 }
254 
255 } // namespace