// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef __WINDOWS__
#include <sys/wait.h>
#endif // __WINDOWS__

#include <string.h>
#ifndef __WINDOWS__
#include <unistd.h>
#endif // __WINDOWS__

#include <list>
#include <set>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <checks/checker_process.hpp>

#include "docker/docker.hpp"

#include <process/defer.hpp>
#include <process/gmock.hpp>
#include <process/gtest.hpp>
#include <process/owned.hpp>

#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/exit.hpp>
#include <stout/lambda.hpp>
#include <stout/none.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/result.hpp>
#include <stout/stringify.hpp>
#include <stout/strings.hpp>

#include <stout/os/exists.hpp>
#include <stout/os/pstree.hpp>
#include <stout/os/shell.hpp>
#include <stout/os/temp.hpp>
#include <stout/os/which.hpp>

#ifdef __linux__
#include "linux/cgroups.hpp"
#include "linux/fs.hpp"
#include "linux/perf.hpp"
#endif

#ifdef ENABLE_PORT_MAPPING_ISOLATOR
#include "linux/routing/utils.hpp"
#endif

#include "logging/logging.hpp"

#include "tests/environment.hpp"
#include "tests/flags.hpp"
#include "tests/utils.hpp"

#ifdef ENABLE_PORT_MAPPING_ISOLATOR
using namespace routing;
#endif

using std::list;
using std::set;
using std::string;
using std::vector;

using process::Failure;
using process::Future;
using process::Owned;

using stout::internal::tests::TestFilter;


