blob: 909ad7f41db819d8f00add1322e40a04d54899f9 [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
Ratan Guptaed123a32017-06-15 09:07:31 +05307#include <exception>
Ratan Guptaed123a32017-06-15 09:07:31 +05308#include <fstream>
Gunnar Mills57d9c502018-09-14 14:42:34 -05009#include <phosphor-logging/elog-errors.hpp>
10#include <stdexcept>
William A. Kennington IIId9e2d722022-08-18 15:21:08 -070011#include <stdplus/fd/atomic.hpp>
12#include <stdplus/fd/fmt.hpp>
William A. Kennington III84bfe672022-07-13 14:15:30 -070013#include <stdplus/gtest/tmp.hpp>
Patrick Venturea9733402019-01-07 13:27:01 -080014#include <xyz/openbmc_project/Common/error.hpp>
Gunnar Mills57d9c502018-09-14 14:42:34 -050015
William A. Kennington III25511a12022-08-04 16:32:28 -070016#include <gmock/gmock.h>
Gunnar Mills57d9c502018-09-14 14:42:34 -050017#include <gtest/gtest.h>
Ratan Guptaed123a32017-06-15 09:07:31 +053018
19namespace phosphor
20{
21namespace network
22{
William A. Kennington III25511a12022-08-04 16:32:28 -070023namespace config
24{
25
26using testing::ElementsAre;
Ratan Guptaed123a32017-06-15 09:07:31 +053027
William A. Kennington III150753f2022-08-05 15:20:54 -070028TEST(TestConvert, iCaseEq)
29{
30 EXPECT_TRUE(icaseeq("VaL", "val"));
31 EXPECT_TRUE(icaseeq("[ab1", "[ab1"));
32}
33
34TEST(TestConvert, ParseBool)
35{
36 EXPECT_TRUE(parseBool("tRue").value());
37 EXPECT_FALSE(parseBool("tru").has_value());
38 EXPECT_TRUE(parseBool("t").value());
39 EXPECT_TRUE(parseBool("Yes").value());
40 EXPECT_FALSE(parseBool("ye").has_value());
41 EXPECT_TRUE(parseBool("y").value());
42 EXPECT_TRUE(parseBool("oN").value());
43
44 EXPECT_FALSE(parseBool("fAlse").value());
45 EXPECT_FALSE(parseBool("fal").has_value());
46 EXPECT_FALSE(parseBool("f").value());
47 EXPECT_FALSE(parseBool("No").value());
48 EXPECT_FALSE(parseBool("n").value());
49 EXPECT_FALSE(parseBool("oFf").value());
50}
51
William A. Kennington III84bfe672022-07-13 14:15:30 -070052class TestConfigParser : public stdplus::gtest::TestWithTmp
Ratan Guptaed123a32017-06-15 09:07:31 +053053{
Gunnar Mills57d9c502018-09-14 14:42:34 -050054 public:
William A. Kennington III25511a12022-08-04 16:32:28 -070055 std::string filename = fmt::format("{}/eth0.network", CaseTmpDir());
56 Parser parser;
57
58 void WriteSampleFile()
Gunnar Mills57d9c502018-09-14 14:42:34 -050059 {
William A. Kennington III84bfe672022-07-13 14:15:30 -070060 std::ofstream filestream(filename);
William A. Kennington III25511a12022-08-04 16:32:28 -070061 filestream << "\n\n\n\nBad=key\n[Match]\n # K=v \nName =eth0\n"
62 << "[Network\nDHCP=true\n[DHCP]\nClientIdentifier= mac\n"
63 << "[Network] a\nDHCP=false #hi\n\n\nDHCP = yes \n"
64 << " [ SEC ] \n'DHCP#'=\"#hi\"\nDHCP#=ho\n[Network]\n"
65 << "Key=val\nAddress=::/0\n[]\n=\nKey";
Gunnar Mills57d9c502018-09-14 14:42:34 -050066 filestream.close();
Gunnar Mills57d9c502018-09-14 14:42:34 -050067 }
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -070068
69 void ValidateSectionMap()
70 {
71 EXPECT_THAT(
72 parser.getMap(),
73 testing::ContainerEq(SectionMap(SectionMapInt{
74 {"Match", {{{"Name", {"eth0"}}}}},
75 {"Network",
76 {
77 {{"DHCP", {"true"}}},
78 {{"DHCP", {"false #hi", "yes"}}},
79 {{"Key", {"val"}}, {"Address", {"::/0"}}},
80 }},
81 {"DHCP", {{{"ClientIdentifier", {"mac"}}}}},
82 {" SEC ", {{{"'DHCP#'", {"\"#hi\""}}, {"DHCP#", {"ho"}}}}},
83 {"", {{{"", {""}}}}},
84 })));
85 }
Ratan Guptaed123a32017-06-15 09:07:31 +053086};
87
William A. Kennington IIIbc52d932022-08-18 16:34:02 -070088TEST_F(TestConfigParser, EmptyObject)
89{
William A. Kennington IIIa520a392022-08-08 12:17:34 -070090 EXPECT_TRUE(parser.getFilename().empty());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -070091 EXPECT_EQ(0, parser.getWarnings().size());
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -070092 EXPECT_EQ(SectionMap(), parser.getMap());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -070093}
94
95TEST_F(TestConfigParser, ReadDirectory)
96{
97 parser.setFile("/");
William A. Kennington IIIa520a392022-08-08 12:17:34 -070098 EXPECT_EQ("/", parser.getFilename());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -070099 EXPECT_EQ(1, parser.getWarnings().size());
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700100 EXPECT_EQ(SectionMap(), parser.getMap());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700101}
102
103TEST_F(TestConfigParser, ReadConfigDataMissingFile)
104{
105 parser.setFile("/no-such-path");
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700106 EXPECT_EQ("/no-such-path", parser.getFilename());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700107 EXPECT_EQ(1, parser.getWarnings().size());
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700108 EXPECT_EQ(SectionMap(), parser.getMap());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700109}
110
Ratan Guptaed123a32017-06-15 09:07:31 +0530111TEST_F(TestConfigParser, ReadConfigDataFromFile)
112{
William A. Kennington III25511a12022-08-04 16:32:28 -0700113 WriteSampleFile();
114 parser.setFile(filename);
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700115 EXPECT_EQ(filename, parser.getFilename());
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700116 EXPECT_EQ(4, parser.getWarnings().size());
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700117 ValidateSectionMap();
Ratan Guptac27170a2017-11-22 15:44:42 +0530118
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700119 const auto& map = parser.getMap();
120
121 EXPECT_EQ("eth0", *map.getLastValueString("Match", "Name"));
122 EXPECT_EQ("yes", *map.getLastValueString("Network", "DHCP"));
123 EXPECT_EQ(nullptr, map.getLastValueString("Match", "BadKey"));
124 EXPECT_EQ(nullptr, map.getLastValueString("BadSec", "Name"));
125 EXPECT_EQ(nullptr, map.getLastValueString("BadSec", "Name"));
126
127 EXPECT_THAT(map.getValueStrings("Match", "Name"), ElementsAre("eth0"));
128 EXPECT_THAT(map.getValueStrings("DHCP", "ClientIdentifier"),
William A. Kennington III25511a12022-08-04 16:32:28 -0700129 ElementsAre("mac"));
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700130 EXPECT_THAT(map.getValueStrings("Network", "DHCP"),
William A. Kennington III61ef4f22022-08-18 16:29:09 -0700131 ElementsAre("true", "false #hi", "yes"));
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700132 EXPECT_THAT(map.getValueStrings(" SEC ", "'DHCP#'"),
133 ElementsAre("\"#hi\""));
134 EXPECT_THAT(map.getValueStrings("Blah", "nil"), ElementsAre());
135 EXPECT_THAT(map.getValueStrings("Network", "nil"), ElementsAre());
Ratan Guptaed123a32017-06-15 09:07:31 +0530136}
137
William A. Kennington IIId9e2d722022-08-18 15:21:08 -0700138TEST_F(TestConfigParser, Perf)
139{
140 GTEST_SKIP();
141 stdplus::fd::AtomicWriter file(fmt::format("{}/tmp.XXXXXX", CaseTmpDir()),
142 0600);
143 stdplus::fd::FormatBuffer out(file);
144 for (size_t i = 0; i < 500; ++i)
145 {
146 out.append(FMT_COMPILE("[{:a>{}}]\n"), "", i + 1);
147 for (size_t j = 0; j < 70; j++)
148 {
149 const size_t es = i * 70 + j + 1;
150 out.append(FMT_COMPILE("{:b>{}}={:c>{}}\n"), "", es, "", es);
151 }
152 }
153 out.flush();
154 file.commit();
155
156 auto start = std::chrono::steady_clock::now();
157 parser.setFile(filename);
158 fmt::print("Duration: {}\n", std::chrono::steady_clock::now() - start);
159 // Make sure this test isn't enabled
160 EXPECT_FALSE(true);
161}
162
William A. Kennington III25511a12022-08-04 16:32:28 -0700163} // namespace config
Gunnar Mills57d9c502018-09-14 14:42:34 -0500164} // namespace network
165} // namespace phosphor