| // Copyright 2018 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. |
| |
| #include "crosdns/hosts_modifier.h" |
| |
| #include <string> |
| |
| #include <base/files/scoped_temp_dir.h> |
| #include <base/files/file_path.h> |
| #include <base/files/file_util.h> |
| #include <gtest/gtest.h> |
| |
| namespace crosdns { |
| |
| namespace { |
| |
| constexpr char kBaseFileContents[] = |
| "# Example /etc/hosts file\n" |
| "127.0.0.1 localhost\n"; |
| constexpr char kFileModificationDelimeter[] = |
| "\n#####DYNAMIC-CROSDNS-ENTRIES#####\n"; |
| |
| class HostsModifierTest : public ::testing::Test { |
| public: |
| HostsModifierTest() { |
| CHECK(temp_dir_.CreateUniqueTempDir()); |
| hosts_file_ = temp_dir_.GetPath().Append("hosts"); |
| WriteHostsContents(kBaseFileContents); |
| } |
| ~HostsModifierTest() override = default; |
| |
| void WriteHostsContents(const std::string& file_contents) { |
| EXPECT_EQ(file_contents.size(), |
| base::WriteFile(hosts_file_, file_contents.c_str(), |
| file_contents.size())); |
| } |
| |
| std::string ReadHostsContents() const { |
| std::string ret; |
| EXPECT_TRUE(base::ReadFileToString(hosts_file_, &ret)); |
| return ret; |
| } |
| |
| HostsModifier* hosts_modifier() { return &hosts_modifier_; } |
| base::FilePath hosts_file() const { return hosts_file_; } |
| |
| private: |
| base::ScopedTempDir temp_dir_; |
| base::FilePath hosts_file_; |
| HostsModifier hosts_modifier_; |
| |
| DISALLOW_COPY_AND_ASSIGN(HostsModifierTest); |
| }; |
| |
| } // namespace |
| |
| TEST_F(HostsModifierTest, InitSucceeds) { |
| EXPECT_TRUE(hosts_modifier()->Init(hosts_file())); |
| // The hosts file contents should be unchanged now. |
| EXPECT_EQ(kBaseFileContents, ReadHostsContents()); |
| } |
| |
| TEST_F(HostsModifierTest, InitFailsNonExistentFile) { |
| EXPECT_TRUE(base::DeleteFile(hosts_file(), false)); |
| EXPECT_FALSE(hosts_modifier()->Init(hosts_file())); |
| } |
| |
| TEST_F(HostsModifierTest, InitRemovesOldEntries) { |
| std::string extra_contents = kBaseFileContents; |
| extra_contents += kFileModificationDelimeter; |
| extra_contents += "1.2.3.4 example.com\n"; |
| WriteHostsContents(extra_contents); |
| EXPECT_TRUE(hosts_modifier()->Init(hosts_file())); |
| // The hosts file contents should be the original contents up to our |
| // delimeter. |
| EXPECT_EQ(kBaseFileContents, ReadHostsContents()); |
| } |
| |
| TEST_F(HostsModifierTest, SettingRemovingHostnames) { |
| std::string err; |
| EXPECT_TRUE(hosts_modifier()->Init(hosts_file())); |
| // Valid hostname for default container. |
| EXPECT_TRUE(hosts_modifier()->SetHostnameIpMapping( |
| "penguin.linux.test", "100.115.92.24", "", &err)); |
| // Valid hostnames for vm/container. |
| EXPECT_TRUE(hosts_modifier()->SetHostnameIpMapping( |
| "foo12.linux.test", "100.115.92.22", "", &err)); |
| EXPECT_TRUE(hosts_modifier()->SetHostnameIpMapping( |
| "penguin.termina.linux.test", "100.115.92.253", "", &err)); |
| // Invalid hostnames. |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| "google.com", "100.115.92.24", "", &err)); |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| "localhost", "100.115.92.24", "", &err)); |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| "-foo-local", "100.115.92.24", "", &err)); |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| "foo..linux.test", "100.115.92.24", "", &err)); |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| ".linux.test", "100.115.92.24", "", &err)); |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| "linux.test", "100.115.92.24", "", &err)); |
| EXPECT_FALSE( |
| hosts_modifier()->SetHostnameIpMapping("", "100.115.92.24", "", &err)); |
| // Invalid IPs. |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| "penguin.linux.test", "100.115.91.24", "", &err)); |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping("penguin.linux.test", |
| "8.8.8.8", "", &err)); |
| EXPECT_FALSE(hosts_modifier()->SetHostnameIpMapping( |
| "penguin.linux.test", "101.115.92.24", "", &err)); |
| // Verify the contents of the hosts file. We are assuming an ordered map is |
| // used here (which it is in the code) to make analyzing the results easier. |
| std::string extra_contents = kBaseFileContents; |
| extra_contents += kFileModificationDelimeter; |
| extra_contents += "100.115.92.22 foo12.linux.test\n"; |
| extra_contents += "100.115.92.24 penguin.linux.test\n"; |
| extra_contents += "100.115.92.253 penguin.termina.linux.test\n"; |
| EXPECT_EQ(extra_contents, ReadHostsContents()); |
| |
| // Removing an invalid hostname should fail. |
| EXPECT_FALSE(hosts_modifier()->RemoveHostnameIpMapping("bar-local", &err)); |
| EXPECT_FALSE(hosts_modifier()->RemoveHostnameIpMapping("google.com", &err)); |
| // Removing a valid hostname should succeed. |
| EXPECT_TRUE( |
| hosts_modifier()->RemoveHostnameIpMapping("penguin.linux.test", &err)); |
| EXPECT_TRUE( |
| hosts_modifier()->RemoveHostnameIpMapping("foo12.linux.test", &err)); |
| |
| // Verify the contents of the hosts file again, there should be one entry |
| // left. |
| extra_contents = kBaseFileContents; |
| extra_contents += kFileModificationDelimeter; |
| extra_contents += "100.115.92.253 penguin.termina.linux.test\n"; |
| EXPECT_EQ(extra_contents, ReadHostsContents()); |
| } |
| |
| } // namespace crosdns |