namespace mesos {
namespace internal {
namespace tests {

// Storage for the global environment instance.
Environment* environment;


class BenchmarkFilter : public TestFilter
{
public:
  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "BENCHMARK_") && !flags.benchmark;
  }
};


class CfsFilter : public TestFilter
{
public:
  CfsFilter()
  {
#ifdef __linux__
    Result<string> hierarchy = cgroups::hierarchy("cpu");
    if (hierarchy.isSome()) {
      bool cfsQuotaEnabled =
        os::exists(path::join(hierarchy.get(), "cpu.cfs_quota_us"));

      if (cfsQuotaEnabled) {
        cfsError = None();
      } else {
        cfsError = Error("CFS bandwidth control is not available");
      }
    } else if (hierarchy.isError()) {
      cfsError = Error(
          "There was an error finding the 'cpu' cgroup hierarchy:\n" +
          hierarchy.error());
    } else {
      cfsError = Error(
          "The 'cpu' cgroup hierarchy was not found, which means\n"
          "that CFS bandwidth control is not available");
    }

    if (cfsError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "The 'CFS_' tests cannot be run because:\n"
        << cfsError->message << "\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
#else
    cfsError = Error(
        "These tests require CFS bandwidth control, which is a "
        "Linux kernel feature, but Linux has not been detected");
#endif // __linux__
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "CFS_") && cfsError.isSome();
  }

private:
  Option<Error> cfsError;
};


class CgroupsFilter : public TestFilter
{
public:
  CgroupsFilter()
  {
#ifdef __linux__
    Try<set<string>> hierarchies = cgroups::hierarchies();
    if (hierarchies.isError()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any cgroups tests that require mounting\n"
        << "hierarchies because reading cgroup heirarchies failed:\n"
        << hierarchies.error() << "\n"
        << "We'll disable the CgroupsNoHierarchyTest test fixture for now.\n"
        << "-------------------------------------------------------------"
        << std::endl;

      error = hierarchies.error();
    } else if (!hierarchies->empty()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any cgroups tests that require mounting\n"
        << "hierarchies because you have the following hierarchies mounted:\n"
        << strings::trim(stringify(hierarchies.get()), " {},") << "\n"
        << "We'll disable the CgroupsNoHierarchyTest test fixture for now.\n"
        << "-------------------------------------------------------------"
        << std::endl;

      error = Error("Hierarchies exist");
    }
#endif // __linux__
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    if (matches(test, "CGROUPS_") || matches(test, "Cgroups")) {
#ifdef __linux__
      Result<string> user = os::user();
      CHECK_SOME(user);

      if (matches(test, "NOHIERARCHY_")) {
        return user.get() != "root" ||
               !cgroups::enabled() ||
               error.isSome();
      }

      return user.get() != "root" || !cgroups::enabled();
#else
      return true;
#endif // __linux__
    }

    return false;
  }

private:
  Option<Error> error;
};


class CurlFilter : public TestFilter
{
public:
  CurlFilter()
  {
#ifndef __WINDOWS__
    curlError = os::which("curl").isNone();
#else
    // NOTE: We cannot use `os::which` here because it specifically checks the
    // `PATH` for `curl`, but on Windows, we rely on `curl` being placed by the
    // build next to the other executables (e.g. `mesos-agent` and
    // `mesos-tests`). When placed like this, `::CreateProcess` is guaranteed to
    // find it, regardless of `PATH` (and likewise `os::which`). Because it is
    // built and placed as a build dependency of `mesos-agent`, it will always
    // be available for testing.
    curlError = false;
#endif // __WINDOWS__
    if (curlError) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "No 'curl' command found so no 'curl' tests will be run\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "CURL_") && curlError;
  }

private:
  bool curlError;
};


class NvidiaGpuFilter : public TestFilter
{
public:
  NvidiaGpuFilter()
  {
    nvidiaGpuError = os::which("nvidia-smi").isNone();
    if (nvidiaGpuError) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "No 'nvidia-smi' command found so no Nvidia GPU tests will run\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "NVIDIA_GPU_") && nvidiaGpuError;
  }

private:
  bool nvidiaGpuError;
};


class DockerFilter : public TestFilter
{
public:
  DockerFilter()
  {
#if defined(__linux__) || defined(__WINDOWS__)
    Try<Owned<Docker>> docker = Docker::create(
        flags.docker,
        flags.docker_socket);

    if (!docker.isError()) {
      Try<Nothing> version = docker.get()->validateVersion(Version(1, 9, 0));
      if (version.isError()) {
        dockerUserNetworkError = version.error();
      }
    } else {
      dockerError = docker.error();
    }

#ifdef __WINDOWS__
    // On Windows, the ability to enter another container's namespace was
    // enabled on newer Windows builds (>=1709). So, check if we can do
    // this to run the docker health check tests.
    LOG(WARNING) << "Testing shared container network namespaces on Windows. "
                 << "This might take up to 30 seconds...";

    if (dockerError.isNone() && dockerUserNetworkError.isNone()) {
      dockerNamespaceError = runNetNamespaceCheck(docker.get());
    }
#endif // __WINDOWS__
#else
    dockerError = Error("Docker tests are not supported on this platform");
#endif // __linux__ || __WINDOWS__

    if (dockerError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any Docker tests because:\n"
        << dockerError->message << "\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }

    if (dockerUserNetworkError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any Docker user network tests because:\n"
        << dockerUserNetworkError->message << "\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }

    if (dockerNamespaceError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any Docker network health checks tests because:\n"
        << dockerNamespaceError->message << "\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    if (dockerError.isSome()) {
      return matches(test, "DOCKER_");
    }

    if (dockerUserNetworkError.isSome()) {
      return matches(test, "DOCKER_USERNETWORK_");
    }

    return matches(test, "DOCKER_") &&
      matches(test, "NETNAMESPACE_") &&
      dockerNamespaceError.isSome();
  }

private:
#ifdef __WINDOWS__
  Future<Nothing> launchContainer(
      const Owned<Docker>& docker,
      const string& containerName,
      const string& networkName,
      const string& imageName)
  {
    Docker::RunOptions opts;
    opts.privileged = false;
    opts.name = containerName;
    opts.network = networkName;
    opts.additionalOptions = {"-d", "--rm"};
    opts.image = imageName;
    opts.arguments = {"ping", "-n", "60", "127.0.0.1"};

    // Launches the container in detached mode, which means that docker
    // run should return as soon as the container successfully launched.
    return docker->run(opts, process::Subprocess::PATH(os::DEV_NULL))
      .then([=](const Option<int>& status) -> Future<Nothing> {
        if (!status.isSome()) {
          return Failure(
              "Container " + containerName + " failed with unknown exit code");
        }

        if (status.get() != 0) {
          return Failure(
              "Container " + containerName + " returned exit code " +
              stringify(status.get()));
        }

        return Nothing();
      });
  }

  Option<Error> runNetNamespaceCheck(const Owned<Docker>& docker)
  {
    const string image =
      string(mesos::internal::checks::DOCKER_HEALTH_CHECK_IMAGE);

    // Use `os::system` here because `docker->inspect()` only works on
    // containers even though `docker inspect` cli command works on images.
    const Option<int> res = os::system(strings::join(
        " ",
        docker->getPath(),
        "-H",
        docker->getSocket(),
        "inspect",
        image,
        "> NUL"));

    if (res != 0) {
      return Error("Cannot find " + image);
    }

    // Launch two containers. One with regular network settings and the
    // other with "--network=container:<ID>" to enter the first container's
    // namespace.
    const string container1 = id::UUID::random().toString();
    const string container2 = id::UUID::random().toString();

    Future<Nothing> containers =
      launchContainer(docker, container1, "nat", image)
        .then(process::defer([=]() {
          return launchContainer(
              docker, container2, "container:" + container1, image)
            .then(lambda::bind(&Docker::rm, docker, container2, true))
            .onAny(lambda::bind(&Docker::rm, docker, container1, true));
      }));

    // A minute should be enough for both containers to lauch and delete.
    containers.await(Minutes(1));

    if (containers.isFailed()) {
      return Error("Failed to launch containers: " + containers.failure());
    } else if (!containers.isReady()) {
      return Error("Container launch timed out");
    }

    return None();
  }
#endif // __WINDOWS__

  Option<Error> dockerError;
  Option<Error> dockerUserNetworkError;
  Option<Error> dockerNamespaceError;
};


// Note: This is a temporary filter to disable tests that use
// overlay as backend on filesystems where `d_type` support is
// missing. In particular, many XFS nodes are known to have this
// issue due to mkfs option with `f_type = 0`. Please see
// MESOS-8121 for more info.
//
// This filter assumes that the affected tests will use
// `/tmp` as root directory of the agent's work dir.
class DtypeFilter : public TestFilter
{
public:
  DtypeFilter()
  {
#ifdef __linux__
    auto checkDirDtype = [this](const string& directory) {
      string probeDir = path::join(directory, ".probe");

      Try<Nothing> mkdir = os::mkdir(probeDir);
      if (mkdir.isError()) {
        dtypeError = Error(
            "Cannot verify filesystem d_type attribute: "
            "Failed to create temporary directory '" +
            probeDir + "': " + mkdir.error());
      }

      Try<bool> supportDType = fs::dtypeSupported(directory);

      // Clean up the temporary directory that is used
      // for d_type detection.
      Try<Nothing> rmdir = os::rmdir(probeDir);
      if (rmdir.isError()) {
        LOG(WARNING) << "Failed to remove temporary directory"
                     << "' " << probeDir << "': " << rmdir.error();
      }

      if (supportDType.isError()) {
        dtypeError = Error(
          "Cannot verify filesystem d_type attribute: " +
          supportDType.error());
      }

      if (!supportDType.get()) {
        dtypeError = Error(
            "The underlying filesystem of " + directory +
            " misses d_type support.");
      }
    };

    // TODO(mzhu): Avoid hard coding a specific directory for
    // filtering. This is a temporary solution.
    checkDirDtype(os::temp());

    if (dtypeError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any overlay backend tests because:\n"
        << dtypeError->message << "\n"
        << "-------------------------------------------------------------\n";
      return;
    }
#endif
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return dtypeError.isSome() && matches(test, "DTYPE_");
  }

private:
  Option<Error> dtypeError;
};


class InternetFilter : public TestFilter
{
public:
  InternetFilter()
  {
#ifdef __WINDOWS__
    error = os::system("ping -n 1 -w 1000 google.com") != 0;
#else
    error = os::system("ping -c 1 -W 1 google.com") != 0;
#endif // __WINDOWS__
    if (error) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any INTERNET tests because no internet access\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "INTERNET_") && error;
  }

private:
  bool error;
};


class IPTablesFilter : public TestFilter
{
public:
  IPTablesFilter()
  {
#ifdef __linux__
    // Check iptables -w option
    //
    if (os::which("iptables").isNone()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "No 'iptables' command found so no tests depending\n"
        << "on 'iptables' will be run\n"
        << "-------------------------------------------------------------"
        << std::endl;

      iptablesError = Error("iptables command not found");
      return;
    }

    if (::geteuid() != 0) {
      iptablesError = Error("iptables command requires root");
      return;
    }

    Try<string> iptables = os::shell("iptables -w -n -L OUTPUT");
    if (iptables.isError()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "'iptables' command does not support '-w' option\n"
        << "-------------------------------------------------------------"
        << std::endl;

      iptablesError = Error("iptables command does not support -w option");
      return;
    }
#else
    iptablesError = Error("Unsupported platform");
#endif
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return iptablesError.isSome() && matches(test, "IPTABLES_");
  }

private:
  Option<Error> iptablesError;
};


class LogrotateFilter : public TestFilter
{
public:
  LogrotateFilter()
  {
    logrotateError = os::which("logrotate").isNone();
    if (logrotateError) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "No 'logrotate' command found so no 'logrotate' tests\n"
        << "will be run\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "LOGROTATE_") && logrotateError;
  }

private:
  bool logrotateError;
};


class NetcatFilter : public TestFilter
{
public:
  NetcatFilter()
  {
    netcatError = os::which("nc").isNone();
    if (netcatError) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "No 'nc' command found so no tests depending on 'nc' will run\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "NC_") && netcatError;
  }

private:
  bool netcatError;
};


// This filter enables tests for the cgroups/net_cls isolator after
// checking that net_cls cgroup subsystem has been enabled on the
// system. We cannot rely on the generic cgroups test filter
// ('CgroupsFilter') to enable the cgroups/net_cls isolator tests
// since, although cgroups might be enabled on a linux distribution
// the net_cls subsystem is not turned on, by default, on all
// distributions.
class NetClsCgroupsFilter : public TestFilter
{
public:
  NetClsCgroupsFilter()
  {
    netClsError = true;
#ifdef __linux__
    Try<bool> netCls = cgroups::enabled("net_cls");

    if (netCls.isError()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "Cannot enable net_cls cgroup subsystem associated test cases \n"
        << "since we cannot determine the existence of the net_cls cgroup\n"
        << "subsystem.\n"
        << "-------------------------------------------------------------\n";
      return;
    }

    if (netCls.isSome() && !netCls.get()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "Cannot enable net_cls cgroup subsystem associated test cases \n"
        << "since net_cls cgroup subsystem is not enabled. Check instructions\n"
        << "for your linux distrubtion to enable the net_cls cgroup subsystem\n"
        << "on your system.\n"
        << "-----------------------------------------------------------\n";
      return;
    }
    netClsError = false;
#else
    std::cerr
        << "-----------------------------------------------------------\n"
        << "Cannot enable net_cls cgroup subsystem associated test cases\n"
        << "since this platform does not support cgroups.\n"
        << "-----------------------------------------------------------\n";
#endif
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "NET_CLS_") && netClsError;
  }

private:
  bool netClsError;
};


class NetworkIsolatorTestFilter : public TestFilter
{
public:
  NetworkIsolatorTestFilter()
  {
#ifdef ENABLE_PORT_MAPPING_ISOLATOR
    Try<Nothing> check = routing::check();
    if (check.isError()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any PortMapping tests because:\n"
        << check.error() << "\n"
        << "-------------------------------------------------------------\n";

      portMappingError = Error(check.error());
    }
#endif
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    if (matches(test, "PortMappingIsolatorTest") ||
        matches(test, "PortMappingMesosTest")) {
#ifdef ENABLE_PORT_MAPPING_ISOLATOR
      return !portMappingError.isNone();
#else
      return true;
#endif
    }

    return false;
  }

private:
  Option<Error> portMappingError;
};


class SupportedFilesystemTestFilter : public TestFilter
{
public:
  explicit SupportedFilesystemTestFilter(const string& fsname)
  {
#ifdef __linux__
    Try<bool> check = fs::supported(fsname);
    if (check.isError()) {
      fsSupportError = check.error();
    } else if (!check.get()) {
      fsSupportError = Error(fsname + " is not supported on your systems");
    }
#else
    fsSupportError =
      Error(fsname + " tests not supported on non-Linux systems");
#endif

    if (fsSupportError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We cannot run any " << fsname << " tests because:\n"
        << fsSupportError->message << "\n"
        << "-------------------------------------------------------------\n";
    }
  }

