Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / base / posix / file_descriptor_shuffle_unittest.cc
blob3dfbf7e246e5b2f9004c99c06206060e7e5f79be
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 bool Duplicate(int* result, int fd) override {
48 *result = next_duplicate_++;
49 actions_.push_back(Action(Action::DUPLICATE, *result, fd));
50 return true;
53 bool Move(int src, int dest) override {
54 actions_.push_back(Action(Action::MOVE, src, dest));
55 return true;
58 void Close(int fd) override { actions_.push_back(Action(Action::CLOSE, fd)); }
60 const std::vector<Action>& actions() const { return actions_; }
62 private:
63 int next_duplicate_;
64 std::vector<Action> actions_;
67 TEST(FileDescriptorShuffleTest, Empty) {
68 InjectiveMultimap map;
69 InjectionTracer tracer;
71 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
72 EXPECT_EQ(0u, tracer.actions().size());
75 TEST(FileDescriptorShuffleTest, Noop) {
76 InjectiveMultimap map;
77 InjectionTracer tracer;
78 map.push_back(InjectionArc(0, 0, false));
80 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
81 EXPECT_EQ(0u, tracer.actions().size());
84 TEST(FileDescriptorShuffleTest, NoopAndClose) {
85 InjectiveMultimap map;
86 InjectionTracer tracer;
87 map.push_back(InjectionArc(0, 0, true));
89 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
90 EXPECT_EQ(0u, tracer.actions().size());
93 TEST(FileDescriptorShuffleTest, Simple1) {
94 InjectiveMultimap map;
95 InjectionTracer tracer;
96 map.push_back(InjectionArc(0, 1, false));
98 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
99 ASSERT_EQ(1u, tracer.actions().size());
100 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
103 TEST(FileDescriptorShuffleTest, Simple2) {
104 InjectiveMultimap map;
105 InjectionTracer tracer;
106 map.push_back(InjectionArc(0, 1, false));
107 map.push_back(InjectionArc(2, 3, false));
109 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
110 ASSERT_EQ(2u, tracer.actions().size());
111 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
112 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 2, 3));
115 TEST(FileDescriptorShuffleTest, Simple3) {
116 InjectiveMultimap map;
117 InjectionTracer tracer;
118 map.push_back(InjectionArc(0, 1, true));
120 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
121 ASSERT_EQ(2u, tracer.actions().size());
122 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
123 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 0));
126 TEST(FileDescriptorShuffleTest, Simple4) {
127 InjectiveMultimap map;
128 InjectionTracer tracer;
129 map.push_back(InjectionArc(10, 0, true));
130 map.push_back(InjectionArc(1, 1, true));
132 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
133 ASSERT_EQ(2u, tracer.actions().size());
134 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 10, 0));
135 EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 10));
138 TEST(FileDescriptorShuffleTest, Cycle) {
139 InjectiveMultimap map;
140 InjectionTracer tracer;
141 map.push_back(InjectionArc(0, 1, false));
142 map.push_back(InjectionArc(1, 0, false));
144 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
145 ASSERT_EQ(4u, tracer.actions().size());
146 EXPECT_TRUE(tracer.actions()[0] ==
147 Action(Action::DUPLICATE, kDuplicateBase, 1));
148 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
149 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
150 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
153 TEST(FileDescriptorShuffleTest, CycleAndClose1) {
154 InjectiveMultimap map;
155 InjectionTracer tracer;
156 map.push_back(InjectionArc(0, 1, true));
157 map.push_back(InjectionArc(1, 0, false));
159 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
160 ASSERT_EQ(4u, tracer.actions().size());
161 EXPECT_TRUE(tracer.actions()[0] ==
162 Action(Action::DUPLICATE, kDuplicateBase, 1));
163 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
164 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
165 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
168 TEST(FileDescriptorShuffleTest, CycleAndClose2) {
169 InjectiveMultimap map;
170 InjectionTracer tracer;
171 map.push_back(InjectionArc(0, 1, false));
172 map.push_back(InjectionArc(1, 0, true));
174 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
175 ASSERT_EQ(4u, tracer.actions().size());
176 EXPECT_TRUE(tracer.actions()[0] ==
177 Action(Action::DUPLICATE, kDuplicateBase, 1));
178 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
179 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
180 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
183 TEST(FileDescriptorShuffleTest, CycleAndClose3) {
184 InjectiveMultimap map;
185 InjectionTracer tracer;
186 map.push_back(InjectionArc(0, 1, true));
187 map.push_back(InjectionArc(1, 0, true));
189 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
190 ASSERT_EQ(4u, tracer.actions().size());
191 EXPECT_TRUE(tracer.actions()[0] ==
192 Action(Action::DUPLICATE, kDuplicateBase, 1));
193 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
194 EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
195 EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
198 TEST(FileDescriptorShuffleTest, Fanout) {
199 InjectiveMultimap map;
200 InjectionTracer tracer;
201 map.push_back(InjectionArc(0, 1, false));
202 map.push_back(InjectionArc(0, 2, false));
204 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
205 ASSERT_EQ(2u, tracer.actions().size());
206 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
207 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
210 TEST(FileDescriptorShuffleTest, FanoutAndClose1) {
211 InjectiveMultimap map;
212 InjectionTracer tracer;
213 map.push_back(InjectionArc(0, 1, true));
214 map.push_back(InjectionArc(0, 2, false));
216 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
217 ASSERT_EQ(3u, tracer.actions().size());
218 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
219 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
220 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
223 TEST(FileDescriptorShuffleTest, FanoutAndClose2) {
224 InjectiveMultimap map;
225 InjectionTracer tracer;
226 map.push_back(InjectionArc(0, 1, false));
227 map.push_back(InjectionArc(0, 2, true));
229 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
230 ASSERT_EQ(3u, tracer.actions().size());
231 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
232 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
233 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
236 TEST(FileDescriptorShuffleTest, FanoutAndClose3) {
237 InjectiveMultimap map;
238 InjectionTracer tracer;
239 map.push_back(InjectionArc(0, 1, true));
240 map.push_back(InjectionArc(0, 2, true));
242 EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
243 ASSERT_EQ(3u, tracer.actions().size());
244 EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
245 EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
246 EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
249 class FailingDelegate : public InjectionDelegate {
250 public:
251 bool Duplicate(int* result, int fd) override { return false; }
253 bool Move(int src, int dest) override { return false; }
255 void Close(int fd) override {}
258 TEST(FileDescriptorShuffleTest, EmptyWithFailure) {
259 InjectiveMultimap map;
260 FailingDelegate failing;
262 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
265 TEST(FileDescriptorShuffleTest, NoopWithFailure) {
266 InjectiveMultimap map;
267 FailingDelegate failing;
268 map.push_back(InjectionArc(0, 0, false));
270 EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
273 TEST(FileDescriptorShuffleTest, Simple1WithFailure) {
274 InjectiveMultimap map;
275 FailingDelegate failing;
276 map.push_back(InjectionArc(0, 1, false));
278 EXPECT_FALSE(PerformInjectiveMultimap(map, &failing));
281 } // namespace base