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 #if defined(OS_ANDROID)
85 #define MAYBE_SetDescriptors DISABLED_SetDescriptors
87 #define MAYBE_SetDescriptors SetDescriptors
89 TEST(MessageAttachmentSet
, MAYBE_SetDescriptors
) {
90 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
92 ASSERT_TRUE(set
->empty());
93 set
->AddDescriptorsToOwn(NULL
, 0);
94 ASSERT_TRUE(set
->empty());
96 const int fd
= GetSafeFd();
97 static const int fds
[] = {fd
};
98 set
->AddDescriptorsToOwn(fds
, 1);
99 ASSERT_TRUE(!set
->empty());
100 ASSERT_EQ(set
->size(), 1u);
104 ASSERT_TRUE(VerifyClosed(fd
));
107 TEST(MessageAttachmentSet
, PeekDescriptors
) {
108 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
110 set
->PeekDescriptors(NULL
);
112 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
116 set
->PeekDescriptors(fds
);
117 ASSERT_EQ(fds
[0], kFDBase
);
119 ASSERT_TRUE(set
->empty());
122 TEST(MessageAttachmentSet
, WalkInOrder
) {
123 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
125 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
126 // used to retrieve borrowed descriptors. That never happens in production.
128 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
130 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 1)));
132 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 2)));
134 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
135 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
136 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
141 TEST(MessageAttachmentSet
, WalkWrongOrder
) {
142 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
144 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
145 // used to retrieve borrowed descriptors. That never happens in production.
147 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
149 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 1)));
151 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 2)));
153 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
154 ASSERT_EQ(set
->GetAttachmentAt(2), nullptr);
159 TEST(MessageAttachmentSet
, WalkCycle
) {
160 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
162 // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
163 // used to retrieve borrowed descriptors. That never happens in production.
165 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
)));
167 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 1)));
169 set
->AddAttachment(new internal::PlatformFileAttachment(kFDBase
+ 2)));
171 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
172 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
173 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
174 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
175 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
176 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
177 ASSERT_EQ(set
->GetAttachmentAt(0)->TakePlatformFile(), kFDBase
);
178 ASSERT_EQ(set
->GetAttachmentAt(1)->TakePlatformFile(), kFDBase
+ 1);
179 ASSERT_EQ(set
->GetAttachmentAt(2)->TakePlatformFile(), kFDBase
+ 2);
184 #if defined(OS_ANDROID)
185 #define MAYBE_DontClose DISABLED_DontClose
187 #define MAYBE_DontClose DontClose
189 TEST(MessageAttachmentSet
, MAYBE_DontClose
) {
190 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
192 const int fd
= GetSafeFd();
193 ASSERT_TRUE(set
->AddAttachment(new internal::PlatformFileAttachment(fd
)));
196 ASSERT_FALSE(VerifyClosed(fd
));
199 TEST(MessageAttachmentSet
, DoClose
) {
200 scoped_refptr
<MessageAttachmentSet
> set(new MessageAttachmentSet
);
202 const int fd
= GetSafeFd();
203 ASSERT_TRUE(set
->AddAttachment(
204 new internal::PlatformFileAttachment(base::ScopedFD(fd
))));
207 ASSERT_TRUE(VerifyClosed(fd
));