1/*
2 * Copyright (c) 2022 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#include "hilog_utils_test.h"
16#include "hilog_common.h"
17#include <log_utils.h>
18#include <hilog/log_c.h>
19#include <list>
20
21using namespace std;
22using namespace testing::ext;
23using namespace OHOS;
24using namespace OHOS::HiviewDFX;
25
26static std::string GetCmdResultFromPopen(const std::string& cmd)
27{
28    if (cmd.empty()) {
29        return "";
30    }
31    FILE* fp = popen(cmd.c_str(), "r");
32    if (fp == nullptr) {
33        return "";
34    }
35    std::string ret = "";
36    char* buffer = nullptr;
37    size_t len = 0;
38    while (getline(&buffer, &len, fp) != -1) {
39        std::string line = buffer;
40        ret += line;
41    }
42    if (buffer != nullptr) {
43        free(buffer);
44        buffer = nullptr;
45    }
46    pclose(fp);
47    return ret;
48}
49
50namespace {
51/**
52 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_001
53 * @tc.desc: Size2Str & Str2Size.
54 * @tc.type: FUNC
55 */
56HWTEST_F(HilogUtilsTest, HilogUtilsTest_001, TestSize.Level1)
57{
58    GTEST_LOG_(INFO) << "HilogUtilsTest_001: start.";
59    const std::list<pair<uint64_t, string>> sizeStrList = {
60        /* size, unit */
61        {1, "B"},
62        {1ULL << 10, "K"},
63        {1ULL << 20, "M"},
64        {1ULL << 30, "G"},
65        {1ULL << 40, "T"},
66    };
67    for (auto &it : sizeStrList) {
68        EXPECT_EQ(Size2Str(it.first), "1.0" + it.second);
69        EXPECT_EQ(Str2Size("1" + it.second), it.first);
70    }
71
72    // valid str reg [0-9]+[BKMGT]?
73    EXPECT_EQ(Str2Size("1.2A"), 0);
74}
75
76/**
77 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_002
78 * @tc.desc: LogType2Str & Str2LogType.
79 * @tc.type: FUNC
80 */
81HWTEST_F(HilogUtilsTest, HilogUtilsTest_002, TestSize.Level1)
82{
83    GTEST_LOG_(INFO) << "HilogUtilsTest_002: start.";
84    const std::list<pair<LogType, string>> logTypesList = {
85        {LOG_INIT, "init"},
86        {LOG_CORE, "core"},
87        {LOG_APP, "app"},
88        {LOG_KMSG, "kmsg"},
89        {LOG_ONLY_PRERELEASE, "only_prerelease"},
90        {LOG_TYPE_MAX, "invalid"},
91    };
92    for (auto &it : logTypesList) {
93        EXPECT_EQ(LogType2Str(it.first), it.second);
94        EXPECT_EQ(Str2LogType(it.second), it.first);
95    }
96}
97
98/**
99 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_003
100 * @tc.desc: ComboLogType2Str & Str2ComboLogType.
101 * @tc.type: FUNC
102 */
103HWTEST_F(HilogUtilsTest, HilogUtilsTest_003, TestSize.Level1)
104{
105    GTEST_LOG_(INFO) << "HilogUtilsTest_003: start.";
106    const std::list<pair<uint16_t, string>> logTypesList = {
107        /* ComboLogType, str */
108        {1 << LOG_APP, "app"},
109        {1 << LOG_INIT, "init"},
110        {1 << LOG_CORE, "core"},
111        {1 << LOG_ONLY_PRERELEASE, "only_prerelease"},
112        {1 << LOG_KMSG, "kmsg"},
113        {(1 << LOG_APP) + (1 << LOG_INIT) + (1 << LOG_CORE) + (1 << LOG_ONLY_PRERELEASE) + (1 << LOG_KMSG),
114            "init,core,app,only_prerelease,kmsg"},
115    };
116    for (auto &it : logTypesList) {
117        EXPECT_EQ(ComboLogType2Str(it.first), it.second);
118        EXPECT_EQ(Str2ComboLogType(it.second), it.first);
119    }
120
121    EXPECT_EQ(Str2ComboLogType(""), (1 << LOG_APP) + (1 << LOG_CORE) + (1 << LOG_ONLY_PRERELEASE));
122    EXPECT_EQ(Str2ComboLogType("invalid"), 0);
123}
124
125/**
126 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_004
127 * @tc.desc: LogLevel2Str & Str2LogLevel.
128 * @tc.type: FUNC
129 */
130HWTEST_F(HilogUtilsTest, HilogUtilsTest_004, TestSize.Level1)
131{
132    GTEST_LOG_(INFO) << "HilogUtilsTest_004: start.";
133    struct LogLevelEntry {
134        const LogLevel logLevel;
135        const std::string str;
136        const std::string shortStr;
137        const int comboLogLevel;
138    };
139
140    LogLevelEntry logLevelEntries[] = {
141        {LOG_LEVEL_MIN, "INVALID", "V", 0},
142        {LOG_DEBUG, "DEBUG", "D", 1 << LOG_DEBUG},
143        {LOG_INFO, "INFO", "I", 1 << LOG_INFO},
144        {LOG_WARN, "WARN", "W", 1 << LOG_WARN},
145        {LOG_ERROR, "ERROR", "E", 1 << LOG_ERROR},
146        {LOG_FATAL, "FATAL", "F", 1 << LOG_FATAL, },
147        {LOG_LEVEL_MAX, "X", "X", 0},
148    };
149
150    constexpr int logLevelEntryCnt = sizeof(logLevelEntries) / sizeof(LogLevelEntry);
151
152    for (int i = 0; i < logLevelEntryCnt; i++) {
153        EXPECT_EQ(LogLevel2Str(logLevelEntries[i].logLevel), logLevelEntries[i].str);
154        EXPECT_EQ(Str2LogLevel(logLevelEntries[i].str), logLevelEntries[i].logLevel);
155        EXPECT_EQ(LogLevel2ShortStr(logLevelEntries[i].logLevel), logLevelEntries[i].shortStr);
156        EXPECT_EQ(ShortStr2LogLevel(logLevelEntries[i].shortStr), logLevelEntries[i].logLevel);
157        if (logLevelEntries[i].comboLogLevel != 0) {
158            EXPECT_EQ(ComboLogLevel2Str(logLevelEntries[i].comboLogLevel), logLevelEntries[i].str);
159        }
160        EXPECT_EQ(Str2ComboLogLevel(logLevelEntries[i].str), logLevelEntries[i].comboLogLevel);
161    }
162
163    EXPECT_EQ(Str2ComboLogLevel(""), 0xFFFF);
164}
165
166/**
167 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_005
168 * @tc.desc: GetBitsCount & GetBitPos.
169 * @tc.type: FUNC
170 */
171HWTEST_F(HilogUtilsTest, HilogUtilsTest_005, TestSize.Level1)
172{
173    GTEST_LOG_(INFO) << "HelperTest_005: start.";
174    uint64_t num1 = 1 << 4;
175    uint64_t num2 = (1 << 2) + (1 << 3) + (1 << 4);
176    EXPECT_EQ(GetBitPos(num1), 4);
177    // only accpet the number which is power of 2
178    EXPECT_EQ(GetBitPos(num2), 0);
179    EXPECT_EQ(GetBitsCount(num2), 3);
180}
181
182/**
183 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_006
184 * @tc.desc: Uint2DecStr DecStr2Uint Uint2HexStr & HexStr2Uint.
185 * @tc.type: FUNC
186 */
187HWTEST_F(HilogUtilsTest, HilogUtilsTest_006, TestSize.Level1)
188{
189    GTEST_LOG_(INFO) << "HilogUtilsTest_006: start.";
190    uint32_t decNum = 1250;
191    uint32_t hexNum = 0xd002d00;
192    std::string decStr = "1250";
193    std::string hexStr = "d002d00";
194    EXPECT_EQ(Uint2DecStr(decNum), decStr);
195    EXPECT_EQ(DecStr2Uint(decStr), decNum);
196    EXPECT_EQ(Uint2HexStr(hexNum), hexStr);
197    EXPECT_EQ(HexStr2Uint(hexStr), hexNum);
198}
199
200/**
201 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_007
202 * @tc.desc: GetAllLogTypes.
203 * @tc.type: FUNC
204 */
205HWTEST_F(HilogUtilsTest, HilogUtilsTest_007, TestSize.Level1)
206{
207    GTEST_LOG_(INFO) << "HilogUtilsTest_007: start.";
208    vector<uint16_t> vec = GetAllLogTypes();
209    sort(vec.begin(), vec.end());
210    vector<uint16_t> allTypes {0, 1, 3, 4, 5};
211    EXPECT_TRUE(vec == allTypes);
212}
213
214/**
215 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_008
216 * @tc.desc: GetPPidByPid.
217 * @tc.type: FUNC
218 */
219HWTEST_F(HilogUtilsTest, HilogUtilsTest_008, TestSize.Level1)
220{
221    GTEST_LOG_(INFO) << "HilogUtilsTest_008: start.";
222    uint32_t pid = stoi(GetCmdResultFromPopen("pidof hilogd"));
223    EXPECT_EQ(GetPPidByPid(pid), 1);
224
225    uint32_t invalidPid = 999999;
226    EXPECT_EQ(GetPPidByPid(invalidPid), 0);
227}
228
229/**
230 * @tc.name: Dfx_HilogUtilsTest_HilogUtilsTest_009
231 * @tc.desc: WaitingToDo.
232 * @tc.type: FUNC
233 */
234HWTEST_F(HilogUtilsTest, HilogUtilsTest_009, TestSize.Level1)
235{
236    GTEST_LOG_(INFO) << "HilogUtilsTest_009: start.";
237    int ret = WaitingToDo(WAITING_DATA_MS, "/data/log", [](const string &path) {
238        if (!access(path.c_str(), F_OK)) {
239            return RET_SUCCESS;
240        }
241        return RET_FAIL;
242    });
243    EXPECT_EQ(ret, RET_SUCCESS);
244
245    ret = WaitingToDo(WAITING_DATA_MS, "/test/ttt", [](const string &path) {
246        if (!access(path.c_str(), F_OK)) {
247            return RET_SUCCESS;
248        }
249        return RET_FAIL;
250    });
251    PrintErrorno(errno);
252    EXPECT_EQ(ret, RET_FAIL);
253}
254} // namespace
255