• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstring>
17 #include <dlfcn.h>
18 #include <fcntl.h>
19 #include <hwext/gtest-ext.h>
20 #include <hwext/gtest-tag.h>
21 #include <cinttypes>
22 #include <cstdio>
23 #include <ctime>
24 #include <unistd.h>
25 
26 #include "hiperf_module.h"
27 #include "hiperf_plugin_config.pb.h"
28 #include "plugin_module_api.h"
29 
30 using namespace testing::ext;
31 
32 namespace {
33 #if defined(__arm__)
34 const std::string DEFAULT_LIB_PATH("/system/lib/libhiperfplugin.z.so");
35 #elif defined(__aarch64__)
36 const std::string DEFAULT_LIB_PATH("/system/lib64/libhiperfplugin.z.so");
37 #endif
38 const std::string DEFAULT_OUT_PATH("/data/local/tmp/perf.data");
39 const int DEFAULT_WAIT = 2;
40 
41 class HiperfPluginUnittest : public ::testing::Test {
42 public:
SetUpTestCase()43     static void SetUpTestCase() {};
TearDownTestCase()44     static void TearDownTestCase() {};
45 
SetUp()46     void SetUp() {}
TearDown()47     void TearDown() {}
48 };
49 
WriteFunc(WriterStruct * writer,const void * data,size_t size)50 long WriteFunc(WriterStruct* writer, const void* data, size_t size)
51 {
52     if (writer == nullptr || data == nullptr || size <= 0) {
53         return -1;
54     }
55 
56     return 0;
57 }
58 
FlushFunc(WriterStruct * writer)59 bool FlushFunc(WriterStruct* writer)
60 {
61     if (writer == nullptr) {
62         return false;
63     }
64     return true;
65 }
66 
67 /**
68  * @tc.name: hiperf plugin
69  * @tc.desc: Test framework
70  * @tc.type: FUNC
71  */
72 HWTEST_F(HiperfPluginUnittest, TestFramework, TestSize.Level1)
73 {
74     void* handle = dlopen(DEFAULT_LIB_PATH.c_str(), RTLD_LAZY);
75     EXPECT_NE(handle, nullptr);
76     PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
77     EXPECT_NE(plugin, nullptr);
78     EXPECT_STREQ(plugin->name, "hiperf-plugin");
79 
80     // set config
81     HiperfPluginConfig config;
82     config.set_outfile_name(DEFAULT_OUT_PATH);
83     config.set_record_args("-a -c 0 -d 2");
84     int size = config.ByteSizeLong();
85     ASSERT_GT(size, 0);
86     std::vector<uint8_t> configData(size);
87     ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
88 
89     // test framework process
90     WriterStruct writer = {WriteFunc, FlushFunc};
91     std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
92     EXPECT_EQ(plugin->callbacks->onRegisterWriterStruct(&writer), 0);
93     EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
94     EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
95 
96     dlclose(handle);
97 }
98 
99 HWTEST_F(HiperfPluginUnittest, TestNoRecordTarget, TestSize.Level1)
100 {
101     HiperfPluginConfig config;
102     config.set_outfile_name(DEFAULT_OUT_PATH);
103     std::vector<uint8_t> buffer(config.ByteSizeLong());
104     ASSERT_TRUE(config.SerializeToArray(buffer.data(), buffer.size())) << "proto serialize FAILED!";
105 
106     ASSERT_NE(HiperfPluginSessionStart(buffer.data(), buffer.size()), 0) << "hiperf should return failed";
107 }
108 
109 HWTEST_F(HiperfPluginUnittest, TestRepeatOutput, TestSize.Level1)
110 {
111     HiperfPluginConfig config;
112     config.set_log_level(HiperfPluginConfig_LogLevel_MUCH);
113     config.set_outfile_name(DEFAULT_OUT_PATH); // 1: set output file
114     // 2: set output file by "-o"
115     config.set_record_args("-a -c 0 -d 2 -o /data/local/tmp/perf.data2");
116     std::vector<uint8_t> buffer(config.ByteSizeLong());
117     ASSERT_TRUE(config.SerializeToArray(buffer.data(), buffer.size())) << "proto serialize FAILED!";
118 
119     ASSERT_NE(HiperfPluginSessionStart(buffer.data(), buffer.size()), 0) << "hiperf should return failed";
120 }
121 
122 HWTEST_F(HiperfPluginUnittest, TestRepeatStart, TestSize.Level1)
123 {
124     HiperfPluginConfig config;
125     config.set_log_level(HiperfPluginConfig_LogLevel_VERBOSE);
126     config.set_outfile_name(DEFAULT_OUT_PATH);
127     config.set_record_args("-a -c 0 -d 2");
128     std::vector<uint8_t> buffer(config.ByteSizeLong());
129     ASSERT_TRUE(config.SerializeToArray(buffer.data(), buffer.size())) << "proto serialize FAILED!";
130 
131     ASSERT_EQ(HiperfPluginSessionStart(buffer.data(), buffer.size()), 0) << "hiperf should return ok";
132     // repeate to start
133     ASSERT_NE(HiperfPluginSessionStart(buffer.data(), buffer.size()), 0) << "hiperf should return failed";
134     ASSERT_EQ(HiperfPluginSessionStop(), 0) << "hiperf should return ok";
135 }
136 
137 HWTEST_F(HiperfPluginUnittest, TestStopBeforeHiperfExit, TestSize.Level1)
138 {
139     HiperfPluginConfig config;
140     config.set_log_level(HiperfPluginConfig_LogLevel_DEBUG);
141     config.set_outfile_name(DEFAULT_OUT_PATH);
142     config.set_record_args("-a -c 0 -d 20"); // hiperf will exit after 20s
143     std::vector<uint8_t> buffer(config.ByteSizeLong());
144     ASSERT_TRUE(config.SerializeToArray(buffer.data(), buffer.size())) << "proto serialize FAILED!";
145 
146     ASSERT_EQ(HiperfPluginSessionStart(buffer.data(), buffer.size()), 0) << "hiperf should return ok";
147 
148     sleep(DEFAULT_WAIT);
149     ASSERT_EQ(HiperfPluginSessionStop(), 0) << "hiperf should return ok";
150 }
151 
152 HWTEST_F(HiperfPluginUnittest, TestStopAfterHiperfExit, TestSize.Level1)
153 {
154     HiperfPluginConfig config;
155     config.set_outfile_name(DEFAULT_OUT_PATH);
156     config.set_record_args("-a -c 0 -d 1"); // hiperf will exit after 1s
157     std::vector<uint8_t> buffer(config.ByteSizeLong());
158     ASSERT_TRUE(config.SerializeToArray(buffer.data(), buffer.size())) << "proto serialize FAILED!";
159 
160     ASSERT_EQ(HiperfPluginSessionStart(buffer.data(), buffer.size()), 0) << "hiperf should return ok";
161     sleep(DEFAULT_WAIT);
162     ASSERT_EQ(HiperfPluginSessionStop(), 0) << "hiperf should return ok";
163 }
164 
CheckRecordFile(const std::string & fileName)165 void CheckRecordFile(const std::string& fileName)
166 {
167     ASSERT_EQ(access(fileName.c_str(), F_OK), 0) << "perf.data should be exist";
168 
169     std::unique_ptr<FILE, int (*)(FILE*)> fp(fopen(fileName.c_str(), "rb"), fclose);
170     ASSERT_NE(fp, nullptr);
171 
172     constexpr long perfDataHeaderLen = 13 * 8;
173     fseek(fp.get(), 0, SEEK_END);
174     ASSERT_GE(ftell(fp.get()), perfDataHeaderLen) << "perf.data should have data";
175     fseek(fp.get(), 0, SEEK_SET);
176 
177     char buff[perfDataHeaderLen] = {0};
178     long rLen = fread(buff, 1, perfDataHeaderLen, fp.get());
179     ASSERT_EQ(rLen, perfDataHeaderLen);
180     ASSERT_EQ(strncmp(buff, "PERFILE2", strlen("PERFILE2")), 0) << "perf.data magic error";
181 }
182 
183 HWTEST_F(HiperfPluginUnittest, TestCheckOutputFile, TestSize.Level1)
184 {
185     HiperfPluginConfig config;
186     config.set_outfile_name(DEFAULT_OUT_PATH);
187     config.set_record_args("-a -c 0 -d 2");
188     std::vector<uint8_t> buffer(config.ByteSizeLong());
189     ASSERT_TRUE(config.SerializeToArray(buffer.data(), buffer.size())) << "proto serialize FAILED!";
190 
191     ASSERT_EQ(HiperfPluginSessionStart(buffer.data(), buffer.size()), 0) << "hiperf should return ok";
192     sleep(DEFAULT_WAIT);
193     ASSERT_EQ(HiperfPluginSessionStop(), 0) << "hiperf should return ok";
194 
195     CheckRecordFile(DEFAULT_OUT_PATH);
196 }
197 } // namespace
198