1 // Copyright 2021 Google LLC
2 //
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 "util.hpp"
16 
17 #include <filesystem>
18 #include <fstream>
19 
20 #include "gtest/gtest.h"
21 
22 TEST(IsNumericPath, invalidNumericPath)
23 {
24     std::string badPath{"badNumericPath"};
25     int id = -1;
26     EXPECT_FALSE(metric_blob::isNumericPath(badPath, id));
27     EXPECT_EQ(id, -1);
28 }
29 
30 TEST(IsNumericPath, validNumericPath)
31 {
32     std::string goodPath{"proc/10000"};
33     int id = -1;
34     EXPECT_TRUE(metric_blob::isNumericPath(goodPath, id));
35     EXPECT_EQ(id, 10000);
36 }
37 
38 TEST(ReadFileThenGrepIntoString, goodFile)
39 {
40     const std::string& fileName = "./test_file";
41     std::ofstream ofs(fileName, std::ios::trunc);
42     std::string_view content = "This is\ntest\tcontentt\n\n\n\n.\n\n##$#$";
43     ofs << content;
44     ofs.close();
45     std::string readContent = metric_blob::readFileThenGrepIntoString(fileName);
46     std::filesystem::remove(fileName);
47     EXPECT_EQ(readContent, content);
48 }
49 
50 TEST(ReadFileThenGrepIntoString, inexistentFile)
51 {
52     const std::string& fileName = "./inexistent_file";
53     std::string readContent = metric_blob::readFileThenGrepIntoString(fileName);
54     EXPECT_EQ(readContent, "");
55 }
56 
57 TEST(GetTcommUtimeStime, validInput)
58 {
59     // ticks_per_sec is usually 100 on the BMC
60     const long ticksPerSec = 100;
61 
62     const std::string_view content = "2596 (dbus-broker) R 2577 2577 2577 0 -1 "
63                                      "4194560 299 0 1 0 333037 246110 0 0 20 0 "
64                                      "1 0 1545 3411968 530 4294967295 65536 "
65                                      "246512 2930531712 0 0 0 81923 4";
66 
67     metric_blob::TcommUtimeStime t =
68         metric_blob::parseTcommUtimeStimeString(content, ticksPerSec);
69     const float EPS = 0.01; // The difference was 0.000117188
70     EXPECT_LT(std::abs(t.utime - 3330.37), EPS);
71     EXPECT_LT(std::abs(t.stime - 2461.10), EPS);
72     EXPECT_EQ(t.tcomm, "(dbus-broker)");
73 }
74 
75 TEST(GetTcommUtimeStime, invalidInput)
76 {
77     // ticks_per_sec is usually 100 on the BMC
78     const long ticksPerSec = 100;
79 
80     const std::string_view content =
81         "x invalid x x x x x x x x x x x x x x x x x x x x x x x x x x x";
82 
83     metric_blob::TcommUtimeStime t =
84         metric_blob::parseTcommUtimeStimeString(content, ticksPerSec);
85 
86     EXPECT_EQ(t.utime, 0);
87     EXPECT_EQ(t.stime, 0);
88     EXPECT_EQ(t.tcomm, "invalid");
89 }
90 
91 TEST(ParseMeminfoValue, validInput)
92 {
93     const std::string_view content = "MemTotal:        1027040 kB\n"
94                                      "MemFree:          868144 kB\n"
95                                      "MemAvailable:     919308 kB\n"
96                                      "Buffers:           13008 kB\n"
97                                      "Cached:            82840 kB\n"
98                                      "SwapCached:            0 kB\n"
99                                      "Active:            62076 kB\n";
100     int value;
101     EXPECT_TRUE(metric_blob::parseMeminfoValue(content, "MemTotal:", value));
102     EXPECT_EQ(value, 1027040);
103     EXPECT_TRUE(metric_blob::parseMeminfoValue(content, "MemFree:", value));
104     EXPECT_EQ(value, 868144);
105     EXPECT_TRUE(
106         metric_blob::parseMeminfoValue(content, "MemAvailable:", value));
107     EXPECT_EQ(value, 919308);
108     EXPECT_TRUE(metric_blob::parseMeminfoValue(content, "Buffers:", value));
109     EXPECT_EQ(value, 13008);
110     EXPECT_TRUE(metric_blob::parseMeminfoValue(content, "Cached:", value));
111     EXPECT_EQ(value, 82840);
112     EXPECT_TRUE(metric_blob::parseMeminfoValue(content, "SwapCached:", value));
113     EXPECT_EQ(value, 0);
114     EXPECT_TRUE(metric_blob::parseMeminfoValue(content, "Active:", value));
115     EXPECT_EQ(value, 62076);
116 }
117 
118 TEST(ParseMeminfoValue, invalidInput)
119 {
120     const std::string_view invalid = "MemTotal: 1";
121     int value = -999;
122     EXPECT_FALSE(metric_blob::parseMeminfoValue(invalid, "MemTotal:", value));
123     EXPECT_EQ(value, -999);
124     EXPECT_FALSE(metric_blob::parseMeminfoValue(invalid, "x", value));
125     EXPECT_EQ(value, -999);
126 }
127 
128 TEST(ParseProcUptime, validInput)
129 {
130     const std::string_view content = "266923.67 512184.95";
131     const double eps =
132         1e-4; // Empirical threshold for floating point number compare
133     double uptime, idleProcessTime;
134     EXPECT_EQ(metric_blob::parseProcUptime(content, uptime, idleProcessTime),
135               true);
136     EXPECT_LT(abs(uptime - 266923.67), eps);
137     EXPECT_LT(abs(idleProcessTime - 512184.95), eps);
138 }
139 
140 TEST(TrimStringRight, nonEmptyResult)
141 {
142     EXPECT_EQ(
143         metric_blob::trimStringRight("\n\nabc\n\t\r\x00\x01\x02\x03").size(),
144         5); // "\n\nabc" is left
145 }
146 
147 TEST(TrimStringRight, trimToEmpty)
148 {
149     EXPECT_TRUE(metric_blob::trimStringRight("    ").empty());
150     EXPECT_TRUE(metric_blob::trimStringRight("").empty());
151 }
152 
153 int main(int argc, char** argv)
154 {
155     ::testing::InitGoogleTest(&argc, argv);
156     return RUN_ALL_TESTS();
157 }
158