-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathtests_log_checker.h
129 lines (112 loc) · 3.86 KB
/
tests_log_checker.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* @file tests/tests_log_checker.h
* @brief Utility functions to check log file contents.
*/
#pragma once
#include <algorithm>
#include <fstream>
#include <regex>
#include <src/logging.h>
#include <string>
namespace log_checker {
/**
* @brief Remove the timestamp prefix from a log line.
* @param line The log line.
* @return The log line without the timestamp prefix.
*/
inline std::string remove_timestamp_prefix(const std::string &line) {
static const std::regex timestamp_regex(R"(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}\]: )");
return std::regex_replace(line, timestamp_regex, "");
}
/**
* @brief Check if a log file contains a line that starts with the given string.
* @param log_file Path to the log file.
* @param start_str The string that the line should start with.
* @return True if such a line is found, false otherwise.
*/
inline bool line_starts_with(const std::string &log_file, const std::string_view &start_str) {
logging::log_flush();
std::ifstream input(log_file);
if (!input.is_open()) {
return false;
}
for (std::string line; std::getline(input, line);) {
line = remove_timestamp_prefix(line);
if (line.rfind(start_str, 0) == 0) {
return true;
}
}
return false;
}
/**
* @brief Check if a log file contains a line that ends with the given string.
* @param log_file Path to the log file.
* @param end_str The string that the line should end with.
* @return True if such a line is found, false otherwise.
*/
inline bool line_ends_with(const std::string &log_file, const std::string_view &end_str) {
logging::log_flush();
std::ifstream input(log_file);
if (!input.is_open()) {
return false;
}
for (std::string line; std::getline(input, line);) {
line = remove_timestamp_prefix(line);
if (line.size() >= end_str.size() &&
line.compare(line.size() - end_str.size(), end_str.size(), end_str) == 0) {
return true;
}
}
return false;
}
/**
* @brief Check if a log file contains a line that equals the given string.
* @param log_file Path to the log file.
* @param str The string that the line should equal.
* @return True if such a line is found, false otherwise.
*/
inline bool line_equals(const std::string &log_file, const std::string_view &str) {
logging::log_flush();
std::ifstream input(log_file);
if (!input.is_open()) {
return false;
}
for (std::string line; std::getline(input, line);) {
line = remove_timestamp_prefix(line);
if (line == str) {
return true;
}
}
return false;
}
/**
* @brief Check if a log file contains a line that contains the given substring.
* @param log_file Path to the log file.
* @param substr The substring to search for.
* @param case_insensitive Whether the search should be case-insensitive.
* @return True if such a line is found, false otherwise.
*/
inline bool line_contains(const std::string &log_file, const std::string_view &substr, bool case_insensitive = false) {
logging::log_flush();
std::ifstream input(log_file);
if (!input.is_open()) {
return false;
}
std::string search_str(substr);
if (case_insensitive) {
// sonarcloud complains about this, but the solution doesn't work for macOS-12
std::transform(search_str.begin(), search_str.end(), search_str.begin(), ::tolower);
}
for (std::string line; std::getline(input, line);) {
line = remove_timestamp_prefix(line);
if (case_insensitive) {
// sonarcloud complains about this, but the solution doesn't work for macOS-12
std::transform(line.begin(), line.end(), line.begin(), ::tolower);
}
if (line.find(search_str) != std::string::npos) {
return true;
}
}
return false;
}
} // namespace log_checker