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

// General fdio_spawn tests

#include <fcntl.h>
#include <fuchsia/io/llcpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/spawn.h>
#include <lib/zx/channel.h>
#include <lib/zx/clock.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/socket.h>
#include <lib/zx/vmo.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/limits.h>
#include <zircon/processargs.h>
#include <zircon/syscalls/policy.h>
#include <zircon/utc.h>

#include <gtest/gtest.h>

#include "fake_launcher_util.h"

namespace fio = ::llcpp::fuchsia::io;

namespace {

#define FDIO_SPAWN_CLONE_ALL_EXCEPT_NS (FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_NAMESPACE)

static constexpr char kSpawnChild[] = "/pkg/bin/spawn_child_util";
static constexpr char kSpawnLauncher[] = "/pkg/bin/fake_launcher_util";

static bool has_fd(int fd) {
  zx::handle handle;
  zx_status_t status = fdio_fd_clone(fd, handle.reset_and_get_address());
  if (status == ZX_OK) {
    return true;
  }
  return false;
}

static void join(const zx::process& process, int64_t* return_code) {
  zx_status_t status = process.wait_one(ZX_TASK_TERMINATED, zx::time::infinite(), nullptr);
  ASSERT_EQ(status, ZX_OK);

  zx_info_process_t proc_info{};
  status = process.get_info(ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), nullptr, nullptr);
  ASSERT_EQ(status, ZX_OK);

  *return_code = proc_info.return_code;
}

TEST(SpawnTest, SpawnControl) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;

  {
    const char* argv[] = {bin_path, nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 43);
  }

  {
    const char* argv[] = {bin_path, "--argc", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 2);
  }

  {
    const char* argv[] = {bin_path, "--argc", "three", "four", "five", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 5);
  }
}

TEST(SpawnTest, SpawnLauncher) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* launcher_bin_path = kSpawnLauncher;
  const char* argv[] = {launcher_bin_path, nullptr};

  // Check that setting |ZX_POL_NEW_PROCESS| to |ZX_POL_ACTION_DENY| prevents
  // the launcher from launching the child.
  {
    zx::job job;
    ASSERT_EQ(ZX_OK, zx::job::create(*zx::job::default_job(), 0, &job));
    zx_policy_basic_v2_t policy = {.condition = ZX_POL_NEW_PROCESS,
                                   .action = ZX_POL_ACTION_DENY,
                                   .flags = ZX_POL_OVERRIDE_DENY};
    ASSERT_EQ(ZX_OK, job.set_policy(ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC_V2, &policy, 1));

    status = fdio_spawn(job.get(), FDIO_SPAWN_CLONE_ALL, launcher_bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, LAUNCHER_FAILURE);
    ASSERT_EQ(ZX_OK, job.kill());
  }
}

TEST(SpawnTest, SpawnNested) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;

  {
    const char* argv[] = {bin_path, "--spawn", bin_path, nullptr};
    int flags = FDIO_SPAWN_DEFAULT_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_CLONE_JOB;
    status = fdio_spawn(ZX_HANDLE_INVALID, flags, bin_path, argv, process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 43);
  }

  {
    const char* argv[] = {bin_path, "--spawn", bin_path, nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 43);
  }

  {
    setenv("DUMMY_ENV", "1", 1);

    const char* argv[] = {bin_path, "--spawn", bin_path, "--flags", "all", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 56);

    unsetenv("DUMMY_ENV");
  }
}

TEST(SpawnTest, SpawnInvalidArgs) {
  zx_status_t status;
  zx::process process;
  const char* bin_path = kSpawnChild;
  const char* argv[] = {bin_path, nullptr};

  status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, "/bogus/not/a/file", argv,
                      process.reset_and_get_address());
  ASSERT_EQ(ZX_ERR_NOT_FOUND, status);

  status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, NULL,
                      process.reset_and_get_address());
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, status);

  status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv + 1,
                      process.reset_and_get_address());
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, status);
}

