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.
5 // This test is POSIX only.
7 #include "ipc/ipc_message_attachment_set.h"
12 #include "base/basictypes.h"
13 #include "base/posix/eintr_wrapper.h"
14 #include "ipc/ipc_platform_file_attachment_posix.h"
15 #include "testing/gtest/include/gtest/gtest.h"
20 // Get a safe file descriptor for test purposes.
22 return open("/dev/null", O_RDONLY
);
25 // Returns true if fd was already closed. Closes fd if not closed.
26 bool VerifyClosed(int fd
) {
27 const int duped
= dup(fd
);
29 EXPECT_NE(IGNORE_EINTR(close(duped
)), -1);
30 EXPECT_NE(IGNORE_EINTR(close(fd
)), -1);
36 // The MessageAttachmentSet will try and close some of the descriptor numbers
37 // which we given it. This is the base descriptor value. It's great enough such
38 // that no real descriptor will accidently be closed.
39 static const int kFDBase
= 50000;
41 TEST(MessageAttachmentSet
, BasicAdd
) {
42 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
44 ASSERT_EQ(set
->size(), 0u);
45 ASSERT_TRUE(set
->empty());
47 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
48 ASSERT_EQ(set
->size(), 1u);
49 ASSERT_TRUE(!set
->empty());
51 // Empties the set and stops a warning about deleting a set with unconsumed
56 TEST(MessageAttachmentSet
, BasicAddAndClose
) {
57 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
59 ASSERT_EQ(set
->size(), 0u);
60 ASSERT_TRUE(set
->empty());
61 const int fd
= GetSafeFd();
62 ASSERT_TRUE(set
->AddAttachment(
63 new internal::PlatformFileAttachment(base::ScopedFD(fd
))));
64 ASSERT_EQ(set
->size(), 1u);
65 ASSERT_TRUE(!set
->empty());
69 ASSERT_TRUE(VerifyClosed(fd
));
71 TEST(MessageAttachmentSet
, MaxSize
) {
72 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
74 for (size_t i
= 0; i
< MessageAttachmentSet::kMaxDescriptorsPerMessage
; ++i
)
75 ASSERT_TRUE(set
->AddAttachment(
76 new internal::PlatformFileAttachment(kFDBase
+ 1 + i
)));
79 !set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
84 TEST(MessageAttachmentSet
, SetDescriptors
) {
85 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
87 ASSERT_TRUE(set
->empty());
88 set
->AddDescriptorsToOwn(NULL
, 0);
89 ASSERT_TRUE(set
->empty());
91 const int fd
= GetSafeFd();
92 static const int fds
[] = {fd
};
93 set
->AddDescriptorsToOwn(fds
, 1);
94 ASSERT_TRUE(!set
->empty());
95 ASSERT_EQ(set
->size(), 1u);
99 ASSERT_TRUE(VerifyClosed(fd
));
102 TEST(MessageAttachmentSet
, PeekDescriptors
) {
103 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
105 set
->PeekDescriptors(NULL
);
107 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
111 set
->PeekDescriptors(fds
);
112 ASSERT_EQ(fds
[0], kFDBase
);
114 ASSERT_TRUE(set
->empty());
117 TEST(MessageAttachmentSet
, WalkInOrder
) {
118 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
120 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
121 // used to retrieve borrowed descriptors. That never happens in production.
123 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
125 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 1)));
127 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 2)));
129 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
130 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
131 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
136 TEST(MessageAttachmentSet
, WalkWrongOrder
) {
137 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
139 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
140 // used to retrieve borrowed descriptors. That never happens in production.
142 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
144 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 1)));
146 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 2)));
148 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
149 ASSERT_EQ(set
->GetAttachmentAt(2), nullptr);
154 TEST(MessageAttachmentSet
, WalkCycle
) {
155 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
157 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
158 // used to retrieve borrowed descriptors. That never happens in production.
160 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
162 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 1)));
164 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 2)));
166 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
167 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
168 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
169 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
170 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
171 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
172 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
173 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
174 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
179 TEST(MessageAttachmentSet
, DontClose
) {
180 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
182 const int fd
= GetSafeFd();
183 ASSERT_TRUE(set
->AddAttachment(new internal::PlatformFileAttachment(fd
)));
186 ASSERT_FALSE(VerifyClosed(fd
));
189 TEST(MessageAttachmentSet
, DoClose
) {
190 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
192 const int fd
= GetSafeFd();
193 ASSERT_TRUE(set
->AddAttachment(
194 new internal::PlatformFileAttachment(base::ScopedFD(fd
))));
197 ASSERT_TRUE(VerifyClosed(fd
));