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