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