blob: 9b3f9597c649caf09cbe0b7963ec6cc9185c995d [file] [log] [blame]
[email protected]58b916e2011-06-28 22:56:331// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]3f04f2b2009-04-30 19:40:032// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/file_descriptor_shuffle.h"
6#include "testing/gtest/include/gtest/gtest.h"
7
[email protected]3f04f2b2009-04-30 19:40:038namespace {
[email protected]3f04f2b2009-04-30 19:40:039
10// 'Duplicated' file descriptors start at this number
[email protected]58b916e2011-06-28 22:56:3311const int kDuplicateBase = 1000;
12
13} // namespace
14
15namespace base {
[email protected]3f04f2b2009-04-30 19:40:0316
17struct Action {
18 enum Type {
19 CLOSE,
20 MOVE,
21 DUPLICATE,
22 };
23
24 Action(Type in_type, int in_fd1, int in_fd2 = -1)
25 : type(in_type),
26 fd1(in_fd1),
27 fd2(in_fd2) {
28 }
29
30 bool operator==(const Action& other) const {
31 return other.type == type &&
32 other.fd1 == fd1 &&
33 other.fd2 == fd2;
34 }
35
36 Type type;
37 int fd1;
38 int fd2;
39};
40
41class InjectionTracer : public InjectionDelegate {
42 public:
43 InjectionTracer()
44 : next_duplicate_(kDuplicateBase) {
45 }
46
47 bool Duplicate(int* result, int fd) {
48 *result = next_duplicate_++;
49 actions_.push_back(Action(Action::DUPLICATE, *result, fd));
50 return true;
51 }
52
53 bool Move(int src, int dest) {
54 actions_.push_back(Action(Action::MOVE, src, dest));
55 return true;
56 }
57
58 void Close(int fd) {
59 actions_.push_back(Action(Action::CLOSE, fd));
60 }
61
62 const std::vector<Action>& actions() const { return actions_; }
63
64 private:
65 int next_duplicate_;
66 std::vector<Action> actions_;
67};
68
69TEST(FileDescriptorShuffleTest, Empty) {
70 InjectiveMultimap map;
71 InjectionTracer tracer;
72
73 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
74 EXPECT_EQ(0u, tracer.actions().size());
75}
76
77TEST(FileDescriptorShuffleTest, Noop) {
78 InjectiveMultimap map;
79 InjectionTracer tracer;
80 map.push_back(InjectionArc(0, 0, false));
81
82 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
83 EXPECT_EQ(0u, tracer.actions().size());
84}
85
86TEST(FileDescriptorShuffleTest, NoopAndClose) {
87 InjectiveMultimap map;
88 InjectionTracer tracer;
89 map.push_back(InjectionArc(0, 0, true));
90
91 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
92 EXPECT_EQ(0u, tracer.actions().size());
93}
94
95TEST(FileDescriptorShuffleTest, Simple1) {
96 InjectiveMultimap map;
97 InjectionTracer tracer;
98 map.push_back(InjectionArc(0, 1, false));
99
100 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52101 ASSERT_EQ(1u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03102 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
103}
104
105TEST(FileDescriptorShuffleTest, Simple2) {
106 InjectiveMultimap map;
107 InjectionTracer tracer;
108 map.push_back(InjectionArc(0, 1, false));
109 map.push_back(InjectionArc(2, 3, false));
110
111 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52112 ASSERT_EQ(2u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03113 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
114 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 2, 3));
115}
116
117TEST(FileDescriptorShuffleTest, Simple3) {
118 InjectiveMultimap map;
119 InjectionTracer tracer;
120 map.push_back(InjectionArc(0, 1, true));
121
122 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52123 ASSERT_EQ(2u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03124 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
125 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 0));
126}
127
128TEST(FileDescriptorShuffleTest, Simple4) {
129 InjectiveMultimap map;
130 InjectionTracer tracer;
131 map.push_back(InjectionArc(10, 0, true));
132 map.push_back(InjectionArc(1, 1, true));
133
134 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52135 ASSERT_EQ(2u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03136 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 10, 0));
137 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 10));
138}
139
140TEST(FileDescriptorShuffleTest, Cycle) {
141 InjectiveMultimap map;
142 InjectionTracer tracer;
143 map.push_back(InjectionArc(0, 1, false));
144 map.push_back(InjectionArc(1, 0, false));
145
146 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52147 ASSERT_EQ(4u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03148 EXPECT_TRUE(tracer.actions()[0] ==
149 Action(Action::DUPLICATE, kDuplicateBase, 1));
150 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
151 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
152 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
153}
154
155TEST(FileDescriptorShuffleTest, CycleAndClose1) {
156 InjectiveMultimap map;
157 InjectionTracer tracer;
158 map.push_back(InjectionArc(0, 1, true));
159 map.push_back(InjectionArc(1, 0, false));
160
161 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52162 ASSERT_EQ(4u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03163 EXPECT_TRUE(tracer.actions()[0] ==
164 Action(Action::DUPLICATE, kDuplicateBase, 1));
165 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
166 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
167 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
168}
169
170TEST(FileDescriptorShuffleTest, CycleAndClose2) {
171 InjectiveMultimap map;
172 InjectionTracer tracer;
173 map.push_back(InjectionArc(0, 1, false));
174 map.push_back(InjectionArc(1, 0, true));
175
176 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52177 ASSERT_EQ(4u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03178 EXPECT_TRUE(tracer.actions()[0] ==
179 Action(Action::DUPLICATE, kDuplicateBase, 1));
180 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
181 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
182 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
183}
184
185TEST(FileDescriptorShuffleTest, CycleAndClose3) {
186 InjectiveMultimap map;
187 InjectionTracer tracer;
188 map.push_back(InjectionArc(0, 1, true));
189 map.push_back(InjectionArc(1, 0, true));
190
191 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52192 ASSERT_EQ(4u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03193 EXPECT_TRUE(tracer.actions()[0] ==
194 Action(Action::DUPLICATE, kDuplicateBase, 1));
195 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
196 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
197 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
198}
199
200TEST(FileDescriptorShuffleTest, Fanout) {
201 InjectiveMultimap map;
202 InjectionTracer tracer;
203 map.push_back(InjectionArc(0, 1, false));
204 map.push_back(InjectionArc(0, 2, false));
205
206 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52207 ASSERT_EQ(2u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03208 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
209 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
210}
211
212TEST(FileDescriptorShuffleTest, FanoutAndClose1) {
213 InjectiveMultimap map;
214 InjectionTracer tracer;
215 map.push_back(InjectionArc(0, 1, true));
216 map.push_back(InjectionArc(0, 2, false));
217
218 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52219 ASSERT_EQ(3u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03220 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
221 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
222 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
223}
224
225TEST(FileDescriptorShuffleTest, FanoutAndClose2) {
226 InjectiveMultimap map;
227 InjectionTracer tracer;
228 map.push_back(InjectionArc(0, 1, false));
229 map.push_back(InjectionArc(0, 2, true));
230
231 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52232 ASSERT_EQ(3u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03233 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
234 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
235 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
236}
237
238TEST(FileDescriptorShuffleTest, FanoutAndClose3) {
239 InjectiveMultimap map;
240 InjectionTracer tracer;
241 map.push_back(InjectionArc(0, 1, true));
242 map.push_back(InjectionArc(0, 2, true));
243
244 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
[email protected]4fab4ac2009-12-15 10:09:52245 ASSERT_EQ(3u, tracer.actions().size());
[email protected]3f04f2b2009-04-30 19:40:03246 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
247 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
248 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
249}
250
251class FailingDelegate : public InjectionDelegate {
252 public:
253 bool Duplicate(int* result, int fd) {
254 return false;
255 }
256
257 bool Move(int src, int dest) {
258 return false;
259 }
260
261 void Close(int fd) {
262 }
263};
264
265TEST(FileDescriptorShuffleTest, EmptyWithFailure) {
266 InjectiveMultimap map;
267 FailingDelegate failing;
268
269 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
270}
271
272TEST(FileDescriptorShuffleTest, NoopWithFailure) {
273 InjectiveMultimap map;
274 FailingDelegate failing;
275 map.push_back(InjectionArc(0, 0, false));
276
277 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
278}
279
280TEST(FileDescriptorShuffleTest, Simple1WithFailure) {
281 InjectiveMultimap map;
282 FailingDelegate failing;
283 map.push_back(InjectionArc(0, 1, false));
284
285 EXPECT_FALSE(PerformInjectiveMultimap(map, &failing));
286}
[email protected]58b916e2011-06-28 22:56:33287
288} // namespace base