| Index: base/file_descriptor_shuffle_unittest.cc
|
| diff --git a/base/file_descriptor_shuffle_unittest.cc b/base/file_descriptor_shuffle_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..84d6c022361cef9181e983f82a259c5f8ee3f9b7
|
| --- /dev/null
|
| +++ b/base/file_descriptor_shuffle_unittest.cc
|
| @@ -0,0 +1,290 @@
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/file_descriptor_shuffle.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using base::InjectiveMultimap;
|
| +using base::InjectionArc;
|
| +using base::PerformInjectiveMultimap;
|
| +using base::InjectionDelegate;
|
| +
|
| +namespace {
|
| +typedef testing::Test FileDescriptorShuffleTest;
|
| +}
|
| +
|
| +// 'Duplicated' file descriptors start at this number
|
| +static const int kDuplicateBase = 1000;
|
| +
|
| +struct Action {
|
| + enum Type {
|
| + CLOSE,
|
| + MOVE,
|
| + DUPLICATE,
|
| + };
|
| +
|
| + Action(Type in_type, int in_fd1, int in_fd2 = -1)
|
| + : type(in_type),
|
| + fd1(in_fd1),
|
| + fd2(in_fd2) {
|
| + }
|
| +
|
| + bool operator==(const Action& other) const {
|
| + return other.type == type &&
|
| + other.fd1 == fd1 &&
|
| + other.fd2 == fd2;
|
| + }
|
| +
|
| + Type type;
|
| + int fd1;
|
| + int fd2;
|
| +};
|
| +
|
| +class InjectionTracer : public InjectionDelegate {
|
| + public:
|
| + InjectionTracer()
|
| + : next_duplicate_(kDuplicateBase) {
|
| + }
|
| +
|
| + bool Duplicate(int* result, int fd) {
|
| + *result = next_duplicate_++;
|
| + actions_.push_back(Action(Action::DUPLICATE, *result, fd));
|
| + return true;
|
| + }
|
| +
|
| + bool Move(int src, int dest) {
|
| + actions_.push_back(Action(Action::MOVE, src, dest));
|
| + return true;
|
| + }
|
| +
|
| + void Close(int fd) {
|
| + actions_.push_back(Action(Action::CLOSE, fd));
|
| + }
|
| +
|
| + const std::vector<Action>& actions() const { return actions_; }
|
| +
|
| + private:
|
| + int next_duplicate_;
|
| + std::vector<Action> actions_;
|
| +};
|
| +
|
| +TEST(FileDescriptorShuffleTest, Empty) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(0u, tracer.actions().size());
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Noop) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 0, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(0u, tracer.actions().size());
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, NoopAndClose) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 0, true));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(0u, tracer.actions().size());
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Simple1) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(1u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Simple2) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, false));
|
| + map.push_back(InjectionArc(2, 3, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(2u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 2, 3));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Simple3) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, true));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(2u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 0));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Simple4) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(10, 0, true));
|
| + map.push_back(InjectionArc(1, 1, true));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(2u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 10, 0));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::CLOSE, 10));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Cycle) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, false));
|
| + map.push_back(InjectionArc(1, 0, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(4u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] ==
|
| + Action(Action::DUPLICATE, kDuplicateBase, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
|
| + EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, CycleAndClose1) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, true));
|
| + map.push_back(InjectionArc(1, 0, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(4u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] ==
|
| + Action(Action::DUPLICATE, kDuplicateBase, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
|
| + EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, CycleAndClose2) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, false));
|
| + map.push_back(InjectionArc(1, 0, true));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(4u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] ==
|
| + Action(Action::DUPLICATE, kDuplicateBase, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
|
| + EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, CycleAndClose3) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, true));
|
| + map.push_back(InjectionArc(1, 0, true));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(4u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] ==
|
| + Action(Action::DUPLICATE, kDuplicateBase, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[2] == Action(Action::MOVE, kDuplicateBase, 0));
|
| + EXPECT_TRUE(tracer.actions()[3] == Action(Action::CLOSE, kDuplicateBase));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Fanout) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, false));
|
| + map.push_back(InjectionArc(0, 2, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(2u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, FanoutAndClose1) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, true));
|
| + map.push_back(InjectionArc(0, 2, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(3u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
|
| + EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, FanoutAndClose2) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, false));
|
| + map.push_back(InjectionArc(0, 2, true));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(3u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
|
| + EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, FanoutAndClose3) {
|
| + InjectiveMultimap map;
|
| + InjectionTracer tracer;
|
| + map.push_back(InjectionArc(0, 1, true));
|
| + map.push_back(InjectionArc(0, 2, true));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &tracer));
|
| + EXPECT_EQ(3u, tracer.actions().size());
|
| + EXPECT_TRUE(tracer.actions()[0] == Action(Action::MOVE, 0, 1));
|
| + EXPECT_TRUE(tracer.actions()[1] == Action(Action::MOVE, 0, 2));
|
| + EXPECT_TRUE(tracer.actions()[2] == Action(Action::CLOSE, 0));
|
| +}
|
| +
|
| +class FailingDelegate : public InjectionDelegate {
|
| + public:
|
| + bool Duplicate(int* result, int fd) {
|
| + return false;
|
| + }
|
| +
|
| + bool Move(int src, int dest) {
|
| + return false;
|
| + }
|
| +
|
| + void Close(int fd) {
|
| + }
|
| +};
|
| +
|
| +TEST(FileDescriptorShuffleTest, EmptyWithFailure) {
|
| + InjectiveMultimap map;
|
| + FailingDelegate failing;
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, NoopWithFailure) {
|
| + InjectiveMultimap map;
|
| + FailingDelegate failing;
|
| + map.push_back(InjectionArc(0, 0, false));
|
| +
|
| + EXPECT_TRUE(PerformInjectiveMultimap(map, &failing));
|
| +}
|
| +
|
| +TEST(FileDescriptorShuffleTest, Simple1WithFailure) {
|
| + InjectiveMultimap map;
|
| + FailingDelegate failing;
|
| + map.push_back(InjectionArc(0, 1, false));
|
| +
|
| + EXPECT_FALSE(PerformInjectiveMultimap(map, &failing));
|
| +}
|
| +
|
|
|