Roll breakpad a513e85:7caf028 (svn 1384:1385)
[chromium-blink-merge.git] / base / posix / file_descriptor_shuffle_unittest.cc
blob9e1b25000e203796659f0bf2caad2de4df084b3d
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.
5 #include "base/posix/file_descriptor_shuffle.h"
6 #include "testing/gtest/include/gtest/gtest.h"
8 namespace {
10 // 'Duplicated' file descriptors start at this number
11 const int kDuplicateBase = 1000;
13 } // namespace
15 namespace base {
17 struct Action {
18 enum Type {
19 CLOSE,
20 MOVE,
21 DUPLICATE,
24 Action(Type in_type, int in_fd1, int in_fd2 = -1)
25 : type(in_type),
26 fd1(in_fd1),
27 fd2(in_fd2) {
30 bool operator==(const Action& other) const {
31 return other.type == type &&
32 other.fd1 == fd1 &&
33 other.fd2 == fd2;
36 Type type;
37 int fd1;
38 int fd2;
41 class InjectionTracer : public InjectionDelegate {
42 public:
43 InjectionTracer()
44 : next_duplicate_(kDuplicateBase) {
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;
53 virtual bool Move(int src, int dest) OVERRIDE {
54 actions_.push_back(Action(Action::MOVE, src, dest));
55 return true;
58 virtual void Close(int fd) OVERRIDE {
59 actions_.push_back(Action(Action::CLOSE, fd));
62 const std::vector<Action>& actions() const { return actions_; }
64 private:
65 int next_duplicate_;
66 std::vector<Action> actions_;
69 TEST(FileDescriptorShuffleTest, Empty) {
70 InjectiveMultimap map;
71 InjectionTracer tracer;
73 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
74 EXPECT_EQ(0u, tracer.actions().size());
77 TEST(FileDescriptorShuffleTest, Noop) {
78 InjectiveMultimap map;
79 InjectionTracer tracer;
80 map.push_back(InjectionArc(0, 0, false));
82 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
83 EXPECT_EQ(0u, tracer.actions().size());
86 TEST(FileDescriptorShuffleTest, NoopAndClose) {
87 InjectiveMultimap map;
88 InjectionTracer tracer;
89 map.push_back(InjectionArc(0, 0, true));
91 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
92 EXPECT_EQ(0u, tracer.actions().size());
95 TEST(FileDescriptorShuffleTest, Simple1) {
96 InjectiveMultimap map;
97 InjectionTracer tracer;
98 map.push_back(InjectionArc(0, 1, false));
100 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
101 ASSERT_EQ(1u, tracer.actions().size());
102 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
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));
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));
117 TEST(FileDescriptorShuffleTest, Simple3) {
118 InjectiveMultimap map;
119 InjectionTracer tracer;
120 map.push_back(InjectionArc(0, 1, true));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
251 class FailingDelegate : public InjectionDelegate {
252 public:
253 virtual bool Duplicate(int* result, int fd) OVERRIDE {
254 return false;
257 virtual bool Move(int src, int dest) OVERRIDE {
258 return false;
261 virtual void Close(int fd) OVERRIDE {}
264 TEST(FileDescriptorShuffleTest, EmptyWithFailure) {
265 InjectiveMultimap map;
266 FailingDelegate failing;
268 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
271 TEST(FileDescriptorShuffleTest, NoopWithFailure) {
272 InjectiveMultimap map;
273 FailingDelegate failing;
274 map.push_back(InjectionArc(0, 0, false));
276 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
279 TEST(FileDescriptorShuffleTest, Simple1WithFailure) {
280 InjectiveMultimap map;
281 FailingDelegate failing;
282 map.push_back(InjectionArc(0, 1, false));
284 EXPECT_FALSE(PerformInjectiveMultimap(map, &failing));
287 } // namespace base