1 // Copyright 2011 The Chromium Authors
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"
13 #include "base/posix/eintr_wrapper.h"
14 #include "build/build_config.h"
15 #include "ipc/ipc_platform_file_attachment_posix.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 #if BUILDFLAG(IS_FUCHSIA)
19 #include <lib/fdio/fdio.h>
25 // Get a safe file descriptor for test purposes.
27 #if BUILDFLAG(IS_FUCHSIA)
28 return fdio_fd_create_null();
30 return open("/dev/null", O_RDONLY);
34 // Returns true if fd was already closed. Closes fd if not closed.
35 bool VerifyClosed(int fd) {
36 const int duped = HANDLE_EINTR(dup(fd));
38 EXPECT_NE(IGNORE_EINTR(close(duped)), -1);
39 EXPECT_NE(IGNORE_EINTR(close(fd)), -1);
45 int GetFdAt(MessageAttachmentSet* set, int id) {
46 return static_cast<internal::PlatformFileAttachment&>(
47 *set->GetAttachmentAt(id))
51 // The MessageAttachmentSet will try and close some of the descriptor numbers
52 // which we given it. This is the base descriptor value. It's great enough such
53 // that no real descriptor will accidentally be closed.
54 static const int kFDBase = 50000;
56 TEST(MessageAttachmentSet, BasicAdd) {
57 scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
59 ASSERT_EQ(set->size(), 0u);
60 ASSERT_TRUE(set->empty());
62 set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
63 ASSERT_EQ(set->size(), 1u);
64 ASSERT_TRUE(!set->empty());
66 // Empties the set and stops a warning about deleting a set with unconsumed
68 set->CommitAllDescriptors();
71 TEST(MessageAttachmentSet, BasicAddAndClose) {
72 scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
74 ASSERT_EQ(set->size(), 0u);
75 ASSERT_TRUE(set->empty());
76 const int fd = GetSafeFd();
77 ASSERT_TRUE(set->AddAttachment(
78 new internal::PlatformFileAttachment(base::ScopedFD(fd))));
79 ASSERT_EQ(set->size(), 1u);
80 ASSERT_TRUE(!set->empty());
82 set->CommitAllDescriptors();
84 ASSERT_TRUE(VerifyClosed(fd));
86 TEST(MessageAttachmentSet, MaxSize) {
87 scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
89 for (size_t i = 0; i < MessageAttachmentSet::kMaxDescriptorsPerMessage; ++i)
90 ASSERT_TRUE(set->AddAttachment(
91 new internal::PlatformFileAttachment(kFDBase + 1 + i)));
94 !set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
96 set->CommitAllDescriptors();
99 TEST(MessageAttachmentSet, WalkInOrder) {
100 scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
103 set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
105 set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 1)));
107 set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 2)));
109 ASSERT_EQ(GetFdAt(set.get(), 0), kFDBase);
110 ASSERT_EQ(GetFdAt(set.get(), 1), kFDBase + 1);
111 ASSERT_EQ(GetFdAt(set.get(), 2), kFDBase + 2);
112 ASSERT_FALSE(set->GetAttachmentAt(0));
114 set->CommitAllDescriptors();
117 TEST(MessageAttachmentSet, WalkWrongOrder) {
118 scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
121 set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
123 set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 1)));
125 set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 2)));
127 ASSERT_EQ(GetFdAt(set.get(), 0), kFDBase);
128 ASSERT_FALSE(set->GetAttachmentAt(2));
130 set->CommitAllDescriptors();
133 #if BUILDFLAG(IS_ANDROID)
134 #define MAYBE_DontClose DISABLED_DontClose
136 #define MAYBE_DontClose DontClose
138 TEST(MessageAttachmentSet, MAYBE_DontClose) {
139 scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
141 const int fd = GetSafeFd();
142 ASSERT_TRUE(set->AddAttachment(new internal::PlatformFileAttachment(fd)));
143 set->CommitAllDescriptors();
145 ASSERT_FALSE(VerifyClosed(fd));
148 TEST(MessageAttachmentSet, DoClose) {
149 scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
151 const int fd = GetSafeFd();
152 ASSERT_TRUE(set->AddAttachment(
153 new internal::PlatformFileAttachment(base::ScopedFD(fd))));
154 set->CommitAllDescriptors();
156 ASSERT_TRUE(VerifyClosed(fd));