1/*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. 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 <thread>
18
19#include "common.h"
20#include "plugin_module.h"
21#include "common_types.pb.h"
22
23using namespace testing::ext;
24
25namespace {
26const std::string SUCCESS_PLUGIN_NAME = "libmemdataplugin.z.so";
27constexpr size_t READ_BUFFER_SIZE = 4 * 1024 * 1024;
28#if defined(__LP64__)
29std::string g_testPluginDir("/system/lib64/");
30#else
31std::string g_testPluginDir("/system/lib/");
32#endif
33
34class PluginModuleTest : public ::testing::Test {
35protected:
36    static constexpr auto TEMP_DELAY = std::chrono::milliseconds(20);
37    static void SetUpTestCase()
38    {
39#if defined(__i386__) || defined(__x86_64__)
40        char pluginDir[PATH_MAX + 1] = {0};
41        if (readlink("/proc/self/exe", pluginDir, PATH_MAX) > 0) {
42            char* pos = strrchr(pluginDir, '/');
43            if (pos != nullptr) {
44                *(pos++) = '\0';
45                g_testPluginDir = pluginDir;
46            }
47        }
48#endif
49
50        std::this_thread::sleep_for(TEMP_DELAY);
51    }
52
53    static void TearDownTestCase() {}
54};
55
56/**
57 * @tc.name: plugin
58 * @tc.desc: pluginmodule normal test.
59 * @tc.type: FUNC
60 */
61HWTEST_F(PluginModuleTest, PluginModuleNormal, TestSize.Level1)
62{
63    std::string pluginPath = g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME;
64    PluginModuleInfo info;
65    auto plugin = std::make_shared<PluginModule>(pluginPath);
66    EXPECT_TRUE(plugin->Load());
67    EXPECT_TRUE(plugin->BindFunctions());
68    EXPECT_TRUE(plugin->GetInfo(info));
69    EXPECT_TRUE(plugin->IsLoaded());
70
71    uint32_t size = 0;
72    plugin->GetBufferSizeHint(size);
73    EXPECT_EQ(size, READ_BUFFER_SIZE);
74    std::string name;
75    EXPECT_TRUE(plugin->GetPluginName(name));
76    EXPECT_STREQ(name.c_str(), "memory-plugin");
77
78    const uint8_t configData[] = {74, 1, 10};
79    ProfilerPluginConfig config;
80    config.set_name(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME);
81    config.set_config_data((const void*)configData, 3);
82    config.set_sample_interval(1000);
83    plugin->SetConfigData(config.config_data());
84
85    std::string cfgData = plugin->GetConfigData();
86    EXPECT_EQ(cfgData.c_str()[0], 74);
87    EXPECT_EQ(cfgData.c_str()[1], 1);
88    EXPECT_EQ(cfgData.c_str()[2], 10);
89
90    std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
91    EXPECT_NE(buffer, nullptr);
92    plugin->SetClockId(COMMON::GetClockId("realtime"));
93    (void)plugin->GetClockId();
94    EXPECT_FALSE(plugin->GetPath().empty());
95    EXPECT_TRUE(plugin->StartSession(reinterpret_cast<const uint8_t*>(cfgData.c_str()), cfgData.size()));
96    EXPECT_FALSE(plugin->GetStandaloneFileData());
97    EXPECT_TRUE(plugin->IsRunning());
98    EXPECT_NE(plugin->ReportResult(buffer.get(), size), 0);
99    EXPECT_TRUE(plugin->StopSession());
100
101    EXPECT_TRUE(plugin->StartSession(nullptr, 0));
102    EXPECT_EQ(plugin->ReportResult(buffer.get(), size), 0);
103    EXPECT_TRUE(plugin->StopSession());
104
105    EXPECT_TRUE(plugin->StartSession(reinterpret_cast<const uint8_t*>(cfgData.c_str()), cfgData.size()));
106    EXPECT_NE(plugin->ReportResult(nullptr, 0), 0);
107    EXPECT_NE(plugin->ReportResult(nullptr, 0), -1);
108    EXPECT_TRUE(plugin->StopSession());
109
110    EXPECT_TRUE(plugin->StartSession(nullptr, 0));
111    EXPECT_EQ(plugin->ReportResult(nullptr, 0), 0);
112    EXPECT_TRUE(plugin->StopSession());
113
114    EXPECT_TRUE(plugin->Unload());
115    EXPECT_FALSE(plugin->IsLoaded());
116}
117
118/**
119 * @tc.name: plugin
120 * @tc.desc: pluginmodule abnormal test.
121 * @tc.type: FUNC
122 */
123HWTEST_F(PluginModuleTest, PluginModuleAbnormal, TestSize.Level1)
124{
125    std::string pluginPath = "invalid.z.so";
126    PluginModuleInfo info;
127    auto plugin = std::make_shared<PluginModule>(pluginPath);
128    EXPECT_FALSE(plugin->Load());
129    EXPECT_FALSE(plugin->BindFunctions());
130    EXPECT_FALSE(plugin->GetInfo(info));
131    EXPECT_FALSE(plugin->IsLoaded());
132
133    uint32_t size = 0;
134    plugin->GetBufferSizeHint(size);
135    EXPECT_EQ(size, 0);
136
137    std::string name;
138    EXPECT_FALSE(plugin->GetPluginName(name));
139    EXPECT_STREQ(name.c_str(), "");
140
141    std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
142    EXPECT_FALSE(plugin->StartSession(nullptr, 0));
143    EXPECT_FALSE(plugin->GetStandaloneFileData());
144    EXPECT_FALSE(plugin->IsRunning());
145    EXPECT_EQ(plugin->ReportResult(buffer.get(), size), -1);
146    EXPECT_FALSE(plugin->StopSession());
147    EXPECT_FALSE(plugin->Unload());
148}
149
150/**
151 * @tc.name: plugin
152 * @tc.desc: pluginmodule  test.
153 * @tc.type: FUNC
154 */
155HWTEST_F(PluginModuleTest, PluginModuleTest, TestSize.Level1)
156{
157    std::string pluginPath = g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME;
158    PluginModuleInfo info;
159    auto plugin = std::make_shared<PluginModule>(pluginPath);
160
161    std::string outFileName;
162    EXPECT_FALSE(plugin->GetOutFileName(outFileName));
163    std::string pluginVersion;
164    EXPECT_FALSE(plugin->GetPluginVersion(pluginVersion));
165    EXPECT_EQ(plugin->GetWriter(), nullptr);
166
167    EXPECT_TRUE(plugin->Load());
168    EXPECT_TRUE(plugin->BindFunctions());
169    EXPECT_TRUE(plugin->GetInfo(info));
170    EXPECT_TRUE(plugin->IsLoaded());
171    EXPECT_TRUE(plugin->GetOutFileName(outFileName));
172    EXPECT_EQ(outFileName, "");
173    EXPECT_TRUE(plugin->GetPluginVersion(pluginVersion));
174    EXPECT_EQ(pluginVersion, "1.02");
175    BufferWriterPtr writer;
176    EXPECT_TRUE(plugin->RegisterWriter(writer));
177}
178} // namespace
179