blob: 3620f8cf12e092579b92c33d24e23093d1095825 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/system/name_value_pairs_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace system {
// A parameterized test class running tests for all the formats that are
// compatible with VPD dumps.
class VpdDumpNameValuePairsParserTest
: public testing::TestWithParam<NameValuePairsFormat> {
protected:
NameValuePairsParser::NameValueMap map;
};
TEST_P(VpdDumpNameValuePairsParserTest, TestParseNameValuePairs) {
const NameValuePairsFormat format = GetParam();
NameValuePairsParser parser(&map);
const std::string contents1 = R"(
"initial_locale"="ja"
"keyboard_layout"="mozc-jp"
"empty"=""
)";
EXPECT_TRUE(parser.ParseNameValuePairs(contents1, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(3U, map.size());
EXPECT_EQ("ja", map["initial_locale"]);
EXPECT_EQ("mozc-jp", map["keyboard_layout"]);
EXPECT_EQ("", map["empty"]);
map.clear();
const std::string contents2 = R"(
"quoted"=""quote""
"serial_number"="BADBADBAD""
"model_name"="15" Chromebook"
)";
EXPECT_TRUE(parser.ParseNameValuePairs(contents2, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(3U, map.size());
EXPECT_EQ("\"quote\"", map["quoted"]);
EXPECT_EQ("BADBADBAD\"", map["serial_number"]);
EXPECT_EQ("15\" Chromebook", map["model_name"]);
map.clear();
const std::string contents3 = R"(
"a"="
"a"=
"a=b"="c"
""="value"
)";
EXPECT_FALSE(parser.ParseNameValuePairs(contents3, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(0U, map.size());
// This is just for visual confirmations that we have warnings logged and
// that we don't expose the value of the device stable secret in logs.
// TODO(crbug.com/1250037): Delete after logging is fixed.
map.clear();
const std::string contents5 = R"(
"stable_device_secret_DO_NOT_SHARE"="prettybadtobehere"
"stable_device_secret_DO_NOT_SHARE"="stillprettybadtobehere"
)";
EXPECT_TRUE(parser.ParseNameValuePairs(contents5, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(1U, map.size());
}
INSTANTIATE_TEST_SUITE_P(NameValuePairs,
VpdDumpNameValuePairsParserTest,
testing::Values(NameValuePairsFormat::kVpdDump,
NameValuePairsFormat::kMachineInfo));
TEST(NameValuePairsParser, TestParseNameValuePairsInVpdDumpFormat) {
constexpr NameValuePairsFormat format = NameValuePairsFormat::kVpdDump;
NameValuePairsParser::NameValueMap map;
NameValuePairsParser parser(&map);
// Names must be quoted in VPD dump format. Unquoted names are ignored.
const std::string contents1 = R"(
"name1"="value1"
name2="value2"
"name3"="value3"
name4="value4"
)";
EXPECT_FALSE(parser.ParseNameValuePairs(contents1, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(2U, map.size());
EXPECT_EQ("value1", map["name1"]);
EXPECT_EQ("value3", map["name3"]);
}
TEST(NameValuePairsParser, TestParseErrorInVpdDumpFormat) {
constexpr NameValuePairsFormat format = NameValuePairsFormat::kVpdDump;
NameValuePairsParser::NameValueMap map;
NameValuePairsParser parser(&map);
// Names must be quoted in VPD dump format. Unquoted names are ignored.
const std::string contents1 = R"(
"name1"="value1"
# RW_VPD execute error.
)";
EXPECT_FALSE(parser.ParseNameValuePairs(contents1, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(1U, map.size());
EXPECT_EQ("value1", map["name1"]);
}
TEST(NameValuePairsParser, TestParseNameValuePairsInMachineInfoFormat) {
constexpr NameValuePairsFormat format = NameValuePairsFormat::kMachineInfo;
NameValuePairsParser::NameValueMap map;
NameValuePairsParser parser(&map);
// Names do not have to be quoted in machine info format.
const std::string contents1 = R"(
"name1"="value1"
name2="value2"
"name3"="value3"
name4="value4"
)";
EXPECT_TRUE(parser.ParseNameValuePairs(contents1, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(4U, map.size());
EXPECT_EQ("value1", map["name1"]);
EXPECT_EQ("value2", map["name2"]);
EXPECT_EQ("value3", map["name3"]);
EXPECT_EQ("value4", map["name4"]);
map.clear();
const std::string contents2 = R"(
="value"
)";
EXPECT_FALSE(parser.ParseNameValuePairs(contents2, format,
/*debug_source=*/"unit test"));
EXPECT_EQ(0U, map.size());
}
TEST(NameValuePairsParser, TestParseNameValuePairsFromCrossystemTool) {
// Sample output is taken from the /usr/bin/crosssytem tool.
const char* command[] = {
"/bin/echo",
"arch = x86 # Platform architecture\n"
"cros_debug = 1 # OS should allow debug\n"
"dbg_reset = (error) # Debug reset mode request\n"
"key#with_comment = some value # Multiple # comment # delims\n"
"key = # No value.\n"
"vdat_timers = "
"LFS=0,0 LF=1784220250,2971030570 LK=9064076660,9342689170 "
"# Timer values from VbSharedData\n"
"wpsw_cur = 1 # Firmware hardware WP switch "
"pos\n"};
NameValuePairsParser::NameValueMap map;
NameValuePairsParser parser(&map);
parser.ParseNameValuePairsFromTool(std::size(command), command,
NameValuePairsFormat::kCrossystem);
EXPECT_EQ(7u, map.size());
EXPECT_EQ("x86", map["arch"]);
EXPECT_EQ("1", map["cros_debug"]);
EXPECT_EQ("(error)", map["dbg_reset"]);
EXPECT_EQ("some value", map["key#with_comment"]);
EXPECT_EQ("", map["key"]);
EXPECT_EQ("LFS=0,0 LF=1784220250,2971030570 LK=9064076660,9342689170",
map["vdat_timers"]);
EXPECT_EQ("1", map["wpsw_cur"]);
}
TEST(NameValuePairsParser, DeletePairsWithValue) {
NameValuePairsParser::NameValueMap map = {
{"foo", "good"}, {"bar", "bad"}, {"baz", "good"}, {"end", "bad"},
};
NameValuePairsParser parser(&map);
parser.DeletePairsWithValue("bad");
ASSERT_EQ(2u, map.size());
EXPECT_EQ("good", map["foo"]);
EXPECT_EQ("good", map["baz"]);
}
} // namespace system
} // namespace chromeos