/* Copyright 2021 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * * Test config_parser.c using gtest. */ #include #include #include "config_parser.h" #include "test_util.h" #include "util.h" namespace { class ConfigFileTest : public ::testing::Test { protected: virtual void SetUp() { list_ = new_config_entry_list(); ASSERT_NE(list_, nullptr); } virtual void TearDown() { free_config_entry_list(list_); } struct config_entry_list *list_; }; } // namespace TEST(ParsingConfigTest, valid_config_line) { ScopedConfigEntry entry( (config_entry *)calloc(1, sizeof(struct config_entry))); const std::vector valid_conf_lines = { "mount=none", "valueless_key" "binding = none", " xyz = abc ", }; for (const auto& conf_line : valid_conf_lines) { ASSERT_TRUE(parse_config_line(conf_line.c_str(), entry.get())); clear_config_entry(entry.get()); } } TEST(ParsingConfigTest, invalid_config_line) { ScopedConfigEntry entry( (config_entry *)calloc(1, sizeof(struct config_entry))); const std::vector invalid_conf_lines = { "= none", "", "empty_arg=", "empty_arg= ", }; for (const auto& conf_line : invalid_conf_lines) { ASSERT_FALSE(parse_config_line(conf_line.c_str(), entry.get())); } } TEST_F(ConfigFileTest, malformed_config_line) { std::string config = "% minijail-config-file v0\n" "=malformed"; ScopedFILE config_file(write_to_pipe(config)); ASSERT_NE(config_file.get(), nullptr); bool res = parse_config_file(config_file.get(), list_); // Policy is malformed, but process should not crash. ASSERT_FALSE(res); ASSERT_EQ(list_->num_entries, 0); } TEST_F(ConfigFileTest, bad_directive) { std::string config = "% bad-directive\n" "# comments"; ScopedFILE config_file(write_to_pipe(config)); ASSERT_NE(config_file.get(), nullptr); bool res = parse_config_file(config_file.get(), list_); // Policy is malformed, but process should not crash. ASSERT_FALSE(res); ASSERT_EQ(list_->num_entries, 0); } TEST_F(ConfigFileTest, wellformed_single_line) { std::string config = "% minijail-config-file v0\n" "# Comments \n" "\n" "uts\n" "mount= xyz\n" "binding = none,/tmp"; ScopedFILE config_file(write_to_pipe(config)); ASSERT_NE(config_file.get(), nullptr); bool res = parse_config_file(config_file.get(), list_); ASSERT_TRUE(res); ASSERT_EQ(list_->num_entries, 3); struct config_entry *first_entry = list_->entries; struct config_entry *second_entry = list_->entries + 1; struct config_entry *third_entry = list_->entries + 2; ASSERT_EQ(std::string(first_entry->key), "uts"); ASSERT_EQ(first_entry->value, nullptr); ASSERT_EQ(std::string(second_entry->key), "mount"); ASSERT_EQ(std::string(second_entry->value), "xyz"); ASSERT_EQ(std::string(third_entry->key), "binding"); ASSERT_EQ(std::string(third_entry->value), "none,/tmp"); } TEST_F(ConfigFileTest, wellformed_multi_line) { std::string config = "% minijail-config-file v0\n" "# Comments \n" "\n" "mount = \\\n" "none\n" "binding = none,\\\n" "/tmp"; ScopedFILE config_file(write_to_pipe(config)); ASSERT_NE(config_file.get(), nullptr); int res = parse_config_file(config_file.get(), list_); ASSERT_TRUE(res); ASSERT_EQ(list_->num_entries, 2); struct config_entry *first_entry = list_->entries; struct config_entry *second_entry = list_->entries + 1; ASSERT_EQ(std::string(first_entry->key), "mount"); ASSERT_EQ(std::string(first_entry->value), "none"); ASSERT_EQ(std::string(second_entry->key), "binding"); ASSERT_EQ(std::string(second_entry->value), "none, /tmp"); }