1 /*
2 * Copyright (c) 2022 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 #include <cstring>
16 #include <dlfcn.h>
17 #include <fcntl.h>
18 #include <hwext/gtest-ext.h>
19 #include <hwext/gtest-tag.h>
20 #include <cinttypes>
21 #include <cstdio>
22 #include <ctime>
23 #include <unistd.h>
24
25 #include "hisysevent_plugin.h"
26 #include "plugin_module_api.h"
27
28 using namespace testing::ext;
29
30 namespace {
31 #if defined(__LP64__)
32 const std::string DEFAULT_TEST_PATH("/system/lib64/");
33 #else
34 const std::string DEFAULT_TEST_PATH("/system/lib/");
35 #endif
36 const int US_PER_S = 1000000;
37 const int DEFAULT_WAIT = 5;
38
39 std::atomic<uint64_t> g_testId(1);
40
41 std::vector<HisyseventInfo> g_proto;
42
43 class HisyseventPluginTest : public ::testing::Test {
44 public:
SetUpTestCase()45 static void SetUpTestCase() {};
TearDownTestCase()46 static void TearDownTestCase() {};
47
SetUp()48 void SetUp() {}
TearDown()49 void TearDown() {}
50 };
51
WriteFunc(WriterStruct * writer,const void * data,size_t size)52 long WriteFunc(WriterStruct* writer, const void* data, size_t size)
53 {
54 if (writer == nullptr || data == nullptr || size <= 0) {
55 return -1;
56 }
57
58 HisyseventInfo info;
59 if (info.ParseFromArray(data, size) <= 0) {
60 return -1;
61 }
62 g_proto.push_back(info);
63 return 0;
64 }
65
FlushFunc(WriterStruct * writer)66 bool FlushFunc(WriterStruct* writer)
67 {
68 if (writer == nullptr) {
69 return false;
70 }
71 return true;
72 }
73
PluginStart(HisyseventPlugin & plugin,HisyseventConfig & config)74 bool PluginStart(HisyseventPlugin& plugin, HisyseventConfig& config)
75 {
76 // serialize
77 int size = config.ByteSizeLong();
78 std::vector<uint8_t> configData(size);
79 int ret = config.SerializeToArray(configData.data(), configData.size());
80 CHECK_TRUE(ret > 0, false, "HisyseventPluginTest: SerializeToArray fail!!!");
81 HILOG_INFO(LOG_CORE, "HisyseventPluginTest: SerializeToArray success");
82
83 // start
84 ret = plugin.Start(configData.data(), configData.size());
85 CHECK_TRUE(ret == 0, false, "HisyseventPluginTest: start plugin fail!!!");
86 HILOG_INFO(LOG_CORE, "HisyseventPluginTest: Start success");
87
88 return true;
89 }
90
91 /**
92 * @tc.name: hisysevent plugin
93 * @tc.desc: Test default cmd
94 * @tc.type: FUNC
95 * @tc.require: issueI5UGTK
96 */
97 HWTEST_F(HisyseventPluginTest, TestDefaultCmd, TestSize.Level1)
98 {
99 HisyseventConfig config;
100 HisyseventPlugin plugin;
101 WriterStruct writer = {WriteFunc, FlushFunc};
102
103 g_proto.erase(g_proto.begin(), g_proto.end());
104 // set config
105 config.set_msg("Hisysevent Config.");
106
107 // test plugin process
108 plugin.SetWriter(&writer);
109 EXPECT_TRUE(PluginStart(plugin, config));
110 usleep(US_PER_S * DEFAULT_WAIT); // 5s
111 EXPECT_EQ(plugin.Stop(), 0);
112
113 // test proto data
114 int protoSize = g_proto.size();
115 EXPECT_TRUE(protoSize >= 0);
116 g_testId = 1;
117 for (int i = 0; i < protoSize; i++) {
118 HisyseventInfo info = g_proto[i];
119 for (int j = 0; j < info.info_size(); j++) {
120 EXPECT_EQ(info.info(j).id(), g_testId);
121 g_testId++;
122 }
123 }
124 }
125
126 /**
127 * @tc.name: hisysevent plugin
128 * @tc.desc: Framework test
129 * @tc.type: FUNC
130 * @tc.require: issueI5UGTK
131 */
132 HWTEST_F(HisyseventPluginTest, TestFramework, TestSize.Level1)
133 {
134 std::string path = DEFAULT_TEST_PATH + std::string("libhisyseventplugin.z.so");
135 void* handle = dlopen(path.c_str(), RTLD_LAZY);
136 EXPECT_NE(handle, nullptr);
137 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
138 EXPECT_NE(plugin, nullptr);
139 EXPECT_STREQ(plugin->name, "hisysevent-plugin");
140
141 g_testId = 1;
142 g_proto.erase(g_proto.begin(), g_proto.end());
143
144 // set config
145 HisyseventConfig config;
146 config.set_msg("Hisysevent Config.");
147 int size = config.ByteSizeLong();
148 ASSERT_GT(size, 0);
149 std::vector<uint8_t> configData(size);
150 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
151
152 // test framework process
153 WriterStruct writer = {WriteFunc, FlushFunc};
154 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
155 EXPECT_EQ(plugin->callbacks->onRegisterWriterStruct(&writer), 0);
156 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
157 usleep(US_PER_S * DEFAULT_WAIT); // 5s
158 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
159
160 // test proto data
161 int protoSize = g_proto.size();
162 EXPECT_TRUE(protoSize >= 0);
163 g_testId = 1;
164 for (int i = 0; i < protoSize; i++) {
165 HisyseventInfo info = g_proto[i];
166 for (int j = 0; j < info.info_size(); j++) {
167 EXPECT_EQ(info.info(j).id(), g_testId);
168 g_testId++;
169 }
170 }
171 }
172
173 /**
174 * @tc.name: hisysevent plugin
175 * @tc.desc: start fail test
176 * @tc.type: FUNC
177 * @tc.require: issueI5UGTK
178 */
179 HWTEST_F(HisyseventPluginTest, TestStartFail, TestSize.Level1)
180 {
181 HisyseventConfig config;
182 HisyseventPlugin plugin;
183 WriterStruct writer = {WriteFunc, FlushFunc};
184
185 g_testId = 1;
186 g_proto.erase(g_proto.begin(), g_proto.end());
187 // set config
188 config.set_msg("H");
189
190 // test plugin process
191 plugin.SetWriter(&writer);
192
193 // serialize
194 int size = config.ByteSizeLong();
195 ASSERT_GT(size, 0);
196 std::vector<uint8_t> configData(size);
197 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
198
199 // start
200 EXPECT_EQ(plugin.Start(configData.data(), 0), 0);
201 usleep(US_PER_S * DEFAULT_WAIT); // 5s
202 plugin.Stop();
203
204 EXPECT_NE(plugin.Start(nullptr, configData.size()), 0);
205 EXPECT_EQ(plugin.Start(configData.data(), configData.size()), 0);
206 usleep(US_PER_S * DEFAULT_WAIT); // 5s
207 plugin.Stop();
208 }
209
210 /**
211 * @tc.name: hisysevent plugin
212 * @tc.desc: customer popen test
213 * @tc.type: FUNC
214 */
215 HWTEST_F(HisyseventPluginTest, TestCustomPopenClose, TestSize.Level1)
216 {
217 HisyseventConfig config;
218 HisyseventPlugin plugin;
219 WriterStruct writer = {WriteFunc, FlushFunc};
220 plugin.SetWriter(&writer);
221 // set config
222 config.set_msg("H");
223 int size = config.ByteSizeLong();
224 std::vector<uint8_t> configData(size);
225 config.SerializeToArray(configData.data(), configData.size());
226 EXPECT_EQ(plugin.Start(configData.data(), configData.size()), 0);
227 EXPECT_EQ(plugin.GetFullCmd(), "/bin/hisysevent hisysevent -rd");
228 std::vector<std::string> fullCmdTest;
229 fullCmdTest.push_back("/bin/hisysevent");
230 fullCmdTest.push_back("hisysevent");
231 fullCmdTest.push_back("-rd");
232 volatile pid_t childPid = -1;
233 int pipeFds[2] = {-1, -1};
234 FILE* fpr = COMMON::CustomPopen(fullCmdTest, nullptr, pipeFds, childPid, true);
235 EXPECT_EQ(fpr, nullptr);
236 EXPECT_EQ(COMMON::CustomPclose(fpr, pipeFds, childPid, true), -1);
237
238 childPid = -1;
239 pipeFds[0] = -1;
240 pipeFds[1] = -1;
241 FILE* fpw = COMMON::CustomPopen(fullCmdTest, "w", pipeFds, childPid);
242 EXPECT_NE(fpw, nullptr);
243 EXPECT_EQ(COMMON::CustomPclose(fpw, pipeFds, childPid, true), -1);
244 usleep(US_PER_S * DEFAULT_WAIT); // 5s
245 plugin.Stop();
246 }
247 }