  Option<Error> fsSupportError;
};


class AufsFilter : public SupportedFilesystemTestFilter
{
public:
  AufsFilter() : SupportedFilesystemTestFilter("aufs") {}

  bool disable(const ::testing::TestInfo* test) const override
  {
    return fsSupportError.isSome() && matches(test, "AUFS_");
  }
};


class OverlayFSFilter : public SupportedFilesystemTestFilter
{
public:
  OverlayFSFilter() : SupportedFilesystemTestFilter("overlayfs") {}

  bool disable(const ::testing::TestInfo* test) const override
  {
    return fsSupportError.isSome() && matches(test, "OVERLAYFS_");
  }
};


class XfsFilter : public SupportedFilesystemTestFilter
{
public:
  XfsFilter() : SupportedFilesystemTestFilter("xfs") {}

  bool disable(const ::testing::TestInfo* test) const override
  {
    return fsSupportError.isSome() && matches(test, "XFS_");
  }
};


class PerfCPUCyclesFilter : public TestFilter
{
public:
  PerfCPUCyclesFilter()
  {
#ifdef __linux__
    bool perfUnavailable = !perf::supported();
    if (perfUnavailable) {
      perfError = Error(
          "Could not find the 'perf' command or its version lower that "
          "2.6.39 so tests using it to sample the 'cpu-cycles' hardware "
          "event will not be run.");
    } else {
      bool cyclesUnavailable =
        os::system("perf list hw | grep cpu-cycles >/dev/null") != 0;
      if (cyclesUnavailable) {
        perfError = Error(
            "The 'cpu-cycles' hardware event of 'perf' is not available on\n"
            "this platform so tests using it will not be run.\n"
            "One likely reason is that the tests are run in a virtual\n"
            "machine that does not provide CPU performance counters");
      }
    }
#else
    perfError = Error("Tests using 'perf' cannot be run on non-Linux systems");
#endif // __linux__

    if (perfError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << perfError->message << "\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    // Disable all tests that try to sample 'cpu-cycles' events using 'perf'.
    return (matches(test, "ROOT_CGROUPS_PERF_PerfTest") ||
            matches(test, "ROOT_CGROUPS_PERF_UserCgroup") ||
            matches(test, "ROOT_CGROUPS_PERF_RollForward") ||
            matches(test, "ROOT_CGROUPS_PERF_Sample")) && perfError.isSome();
  }

private:
  Option<Error> perfError;
};


class PerfFilter : public TestFilter
{
public:
  PerfFilter()
  {
#ifdef __linux__
    perfError = !perf::supported();
    if (perfError) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "require 'perf' version >= 2.6.39 so no 'perf' tests will be run\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
#else
    perfError = true;
#endif // __linux__
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "PERF_") && perfError;
  }

private:
  bool perfError;
};


class RootFilter : public TestFilter
{
public:
  bool disable(const ::testing::TestInfo* test) const override
  {
#ifdef __WINDOWS__
    // On Windows, tests are expected to be run as Administrator.
    return false;
#else
    Result<string> user = os::user();
    CHECK_SOME(user);

#ifdef __linux__
    // On Linux non-privileged users are limited to 64k of locked
    // memory so we cannot run the MemIsolatorTest.Usage.
    if (matches(test, "MemIsolatorTest")) {
      return user.get() != "root";
    }
#endif // __linux__

    return matches(test, "ROOT_") && user.get() != "root";
#endif // __WINDOWS__
  }
};


class SeccompFilter : public TestFilter
{
public:
  SeccompFilter()
  {
    // Since the Seccomp parser depends on CPU architecture, we can run Seccomp
    // tests deterministically only on `x86_64`.
    Try<string> arch = os::shell("arch");
    if (arch.isError()) {
      seccompError = arch.error();
    } else if (strings::trim(arch.get()) != "x86_64") {
      seccompError = Error("Seccomp tests cannot be run on non-x86_64 systems");
    }

    if (seccompError.isSome()) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We can't run any SECCOMP tests:\n"
        << seccompError.get() << "\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "SECCOMP_") && seccompError.isSome();
  }

private:
  Option<Error> seccompError;
};


class UnprivilegedUserFilter : public TestFilter
{
public:
  UnprivilegedUserFilter()
  {
#ifdef __WINDOWS__
    unprivilegedUserFound = false;
#else
    Option<string> user = os::getenv("SUDO_USER");
    if (user.isNone() || user.get() == "root") {
      unprivilegedUserFound = false;
    } else {
      unprivilegedUserFound = true;
    }

    if (!unprivilegedUserFound) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "No usable unprivileged user found from the 'SUDO_USER'\n"
        << "environment variable. So tests that rely on an unprivileged\n"
        << "user will not run\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
#endif
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "UNPRIVILEGED_USER_") && !unprivilegedUserFound;
  }

private:
  bool unprivilegedUserFound;
};


