blob: 2948c730d5774e37ec8ae33134fe9d0e856dacdb [file] [log] [blame]
Ratan Guptaed123a32017-06-15 09:07:31 +05301#include "config_parser.hpp"
Ratan Guptaed123a32017-06-15 09:07:31 +05302
William A. Kennington IIId9e2d722022-08-18 15:21:08 -07003#include <fmt/chrono.h>
4#include <fmt/compile.h>
William A. Kennington III84bfe672022-07-13 14:15:30 -07005#include <fmt/format.h>
6
Gunnar Mills57d9c502018-09-14 14:42:34 -05007#include <phosphor-logging/elog-errors.hpp>
William A. Kennington IIId9e2d722022-08-18 15:21:08 -07008#include <stdplus/fd/atomic.hpp>
9#include <stdplus/fd/fmt.hpp>
William A. Kennington III84bfe672022-07-13 14:15:30 -070010#include <stdplus/gtest/tmp.hpp>
Patrick Venturea9733402019-01-07 13:27:01 -080011#include <xyz/openbmc_project/Common/error.hpp>
Gunnar Mills57d9c502018-09-14 14:42:34 -050012
Patrick Williams89d734b2023-05-10 07:50:25 -050013#include <exception>
14#include <fstream>
15#include <stdexcept>
16
William A. Kennington III25511a12022-08-04 16:32:28 -070017#include <gmock/gmock.h>
Gunnar Mills57d9c502018-09-14 14:42:34 -050018#include <gtest/gtest.h>
Ratan Guptaed123a32017-06-15 09:07:31 +053019
20namespace phosphor
21{
22namespace network
23{
William A. Kennington III25511a12022-08-04 16:32:28 -070024namespace config
25{
26
27using testing::ElementsAre;
Ratan Guptaed123a32017-06-15 09:07:31 +053028
William A. Kennington III150753f2022-08-05 15:20:54 -070029TEST(TestConvert, iCaseEq)
30{
31 EXPECT_TRUE(icaseeq("VaL", "val"));
32 EXPECT_TRUE(icaseeq("[ab1", "[ab1"));
33}
34
35TEST(TestConvert, ParseBool)
36{
37 EXPECT_TRUE(parseBool("tRue").value());
38 EXPECT_FALSE(parseBool("tru").has_value());
39 EXPECT_TRUE(parseBool("t").value());
40 EXPECT_TRUE(parseBool("Yes").value());
41 EXPECT_FALSE(parseBool("ye").has_value());
42 EXPECT_TRUE(parseBool("y").value());
43 EXPECT_TRUE(parseBool("oN").value());
44
45 EXPECT_FALSE(parseBool("fAlse").value());
46 EXPECT_FALSE(parseBool("fal").has_value());
47 EXPECT_FALSE(parseBool("f").value());
48 EXPECT_FALSE(parseBool("No").value());
49 EXPECT_FALSE(parseBool("n").value());
50 EXPECT_FALSE(parseBool("oFf").value());
51}
52
William A. Kennington III0dd09372022-08-18 14:57:07 -070053TEST(TestTypeChecking, Section)
54{
55 Section("");
56 Section("fds#1!'\"");
57 EXPECT_THROW(Section("fds]sf"), std::invalid_argument);
58 EXPECT_THROW(Section("g\ng"), std::invalid_argument);
59}
60
61TEST(TestTypeChecking, Value)
62{
63 Value("");
64 Value("=fds1!'\"#=");
65 Value("fds]sf'' #");
66 EXPECT_THROW(Value("g\ng"), std::invalid_argument);
67}
68
69TEST(TestTypeChecking, Key)
70{
71 Key("");
72 Key("fds1!'\"#");
73 Key("fds]sf'' #");
74 EXPECT_THROW(Key("fds]sf'='"), std::invalid_argument);
75 EXPECT_THROW(Key("g\ng"), std::invalid_argument);
76}
77
William A. Kennington III84bfe672022-07-13 14:15:30 -070078class TestConfigParser : public stdplus::gtest::TestWithTmp
Ratan Guptaed123a32017-06-15 09:07:31 +053079{
Gunnar Mills57d9c502018-09-14 14:42:34 -050080 public:
William A. Kennington III25511a12022-08-04 16:32:28 -070081 std::string filename = fmt::format("{}/eth0.network", CaseTmpDir());
82 Parser parser;
83
84 void WriteSampleFile()
Gunnar Mills57d9c502018-09-14 14:42:34 -050085 {
William A. Kennington III84bfe672022-07-13 14:15:30 -070086 std::ofstream filestream(filename);
William A. Kennington III25511a12022-08-04 16:32:28 -070087 filestream << "\n\n\n\nBad=key\n[Match]\n # K=v \nName =eth0\n"
88 << "[Network\nDHCP=true\n[DHCP]\nClientIdentifier= mac\n"
89 << "[Network] a\nDHCP=false #hi\n\n\nDHCP = yes \n"
90 << " [ SEC ] \n'DHCP#'=\"#hi\"\nDHCP#=ho\n[Network]\n"
91 << "Key=val\nAddress=::/0\n[]\n=\nKey";
Gunnar Mills57d9c502018-09-14 14:42:34 -050092 filestream.close();
Gunnar Mills57d9c502018-09-14 14:42:34 -050093 }
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -070094
95 void ValidateSectionMap()
96 {
97 EXPECT_THAT(
William A. Kennington III34bb3e22022-08-18 15:17:22 -070098 parser.map,
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -070099 testing::ContainerEq(SectionMap(SectionMapInt{
100 {"Match", {{{"Name", {"eth0"}}}}},
101 {"Network",
102 {
103 {{"DHCP", {"true"}}},
104 {{"DHCP", {"false #hi", "yes"}}},
105 {{"Key", {"val"}}, {"Address", {"::/0"}}},
106 }},
107 {"DHCP", {{{"ClientIdentifier", {"mac"}}}}},
108 {" SEC ", {{{"'DHCP#'", {"\"#hi\""}}, {"DHCP#", {"ho"}}}}},
109 {"", {{{"", {""}}}}},
110 })));
111 }
Ratan Guptaed123a32017-06-15 09:07:31 +0530112};
113
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700114TEST_F(TestConfigParser, EmptyObject)
115{
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800116 EXPECT_FALSE(parser.getFileExists());
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700117 EXPECT_TRUE(parser.getFilename().empty());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700118 EXPECT_EQ(0, parser.getWarnings().size());
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700119 EXPECT_EQ(SectionMap(), parser.map);
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700120}
121
122TEST_F(TestConfigParser, ReadDirectory)
123{
124 parser.setFile("/");
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800125 EXPECT_FALSE(parser.getFileExists());
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700126 EXPECT_EQ("/", parser.getFilename());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700127 EXPECT_EQ(1, parser.getWarnings().size());
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700128 EXPECT_EQ(SectionMap(), parser.map);
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700129}
130
131TEST_F(TestConfigParser, ReadConfigDataMissingFile)
132{
133 parser.setFile("/no-such-path");
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800134 EXPECT_FALSE(parser.getFileExists());
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700135 EXPECT_EQ("/no-such-path", parser.getFilename());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700136 EXPECT_EQ(1, parser.getWarnings().size());
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700137 EXPECT_EQ(SectionMap(), parser.map);
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700138}
139
Ratan Guptaed123a32017-06-15 09:07:31 +0530140TEST_F(TestConfigParser, ReadConfigDataFromFile)
141{
William A. Kennington III25511a12022-08-04 16:32:28 -0700142 WriteSampleFile();
143 parser.setFile(filename);
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800144 EXPECT_TRUE(parser.getFileExists());
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700145 EXPECT_EQ(filename, parser.getFilename());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700146 EXPECT_EQ(4, parser.getWarnings().size());
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700147 ValidateSectionMap();
Ratan Guptac27170a2017-11-22 15:44:42 +0530148
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700149 const auto& map = parser.map;
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700150
151 EXPECT_EQ("eth0", *map.getLastValueString("Match", "Name"));
152 EXPECT_EQ("yes", *map.getLastValueString("Network", "DHCP"));
153 EXPECT_EQ(nullptr, map.getLastValueString("Match", "BadKey"));
154 EXPECT_EQ(nullptr, map.getLastValueString("BadSec", "Name"));
155 EXPECT_EQ(nullptr, map.getLastValueString("BadSec", "Name"));
156
157 EXPECT_THAT(map.getValueStrings("Match", "Name"), ElementsAre("eth0"));
158 EXPECT_THAT(map.getValueStrings("DHCP", "ClientIdentifier"),
William A. Kennington III25511a12022-08-04 16:32:28 -0700159 ElementsAre("mac"));
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700160 EXPECT_THAT(map.getValueStrings("Network", "DHCP"),
William A. Kennington III61ef4f22022-08-18 16:29:09 -0700161 ElementsAre("true", "false #hi", "yes"));
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700162 EXPECT_THAT(map.getValueStrings(" SEC ", "'DHCP#'"),
163 ElementsAre("\"#hi\""));
164 EXPECT_THAT(map.getValueStrings("Blah", "nil"), ElementsAre());
165 EXPECT_THAT(map.getValueStrings("Network", "nil"), ElementsAre());
Ratan Guptaed123a32017-06-15 09:07:31 +0530166}
167
William A. Kennington III409f1a62022-08-11 15:44:37 -0700168TEST_F(TestConfigParser, WriteConfigFile)
169{
170 WriteSampleFile();
171 parser.setFile(filename);
172 EXPECT_EQ(4, parser.getWarnings().size());
173 ValidateSectionMap();
174
175 parser.writeFile();
176
177 parser.setFile(filename);
178 EXPECT_EQ(0, parser.getWarnings().size());
179 ValidateSectionMap();
180}
181
William A. Kennington IIId9e2d722022-08-18 15:21:08 -0700182TEST_F(TestConfigParser, Perf)
183{
184 GTEST_SKIP();
185 stdplus::fd::AtomicWriter file(fmt::format("{}/tmp.XXXXXX", CaseTmpDir()),
186 0600);
187 stdplus::fd::FormatBuffer out(file);
188 for (size_t i = 0; i < 500; ++i)
189 {
190 out.append(FMT_COMPILE("[{:a>{}}]\n"), "", i + 1);
191 for (size_t j = 0; j < 70; j++)
192 {
193 const size_t es = i * 70 + j + 1;
194 out.append(FMT_COMPILE("{:b>{}}={:c>{}}\n"), "", es, "", es);
195 }
196 }
197 out.flush();
198 file.commit();
199
200 auto start = std::chrono::steady_clock::now();
201 parser.setFile(filename);
202 fmt::print("Duration: {}\n", std::chrono::steady_clock::now() - start);
203 // Make sure this test isn't enabled
204 EXPECT_FALSE(true);
205}
206
William A. Kennington III25511a12022-08-04 16:32:28 -0700207} // namespace config
Gunnar Mills57d9c502018-09-14 14:42:34 -0500208} // namespace network
209} // namespace phosphor