WebKit Roll 77375:77377.
[chromium-blink-merge.git] / base / file_descriptor_shuffle_unittest.cc
bloba4a703a8eb18f34e6eaa9bd759bcac9c398e084e
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/file_descriptor_shuffle.h"
6 #include "testing/gtest/include/gtest/gtest.h"
8 using base::InjectiveMultimap;
9 using base::InjectionArc;
10 using base::PerformInjectiveMultimap;
11 using base::InjectionDelegate;
13 namespace {
14 typedef testing::Test FileDescriptorShuffleTest;
17 // 'Duplicated' file descriptors start at this number
18 static const int kDuplicateBase = 1000;
20 struct Action {
21 enum Type {
22 CLOSE,
23 MOVE,
24 DUPLICATE,
27 Action(Type in_type, int in_fd1, int in_fd2 = -1)
28 : type(in_type),
29 fd1(in_fd1),
30 fd2(in_fd2) {
33 bool operator==(const Action& other) const {
34 return other.type == type &&
35 other.fd1 == fd1 &&
36 other.fd2 == fd2;
39 Type type;
40 int fd1;
41 int fd2;
44 class InjectionTracer : public InjectionDelegate {
45 public:
46 InjectionTracer()
47 : next_duplicate_(kDuplicateBase) {
50 bool Duplicate(int* result, int fd) {
51 *result = next_duplicate_++;
52 actions_.push_back(Action(Action::DUPLICATE, *result, fd));
53 return true;
56 bool Move(int src, int dest) {
57 actions_.push_back(Action(Action::MOVE, src, dest));
58 return true;
61 void Close(int fd) {
62 actions_.push_back(Action(Action::CLOSE, fd));
65 const std::vector<Action>& actions() const { return actions_; }
67 private:
68 int next_duplicate_;
69 std::vector<Action> actions_;
72 TEST(FileDescriptorShuffleTest, Empty) {
73 InjectiveMultimap map;
74 InjectionTracer tracer;
76 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
77 EXPECT_EQ(0u, tracer.actions().size());
80 TEST(FileDescriptorShuffleTest, Noop) {
81 InjectiveMultimap map;
82 InjectionTracer tracer;
83 map.push_back(InjectionArc(0, 0, false));
85 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
86 EXPECT_EQ(0u, tracer.actions().size());
89 TEST(FileDescriptorShuffleTest, NoopAndClose) {
90 InjectiveMultimap map;
91 InjectionTracer tracer;
92 map.push_back(InjectionArc(0, 0, true));
94 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
95 EXPECT_EQ(0u, tracer.actions().size());
98 TEST(FileDescriptorShuffleTest, Simple1) {
99 InjectiveMultimap map;
100 InjectionTracer tracer;
101 map.push_back(InjectionArc(0, 1, false));
103 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
104 ASSERT_EQ(1u, tracer.actions().size());
105 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
108 TEST(FileDescriptorShuffleTest, Simple2) {
109 InjectiveMultimap map;
110 InjectionTracer tracer;
111 map.push_back(InjectionArc(0, 1, false));
112 map.push_back(InjectionArc(2, 3, false));
114 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
115 ASSERT_EQ(2u, tracer.actions().size());
116 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
117 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 2, 3));
120 TEST(FileDescriptorShuffleTest, Simple3) {
121 InjectiveMultimap map;
122 InjectionTracer tracer;
123 map.push_back(InjectionArc(0, 1, true));
125 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
126 ASSERT_EQ(2u, tracer.actions().size());
127 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
128 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 0));
131 TEST(FileDescriptorShuffleTest, Simple4) {
132 InjectiveMultimap map;
133 InjectionTracer tracer;
134 map.push_back(InjectionArc(10, 0, true));
135 map.push_back(InjectionArc(1, 1, true));
137 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
138 ASSERT_EQ(2u, tracer.actions().size());
139 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 10, 0));
140 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 10));
143 TEST(FileDescriptorShuffleTest, Cycle) {
144 InjectiveMultimap map;
145 InjectionTracer tracer;
146 map.push_back(InjectionArc(0, 1, false));
147 map.push_back(InjectionArc(1, 0, false));
149 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
150 ASSERT_EQ(4u, tracer.actions().size());
151 EXPECT_TRUE(tracer.actions()[0] ==
152 Action(Action::DUPLICATE, kDuplicateBase, 1));
153 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
154 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
155 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
158 TEST(FileDescriptorShuffleTest, CycleAndClose1) {
159 InjectiveMultimap map;
160 InjectionTracer tracer;
161 map.push_back(InjectionArc(0, 1, true));
162 map.push_back(InjectionArc(1, 0, false));
164 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
165 ASSERT_EQ(4u, tracer.actions().size());
166 EXPECT_TRUE(tracer.actions()[0] ==
167 Action(Action::DUPLICATE, kDuplicateBase, 1));
168 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
169 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
170 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
173 TEST(FileDescriptorShuffleTest, CycleAndClose2) {
174 InjectiveMultimap map;
175 InjectionTracer tracer;
176 map.push_back(InjectionArc(0, 1, false));
177 map.push_back(InjectionArc(1, 0, true));
179 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
180 ASSERT_EQ(4u, tracer.actions().size());
181 EXPECT_TRUE(tracer.actions()[0] ==
182 Action(Action::DUPLICATE, kDuplicateBase, 1));
183 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
184 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
185 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
188 TEST(FileDescriptorShuffleTest, CycleAndClose3) {
189 InjectiveMultimap map;
190 InjectionTracer tracer;
191 map.push_back(InjectionArc(0, 1, true));
192 map.push_back(InjectionArc(1, 0, true));
194 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
195 ASSERT_EQ(4u, tracer.actions().size());
196 EXPECT_TRUE(tracer.actions()[0] ==
197 Action(Action::DUPLICATE, kDuplicateBase, 1));
198 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
199 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
200 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
203 TEST(FileDescriptorShuffleTest, Fanout) {
204 InjectiveMultimap map;
205 InjectionTracer tracer;
206 map.push_back(InjectionArc(0, 1, false));
207 map.push_back(InjectionArc(0, 2, false));
209 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
210 ASSERT_EQ(2u, tracer.actions().size());
211 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
212 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
215 TEST(FileDescriptorShuffleTest, FanoutAndClose1) {
216 InjectiveMultimap map;
217 InjectionTracer tracer;
218 map.push_back(InjectionArc(0, 1, true));
219 map.push_back(InjectionArc(0, 2, false));
221 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
222 ASSERT_EQ(3u, tracer.actions().size());
223 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
224 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
225 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
228 TEST(FileDescriptorShuffleTest, FanoutAndClose2) {
229 InjectiveMultimap map;
230 InjectionTracer tracer;
231 map.push_back(InjectionArc(0, 1, false));
232 map.push_back(InjectionArc(0, 2, true));
234 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
235 ASSERT_EQ(3u, tracer.actions().size());
236 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
237 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
238 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
241 TEST(FileDescriptorShuffleTest, FanoutAndClose3) {
242 InjectiveMultimap map;
243 InjectionTracer tracer;
244 map.push_back(InjectionArc(0, 1, true));
245 map.push_back(InjectionArc(0, 2, true));
247 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
248 ASSERT_EQ(3u, tracer.actions().size());
249 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
250 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
251 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
254 class FailingDelegate : public InjectionDelegate {
255 public:
256 bool Duplicate(int* result, int fd) {
257 return false;
260 bool Move(int src, int dest) {
261 return false;
264 void Close(int fd) {
268 TEST(FileDescriptorShuffleTest, EmptyWithFailure) {
269 InjectiveMultimap map;
270 FailingDelegate failing;
272 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
275 TEST(FileDescriptorShuffleTest, NoopWithFailure) {
276 InjectiveMultimap map;
277 FailingDelegate failing;
278 map.push_back(InjectionArc(0, 0, false));
280 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
283 TEST(FileDescriptorShuffleTest, Simple1WithFailure) {
284 InjectiveMultimap map;
285 FailingDelegate failing;
286 map.push_back(InjectionArc(0, 1, false));
288 EXPECT_FALSE(PerformInjectiveMultimap(map, &failing));