class UnzipFilter : public TestFilter
{
public:
  UnzipFilter()
  {
    unzipError = os::which("unzip").isNone();
    if (unzipError) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "No 'unzip' command found so no 'unzip' tests will be run\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "UNZIP_") && unzipError;
  }

private:
  bool unzipError;
};


// This is a test filter for the veth CNI plugin.
class VEthFilter : public TestFilter
{
public:
  VEthFilter()
  {
#ifdef __linux__
    vector<string> messages;

    // Checking if it runs as root.
    Result<string> user = os::user();
    CHECK_SOME(user);

    if (user.get() != "root") {
      messages.emplace_back("non-root user");
    }

    // This command returns `ip utility, iproute2-YYMMDD` where
    // `YYMMDD` is a release (snapshot) date of iproute2.
    Try<string> ipVersion = os::shell("ip -Version");

    // Checking if iproute2 exists.
    if (ipVersion.isError()) {
      messages.emplace_back("iproute2 not found");
    } else {
      // Checking if it supports `ip link set ... netns ...`.
      const string version = strings::trim(ipVersion.get());
      if (version.size() < 6) {
        messages.emplace_back("unexpected version");
      } else {
        Try<int> snapshot = numify<int>(version.substr(version.size() - 6));
        if (snapshot.isError()) {
          messages.emplace_back("iproute2 version is not an integer");
        } else if (snapshot.get() < 100224) {
          // Support for `netns` was added to iproute2 in v2.6.33.
          messages.emplace_back("iproute2 doesn't support network namespaces");
        }
      }
    }

    // Checking if libprocess is bound on loopback address, in that
    // case network namespace with veth network won't be able to
    // connect to parent process on host network namespace.
    // TODO(urbanserj): Improve the network connectivity check.
    process::network::inet::Address address = process::address();
    if (address.ip.isLoopback()) {
      messages.emplace_back("libprocess is bound on loopback address");
    }

    disabled = !messages.empty();
    if (disabled) {
      std::cerr
        << "-------------------------------------------------------------\n"
        << "We can't run any VETH tests:\n"
        << strings::join("\n", messages) << "\n"
        << "-------------------------------------------------------------"
        << std::endl;
    }
#else
    disabled = true;
#endif // __linux__
  }