TEST(SpawnTest, SpawnFlags) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;

  {
    // We can't actually launch a process without FDIO_SPAWN_DEFAULT_LDSVC
    // because we can't load the PT_INTERP.
    const char* argv[] = {bin_path, "--flags", "none", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, 0, bin_path, argv, process.reset_and_get_address());
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, status);
    EXPECT_FALSE(process.is_valid());
  }

  {
    const char* argv[] = {bin_path, "--flags", "none", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 51);
  }

  {
    const char* argv[] = {bin_path, "--flags", "job", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_DEFAULT_LDSVC,
                        bin_path, argv, process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 52);
  }

  {
    const char* argv[] = {bin_path, "--flags", "namespace", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
                        bin_path, argv, process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 53);
  }

  {
    const char* argv[] = {bin_path, "--flags", "stdio", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC | FDIO_SPAWN_CLONE_STDIO,
                        bin_path, argv, process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 54);
  }

  {
    // Redundant CLONE_STDIO vs individual fd actions should work.
    const char* argv[] = {bin_path, "--flags", "stdio", nullptr};
    char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
    const fdio_spawn_action_t actions[] = {
        {.action = FDIO_SPAWN_ACTION_CLONE_FD, .fd = {.local_fd = 0, .target_fd = 0}},
        {.action = FDIO_SPAWN_ACTION_CLONE_FD, .fd = {.local_fd = 1, .target_fd = 1}},
        {.action = FDIO_SPAWN_ACTION_CLONE_FD, .fd = {.local_fd = 2, .target_fd = 2}},
    };
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC | FDIO_SPAWN_CLONE_STDIO,
                            bin_path, argv, nullptr, std::size(actions), actions,
                            process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 54);
  }

  {
    setenv("DUMMY_ENV", "1", 1);

    const char* argv[] = {bin_path, "--flags", "environ", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC | FDIO_SPAWN_CLONE_ENVIRON,
                        bin_path, argv, process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 55);

    unsetenv("DUMMY_ENV");
  }

  {
    setenv("DUMMY_ENV", "1", 1);

    const char* argv[] = {bin_path, "--flags", "all", nullptr};
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 56);

    unsetenv("DUMMY_ENV");
  }
}

TEST(SpawnTest, SpawnEnviron) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  setenv("SPAWN_TEST_PARENT", "1", 1);

  {
    const char* argv[] = {bin_path, "--env", "empty", nullptr};
    const char* env[] = {nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC, bin_path, argv, env, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 61);
  }

  {
    const char* argv[] = {bin_path, "--env", "one", nullptr};
    const char* env[] = {"SPAWN_TEST_CHILD=1", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC, bin_path, argv, env, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 62);
  }

  {
    const char* argv[] = {bin_path, "--env", "one", nullptr};
    const char* env[] = {"SPAWN_TEST_CHILD=1", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, env, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 62);
  }

  {
    const char* argv[] = {bin_path, "--env", "two", nullptr};
    const char* env[] = {"SPAWN_TEST_CHILD=1", "SPAWN_TEST_CHILD2=1", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, env, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 63);
  }

  {
    const char* argv[] = {bin_path, "--env", "clone", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 64);
  }

  unsetenv("SPAWN_TEST_PARENT");
}

