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
99
100 #if defined(__LP64__)
PluginGpuInfoStub(GpuDataPlugin & gpuPlugin,WriterStruct * writer)101 bool PluginGpuInfoStub(GpuDataPlugin& gpuPlugin, WriterStruct *writer)
102 {
103 GpuConfig protoConfig;
104 std::vector<uint8_t> configData(protoConfig.ByteSizeLong());
105 int ret = protoConfig.SerializeToArray(configData.data(), configData.size());
106 if (ret < 0) {
107 return false;
108 }
109 gpuPlugin.SetWriter(writer);
110 // start
111 ret = gpuPlugin.Start(configData.data(), configData.size());
112 if (ret < 0) {
113 return false;
114 }
115 return true;
116 }
117 #endif
118
119 /**
120 * @tc.name: gpu plugin
121 * @tc.desc: Test whether the path exists.
122 * @tc.type: FUNC
123 */
124 HWTEST_F(GpuDataPluginTest, TestPath, TestSize.Level1)
125 {
126 g_path = GetFullPath(DEFAULT_TEST_PATH);
127 g_testPath = g_path;
128 EXPECT_NE("", g_path);
129 g_path += "/gpustat1.txt";
130 }
131
132 /**
133 * @tc.name: gpu plugin
134 * @tc.desc: gpu information test for specific path.
135 * @tc.type: FUNC
136 */
137 HWTEST_F(GpuDataPluginTest, TestPlugin, TestSize.Level1)
138 {
139 #if defined(__LP64__)
140 GpuDataPlugin gpuPlugin;
141 WriterStruct writer = {WriteFunc, FlushFunc};
142 EXPECT_TRUE(PluginGpuInfoStub(gpuPlugin, &writer));
143 sleep(SLEEP_TIME);
144 EXPECT_EQ(gpuPlugin.Stop(), 0);
145 std::vector<std::pair<uint64_t, int>> gpuDataVect = {{1000, 32}, {1001, 43}, {1002, 50}};
146 gpuPlugin.resultWriter_->isProtobufSerialize = true;
147 gpuPlugin.FlushGpuData(gpuDataVect);
148 EXPECT_GT(gpuPlugin.buffer_.size(), 0);
149 #endif
150 }
151
152 /**
153 * @tc.name: gpu plugin
154 * @tc.desc: gpu information test read gpu data
155 * @tc.type: FUNC
156 */
157 HWTEST_F(GpuDataPluginTest, TestReadGpuData, TestSize.Level1)
158 {
159 #if defined(__LP64__)
160 GpuDataPlugin gpuPlugin;
161 WriterStruct writer = {WriteFunc, FlushFunc};
162 gpuPlugin.SetWriter(&writer);
163 gpuPlugin.running_ = true;
164 gpuPlugin.resultWriter_->isProtobufSerialize = true;
165 gpuPlugin.file_.open(g_path);
166 EXPECT_EQ(gpuPlugin.ReadFile(), EXPECT_VAL);
167 gpuPlugin.file_.close();
168 EXPECT_TRUE(PluginGpuInfoStub(gpuPlugin, &writer));
169 sleep(SLEEP_TIME);
170 EXPECT_GT(gpuPlugin.buffer_.size(), 0);
171 EXPECT_EQ(gpuPlugin.Stop(), 0);
172 #endif
173 }
174
175 /**
176 * @tc.name: gpu plugin
177 * @tc.desc: gpu plugin registration test.
178 * @tc.type: FUNC
179 */
180 HWTEST_F(GpuDataPluginTest, TestPluginRegister, TestSize.Level1)
181 {
182 #if defined(__LP64__)
183 void* handle = dlopen(SO_PATH.c_str(), RTLD_LAZY);
184 ASSERT_NE(handle, nullptr);
185 PluginModuleStruct* gpuPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
186 ASSERT_NE(gpuPlugin, nullptr);
187 EXPECT_STREQ(gpuPlugin->name, "gpu-plugin");
188 EXPECT_EQ(gpuPlugin->resultBufferSizeHint, BUF_SIZE);
189
190 // Serialize config
191 GpuConfig protoConfig;
192 int configLength = protoConfig.ByteSizeLong();
193 ASSERT_EQ(configLength, 0);
194 std::vector<uint8_t> configBuffer(configLength);
195 EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer.data(), configLength));
196 // run plugin
197 WriterStruct writer = {WriteFunc, FlushFunc};
198 std::vector<uint8_t> dataBuffer(gpuPlugin->resultBufferSizeHint);
199 EXPECT_EQ(gpuPlugin->callbacks->onRegisterWriterStruct(&writer), 0);
200 EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength), RET_SUCC);
201 EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStop(), RET_SUCC);
202
203 // 反序列化失败导致的start失败
204 configLength++;
205 std::vector<uint8_t> configBuffer2(configLength);
206 EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer2.data(), configLength));
207 EXPECT_EQ(gpuPlugin->callbacks->onPluginSessionStart(configBuffer2.data(), configLength+1), RET_FAIL);
208 #endif
209 }
210
211
212 } // namespace