1/*
2 * Copyright (c) 2021-2023 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 <cmath>
17#include <cstdio>
18#include <gtest/gtest.h>
19#include <mutex>
20#include <fcntl.h>
21#include <functional>
22#include <securec.h>
23#include <unistd.h>
24
25#include "hdf_base.h"
26#include "osal_time.h"
27#include "v1_1/ifan_callback.h"
28#include "v1_1/ithermal_interface.h"
29#include "v1_1/ithermal_callback.h"
30#include "v1_1/thermal_types.h"
31#include "thermal_log.h"
32
33using namespace OHOS::HDI;
34using namespace OHOS::HDI::Thermal::V1_1;
35using namespace testing::ext;
36
37namespace {
38class ThermalCallbackMock : public IThermalCallback {
39public:
40    virtual ~ThermalCallbackMock() {}
41    using ThermalEventCallback = std::function<int32_t(const HdfThermalCallbackInfo &event)>;
42    static int32_t RegisterThermalEvent(const ThermalEventCallback &eventCb)
43    {
44        (void)eventCb;
45        return 0;
46    }
47    int32_t OnThermalDataEvent(const HdfThermalCallbackInfo &event) override
48    {
49        (void)event;
50        return 0;
51    }
52};
53
54class FanCallbackMock : public IFanCallback {
55public:
56    virtual ~FanCallbackMock() {}
57    using FanEventCallback = std::function<int32_t(const HdfThermalCallbackInfo &event)>;
58    static int32_t RegisterFanEvent(const FanEventCallback &eventCb)
59    {
60        (void)eventCb;
61        return 0;
62    }
63    int32_t OnFanDataEvent(const HdfThermalCallbackInfo &event) override
64    {
65        (void)event;
66        return 0;
67    }
68};
69
70sptr<IThermalInterface> g_thermalInterface = nullptr;
71sptr<IThermalCallback> g_callback = new ThermalCallbackMock();
72sptr<IFanCallback> g_fanCallback = new FanCallbackMock();
73std::mutex g_mutex;
74const uint32_t MAX_PATH = 256;
75const std::string CPU_FREQ_PATH = "/data/service/el0/thermal/cooling/cpu/freq";
76const std::string GPU_FREQ_PATH = "/data/service/el0/thermal/cooling/gpu/freq";
77const std::string BATTERY_CHARGER_CURRENT_PATH = "/data/service/el0/thermal/cooling/battery/current";
78const std::string ISOLATE_PATH = "/data/service/el0/thermal/sensor/soc/isolate";
79
80class HdfThermalHdiTest : public testing::Test {
81public:
82    static void SetUpTestCase();
83    static void TearDownTestCase();
84    void SetUp();
85    void TearDown();
86    static int32_t ReadFile(const char *path, char *buf, size_t size);
87    static int32_t ConvertInt(const std::string &value);
88};
89
90void HdfThermalHdiTest::SetUpTestCase()
91{
92    g_thermalInterface = IThermalInterface::Get();
93}
94
95void HdfThermalHdiTest::TearDownTestCase()
96{
97}
98
99void HdfThermalHdiTest::SetUp()
100{
101}
102
103void HdfThermalHdiTest::TearDown()
104{
105}
106
107int32_t HdfThermalHdiTest::ReadFile(const char *path, char *buf, size_t size)
108{
109    std::lock_guard<std::mutex> lck(g_mutex);
110    int32_t ret;
111
112    int32_t fd = open(path, O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
113    if (fd < HDF_SUCCESS) {
114        THERMAL_HILOGE(LABEL_TEST, "WriteFile: failed to open file %{public}d", fd);
115        return HDF_FAILURE;
116    }
117
118    ret = read(fd, buf, size);
119    if (ret < HDF_SUCCESS) {
120        THERMAL_HILOGE(LABEL_TEST, "WriteFile: failed to read file %{public}d", ret);
121        close(fd);
122        return HDF_FAILURE;
123    }
124
125    close(fd);
126    buf[size - 1] = '\0';
127    return HDF_SUCCESS;
128}
129
130int32_t HdfThermalHdiTest::ConvertInt(const std::string &value)
131{
132    return std::stoi(value);
133}
134}
135
136namespace {
137/**
138  * @tc.name: HdfThermalHdiTest001
139  * @tc.desc: Get a client and check whether the client is empty.
140  * @tc.type: FUNC
141  */
142HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest001, TestSize.Level1)
143{
144    ASSERT_NE(nullptr, g_thermalInterface);
145}
146
147/**
148  * @tc.name: HdfThermalHdiTest002
149  * @tc.desc: set cpu freq
150  * @tc.type: FUNC
151  */
152HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest002, TestSize.Level1)
153{
154    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest002: start.");
155    int32_t cpuFreq = 1994100;
156    int32_t ret = g_thermalInterface->SetCpuFreq(cpuFreq);
157    EXPECT_EQ(0, ret);
158
159    char cpuBuf[MAX_PATH] = {0};
160    char freqValue[MAX_PATH] = {0};
161
162    if (snprintf_s(cpuBuf, MAX_PATH, sizeof(cpuBuf) - 1, CPU_FREQ_PATH.c_str()) < EOK) {
163        return;
164    }
165
166    ret = HdfThermalHdiTest::ReadFile(cpuBuf, freqValue, sizeof(freqValue));
167    if (ret != HDF_SUCCESS) {
168        THERMAL_HILOGE(LABEL_TEST, "HdfThermalHdiTest002: Failed to read file ");
169        return;
170    }
171
172    std::string freq = freqValue;
173    int32_t value = HdfThermalHdiTest::ConvertInt(freq);
174    THERMAL_HILOGD(LABEL_TEST, "freq is %{public}d", value);
175    EXPECT_EQ(value, cpuFreq) << "HdfThermalHdiTest002 failed";
176    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest002: return.");
177}
178
179/**
180  * @tc.name: HdfThermalHdiTest003
181  * @tc.desc: set gpu freq
182  * @tc.type: FUNC
183  */
184HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest003, TestSize.Level1)
185{
186    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest003: start.");
187    int32_t gpuFreq = 40000;
188    int32_t ret = g_thermalInterface->SetGpuFreq(gpuFreq);
189    EXPECT_EQ(0, ret);
190
191    char cpuBuf[MAX_PATH] = {0};
192    char freqValue[MAX_PATH] = {0};
193
194    if (snprintf_s(cpuBuf, MAX_PATH, sizeof(cpuBuf) - 1, GPU_FREQ_PATH.c_str()) < EOK) {
195        return;
196    }
197
198    ret = HdfThermalHdiTest::ReadFile(cpuBuf, freqValue, sizeof(freqValue));
199    if (ret != HDF_SUCCESS) {
200        THERMAL_HILOGE(LABEL_TEST, "HdfThermalHdiTest003: Failed to read file ");
201        return;
202    }
203
204    std::string freq = freqValue;
205    int32_t value = HdfThermalHdiTest::ConvertInt(freq);
206    THERMAL_HILOGD(LABEL_TEST, "freq is %{public}d", value);
207    EXPECT_EQ(value, gpuFreq) << "HdfThermalHdiTest003 failed";
208    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest003: return.");
209}
210
211/**
212  * @tc.name: HdfThermalHdiTest004
213  * @tc.desc: set battery current
214  * @tc.type: FUNC
215  */
216HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest004, TestSize.Level1)
217{
218    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest004: start.");
219    int32_t batteryCurrent = 1000;
220    int32_t ret = g_thermalInterface->SetBatteryCurrent(batteryCurrent);
221    EXPECT_EQ(0, ret);
222
223    char cpuBuf[MAX_PATH] = {0};
224    char currentValue[MAX_PATH] = {0};
225
226    if (snprintf_s(cpuBuf, MAX_PATH, sizeof(cpuBuf) - 1, BATTERY_CHARGER_CURRENT_PATH.c_str()) < EOK) {
227        return;
228    }
229
230    ret = HdfThermalHdiTest::ReadFile(cpuBuf, currentValue, sizeof(currentValue));
231    if (ret != HDF_SUCCESS) {
232        THERMAL_HILOGE(LABEL_TEST, "HdfThermalHdiTest004: Failed to read file ");
233        return;
234    }
235
236    std::string current = currentValue;
237    int32_t value = HdfThermalHdiTest::ConvertInt(current);
238    THERMAL_HILOGD(LABEL_TEST, "freq is %{public}d", value);
239    EXPECT_EQ(value, batteryCurrent) << "HdfThermalHdiTest004 failed";
240    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest004: return.");
241}
242
243/**
244  * @tc.name: HdfThermalHdiTest005
245  * @tc.desc: get thermal zone info
246  * @tc.type: FUNC
247  */
248HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest005, TestSize.Level1)
249{
250    HdfThermalCallbackInfo event;
251    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest005: start.");
252    int32_t ret = g_thermalInterface->GetThermalZoneInfo(event);
253    EXPECT_EQ(0, ret) << "HdfThermalHdiTest005 failed";
254    for (auto iter : event.info) {
255        THERMAL_HILOGD(LABEL_TEST, "type is %{public}s", iter.type.c_str());
256        THERMAL_HILOGD(LABEL_TEST, "temp is %{public}d", iter.temp);
257    }
258    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest005: return.");
259}
260
261/**
262  * @tc.name: HdfThermalHdiTest006
263  * @tc.desc: register callback
264  * @tc.type: FUNC
265  */
266HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest006, TestSize.Level1)
267{
268    HdfThermalCallbackInfo event;
269    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest006: start.");
270    int32_t ret = g_thermalInterface->Register(g_callback);
271    EXPECT_EQ(0, ret) << "HdfThermalHdiTest006 failed";
272    ret = g_thermalInterface->Unregister();
273    EXPECT_EQ(0, ret) << "HdfThermalHdiTest006 failed";
274    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest006: return.");
275}
276
277/**
278  * @tc.name: HdfThermalHdiTest007
279  * @tc.desc: isolate cpu num
280  * @tc.type: FUNC
281  */
282HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest007, TestSize.Level1)
283{
284    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest007: start.");
285    int32_t isolateNum = 2;
286    int32_t ret = g_thermalInterface->IsolateCpu(isolateNum);
287
288    char path[MAX_PATH] = {0};
289    char valueBuf[MAX_PATH] = {0};
290
291    if (snprintf_s(path, MAX_PATH, sizeof(path) - 1, ISOLATE_PATH.c_str()) < EOK) {
292        return;
293    }
294
295    ret = HdfThermalHdiTest::ReadFile(path, valueBuf, sizeof(valueBuf));
296    if (ret != HDF_SUCCESS) {
297        THERMAL_HILOGE(LABEL_TEST, "HdfThermalHdiTest007: Failed to read file ");
298        return;
299    }
300
301    std::string isolateNumStr = valueBuf;
302    int32_t value = HdfThermalHdiTest::ConvertInt(isolateNumStr);
303    THERMAL_HILOGD(LABEL_TEST, "isolate cpu num is %{public}d", value);
304    EXPECT_EQ(value, isolateNum) << "HdfThermalHdiTest007 failed";
305    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest007: return.");
306}
307
308/**
309  * @tc.name: HdfThermalHdiTest008
310  * @tc.desc: register fan callback
311  * @tc.type: FUNC
312  */
313HWTEST_F(HdfThermalHdiTest, HdfThermalHdiTest008, TestSize.Level1)
314{
315    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest008: start.");
316    int32_t ret = g_thermalInterface->RegisterFanCallback(g_fanCallback);
317    EXPECT_EQ(0, ret) << "HdfThermalHdiTest008 failed";
318    ret = g_thermalInterface->UnregisterFanCallback();
319    EXPECT_EQ(0, ret) << "HdfThermalHdiTest008 failed";
320    THERMAL_HILOGD(LABEL_TEST, "HdfThermalHdiTest008: return.");
321}
322}
323