xref: /aosp_15_r20/external/cronet/ipc/ipc_message_attachment_set_posix_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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.
4 
5 // This test is POSIX only.
6 
7 #include "ipc/ipc_message_attachment_set.h"
8 
9 #include <fcntl.h>
10 #include <stddef.h>
11 #include <unistd.h>
12 
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"
17 
18 #if BUILDFLAG(IS_FUCHSIA)
19 #include <lib/fdio/fdio.h>
20 #endif
21 
22 namespace IPC {
23 namespace {
24 
25 // Get a safe file descriptor for test purposes.
GetSafeFd()26 int GetSafeFd() {
27 #if BUILDFLAG(IS_FUCHSIA)
28   return fdio_fd_create_null();
29 #else
30   return open("/dev/null", O_RDONLY);
31 #endif
32 }
33 
34 // Returns true if fd was already closed.  Closes fd if not closed.
VerifyClosed(int fd)35 bool VerifyClosed(int fd) {
36   const int duped = HANDLE_EINTR(dup(fd));
37   if (duped != -1) {
38     EXPECT_NE(IGNORE_EINTR(close(duped)), -1);
39     EXPECT_NE(IGNORE_EINTR(close(fd)), -1);
40     return false;
41   }
42   return true;
43 }
44 
GetFdAt(MessageAttachmentSet * set,int id)45 int GetFdAt(MessageAttachmentSet* set, int id) {
46   return static_cast<internal::PlatformFileAttachment&>(
47              *set->GetAttachmentAt(id))
48       .TakePlatformFile();
49 }
50 
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;
55 
TEST(MessageAttachmentSet,BasicAdd)56 TEST(MessageAttachmentSet, BasicAdd) {
57   scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
58 
59   ASSERT_EQ(set->size(), 0u);
60   ASSERT_TRUE(set->empty());
61   ASSERT_TRUE(
62       set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
63   ASSERT_EQ(set->size(), 1u);
64   ASSERT_TRUE(!set->empty());
65 
66   // Empties the set and stops a warning about deleting a set with unconsumed
67   // descriptors
68   set->CommitAllDescriptors();
69 }
70 
TEST(MessageAttachmentSet,BasicAddAndClose)71 TEST(MessageAttachmentSet, BasicAddAndClose) {
72   scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
73 
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());
81 
82   set->CommitAllDescriptors();
83 
84   ASSERT_TRUE(VerifyClosed(fd));
85 }
TEST(MessageAttachmentSet,MaxSize)86 TEST(MessageAttachmentSet, MaxSize) {
87   scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
88 
89   for (size_t i = 0; i < MessageAttachmentSet::kMaxDescriptorsPerMessage; ++i)
90     ASSERT_TRUE(set->AddAttachment(
91         new internal::PlatformFileAttachment(kFDBase + 1 + i)));
92 
93   ASSERT_TRUE(
94       !set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
95 
96   set->CommitAllDescriptors();
97 }
98 
TEST(MessageAttachmentSet,WalkInOrder)99 TEST(MessageAttachmentSet, WalkInOrder) {
100   scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
101 
102   ASSERT_TRUE(
103       set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
104   ASSERT_TRUE(
105       set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 1)));
106   ASSERT_TRUE(
107       set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 2)));
108 
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));
113 
114   set->CommitAllDescriptors();
115 }
116 
TEST(MessageAttachmentSet,WalkWrongOrder)117 TEST(MessageAttachmentSet, WalkWrongOrder) {
118   scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
119 
120   ASSERT_TRUE(
121       set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
122   ASSERT_TRUE(
123       set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 1)));
124   ASSERT_TRUE(
125       set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 2)));
126 
127   ASSERT_EQ(GetFdAt(set.get(), 0), kFDBase);
128   ASSERT_FALSE(set->GetAttachmentAt(2));
129 
130   set->CommitAllDescriptors();
131 }
132 
133 #if BUILDFLAG(IS_ANDROID)
134 #define MAYBE_DontClose DISABLED_DontClose
135 #else
136 #define MAYBE_DontClose DontClose
137 #endif
TEST(MessageAttachmentSet,MAYBE_DontClose)138 TEST(MessageAttachmentSet, MAYBE_DontClose) {
139   scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
140 
141   const int fd = GetSafeFd();
142   ASSERT_TRUE(set->AddAttachment(new internal::PlatformFileAttachment(fd)));
143   set->CommitAllDescriptors();
144 
145   ASSERT_FALSE(VerifyClosed(fd));
146 }
147 
TEST(MessageAttachmentSet,DoClose)148 TEST(MessageAttachmentSet, DoClose) {
149   scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
150 
151   const int fd = GetSafeFd();
152   ASSERT_TRUE(set->AddAttachment(
153       new internal::PlatformFileAttachment(base::ScopedFD(fd))));
154   set->CommitAllDescriptors();
155 
156   ASSERT_TRUE(VerifyClosed(fd));
157 }
158 
159 }  // namespace
160 }  // namespace IPC
161