  bool disable(const ::testing::TestInfo* test) const override
  {
    return matches(test, "VETH_") && disabled;
  }

private:
  bool disabled;
};


Environment::Environment(const Flags& _flags)
  : stout::internal::tests::Environment(
        std::vector<std::shared_ptr<TestFilter>>{
            std::make_shared<AufsFilter>(),
            std::make_shared<BenchmarkFilter>(),
            std::make_shared<CfsFilter>(),
            std::make_shared<CgroupsFilter>(),
            std::make_shared<CurlFilter>(),
            std::make_shared<DockerFilter>(),
            std::make_shared<DtypeFilter>(),
            std::make_shared<InternetFilter>(),
            std::make_shared<IPTablesFilter>(),
            std::make_shared<LogrotateFilter>(),
            std::make_shared<NetcatFilter>(),
            std::make_shared<NetClsCgroupsFilter>(),
            std::make_shared<NetworkIsolatorTestFilter>(),
            std::make_shared<NvidiaGpuFilter>(),
            std::make_shared<OverlayFSFilter>(),
            std::make_shared<PerfCPUCyclesFilter>(),
            std::make_shared<PerfFilter>(),
            std::make_shared<RootFilter>(),
            std::make_shared<SeccompFilter>(),
            std::make_shared<UnprivilegedUserFilter>(),
            std::make_shared<UnzipFilter>(),
            std::make_shared<VEthFilter>(),
            std::make_shared<XfsFilter>()}),
    flags(_flags)
{
  // Add our test event listeners.
  ::testing::TestEventListeners& listeners =
    ::testing::UnitTest::GetInstance()->listeners();

  listeners.Append(process::FilterTestEventListener::instance());
  listeners.Append(process::ClockTestEventListener::instance());

  // Add the temporary directory event listener which will clean up
  // any directories created after each test finishes.
  temporaryDirectoryEventListener = new TemporaryDirectoryEventListener();
  listeners.Append(temporaryDirectoryEventListener);
}


