• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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.
4 
5 // This test is POSIX only.
6 
7 #include "ipc/file_descriptor_set_posix.h"
8 
9 #include <unistd.h>
10 #include <fcntl.h>
11 
12 #include "base/basictypes.h"
13 #include "base/posix/eintr_wrapper.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 namespace {
17 
18 // Get a safe file descriptor for test purposes.
GetSafeFd()19 int GetSafeFd() {
20   return open("/dev/null", O_RDONLY);
21 }
22 
23 // Returns true if fd was already closed.  Closes fd if not closed.
VerifyClosed(int fd)24 bool VerifyClosed(int fd) {
25   const int duped = dup(fd);
26   if (duped != -1) {
27     EXPECT_NE(IGNORE_EINTR(close(duped)), -1);
28     EXPECT_NE(IGNORE_EINTR(close(fd)), -1);
29     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.
37 static const int kFDBase = 50000;
38 
TEST(FileDescriptorSet,BasicAdd)39 TEST(FileDescriptorSet, BasicAdd) {
40   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
41 
42   ASSERT_EQ(set->size(), 0u);
43   ASSERT_TRUE(set->empty());
44   ASSERT_TRUE(set->Add(kFDBase));
45   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 
TEST(FileDescriptorSet,BasicAddAndClose)53 TEST(FileDescriptorSet, BasicAddAndClose) {
54   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
55 
56   ASSERT_EQ(set->size(), 0u);
57   ASSERT_TRUE(set->empty());
58   const int fd = GetSafeFd();
59   ASSERT_TRUE(set->AddAndAutoClose(fd));
60   ASSERT_EQ(set->size(), 1u);
61   ASSERT_TRUE(!set->empty());
62 
63   set->CommitAll();
64 
65   ASSERT_TRUE(VerifyClosed(fd));
66 }
TEST(FileDescriptorSet,MaxSize)67 TEST(FileDescriptorSet, MaxSize) {
68   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
69 
70   for (size_t i = 0; i < FileDescriptorSet::kMaxDescriptorsPerMessage; ++i)
71     ASSERT_TRUE(set->Add(kFDBase + 1 + i));
72 
73   ASSERT_TRUE(!set->Add(kFDBase));
74 
75   set->CommitAll();
76 }
77 
TEST(FileDescriptorSet,SetDescriptors)78 TEST(FileDescriptorSet, SetDescriptors) {
79   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
80 
81   ASSERT_TRUE(set->empty());
82   set->SetDescriptors(NULL, 0);
83   ASSERT_TRUE(set->empty());
84 
85   const int fd = GetSafeFd();
86   static const int fds[] = {fd};
87   set->SetDescriptors(fds, 1);
88   ASSERT_TRUE(!set->empty());
89   ASSERT_EQ(set->size(), 1u);
90 
91   set->CommitAll();
92 
93   ASSERT_TRUE(VerifyClosed(fd));
94 }
95 
TEST(FileDescriptorSet,GetDescriptors)96 TEST(FileDescriptorSet, GetDescriptors) {
97   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
98 
99   set->GetDescriptors(NULL);
100   ASSERT_TRUE(set->Add(kFDBase));
101 
102   int fds[1];
103   fds[0] = 0;
104   set->GetDescriptors(fds);
105   ASSERT_EQ(fds[0], kFDBase);
106   set->CommitAll();
107   ASSERT_TRUE(set->empty());
108 }
109 
TEST(FileDescriptorSet,WalkInOrder)110 TEST(FileDescriptorSet, WalkInOrder) {
111   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
112 
113   ASSERT_TRUE(set->Add(kFDBase));
114   ASSERT_TRUE(set->Add(kFDBase + 1));
115   ASSERT_TRUE(set->Add(kFDBase + 2));
116 
117   ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
118   ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
119   ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
120 
121   set->CommitAll();
122 }
123 
TEST(FileDescriptorSet,WalkWrongOrder)124 TEST(FileDescriptorSet, WalkWrongOrder) {
125   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
126 
127   ASSERT_TRUE(set->Add(kFDBase));
128   ASSERT_TRUE(set->Add(kFDBase + 1));
129   ASSERT_TRUE(set->Add(kFDBase + 2));
130 
131   ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
132   ASSERT_EQ(set->GetDescriptorAt(2), -1);
133 
134   set->CommitAll();
135 }
136 
TEST(FileDescriptorSet,WalkCycle)137 TEST(FileDescriptorSet, WalkCycle) {
138   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
139 
140   ASSERT_TRUE(set->Add(kFDBase));
141   ASSERT_TRUE(set->Add(kFDBase + 1));
142   ASSERT_TRUE(set->Add(kFDBase + 2));
143 
144   ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
145   ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
146   ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
147   ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
148   ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
149   ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
150   ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
151   ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
152   ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
153 
154   set->CommitAll();
155 }
156 
TEST(FileDescriptorSet,DontClose)157 TEST(FileDescriptorSet, DontClose) {
158   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
159 
160   const int fd = GetSafeFd();
161   ASSERT_TRUE(set->Add(fd));
162   set->CommitAll();
163 
164   ASSERT_FALSE(VerifyClosed(fd));
165 }
166 
TEST(FileDescriptorSet,DoClose)167 TEST(FileDescriptorSet, DoClose) {
168   scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
169 
170   const int fd = GetSafeFd();
171   ASSERT_TRUE(set->AddAndAutoClose(fd));
172   set->CommitAll();
173 
174   ASSERT_TRUE(VerifyClosed(fd));
175 }
176 
177 }  // namespace
178