* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "test_utils.h"
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <random>
#include <regex>
#include <sstream>
namespace OHOS {
namespace HiviewDFX {
int GetLogLineCountForHilogCmd(const std::string& cmd)
{
FILE* pipe = popen(cmd.c_str(), "r");
if (pipe == nullptr) {
return -1;
}
char buffer[MAX_LOG_OUTPUT_LEN] = {0};
int lineCount = 0;
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
if (!IsValidHilog(buffer)) {
continue;
}
lineCount++;
}
pclose(pipe);
return lineCount;
}
void ExecuteCmd(const std::string& cmd)
{
FILE* pipe = popen(cmd.c_str(), "r");
if (pipe == nullptr) {
return;
}
char buffer[MAX_LOG_OUTPUT_LEN] = {0};
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
std::cout << buffer << std::endl;
}
pclose(pipe);
}
std::vector<std::string> GetCmdResFromPopen(const std::string& cmd)
{
std::vector<std::string> result;
FILE* pipe = popen(cmd.c_str(), "r");
if (pipe == nullptr) {
return result;
}
char buffer[MAX_LOG_OUTPUT_LEN] = {0};
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
std::string line(buffer);
if (!line.empty() && line.back() == '\n') {
line.pop_back();
}
result.push_back(line);
}
pclose(pipe);
return result;
}
bool IsValidHilog(const std::string& logLine)
{
if (logLine.empty()) {
return false;
}
std::string pattern =
"^\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} +\\d+ +\\d+ [DIWEF] [IACP][0-9a-f]{5}/[^:]+:(.*)\\s*$";
std::regex regex(pattern);
return std::regex_match(logLine, regex);
}
static const char HILOG_LEVEL_CHARS[] = {
0, 0, 0, 'D', 'I', 'W', 'E', 'F'
};
bool IsValidHilogByLevel(const std::string& logLine, LogLevel level)
{
if (logLine.empty() || level >= LOG_LEVEL_MAX || level < LOG_DEBUG) {
return false;
}
char expectedLevel = HILOG_LEVEL_CHARS[level];
std::string pattern = "^\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} +\\d+ +\\d+ " +
std::string(1, expectedLevel) + " [IACP][0-9a-f]{5}/[^:]+:(.*)\\s*$";
std::regex regex(pattern);
return std::regex_match(logLine, regex);
}
static const char HILOG_TYPE_CHARS[] = {
'A', 'I', '0', 'C', 'K', 'P'
};
bool IsValidHilogByType(const std::string& logLine, LogType type)
{
if (logLine.empty() || type >= LOG_TYPE_MAX || type < LOG_APP || type == 2) {
return false;
}
if (type == LOG_KMSG) {
std::string devKmsgPattern = "^\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} +\\d+,\\d+,\\d+,-[;,](.*)\\s*$";
std::regex devKmsgRegex(devKmsgPattern);
std::string procKmsgPattern =
"^\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} +<\\d+>\\[ +\\d+\\.\\d+\\] (.*)\\s*$";
std::regex procKmsgRegex(procKmsgPattern);
return (std::regex_match(logLine, devKmsgRegex) || std::regex_match(logLine, procKmsgRegex));
}
char expectedType = HILOG_TYPE_CHARS[type];
std::string pattern = "^\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} +\\d+ +\\d+ [DIWEF] " +
std::string(1, expectedType) + "[0-9a-f]{5}/[^:]+:(.*)\\s*$";
std::regex regex(pattern);
return std::regex_match(logLine, regex);
}
std::string RandomStringGenerator(size_t length)
{
std::string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dis(0, chars.size() - 1);
std::string res;
for (size_t i = 0; i < length; i++) {
res += chars[dis(gen)];
}
return res;
}
void LogPrintTest(int numLogs, LogType type, LogLevel level)
{
std::string logMessage = RandomStringGenerator(DEFAULT_RANDOM_LOG_LENGTH);
for (int i = 0; i < numLogs; i++) {
HILOG_IMPL(type, level, 0xD002D00,
"HILOG_TEST_TAG", "%{public}s - Index: %{public}d", logMessage.c_str(), i);
}
}
}
}