void Environment::SetUp()
{
  // Clear any MESOS_ environment variables so they don't affect our tests.
  foreachkey (const string& key, os::environment()) {
    if (key.find("MESOS_") == 0) {
      os::unsetenv(key);
    }
  }

  // Set the path to the native JNI library for running JVM tests.
  // TODO(tillt): Adapt library towards JNI specific name once libmesos
  // has been split.
  if (os::getenv("MESOS_NATIVE_JAVA_LIBRARY").isNone()) {
    string path = getLibMesosPath();
    os::setenv("MESOS_NATIVE_JAVA_LIBRARY", path);
  }

#if !GTEST_IS_THREADSAFE
  EXIT(EXIT_FAILURE) << "Testing environment is not thread safe, bailing!";
#endif // !GTEST_IS_THREADSAFE
}


void Environment::TearDown()
{
  // Make sure we haven't left any child processes lying around.
  // TODO(benh): Look for processes in the same group or session that
  // might have been reparented.
  // TODO(jmlvanre): Consider doing this `OnTestEnd` in a listener so
  // that we can identify leaked processes more precisely.
  Try<os::ProcessTree> pstree = os::pstree(0);

  if (pstree.isSome() && !pstree->children.empty()) {
    FAIL() << "Tests completed with child processes remaining:\n"
           << pstree.get();
  }
}


