blob: fddde01a51a2cd5fc3925ba7a1a71aea44d7b803 [file] [log] [blame]
Mike Frysinger8155d082012-04-06 15:23:18 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
adlr@google.com3defe6a2009-12-04 20:57:17 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <sys/stat.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <set>
9#include <string>
10#include <vector>
adlr@google.com3defe6a2009-12-04 20:57:17 +000011#include <gtest/gtest.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070012#include "base/string_util.h"
Mike Frysinger8155d082012-04-06 15:23:18 -040013#include <base/stringprintf.h>
adlr@google.com3defe6a2009-12-04 20:57:17 +000014#include "update_engine/filesystem_iterator.h"
15#include "update_engine/test_utils.h"
16#include "update_engine/utils.h"
17
18using std::set;
19using std::string;
20using std::vector;
21
22namespace chromeos_update_engine {
23
adlr@google.com3defe6a2009-12-04 20:57:17 +000024class FilesystemIteratorTest : public ::testing::Test {
25 protected:
26 virtual void SetUp() {
Gilad Arnold3db938e2013-07-01 06:45:41 -070027 ASSERT_TRUE(utils::MakeTempDirectory("FilesystemIteratorTest-XXXXXX",
28 &test_dir_));
29 LOG(INFO) << "SetUp() mkdir " << test_dir_;
adlr@google.com3defe6a2009-12-04 20:57:17 +000030 }
Gilad Arnold3db938e2013-07-01 06:45:41 -070031
adlr@google.com3defe6a2009-12-04 20:57:17 +000032 virtual void TearDown() {
Gilad Arnold3db938e2013-07-01 06:45:41 -070033 LOG(INFO) << "TearDown() rmdir " << test_dir_;
adlr@google.com3defe6a2009-12-04 20:57:17 +000034 EXPECT_EQ(0, System(StringPrintf("rm -rf %s", TestDir())));
35 }
Gilad Arnold3db938e2013-07-01 06:45:41 -070036
37 const char* TestDir() {
38 return test_dir_.c_str();
39 }
40
41 private:
42 string test_dir_;
adlr@google.com3defe6a2009-12-04 20:57:17 +000043};
44
45TEST_F(FilesystemIteratorTest, RunAsRootSuccessTest) {
46 ASSERT_EQ(0, getuid());
Gilad Arnold3db938e2013-07-01 06:45:41 -070047 string first_image;
48 ASSERT_TRUE(utils::MakeTempFile("FilesystemIteratorTest.image1-XXXXXX",
49 &first_image, NULL));
50 string sub_image;
51 ASSERT_TRUE(utils::MakeTempFile("FilesystemIteratorTest.image2-XXXXXX",
52 &sub_image, NULL));
adlr@google.com3defe6a2009-12-04 20:57:17 +000053
adlr@google.com3defe6a2009-12-04 20:57:17 +000054 vector<string> expected_paths_vector;
55 CreateExtImageAtPath(first_image, &expected_paths_vector);
56 CreateExtImageAtPath(sub_image, NULL);
57 ASSERT_EQ(0, System(string("mount -o loop ") + first_image + " " +
58 kMountPath));
59 ASSERT_EQ(0, System(string("mount -o loop ") + sub_image + " " +
60 kMountPath + "/some_dir/mnt"));
61 for (vector<string>::iterator it = expected_paths_vector.begin();
62 it != expected_paths_vector.end(); ++it)
63 *it = kMountPath + *it;
64 set<string> expected_paths(expected_paths_vector.begin(),
65 expected_paths_vector.end());
66 VerifyAllPaths(kMountPath, expected_paths);
Ben Chan77a1eba2012-10-07 22:54:55 -070067
68 EXPECT_TRUE(utils::UnmountFilesystem(kMountPath + string("/some_dir/mnt")));
69 EXPECT_TRUE(utils::UnmountFilesystem(kMountPath));
adlr@google.com3defe6a2009-12-04 20:57:17 +000070 EXPECT_EQ(0, System(string("rm -f ") + first_image + " " + sub_image));
71}
72
73TEST_F(FilesystemIteratorTest, NegativeTest) {
74 {
75 FilesystemIterator iter("/non/existent/path", set<string>());
76 EXPECT_TRUE(iter.IsEnd());
77 EXPECT_TRUE(iter.IsErr());
78 }
79
80 {
81 FilesystemIterator iter(TestDir(), set<string>());
82 EXPECT_FALSE(iter.IsEnd());
83 EXPECT_FALSE(iter.IsErr());
84 // Here I'm deleting the exact directory that iterator is point at,
85 // then incrementing (which normally would descend into that directory).
86 EXPECT_EQ(0, rmdir(TestDir()));
87 iter.Increment();
88 EXPECT_TRUE(iter.IsEnd());
89 EXPECT_FALSE(iter.IsErr());
90 }
91}
92
93TEST_F(FilesystemIteratorTest, DeleteWhileTraverseTest) {
Gilad Arnold3db938e2013-07-01 06:45:41 -070094 const string dir_name = TestDir();
95 ASSERT_EQ(0, chmod(dir_name.c_str(), 0755));
96 const string sub_dir_name(dir_name + "/a");
97 ASSERT_EQ(0, mkdir(sub_dir_name.c_str(), 0755));
98 const string sub_sub_dir_name(sub_dir_name + "/b");
99 ASSERT_EQ(0, mkdir(sub_sub_dir_name.c_str(), 0755));
100 ASSERT_EQ(0, mkdir((dir_name + "/b").c_str(), 0755));
101 ASSERT_EQ(0, mkdir((dir_name + "/c").c_str(), 0755));
adlr@google.com3defe6a2009-12-04 20:57:17 +0000102
103 string expected_paths_arr[] = {
104 "",
105 "/a",
106 "/b",
107 "/c"
108 };
109 set<string> expected_paths(expected_paths_arr,
110 expected_paths_arr +
111 arraysize(expected_paths_arr));
112
Gilad Arnold3db938e2013-07-01 06:45:41 -0700113 FilesystemIterator iter(dir_name, set<string>());
adlr@google.com3defe6a2009-12-04 20:57:17 +0000114 while (!iter.IsEnd()) {
115 string path = iter.GetPartialPath();
116 EXPECT_TRUE(expected_paths.find(path) != expected_paths.end());
117 if (expected_paths.find(path) != expected_paths.end()) {
118 expected_paths.erase(path);
119 }
120 if (path == "/a") {
Gilad Arnold3db938e2013-07-01 06:45:41 -0700121 EXPECT_EQ(0, rmdir(sub_sub_dir_name.c_str()));
122 EXPECT_EQ(0, rmdir(sub_dir_name.c_str()));
adlr@google.com3defe6a2009-12-04 20:57:17 +0000123 }
124 iter.Increment();
125 }
126 EXPECT_FALSE(iter.IsErr());
127 EXPECT_TRUE(expected_paths.empty());
adlr@google.com3defe6a2009-12-04 20:57:17 +0000128}
129
130} // namespace chromeos_update_engine