ipc_message_attachment_set_posix_unittest.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. // This test is POSIX only.
  5. #include "ipc/ipc_message_attachment_set.h"
  6. #include <fcntl.h>
  7. #include <stddef.h>
  8. #include <unistd.h>
  9. #include "base/posix/eintr_wrapper.h"
  10. #include "build/build_config.h"
  11. #include "ipc/ipc_platform_file_attachment_posix.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. #if BUILDFLAG(IS_FUCHSIA)
  14. #include <lib/fdio/fdio.h>
  15. #endif
  16. namespace IPC {
  17. namespace {
  18. // Get a safe file descriptor for test purposes.
  19. int GetSafeFd() {
  20. #if BUILDFLAG(IS_FUCHSIA)
  21. return fdio_fd_create_null();
  22. #else
  23. return open("/dev/null", O_RDONLY);
  24. #endif
  25. }
  26. // Returns true if fd was already closed. Closes fd if not closed.
  27. bool VerifyClosed(int fd) {
  28. const int duped = HANDLE_EINTR(dup(fd));
  29. if (duped != -1) {
  30. EXPECT_NE(IGNORE_EINTR(close(duped)), -1);
  31. EXPECT_NE(IGNORE_EINTR(close(fd)), -1);
  32. return false;
  33. }
  34. return true;
  35. }
  36. int GetFdAt(MessageAttachmentSet* set, int id) {
  37. return static_cast<internal::PlatformFileAttachment&>(
  38. *set->GetAttachmentAt(id))
  39. .TakePlatformFile();
  40. }
  41. // The MessageAttachmentSet will try and close some of the descriptor numbers
  42. // which we given it. This is the base descriptor value. It's great enough such
  43. // that no real descriptor will accidently be closed.
  44. static const int kFDBase = 50000;
  45. TEST(MessageAttachmentSet, BasicAdd) {
  46. scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
  47. ASSERT_EQ(set->size(), 0u);
  48. ASSERT_TRUE(set->empty());
  49. ASSERT_TRUE(
  50. set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
  51. ASSERT_EQ(set->size(), 1u);
  52. ASSERT_TRUE(!set->empty());
  53. // Empties the set and stops a warning about deleting a set with unconsumed
  54. // descriptors
  55. set->CommitAllDescriptors();
  56. }
  57. TEST(MessageAttachmentSet, BasicAddAndClose) {
  58. 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());
  66. set->CommitAllDescriptors();
  67. ASSERT_TRUE(VerifyClosed(fd));
  68. }
  69. TEST(MessageAttachmentSet, MaxSize) {
  70. scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
  71. for (size_t i = 0; i < MessageAttachmentSet::kMaxDescriptorsPerMessage; ++i)
  72. ASSERT_TRUE(set->AddAttachment(
  73. new internal::PlatformFileAttachment(kFDBase + 1 + i)));
  74. ASSERT_TRUE(
  75. !set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
  76. set->CommitAllDescriptors();
  77. }
  78. TEST(MessageAttachmentSet, WalkInOrder) {
  79. scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
  80. ASSERT_TRUE(
  81. set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
  82. ASSERT_TRUE(
  83. set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 1)));
  84. ASSERT_TRUE(
  85. set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 2)));
  86. ASSERT_EQ(GetFdAt(set.get(), 0), kFDBase);
  87. ASSERT_EQ(GetFdAt(set.get(), 1), kFDBase + 1);
  88. ASSERT_EQ(GetFdAt(set.get(), 2), kFDBase + 2);
  89. ASSERT_FALSE(set->GetAttachmentAt(0));
  90. set->CommitAllDescriptors();
  91. }
  92. TEST(MessageAttachmentSet, WalkWrongOrder) {
  93. scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
  94. ASSERT_TRUE(
  95. set->AddAttachment(new internal::PlatformFileAttachment(kFDBase)));
  96. ASSERT_TRUE(
  97. set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 1)));
  98. ASSERT_TRUE(
  99. set->AddAttachment(new internal::PlatformFileAttachment(kFDBase + 2)));
  100. ASSERT_EQ(GetFdAt(set.get(), 0), kFDBase);
  101. ASSERT_FALSE(set->GetAttachmentAt(2));
  102. set->CommitAllDescriptors();
  103. }
  104. #if BUILDFLAG(IS_ANDROID)
  105. #define MAYBE_DontClose DISABLED_DontClose
  106. #else
  107. #define MAYBE_DontClose DontClose
  108. #endif
  109. TEST(MessageAttachmentSet, MAYBE_DontClose) {
  110. scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
  111. const int fd = GetSafeFd();
  112. ASSERT_TRUE(set->AddAttachment(new internal::PlatformFileAttachment(fd)));
  113. set->CommitAllDescriptors();
  114. ASSERT_FALSE(VerifyClosed(fd));
  115. }
  116. TEST(MessageAttachmentSet, DoClose) {
  117. scoped_refptr<MessageAttachmentSet> set(new MessageAttachmentSet);
  118. const int fd = GetSafeFd();
  119. ASSERT_TRUE(set->AddAttachment(
  120. new internal::PlatformFileAttachment(base::ScopedFD(fd))));
  121. set->CommitAllDescriptors();
  122. ASSERT_TRUE(VerifyClosed(fd));
  123. }
  124. } // namespace
  125. } // namespace IPC