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 #include "xpower_plugin.h"
16
17 #include <dlfcn.h>
18 #include <fcntl.h>
19 #include <gtest/gtest.h>
20 #include <unistd.h>
21
22 #include <cinttypes>
23 #include <cstdio>
24 #include <cstring>
25 #include <ctime>
26
27 #include "plugin_module_api.h"
28
29 using namespace testing::ext;
30
31 namespace {
32 #if defined(__LP64__)
33 const int US_PER_S = 1000000;
34 const int DEFAULT_WAIT = 9;
35 std::vector<OptimizeReport> g_protoXpower;
WriteFunc(WriterStruct* writer, const void* data, size_t size)36 long WriteFunc(WriterStruct* writer, const void* data, size_t size)
37 {
38 if (writer == nullptr || data == nullptr || size <= 0) {
39 return -1;
40 }
41
42 OptimizeReport info;
43 if (info.ParseFromArray(data, size) <= 0) {
44 return -1;
45 }
46 g_protoXpower.push_back(info);
47 return 0;
48 }
49
FlushFunc(WriterStruct* writer)50 bool FlushFunc(WriterStruct* writer)
51 {
52 if (writer == nullptr) {
53 return false;
54 }
55 return true;
56 }
57 #endif
58
59 class XpowerPluginTest : public ::testing::Test {
60 public:
SetUpTestCase()61 static void SetUpTestCase(){};
TearDownTestCase()62 static void TearDownTestCase(){};
63
SetUp()64 void SetUp() {}
TearDown()65 void TearDown() {}
66 };
67
68 /**
69 * @tc.name: xpower plugin
70 * @tc.desc: Framework test
71 * @tc.type: FUNC
72 */
HWTEST_F(XpowerPluginTest, TestFramework, TestSize.Level1)73 HWTEST_F(XpowerPluginTest, TestFramework, TestSize.Level1)
74 {
75 #if defined(__LP64__)
76 std::string path = std::string("libxpowerplugin.z.so");
77 void* handle = dlopen(path.c_str(), RTLD_LAZY);
78 EXPECT_NE(handle, nullptr);
79 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
80 EXPECT_NE(plugin, nullptr);
81 EXPECT_STREQ(plugin->name, "xpower-plugin");
82 g_protoXpower.clear();
83 // set config
84 XpowerConfig config;
85 config.set_bundle_name("com.ohos.sceneboard");
86 config.add_message_type(XpowerMessageType::REAL_BATTERY);
87 config.add_message_type(XpowerMessageType::APP_STATISTIC);
88 int size = config.ByteSizeLong();
89 ASSERT_GT(size, 0);
90 std::vector<uint8_t> configData(size);
91 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
92 // test framework process
93 WriterStruct writer = {WriteFunc, FlushFunc};
94 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
95 EXPECT_EQ(plugin->callbacks->onRegisterWriterStruct(&writer), 0);
96 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
97 usleep(US_PER_S * DEFAULT_WAIT); // 9s
98 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
99
100 // test proto data
101 int vectSize = g_protoXpower.size();
102 EXPECT_TRUE(vectSize >= 0);
103 #endif
104 }
105
106 /**
107 * @tc.name: xpower plugin
108 * @tc.desc: start fail test
109 * @tc.type: FUNC
110 * @tc.require: issueI5UGTK
111 */
HWTEST_F(XpowerPluginTest, TestStartFail, TestSize.Level1)112 HWTEST_F(XpowerPluginTest, TestStartFail, TestSize.Level1)
113 {
114 #if defined(__LP64__)
115 XpowerConfig config;
116 XpowerPlugin plugin;
117 WriterStruct writer = {WriteFunc, FlushFunc};
118 // set config
119 config.set_bundle_name("");
120 config.add_message_type(XpowerMessageType::REAL_BATTERY);
121 // test plugin process
122 plugin.SetWriter(&writer);
123 // serialize
124 int size = config.ByteSizeLong();
125 ASSERT_GT(size, 0);
126 std::vector<uint8_t> configData(size);
127 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
128 // start
129 EXPECT_EQ(plugin.Start(configData.data(), configData.size()), 0);
130 EXPECT_NE(plugin.Start(nullptr, configData.size()), 0);
131 EXPECT_NE(plugin.Start(configData.data(), 0), 0);
132 #endif
133 }
134
135 /**
136 * @tc.name: xpower plugin
137 * @tc.desc: message queue test
138 * @tc.type: FUNC
139 * @tc.require: issueI5UGTK
140 */
HWTEST_F(XpowerPluginTest, TestMessageQueue, TestSize.Level1)141 HWTEST_F(XpowerPluginTest, TestMessageQueue, TestSize.Level1)
142 {
143 const int msgQueueSize = 2000;
144 std::unique_ptr<PowerMessageQueue> dataQueuePtr = std::make_unique<PowerMessageQueue>(msgQueueSize);
145 auto rawData = std::make_shared<PowerOptimizeData>();
146 rawData->messageType = OptimizeMessageType::MESSAGE_REAL_BATTERY;
147 dataQueuePtr->PushBack(rawData);
148 EXPECT_GE(dataQueuePtr->Size(), 0);
149 EXPECT_TRUE(!dataQueuePtr->Empty());
150 std::shared_ptr<PowerOptimizeData> result = nullptr;
151 const uint32_t waitDuration = 100;
152 EXPECT_TRUE(dataQueuePtr->WaitAndPop(result, std::chrono::milliseconds(waitDuration)));
153 EXPECT_TRUE(result != nullptr);
154 const int batchSize = 5;
155 std::vector<std::shared_ptr<PowerOptimizeData>> araryData(batchSize); // 5: the size of std::vector;
156 EXPECT_FALSE(dataQueuePtr->WaitAndPopBatch(araryData, std::chrono::milliseconds(waitDuration), batchSize));
157 for (size_t i = 0; i < 3; i++) {
158 auto rawData = std::make_shared<PowerOptimizeData>();
159 rawData->messageType = OptimizeMessageType::MESSAGE_REAL_BATTERY;
160 rawData->length = i;
161 dataQueuePtr->PushBack(rawData);
162 }
163 EXPECT_TRUE(dataQueuePtr->WaitAndPopBatch(araryData, std::chrono::milliseconds(waitDuration), batchSize));
164 dataQueuePtr->ShutDown();
165 }
166
167 } // namespace
168