// 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->AddToBorrow(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->AddToOwn(base::ScopedFD(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->AddToBorrow(kFDBase + 1 + i));

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

  set->CommitAll();
}

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

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

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

  set->CommitAll();

  ASSERT_TRUE(VerifyClosed(fd));
}

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

  set->PeekDescriptors(NULL);
  ASSERT_TRUE(set->AddToBorrow(kFDBase));

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

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

  // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
  // used to retrieve borrowed descriptors. That never happens in production.
  ASSERT_TRUE(set->AddToBorrow(kFDBase));
  ASSERT_TRUE(set->AddToBorrow(kFDBase + 1));
  ASSERT_TRUE(set->AddToBorrow(kFDBase + 2));

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

  set->CommitAll();
}

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

  // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
  // used to retrieve borrowed descriptors. That never happens in production.
  ASSERT_TRUE(set->AddToBorrow(kFDBase));
  ASSERT_TRUE(set->AddToBorrow(kFDBase + 1));
  ASSERT_TRUE(set->AddToBorrow(kFDBase + 2));

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

  set->CommitAll();
}

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

  // TODO(morrita): This test is wrong. TakeDescriptorAt() shouldn't be
  // used to retrieve borrowed descriptors. That never happens in production.
  ASSERT_TRUE(set->AddToBorrow(kFDBase));
  ASSERT_TRUE(set->AddToBorrow(kFDBase + 1));
  ASSERT_TRUE(set->AddToBorrow(kFDBase + 2));

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

  set->CommitAll();
}

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

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

  ASSERT_FALSE(VerifyClosed(fd));
}

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

  const int fd = GetSafeFd();
  ASSERT_TRUE(set->AddToOwn(base::ScopedFD(fd)));
  set->CommitAll();

  ASSERT_TRUE(VerifyClosed(fd));
}

}  // namespace