TEST(SpawnTest, SpawnActionsFd) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    const char* argv[] = {nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, status) << err_msg;
  }

  {
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_SET_NAME;
    action.name.data = "spawn-child-name";

    const char* argv[] = {nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 42);

    char name[ZX_MAX_NAME_LEN];
    ASSERT_EQ(ZX_OK, process.get_property(ZX_PROP_NAME, name, sizeof(name)));
    EXPECT_TRUE(!strcmp("spawn-child-name", name));
  }

  {
    int fd;
    zx::socket socket;
    status = fdio_pipe_half(&fd, socket.reset_and_get_address());
    ASSERT_GE(status, ZX_OK);

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_FD;
    action.fd.local_fd = fd;
    action.fd.target_fd = 21;

    const char* argv[] = {bin_path, "--action", "clone-fd", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 71);
    EXPECT_TRUE(has_fd(fd));
    close(fd);
  }

  {
    zx::socket socket;
    int fd;
    status = fdio_pipe_half(&fd, socket.reset_and_get_address());
    ASSERT_GE(status, ZX_OK);

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_TRANSFER_FD;
    action.fd.local_fd = fd;
    action.fd.target_fd = 21;

    const char* argv[] = {bin_path, "--action", "transfer-fd", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 72);
    EXPECT_FALSE(has_fd(fd));
  }

  {
    zx::socket socket;
    int fd;
    status = fdio_pipe_half(&fd, socket.reset_and_get_address());
    ASSERT_GE(status, ZX_OK);

    fdio_spawn_action_t actions[2];
    actions[0].action = FDIO_SPAWN_ACTION_CLONE_FD;
    actions[0].fd.local_fd = fd;
    actions[0].fd.target_fd = 21;
    actions[1].action = FDIO_SPAWN_ACTION_TRANSFER_FD;
    actions[1].fd.local_fd = fd;
    actions[1].fd.target_fd = 22;

    const char* argv[] = {bin_path, "--action", "clone-and-transfer-fd", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 2,
                            actions, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 73);
    EXPECT_FALSE(has_fd(fd));
  }
}

TEST(SpawnTest, SpawnActionsAddNamespaceEntry) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_ADD_NS_ENTRY;
    action.ns.prefix = "/foo/bar/baz";
    action.ns.handle = h1.release();

    const char* argv[] = {bin_path, "--action", "ns-entry", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 74);
  }
}

TEST(SpawnTest, SpawnActionAddHandle) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_ADD_HANDLE;
    action.h.id = PA_USER0;
    action.h.handle = h1.release();

    const char* argv[] = {bin_path, "--action", "add-handle", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 75);
  }
}

TEST(SpawnTest, SpawnActionsSetName) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    fdio_spawn_action_t actions[2];
    actions[0].action = FDIO_SPAWN_ACTION_SET_NAME;
    actions[0].name.data = "proc-name-0";
    actions[1].action = FDIO_SPAWN_ACTION_SET_NAME;
    actions[1].name.data = "proc-name-1";

    const char* argv[] = {bin_path, nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 2,
                            actions, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 43);
    char name[ZX_MAX_NAME_LEN];
    ASSERT_EQ(ZX_OK, process.get_property(ZX_PROP_NAME, name, sizeof(name)));
    EXPECT_EQ(0, strcmp(name, "proc-name-1"));
  }
}

