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