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. 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. 24 bool VerifyClosed(int fd) { 25 const int duped = dup(fd); 26 if (duped != -1) { 27 EXPECT_NE(HANDLE_EINTR(close(duped)), -1); 28 EXPECT_NE(HANDLE_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 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 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 } 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 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 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 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 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 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 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 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