TEST(SpawnTest, SpawnActionsCloneDir) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_DIR;
    action.dir.prefix = "/";

    const char* argv[] = {bin_path, "--flags", "namespace", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_DEFAULT_LDSVC, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 53);
  }

  {
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_DIR;
    action.dir.prefix = "/foo/bar/baz";

    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
    fdio_ns_t* ns = nullptr;
    ASSERT_EQ(ZX_OK, fdio_ns_get_installed(&ns));
    ASSERT_EQ(ZX_OK, fdio_ns_bind(ns, "/foo/bar/baz", h1.release()));

    const char* argv[] = {bin_path, "--action", "ns-entry", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL_EXCEPT_NS, bin_path, argv,
                            nullptr, 1, &action, process.reset_and_get_address(), err_msg);
    EXPECT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 74);

    // Unbind the test namespace.
    EXPECT_EQ(ZX_OK, fdio_ns_unbind(ns, "/foo/bar/baz"));
  }

  {
    // Test using a directory prefix. In this case, sharing /foo/bar should provide access to
    // the /foo/bar/baz namespace.
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_DIR;
    action.dir.prefix = "/foo/bar";

    fdio_ns_t* ns = nullptr;
    ASSERT_EQ(ZX_OK, fdio_ns_get_installed(&ns));

    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
    ASSERT_EQ(ZX_OK, fdio_ns_bind(ns, "/foo/bar/baz", h1.release()));

    const char* argv[] = {bin_path, "--stat", "/foo/bar", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL_EXCEPT_NS, bin_path, argv,
                            nullptr, 1, &action, process.reset_and_get_address(), err_msg);
    EXPECT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 76);

    // Unbind the test namespace.
    EXPECT_EQ(ZX_OK, fdio_ns_unbind(ns, "/foo/bar/baz"));
  }

  {
    // Verify we don't match paths in the middle of directory names. In this case, verify
    // that /foo/bar/baz does not match as a prefix to the directory /foo/bar/bazel.
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_DIR;
    action.dir.prefix = "/foo/bar/baz";

    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
    fdio_ns_t* ns = nullptr;
    ASSERT_EQ(ZX_OK, fdio_ns_get_installed(&ns));
    ASSERT_EQ(ZX_OK, fdio_ns_bind(ns, "/foo/bar/bazel", h1.release()));

    const char* argv[] = {bin_path, "--stat", "/foo/bar", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL_EXCEPT_NS, bin_path, argv,
                            nullptr, 1, &action, process.reset_and_get_address(), err_msg);
    EXPECT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, -6);

    // Unbind the test namespace.
    EXPECT_EQ(ZX_OK, fdio_ns_unbind(ns, "/foo/bar/bazel"));
  }

  {
    // Same as above but the prefix does not exist in our namespace. The fdio_spawn_etc should
    // succeed but the new process should not see any namespaces under that path.
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_DIR;
    action.dir.prefix = "/foo/bar/baz";

    const char* argv[] = {bin_path, "--action", "ns-entry", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL_EXCEPT_NS, bin_path, argv,
                            nullptr, 1, &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, -4);
  }
}

