blob: 34ef465edc05cb5e519ef414b3b76e6243e8c418 [file] [log] [blame]
pkasting@chromium.org9687a8f2011-09-01 09:50:13 +09001// Copyright (c) 2011 The Chromium Authors. All rights reserved.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This test is POSIX only.
6
dmaclach@chromium.orgc1d3d422010-12-20 15:59:23 +09007#include "ipc/file_descriptor_set_posix.h"
8
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09009#include <unistd.h>
10#include <fcntl.h>
11
12#include "base/basictypes.h"
brettw@chromium.orgb1788fb2012-11-15 05:54:35 +090013#include "base/posix/eintr_wrapper.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090014#include "testing/gtest/include/gtest/gtest.h"
15
16namespace {
17
18// Get a safe file descriptor for test purposes.
19int GetSafeFd() {
20 return open("/dev/null", O_RDONLY);
21}
22
23// Returns true if fd was already closed. Closes fd if not closed.
24bool VerifyClosed(int fd) {
25 const int duped = dup(fd);
26 if (duped != -1) {
mark@chromium.orgfa5a0f92013-12-03 23:10:59 +090027 EXPECT_NE(IGNORE_EINTR(close(duped)), -1);
28 EXPECT_NE(IGNORE_EINTR(close(fd)), -1);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090029 return false;
30 }
31 return true;
32}
33
34// The FileDescriptorSet will try and close some of the descriptor numbers
35// which we given it. This is the base descriptor value. It's great enough such
36// that no real descriptor will accidently be closed.
37static const int kFDBase = 50000;
38
39TEST(FileDescriptorSet, BasicAdd) {
thakis@chromium.org625aa232010-11-01 13:16:27 +090040 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090041
42 ASSERT_EQ(set->size(), 0u);
43 ASSERT_TRUE(set->empty());
morritaab207252014-09-25 05:11:45 +090044 ASSERT_TRUE(set->AddToBorrow(kFDBase));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090045 ASSERT_EQ(set->size(), 1u);
46 ASSERT_TRUE(!set->empty());
47
48 // Empties the set and stops a warning about deleting a set with unconsumed
49 // descriptors
50 set->CommitAll();
51}
52
53TEST(FileDescriptorSet, BasicAddAndClose) {
thakis@chromium.org625aa232010-11-01 13:16:27 +090054 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090055
56 ASSERT_EQ(set->size(), 0u);
57 ASSERT_TRUE(set->empty());
58 const int fd = GetSafeFd();
morritaab207252014-09-25 05:11:45 +090059 ASSERT_TRUE(set->AddToOwn(base::ScopedFD(fd)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090060 ASSERT_EQ(set->size(), 1u);
61 ASSERT_TRUE(!set->empty());
62
63 set->CommitAll();
64
65 ASSERT_TRUE(VerifyClosed(fd));
66}
67TEST(FileDescriptorSet, MaxSize) {
thakis@chromium.org625aa232010-11-01 13:16:27 +090068 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090069
pkasting@chromium.org9687a8f2011-09-01 09:50:13 +090070 for (size_t i = 0; i < FileDescriptorSet::kMaxDescriptorsPerMessage; ++i)
morritaab207252014-09-25 05:11:45 +090071 ASSERT_TRUE(set->AddToBorrow(kFDBase + 1 + i));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090072
morritaab207252014-09-25 05:11:45 +090073 ASSERT_TRUE(!set->AddToBorrow(kFDBase));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090074
75 set->CommitAll();
76}
77
78TEST(FileDescriptorSet, SetDescriptors) {
thakis@chromium.org625aa232010-11-01 13:16:27 +090079 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090080
81 ASSERT_TRUE(set->empty());
morritaab207252014-09-25 05:11:45 +090082 set->AddDescriptorsToOwn(NULL, 0);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090083 ASSERT_TRUE(set->empty());
84
85 const int fd = GetSafeFd();
86 static const int fds[] = {fd};
morritaab207252014-09-25 05:11:45 +090087 set->AddDescriptorsToOwn(fds, 1);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090088 ASSERT_TRUE(!set->empty());
89 ASSERT_EQ(set->size(), 1u);
90
91 set->CommitAll();
92
93 ASSERT_TRUE(VerifyClosed(fd));
94}
95
morritaab207252014-09-25 05:11:45 +090096TEST(FileDescriptorSet, PeekDescriptors) {
thakis@chromium.org625aa232010-11-01 13:16:27 +090097 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090098
morritaab207252014-09-25 05:11:45 +090099 set->PeekDescriptors(NULL);
100 ASSERT_TRUE(set->AddToBorrow(kFDBase));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900101
102 int fds[1];
103 fds[0] = 0;
morritaab207252014-09-25 05:11:45 +0900104 set->PeekDescriptors(fds);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900105 ASSERT_EQ(fds[0], kFDBase);
106 set->CommitAll();
107 ASSERT_TRUE(set->empty());
108}
109
110TEST(FileDescriptorSet, WalkInOrder) {
thakis@chromium.org625aa232010-11-01 13:16:27 +0900111 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900112
morritaab207252014-09-25 05:11:45 +0900113 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
114 // used to retrieve borrowed descriptors. That never happens in production.
115 ASSERT_TRUE(set->AddToBorrow(kFDBase));
116 ASSERT_TRUE(set->AddToBorrow(kFDBase + 1));
117 ASSERT_TRUE(set->AddToBorrow(kFDBase + 2));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900118
morritaab207252014-09-25 05:11:45 +0900119 ASSERT_EQ(set->TakeDescriptorAt(0), kFDBase);
120 ASSERT_EQ(set->TakeDescriptorAt(1), kFDBase + 1);
121 ASSERT_EQ(set->TakeDescriptorAt(2), kFDBase + 2);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900122
123 set->CommitAll();
124}
125
126TEST(FileDescriptorSet, WalkWrongOrder) {
thakis@chromium.org625aa232010-11-01 13:16:27 +0900127 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900128
morritaab207252014-09-25 05:11:45 +0900129 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
130 // used to retrieve borrowed descriptors. That never happens in production.
131 ASSERT_TRUE(set->AddToBorrow(kFDBase));
132 ASSERT_TRUE(set->AddToBorrow(kFDBase + 1));
133 ASSERT_TRUE(set->AddToBorrow(kFDBase + 2));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900134
morritaab207252014-09-25 05:11:45 +0900135 ASSERT_EQ(set->TakeDescriptorAt(0), kFDBase);
136 ASSERT_EQ(set->TakeDescriptorAt(2), -1);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900137
138 set->CommitAll();
139}
140
141TEST(FileDescriptorSet, WalkCycle) {
thakis@chromium.org625aa232010-11-01 13:16:27 +0900142 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900143
morritaab207252014-09-25 05:11:45 +0900144 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
145 // used to retrieve borrowed descriptors. That never happens in production.
146 ASSERT_TRUE(set->AddToBorrow(kFDBase));
147 ASSERT_TRUE(set->AddToBorrow(kFDBase + 1));
148 ASSERT_TRUE(set->AddToBorrow(kFDBase + 2));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900149
morritaab207252014-09-25 05:11:45 +0900150 ASSERT_EQ(set->TakeDescriptorAt(0), kFDBase);
151 ASSERT_EQ(set->TakeDescriptorAt(1), kFDBase + 1);
152 ASSERT_EQ(set->TakeDescriptorAt(2), kFDBase + 2);
153 ASSERT_EQ(set->TakeDescriptorAt(0), kFDBase);
154 ASSERT_EQ(set->TakeDescriptorAt(1), kFDBase + 1);
155 ASSERT_EQ(set->TakeDescriptorAt(2), kFDBase + 2);
156 ASSERT_EQ(set->TakeDescriptorAt(0), kFDBase);
157 ASSERT_EQ(set->TakeDescriptorAt(1), kFDBase + 1);
158 ASSERT_EQ(set->TakeDescriptorAt(2), kFDBase + 2);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900159
160 set->CommitAll();
161}
162
163TEST(FileDescriptorSet, DontClose) {
thakis@chromium.org625aa232010-11-01 13:16:27 +0900164 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900165
166 const int fd = GetSafeFd();
morritaab207252014-09-25 05:11:45 +0900167 ASSERT_TRUE(set->AddToBorrow(fd));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900168 set->CommitAll();
169
170 ASSERT_FALSE(VerifyClosed(fd));
171}
172
173TEST(FileDescriptorSet, DoClose) {
thakis@chromium.org625aa232010-11-01 13:16:27 +0900174 scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900175
176 const int fd = GetSafeFd();
morritaab207252014-09-25 05:11:45 +0900177 ASSERT_TRUE(set->AddToOwn(base::ScopedFD(fd)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900178 set->CommitAll();
179
180 ASSERT_TRUE(VerifyClosed(fd));
181}
182
183} // namespace