| // Copyright (c) 2012 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 <sys/stat.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <set> |
| #include <string> |
| #include <vector> |
| #include <gtest/gtest.h> |
| #include <base/strings/string_util.h> |
| #include <base/strings/stringprintf.h> |
| #include "update_engine/filesystem_iterator.h" |
| #include "update_engine/test_utils.h" |
| #include "update_engine/utils.h" |
| |
| using std::set; |
| using std::string; |
| using std::vector; |
| |
| namespace chromeos_update_engine { |
| |
| class FilesystemIteratorTest : public ::testing::Test { |
| protected: |
| virtual void SetUp() { |
| ASSERT_TRUE(utils::MakeTempDirectory("FilesystemIteratorTest-XXXXXX", |
| &test_dir_)); |
| LOG(INFO) << "SetUp() mkdir " << test_dir_; |
| } |
| |
| virtual void TearDown() { |
| LOG(INFO) << "TearDown() rmdir " << test_dir_; |
| EXPECT_EQ(0, System(base::StringPrintf("rm -rf %s", TestDir()))); |
| } |
| |
| const char* TestDir() { |
| return test_dir_.c_str(); |
| } |
| |
| private: |
| string test_dir_; |
| }; |
| |
| TEST_F(FilesystemIteratorTest, RunAsRootSuccessTest) { |
| ASSERT_EQ(0, getuid()); |
| |
| // Create uniquely named main/sub images. |
| string main_image; |
| ASSERT_TRUE(utils::MakeTempFile("FilesystemIteratorTest.image1-XXXXXX", |
| &main_image, NULL)); |
| ScopedPathUnlinker main_image_unlinker(main_image); |
| |
| string sub_image; |
| ASSERT_TRUE(utils::MakeTempFile("FilesystemIteratorTest.image2-XXXXXX", |
| &sub_image, NULL)); |
| ScopedPathUnlinker sub_image_unlinker(sub_image); |
| |
| // Create uniqely named main/sub mount points. |
| string main_image_mount_point; |
| ASSERT_TRUE(utils::MakeTempDirectory( |
| "FilesystemIteratorTest.mount-XXXXXX", |
| &main_image_mount_point)); |
| ScopedPathUnlinker main_image_mount_point_unlinker(main_image_mount_point); |
| const string sub_image_mount_point = main_image_mount_point + "/some_dir/mnt"; |
| |
| vector<string> expected_paths_vector; |
| CreateExtImageAtPath(main_image, &expected_paths_vector); |
| CreateExtImageAtPath(sub_image, NULL); |
| ASSERT_EQ(0, System(string("mount -o loop ") + main_image + " " + |
| main_image_mount_point)); |
| ASSERT_EQ(0, System(string("mount -o loop ") + sub_image + " " + |
| sub_image_mount_point)); |
| for (vector<string>::iterator it = expected_paths_vector.begin(); |
| it != expected_paths_vector.end(); ++it) |
| *it = main_image_mount_point + *it; |
| set<string> expected_paths(expected_paths_vector.begin(), |
| expected_paths_vector.end()); |
| VerifyAllPaths(main_image_mount_point, expected_paths); |
| |
| EXPECT_TRUE(utils::UnmountFilesystem(sub_image_mount_point)); |
| EXPECT_TRUE(utils::UnmountFilesystem(main_image_mount_point)); |
| } |
| |
| TEST_F(FilesystemIteratorTest, NegativeTest) { |
| { |
| FilesystemIterator iter("/non/existent/path", set<string>()); |
| EXPECT_TRUE(iter.IsEnd()); |
| EXPECT_TRUE(iter.IsErr()); |
| } |
| |
| { |
| FilesystemIterator iter(TestDir(), set<string>()); |
| EXPECT_FALSE(iter.IsEnd()); |
| EXPECT_FALSE(iter.IsErr()); |
| // Here I'm deleting the exact directory that iterator is point at, |
| // then incrementing (which normally would descend into that directory). |
| EXPECT_EQ(0, rmdir(TestDir())); |
| iter.Increment(); |
| EXPECT_TRUE(iter.IsEnd()); |
| EXPECT_FALSE(iter.IsErr()); |
| } |
| } |
| |
| TEST_F(FilesystemIteratorTest, DeleteWhileTraverseTest) { |
| const string dir_name = TestDir(); |
| ASSERT_EQ(0, chmod(dir_name.c_str(), 0755)); |
| const string sub_dir_name(dir_name + "/a"); |
| ASSERT_EQ(0, mkdir(sub_dir_name.c_str(), 0755)); |
| const string sub_sub_dir_name(sub_dir_name + "/b"); |
| ASSERT_EQ(0, mkdir(sub_sub_dir_name.c_str(), 0755)); |
| ASSERT_EQ(0, mkdir((dir_name + "/b").c_str(), 0755)); |
| ASSERT_EQ(0, mkdir((dir_name + "/c").c_str(), 0755)); |
| |
| string expected_paths_arr[] = { |
| "", |
| "/a", |
| "/b", |
| "/c" |
| }; |
| set<string> expected_paths(expected_paths_arr, |
| expected_paths_arr + |
| arraysize(expected_paths_arr)); |
| |
| FilesystemIterator iter(dir_name, set<string>()); |
| while (!iter.IsEnd()) { |
| string path = iter.GetPartialPath(); |
| EXPECT_TRUE(expected_paths.find(path) != expected_paths.end()); |
| if (expected_paths.find(path) != expected_paths.end()) { |
| expected_paths.erase(path); |
| } |
| if (path == "/a") { |
| EXPECT_EQ(0, rmdir(sub_sub_dir_name.c_str())); |
| EXPECT_EQ(0, rmdir(sub_dir_name.c_str())); |
| } |
| iter.Increment(); |
| } |
| EXPECT_FALSE(iter.IsErr()); |
| EXPECT_TRUE(expected_paths.empty()); |
| } |
| |
| } // namespace chromeos_update_engine |