// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed 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.

#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>

#include <string.h>
#include <unistd.h>

#include <cerrno>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <cstdlib>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.h"
#include "googletest/include/gtest/gtest.h"

namespace blaze {

// Test fixture for the UnlimitResources function.
//
// The test cases in this fixture are special because the setup forks a
// subprocess and the actual testing is supposed to happen in such subprocess.
// This is because resource limits are process-wide so we must ensure that our
// testing does not interfere with other tests in this fixture or with other
// tests in the whole test program.
//
// What this means is that each test case function must check if IsChild() is
// false first.  If it is, the function must return immediately.  If it is not,
// then the function can proceed to execute the test but care must be taken: the
// test function cannot use any of the gunit functions, nor it can use std::exit
// to terminate.  Instead, the function must use Die() to exit on a failure.
class UnlimitResourcesTest : public testing::Test {
 protected:
  UnlimitResourcesTest() {
    pid_ = fork();
    EXPECT_NE(-1, pid_);
  }

  virtual ~UnlimitResourcesTest() {
    if (IsChild()) {
      _exit(EXIT_SUCCESS);
    } else {
      int status;
      EXPECT_NE(-1, waitpid(pid_, &status, 0));
      EXPECT_TRUE(WIFEXITED(status));
      EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
    }
  }

  // Returns true if the test function is running in the child subprocess.
  bool IsChild() {
    return pid_ == 0;
  }

  // Description of the resource limits to test for.
  static struct limits_spec {
    const char* name;
    const int resource;
  } limits_[];

  // Aborts execution with the given message and fails the test case.
  // This can only be called when IsChild() is true.
  static void Die(const char* fmt, ...) ATTRIBUTE_NORETURN {
    va_list ap;
    va_start(ap, fmt);
    std::vfprintf(stderr, fmt, ap);
    va_end(ap);
    _exit(EXIT_FAILURE);
  }

  // Version of getrlimit(3) that fails the test on error.
  // This can only be called when IsChild() is true.
  static struct rlimit GetrlimitOrDie(const int resource) {
    struct rlimit rl;
    if (getrlimit(resource, &rl) == -1) {
      Die("getrlimit(%d) failed: %s\n", resource, strerror(errno));
    }
    return rl;
  }

  // Version of setrlimit(3) that fails the test on error.
  // This can only be called when IsChild() is true.
  static void SetrlimitOrDie(const int resource, struct rlimit rl) {
    if (setrlimit(resource, &rl) == -1) {
      Die("setrlimit(%d) failed with cur=%" PRIdMAX ", max=%" PRIdMAX ": %s\n",
          resource, static_cast<intmax_t>(rl.rlim_cur),
          static_cast<intmax_t>(rl.rlim_max), strerror(errno));
    }
  }

 private:
  // PID of the test subprocess, or 0 if we are the subprocess.
  pid_t pid_;
};

struct UnlimitResourcesTest::limits_spec UnlimitResourcesTest::limits_[] = {
  { "RLIMIT_NOFILE", RLIMIT_NOFILE },
  { "RLIMIT_NPROC", RLIMIT_NPROC },
  { nullptr, 0 },
};

TEST_F(UnlimitResourcesTest, SuccessWithExplicitLimits) {
  if (!IsChild()) return;
  // The rest of this test runs in a subprocess.  See the fixture's docstring
  // for details on what this implies.

  // Lower the limits to very low values that should always work.
  for (struct limits_spec* limit = limits_; limit->name != nullptr; limit++) {
    struct rlimit rl = GetrlimitOrDie(limit->resource);
    rl.rlim_cur = 1;
    rl.rlim_max = 8;
    SetrlimitOrDie(limit->resource, rl);
  }

  if (!blaze::UnlimitResources()) {
    Die("UnlimitResources returned error; see output for diagnostics\n");
  }

  // Check that the soft limits were raised to the explicit hard limits we set.
  for (struct limits_spec* limit = limits_; limit->name != nullptr; limit++) {
    const struct rlimit rl = GetrlimitOrDie(limit->resource);
    if (rl.rlim_cur != rl.rlim_max) {
      Die("UnlimitResources did not increase the soft %s to its hard limit\n",
          limit->name);
    }
  }
}

TEST_F(UnlimitResourcesTest, SuccessWithPossiblyInfiniteLimits) {
  if (!IsChild()) return;
  // The rest of this test runs in a subprocess.  See the fixture's docstring
  // for details on what this implies.

  if (GetExplicitSystemLimit(-1) == -1) {
    fprintf(stderr, "GetExplicitSystemLimit not implemented for this platform; "
            "cannot verify the behavior of UnlimitResources\n");
    return;
  }

  // Lower only the soft limits to very low values and assume that the hard
  // limits are set to infinity; otherwise, there is nothing we can do because
  // we may not have permissions to increase them.
  for (struct limits_spec* limit = limits_; limit->name != nullptr; limit++) {
    struct rlimit rl = GetrlimitOrDie(limit->resource);
    if (rl.rlim_max != RLIM_INFINITY) {
      fprintf(stderr, "Hard resource limit for %s is not infinity; will not "
              "be able to meaningfully test anything\n", limit->name);
    }
    rl.rlim_cur = 1;
    SetrlimitOrDie(limit->resource, rl);
  }

  if (!blaze::UnlimitResources()) {
    Die("UnlimitResources returned error; see output for diagnostics\n");
  }

  // Check that the soft limits were increased to a higher explicit number.
  for (struct limits_spec* limit = limits_; limit->name != nullptr; limit++) {
    const struct rlimit rl = GetrlimitOrDie(limit->resource);
    if (rl.rlim_cur == 1 || rl.rlim_cur == RLIM_INFINITY) {
      Die("UnlimitResources did not increase the soft %s to the system limit\n",
          limit->name);
    }
  }
}

TEST_F(UnlimitResourcesTest, Coredumps) {
  if (!IsChild()) return;
  // The rest of this test runs in a subprocess.  See the fixture's docstring
  // for details on what this implies.

  // Lower only the soft limit to a very low value and assume that the hard
  // limit is non-zero.
  struct rlimit rl = GetrlimitOrDie(RLIMIT_CORE);
  if (rl.rlim_max <= 1) {
    fprintf(stderr,
            "Hard resource limit for RLIMIT_CORE is %" PRIuMAX
            "; cannot test anything meaningful\n",
            static_cast<uintmax_t>(rl.rlim_max));
    return;
  }
  rl.rlim_cur = 1;
  SetrlimitOrDie(RLIMIT_CORE, rl);

  if (!blaze::UnlimitCoredumps()) {
    Die("UnlimitCoredumps returned error; see output for diagnostics\n");
  }

  // Check that the soft limits were increased to a higher explicit number.
  rl = GetrlimitOrDie(RLIMIT_CORE);
  if (rl.rlim_cur == 1) {
    Die("UnlimitCoredumps did not increase the soft RLIMIT_CORE to the system "
        "limit\n");
  }
}

}  // namespace blaze
