// Copyright 2014 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.

#include "net/socket/unix_domain_server_socket_posix.h"

#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/test/scoped_task_environment.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/socket/unix_domain_client_socket_posix.h"
#include "net/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using net::test::IsError;
using net::test::IsOk;

namespace net {
namespace {

const char kSocketFilename[] = "socket_for_testing";
const char kInvalidSocketPath[] = "/invalid/path";

bool UserCanConnectCallback(bool allow_user,
    const UnixDomainServerSocket::Credentials& credentials) {
  // Here peers are running in same process.
#if defined(OS_LINUX) || defined(OS_ANDROID)
  EXPECT_EQ(getpid(), credentials.process_id);
#endif
  EXPECT_EQ(getuid(), credentials.user_id);
  EXPECT_EQ(getgid(), credentials.group_id);
  return allow_user;
}

UnixDomainServerSocket::AuthCallback CreateAuthCallback(bool allow_user) {
  return base::Bind(&UserCanConnectCallback, allow_user);
}

class UnixDomainServerSocketTest : public testing::Test {
 protected:
  UnixDomainServerSocketTest() {
    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
    socket_path_ = temp_dir_.GetPath().Append(kSocketFilename).value();
  }

  base::ScopedTempDir temp_dir_;
  std::string socket_path_;
};

TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPath) {
  const bool kUseAbstractNamespace = false;
  UnixDomainServerSocket server_socket(CreateAuthCallback(true),
                                       kUseAbstractNamespace);
  EXPECT_EQ(ERR_FILE_NOT_FOUND,
            server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1));
}

TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPathWithAbstractNamespace) {
  const bool kUseAbstractNamespace = true;
  UnixDomainServerSocket server_socket(CreateAuthCallback(true),
                                       kUseAbstractNamespace);
#if defined(OS_ANDROID) || defined(OS_LINUX)
  EXPECT_THAT(server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1),
              IsOk());
#else
  EXPECT_EQ(ERR_ADDRESS_INVALID,
            server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1));
#endif
}

TEST_F(UnixDomainServerSocketTest, ListenAgainAfterFailureWithInvalidPath) {
  const bool kUseAbstractNamespace = false;
  UnixDomainServerSocket server_socket(CreateAuthCallback(true),
                                       kUseAbstractNamespace);
  EXPECT_EQ(ERR_FILE_NOT_FOUND,
            server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1));
  EXPECT_THAT(server_socket.BindAndListen(socket_path_, /*backlog=*/1), IsOk());
}

TEST_F(UnixDomainServerSocketTest, AcceptWithForbiddenUser) {
  base::test::ScopedTaskEnvironment scoped_task_environment(
      base::test::ScopedTaskEnvironment::MainThreadType::IO);

  const bool kUseAbstractNamespace = false;

  UnixDomainServerSocket server_socket(CreateAuthCallback(false),
                                       kUseAbstractNamespace);
  EXPECT_THAT(server_socket.BindAndListen(socket_path_, /*backlog=*/1), IsOk());

  std::unique_ptr<StreamSocket> accepted_socket;
  TestCompletionCallback accept_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            server_socket.Accept(&accepted_socket, accept_callback.callback()));
  EXPECT_FALSE(accepted_socket);

  UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
  EXPECT_FALSE(client_socket.IsConnected());

  // Connect() will return OK before the server rejects the connection.
  TestCompletionCallback connect_callback;
  int rv = connect_callback.GetResult(
      client_socket.Connect(connect_callback.callback()));
  ASSERT_THAT(rv, IsOk());

  // Try to read from the socket.
  const int read_buffer_size = 10;
  scoped_refptr<IOBuffer> read_buffer(new IOBuffer(read_buffer_size));
  TestCompletionCallback read_callback;
  rv = read_callback.GetResult(client_socket.Read(
      read_buffer.get(), read_buffer_size, read_callback.callback()));

  // The server should have disconnected gracefully, without sending any data.
  ASSERT_EQ(0, rv);
  EXPECT_FALSE(client_socket.IsConnected());

  // The server socket should not have called |accept_callback| or modified
  // |accepted_socket|.
  EXPECT_FALSE(accept_callback.have_result());
  EXPECT_FALSE(accepted_socket);
}

TEST_F(UnixDomainServerSocketTest, UnimplementedMethodsFail) {
  const bool kUseAbstractNamespace = false;
  UnixDomainServerSocket server_socket(CreateAuthCallback(true),
                                       kUseAbstractNamespace);

  IPEndPoint ep;
  EXPECT_THAT(server_socket.Listen(ep, 0), IsError(ERR_NOT_IMPLEMENTED));
  EXPECT_EQ(ERR_NOT_IMPLEMENTED,
      server_socket.ListenWithAddressAndPort(kInvalidSocketPath,
                                             0,
                                             /*backlog=*/1));

  EXPECT_THAT(server_socket.GetLocalAddress(&ep), IsError(ERR_ADDRESS_INVALID));
}

// Normal cases including read/write are tested by UnixDomainClientSocketTest.

}  // namespace
}  // namespace net