TEST(SpawnTest, SpawnErrors) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  char err_msg2[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  const char* argv[] = {bin_path, nullptr};

  ASSERT_EQ(ZX_ERR_INVALID_ARGS, fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path,
                                            nullptr, process.reset_and_get_address()));

  ASSERT_EQ(ZX_ERR_INVALID_ARGS,
            fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                           nullptr, process.reset_and_get_address(), err_msg2));

  {
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_ADD_NS_ENTRY;
    action.ns.prefix = "/foo/bar/baz";
    action.ns.handle = ZX_HANDLE_INVALID;

    ASSERT_EQ(ZX_ERR_INVALID_ARGS,
              fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                             &action, process.reset_and_get_address(), err_msg2));
  }

  {
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_ADD_HANDLE;
    action.h.id = PA_USER0;
    action.h.handle = ZX_HANDLE_INVALID;

    ASSERT_EQ(ZX_ERR_INVALID_ARGS,
              fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                             &action, process.reset_and_get_address(), err_msg2));
  }

  {
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_SET_NAME;
    action.name.data = nullptr;

    ASSERT_EQ(ZX_ERR_INVALID_ARGS,
              fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                             &action, process.reset_and_get_address(), err_msg2));
  }

  {
    const char* empty_argv[] = {nullptr};
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path,
                                              empty_argv, process.reset_and_get_address()));
  }

  ASSERT_EQ(ZX_ERR_NOT_FOUND,
            fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, "/bogus/path", argv, nullptr, 0,
                           nullptr, process.reset_and_get_address(), err_msg));
  EXPECT_TRUE(strstr(err_msg, "/bogus/path") != nullptr);

  {
    zx::job job;
    ASSERT_EQ(ZX_OK, zx::job::default_job()->duplicate(0, &job));
    ASSERT_EQ(ZX_ERR_ACCESS_DENIED, fdio_spawn(job.get(), FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                                               process.reset_and_get_address()));
  }

  {
    ASSERT_EQ(30, dup2(0, 30));
    ASSERT_EQ(0, close(0));
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 43);
    ASSERT_EQ(0, dup2(30, 0));
    ASSERT_EQ(0, close(30));
  }

  {
    ASSERT_EQ(30, dup2(0, 30));
    ASSERT_EQ(0, close(0));
    zxio_storage_t* storage = nullptr;
    fdio_t* io = fdio_zxio_create(&storage);
    ASSERT_EQ(0, fdio_bind_to_fd(io, 0, 0));
    status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv,
                        process.reset_and_get_address());
    ASSERT_EQ(ZX_OK, status);
    join(process, &return_code);
    EXPECT_EQ(return_code, 43);
    ASSERT_EQ(0, close(0));
    ASSERT_EQ(0, dup2(30, 0));
    ASSERT_EQ(0, close(30));
  }

  {
    zxio_storage_t* storage = nullptr;
    fdio_t* io = fdio_zxio_create(&storage);
    int fd = fdio_bind_to_fd(io, -1, 0);
    ASSERT_GE(fd, 3);

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_FD;
    action.fd.local_fd = fd;
    action.fd.target_fd = 21;

    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, status) << err_msg;
    ASSERT_EQ(0, close(fd));
  }

  {
    zxio_storage_t* storage = nullptr;
    fdio_t* io = fdio_zxio_create(&storage);
    int fd = fdio_bind_to_fd(io, -1, 0);
    ASSERT_GE(fd, 3);

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_TRANSFER_FD;
    action.fd.local_fd = fd;
    action.fd.target_fd = 21;

    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, status) << err_msg;
    ASSERT_EQ(-1, close(fd));
  }

  {
    // FDIO_SPAWN_ACTION_CLONE_DIR with trailing '/' should be rejected.
    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_CLONE_DIR;
    action.dir.prefix = "/foo/bar/baz/";

    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
    fdio_ns_t* ns = nullptr;
    ASSERT_EQ(ZX_OK, fdio_ns_get_installed(&ns));
    ASSERT_EQ(ZX_OK, fdio_ns_bind(ns, "/foo/bar/baz", h1.release()));

    const char* argv[] = {bin_path, "--action", "ns-entry", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL_EXCEPT_NS, bin_path, argv,
                            nullptr, 1, &action, process.reset_and_get_address(), err_msg);
    EXPECT_EQ(ZX_ERR_INVALID_ARGS, status) << err_msg;

    // Unbind the test namespace.
    EXPECT_EQ(ZX_OK, fdio_ns_unbind(ns, "/foo/bar/baz"));
  }

  {
    ASSERT_EQ(30, dup2(0, 30));
    ASSERT_EQ(31, dup2(0, 31));
    const fdio_spawn_action_t actions[] = {
        {.action = FDIO_SPAWN_ACTION_CLONE_FD, .fd = {.local_fd = 30, .target_fd = 1}},
        {.action = FDIO_SPAWN_ACTION_CLONE_FD, .fd = {.local_fd = 31, .target_fd = 1}},
    };
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr,
                            std::size(actions), actions, process.reset_and_get_address(), err_msg);
    EXPECT_EQ(ZX_ERR_ALREADY_EXISTS, status) << err_msg;
    ASSERT_EQ(0, close(30));
    ASSERT_EQ(0, close(31));
  }

  {
    ASSERT_EQ(30, dup2(0, 30));
    const fdio_spawn_action_t actions[] = {
        {.action = FDIO_SPAWN_ACTION_CLONE_FD, .fd = {.local_fd = 30, .target_fd = FDIO_MAX_FD}},
    };
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr,
                            std::size(actions), actions, process.reset_and_get_address(), err_msg);
    EXPECT_EQ(ZX_ERR_OUT_OF_RANGE, status) << err_msg;
    ASSERT_EQ(0, close(30));
  }
}

