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
;
14 typedef testing::Test FileDescriptorShuffleTest
;
17 // 'Duplicated' file descriptors start at this number
18 static const int kDuplicateBase
= 1000;
27 Action(Type in_type
, int in_fd1
, int in_fd2
= -1)
33 bool operator==(const Action
& other
) const {
34 return other
.type
== type
&&
44 class InjectionTracer
: public InjectionDelegate
{
47 : next_duplicate_(kDuplicateBase
) {
50 bool Duplicate(int* result
, int fd
) {
51 *result
= next_duplicate_
++;
52 actions_
.push_back(Action(Action::DUPLICATE
, *result
, fd
));
56 bool Move(int src
, int dest
) {
57 actions_
.push_back(Action(Action::MOVE
, src
, dest
));
62 actions_
.push_back(Action(Action::CLOSE
, fd
));
65 const std::vector
<Action
>& actions() const { return actions_
; }
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
{
256 bool Duplicate(int* result
, int fd
) {
260 bool Move(int src
, int dest
) {
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
));