Try<string> Environment::mkdtemp()
{
  return temporaryDirectoryEventListener->mkdtemp();
}


void tests::Environment::TemporaryDirectoryEventListener::OnTestEnd(
    const testing::TestInfo&)
{
  foreach (const string& directory, directories) {
#ifdef __linux__
    // Try to remove any mounts under 'directory'.
    if (::geteuid() == 0) {
      Try<Nothing> unmount = fs::unmountAll(directory, MNT_DETACH);
      if (unmount.isError()) {
        LOG(ERROR) << "Failed to umount for directory '" << directory
                   << "': " << unmount.error();
      }
    }
#endif

    Try<Nothing> rmdir = os::rmdir(directory);
    if (rmdir.isError()) {
      LOG(ERROR) << "Failed to remove '" << directory
                 << "': " << rmdir.error();
    }
  }

  directories.clear();
}


Try<string> Environment::TemporaryDirectoryEventListener::mkdtemp()
{
  const ::testing::TestInfo* const testInfo =
    ::testing::UnitTest::GetInstance()->current_test_info();

  if (testInfo == nullptr) {
    return Error("Failed to determine the current test information");
  }

  // We replace any slashes present in the test names (e.g. TYPED_TEST),
  // to make sure the temporary directory resides under '/tmp/'.
  const string& testCase =
    strings::replace(testInfo->test_case_name(), "/", "_");

  string testName = strings::replace(testInfo->name(), "/", "_");

  // Adjust the test name to remove any 'DISABLED_' prefix (to make
  // things easier to read). While this might seem alarming, if we are
  // "running" a disabled test it must be the case that the test was
  // explicitly enabled (e.g., via 'gtest_filter').
  if (strings::startsWith(testName, "DISABLED_")) {
    testName = strings::remove(testName, "DISABLED_", strings::PREFIX);
  }

  const string tmpdir = os::temp();

  const string& path =
#ifndef __WINDOWS__
    path::join(tmpdir, strings::join("_", testCase, testName, "XXXXXX"));
#else
    // TODO(hausdorff): When we resolve MESOS-5849, we should change
    // this back to the same path as the Unix version. This is
    // currently necessary to make the sandbox path short enough to
    // avoid the infamous Windows path length errors, which would
    // normally cause many of our tests to fail.
    path::join(tmpdir, "XXXXXX");
#endif // __WINDOWS__

  Try<string> mkdtemp = os::mkdtemp(path);
  if (mkdtemp.isSome()) {
    directories.push_back(mkdtemp.get());
  }
  return mkdtemp;
}

} // namespace tests {
} // namespace internal {
} // namespace mesos {
