15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is POSIX only.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/file_descriptor_set_posix.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get a safe file descriptor for test purposes.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetSafeFd() {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return open("/dev/null", O_RDONLY);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if fd was already closed.  Closes fd if not closed.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyClosed(int fd) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int duped = dup(fd);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (duped != -1) {
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_NE(IGNORE_EINTR(close(duped)), -1);
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_NE(IGNORE_EINTR(close(fd)), -1);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The FileDescriptorSet will try and close some of the descriptor numbers
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which we given it. This is the base descriptor value. It's great enough such
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that no real descriptor will accidently be closed.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kFDBase = 50000;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, BasicAdd) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->size(), 0u);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->empty());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase));
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->size(), 1u);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(!set->empty());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empties the set and stops a warning about deleting a set with unconsumed
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // descriptors
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, BasicAddAndClose) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->size(), 0u);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->empty());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int fd = GetSafeFd();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->AddAndAutoClose(fd));
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->size(), 1u);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(!set->empty());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(VerifyClosed(fd));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, MaxSize) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < FileDescriptorSet::kMaxDescriptorsPerMessage; ++i)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(set->Add(kFDBase + 1 + i));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(!set->Add(kFDBase));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, SetDescriptors) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->empty());
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->SetDescriptors(NULL, 0);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->empty());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int fd = GetSafeFd();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int fds[] = {fd};
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->SetDescriptors(fds, 1);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(!set->empty());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->size(), 1u);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(VerifyClosed(fd));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, GetDescriptors) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->GetDescriptors(NULL);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fds[1];
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fds[0] = 0;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->GetDescriptors(fds);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(fds[0], kFDBase);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->empty());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, WalkInOrder) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase + 1));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase + 2));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, WalkWrongOrder) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase + 1));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase + 2));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(2), -1);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, WalkCycle) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase + 1));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(kFDBase + 2));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, DontClose) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int fd = GetSafeFd();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->Add(fd));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(VerifyClosed(fd));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FileDescriptorSet, DoClose) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int fd = GetSafeFd();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(set->AddAndAutoClose(fd));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set->CommitAll();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(VerifyClosed(fd));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
178