OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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. | |
4 | |
5 #include "base/file_descriptor_shuffle.h" | |
6 #include "testing/gtest/include/gtest/gtest.h" | |
7 | |
8 namespace { | |
9 | |
10 // 'Duplicated' file descriptors start at this number | |
11 const int kDuplicateBase = 1000; | |
12 | |
13 } // namespace | |
14 | |
15 namespace base { | |
16 | |
17 struct 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 | |
41 class InjectionTracer : public InjectionDelegate { | |
42 public: | |
43 InjectionTracer() | |
44 : next_duplicate_(kDuplicateBase) { | |
45 } | |
46 | |
47 virtual bool Duplicate(int* result, int fd) OVERRIDE { | |
48 *result = next_duplicate_++; | |
49 actions_.push_back(Action(Action::DUPLICATE, *result, fd)); | |
50 return true; | |
51 } | |
52 | |
53 virtual bool Move(int src, int dest) OVERRIDE { | |
54 actions_.push_back(Action(Action::MOVE, src, dest)); | |
55 return true; | |
56 } | |
57 | |
58 virtual void Close(int fd) OVERRIDE { | |
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 | |
69 TEST(FileDescriptorShuffleTest, Empty) { | |
70 InjectiveMultimap map; | |
71 InjectionTracer tracer; | |
72 | |
73 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer)); | |
74 EXPECT_EQ(0u, tracer.actions().size()); | |
75 } | |
76 | |
77 TEST(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 | |
86 TEST(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 | |
95 TEST(FileDescriptorShuffleTest, Simple1) { | |
96 InjectiveMultimap map; | |
97 InjectionTracer tracer; | |
98 map.push_back(InjectionArc(0, 1, false)); | |
99 | |
100 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer)); | |
101 ASSERT_EQ(1u, tracer.actions().size()); | |
102 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1)); | |
103 } | |
104 | |
105 TEST(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)); | |
112 ASSERT_EQ(2u, tracer.actions().size()); | |
113 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1)); | |
114 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 2, 3)); | |
115 } | |
116 | |
117 TEST(FileDescriptorShuffleTest, Simple3) { | |
118 InjectiveMultimap map; | |
119 InjectionTracer tracer; | |
120 map.push_back(InjectionArc(0, 1, true)); | |
121 | |
122 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer)); | |
123 ASSERT_EQ(2u, tracer.actions().size()); | |
124 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1)); | |
125 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 0)); | |
126 } | |
127 | |
128 TEST(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)); | |
135 ASSERT_EQ(2u, tracer.actions().size()); | |
136 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 10, 0)); | |
137 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 10)); | |
138 } | |
139 | |
140 TEST(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)); | |
147 ASSERT_EQ(4u, tracer.actions().size()); | |
148 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 | |
155 TEST(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)); | |
162 ASSERT_EQ(4u, tracer.actions().size()); | |
163 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 | |
170 TEST(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)); | |
177 ASSERT_EQ(4u, tracer.actions().size()); | |
178 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 | |
185 TEST(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)); | |
192 ASSERT_EQ(4u, tracer.actions().size()); | |
193 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 | |
200 TEST(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)); | |
207 ASSERT_EQ(2u, tracer.actions().size()); | |
208 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1)); | |
209 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2)); | |
210 } | |
211 | |
212 TEST(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)); | |
219 ASSERT_EQ(3u, tracer.actions().size()); | |
220 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 | |
225 TEST(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)); | |
232 ASSERT_EQ(3u, tracer.actions().size()); | |
233 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 | |
238 TEST(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)); | |
245 ASSERT_EQ(3u, tracer.actions().size()); | |
246 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 | |
251 class FailingDelegate : public InjectionDelegate { | |
252 public: | |
253 virtual bool Duplicate(int* result, int fd) OVERRIDE { | |
254 return false; | |
255 } | |
256 | |
257 virtual bool Move(int src, int dest) OVERRIDE { | |
258 return false; | |
259 } | |
260 | |
261 virtual void Close(int fd) OVERRIDE {} | |
262 }; | |
263 | |
264 TEST(FileDescriptorShuffleTest, EmptyWithFailure) { | |
265 InjectiveMultimap map; | |
266 FailingDelegate failing; | |
267 | |
268 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing)); | |
269 } | |
270 | |
271 TEST(FileDescriptorShuffleTest, NoopWithFailure) { | |
272 InjectiveMultimap map; | |
273 FailingDelegate failing; | |
274 map.push_back(InjectionArc(0, 0, false)); | |
275 | |
276 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing)); | |
277 } | |
278 | |
279 TEST(FileDescriptorShuffleTest, Simple1WithFailure) { | |
280 InjectiveMultimap map; | |
281 FailingDelegate failing; | |
282 map.push_back(InjectionArc(0, 1, false)); | |
283 | |
284 EXPECT_FALSE(PerformInjectiveMultimap(map, &failing)); | |
285 } | |
286 | |
287 } // namespace base | |
OLD | NEW |