1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
// 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
|