TEST(SpawnTest, SpawnVmo) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    int fd;
    zx::vmo vmo;
    ASSERT_EQ(ZX_OK,
              fdio_open_fd(bin_path, fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_EXECUTABLE, &fd));
    ASSERT_GE(fd, 0);
    ASSERT_EQ(ZX_OK, fdio_get_vmo_exec(fd, vmo.reset_and_get_address()));
    close(fd);

    const char* argv[] = {bin_path, nullptr};
    status = fdio_spawn_vmo(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, vmo.release(), argv, nullptr,
                            0, nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(return_code, 43);
  }
}

class SpawnUtcClockTest : public ::testing::Test {
 protected:
  void SetUp() override {
    // Remove the current global clock. It will be restored at the end of this test.
    ASSERT_EQ(ZX_OK, zx_utc_reference_swap(ZX_HANDLE_INVALID, &prev_clock_));
  }

  void TearDown() override {
    zx_handle_t dummy;
    ASSERT_EQ(ZX_OK, zx_utc_reference_swap(prev_clock_, &dummy));
  }

  zx_koid_t GetKoid(const zx::clock& clock) {
    zx_info_handle_basic_t info;
    zx_status_t status =
        clock.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
    if (status != ZX_OK) {
      ADD_FAILURE() << "failed to get koid of handle";
      return ZX_KOID_INVALID;
    }
    return info.koid;
  }

 private:
  zx_handle_t prev_clock_ = ZX_HANDLE_INVALID;
};

TEST_F(SpawnUtcClockTest, NoGlobalUtcClock) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    const char* argv[] = {bin_path, "--action", "add-handle-clock-utc", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(static_cast<zx_koid_t>(return_code), ZX_KOID_INVALID);
  }
}

TEST_F(SpawnUtcClockTest, SendGlobalUtcClock) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  // Set a global UTC clock.
  zx::clock test_clock;
  zx_handle_t prev_clock;
  ASSERT_EQ(ZX_OK, zx::clock::create(0, nullptr, &test_clock));
  ASSERT_EQ(ZX_OK, zx_utc_reference_swap(test_clock.get_handle(), &prev_clock));
  {
    const char* argv[] = {bin_path, "--action", "add-handle-clock-utc", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 0,
                            nullptr, process.reset_and_get_address(), err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(static_cast<zx_koid_t>(return_code), GetKoid(test_clock));
  }
}

TEST_F(SpawnUtcClockTest, SendExplicitUtcClock) {
  zx_status_t status;
  zx::process process;
  int64_t return_code;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    zx::clock test_clock;
    ASSERT_EQ(ZX_OK, zx::clock::create(0, nullptr, &test_clock));
    zx_koid_t expected_koid = GetKoid(test_clock);

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_ADD_HANDLE;
    action.h.id = PA_CLOCK_UTC;
    action.h.handle = test_clock.release();

    const char* argv[] = {bin_path, "--action", "add-handle-clock-utc", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_UTC_CLOCK,
                            bin_path, argv, nullptr, 1, &action, process.reset_and_get_address(),
                            err_msg);
    ASSERT_EQ(ZX_OK, status) << err_msg;
    join(process, &return_code);
    EXPECT_EQ(static_cast<zx_koid_t>(return_code), expected_koid);
  }
}

TEST_F(SpawnUtcClockTest, CannotCloneGlobalAndSendExplicit) {
  zx_status_t status;
  zx::process process;
  const char* bin_path = kSpawnChild;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  {
    zx::clock test_clock;
    ASSERT_EQ(ZX_OK, zx::clock::create(0, nullptr, &test_clock));

    fdio_spawn_action_t action;
    action.action = FDIO_SPAWN_ACTION_ADD_HANDLE;
    action.h.id = PA_CLOCK_UTC;
    action.h.handle = test_clock.release();

    const char* argv[] = {bin_path, "--action", "add-handle-clock-utc", nullptr};
    status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, bin_path, argv, nullptr, 1,
                            &action, process.reset_and_get_address(), err_msg);
    ASSERT_NE(ZX_OK, status);
  }
}

}  // namespace
