root/ipc/file_descriptor_set_posix_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GetSafeFd
  2. VerifyClosed
  3. TEST
  4. TEST
  5. TEST
  6. TEST
  7. TEST
  8. TEST
  9. TEST
  10. TEST
  11. TEST
  12. TEST

// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This test is POSIX only.

#include "ipc/file_descriptor_set_posix.h"

#include <unistd.h>
#include <fcntl.h>

#include "base/basictypes.h"
#include "base/posix/eintr_wrapper.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Get a safe file descriptor for test purposes.
int GetSafeFd() {
  return open("/dev/null", O_RDONLY);
}

// Returns true if fd was already closed.  Closes fd if not closed.
bool VerifyClosed(int fd) {
  const int duped = dup(fd);
  if (duped != -1) {
    EXPECT_NE(IGNORE_EINTR(close(duped)), -1);
    EXPECT_NE(IGNORE_EINTR(close(fd)), -1);
    return false;
  }
  return true;
}

// The FileDescriptorSet will try and close some of the descriptor numbers
// which we given it. This is the base descriptor value. It's great enough such
// that no real descriptor will accidently be closed.
static const int kFDBase = 50000;

TEST(FileDescriptorSet, BasicAdd) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  ASSERT_EQ(set->size(), 0u);
  ASSERT_TRUE(set->empty());
  ASSERT_TRUE(set->Add(kFDBase));
  ASSERT_EQ(set->size(), 1u);
  ASSERT_TRUE(!set->empty());

  // Empties the set and stops a warning about deleting a set with unconsumed
  // descriptors
  set->CommitAll();
}

TEST(FileDescriptorSet, BasicAddAndClose) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  ASSERT_EQ(set->size(), 0u);
  ASSERT_TRUE(set->empty());
  const int fd = GetSafeFd();
  ASSERT_TRUE(set->AddAndAutoClose(fd));
  ASSERT_EQ(set->size(), 1u);
  ASSERT_TRUE(!set->empty());

  set->CommitAll();

  ASSERT_TRUE(VerifyClosed(fd));
}
TEST(FileDescriptorSet, MaxSize) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  for (size_t i = 0; i < FileDescriptorSet::kMaxDescriptorsPerMessage; ++i)
    ASSERT_TRUE(set->Add(kFDBase + 1 + i));

  ASSERT_TRUE(!set->Add(kFDBase));

  set->CommitAll();
}

TEST(FileDescriptorSet, SetDescriptors) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  ASSERT_TRUE(set->empty());
  set->SetDescriptors(NULL, 0);
  ASSERT_TRUE(set->empty());

  const int fd = GetSafeFd();
  static const int fds[] = {fd};
  set->SetDescriptors(fds, 1);
  ASSERT_TRUE(!set->empty());
  ASSERT_EQ(set->size(), 1u);

  set->CommitAll();

  ASSERT_TRUE(VerifyClosed(fd));
}

TEST(FileDescriptorSet, GetDescriptors) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  set->GetDescriptors(NULL);
  ASSERT_TRUE(set->Add(kFDBase));

  int fds[1];
  fds[0] = 0;
  set->GetDescriptors(fds);
  ASSERT_EQ(fds[0], kFDBase);
  set->CommitAll();
  ASSERT_TRUE(set->empty());
}

TEST(FileDescriptorSet, WalkInOrder) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  ASSERT_TRUE(set->Add(kFDBase));
  ASSERT_TRUE(set->Add(kFDBase + 1));
  ASSERT_TRUE(set->Add(kFDBase + 2));

  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);

  set->CommitAll();
}

TEST(FileDescriptorSet, WalkWrongOrder) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  ASSERT_TRUE(set->Add(kFDBase));
  ASSERT_TRUE(set->Add(kFDBase + 1));
  ASSERT_TRUE(set->Add(kFDBase + 2));

  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
  ASSERT_EQ(set->GetDescriptorAt(2), -1);

  set->CommitAll();
}

TEST(FileDescriptorSet, WalkCycle) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  ASSERT_TRUE(set->Add(kFDBase));
  ASSERT_TRUE(set->Add(kFDBase + 1));
  ASSERT_TRUE(set->Add(kFDBase + 2));

  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
  ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
  ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
  ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);

  set->CommitAll();
}

TEST(FileDescriptorSet, DontClose) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  const int fd = GetSafeFd();
  ASSERT_TRUE(set->Add(fd));
  set->CommitAll();

  ASSERT_FALSE(VerifyClosed(fd));
}

TEST(FileDescriptorSet, DoClose) {
  scoped_refptr<FileDescriptorSet> set(new FileDescriptorSet);

  const int fd = GetSafeFd();
  ASSERT_TRUE(set->AddAndAutoClose(fd));
  set->CommitAll();

  ASSERT_TRUE(VerifyClosed(fd));
}

}  // namespace

/* [<][>][^][v][top][bottom][index][help] */