#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the
# COPYING file in the root directory) and Apache 2.0 License
# (found in the LICENSE.Apache file in the root directory).
#
# Build a single RocksDB unit test binary and run it directly (serially).
# Only recommended with --gtest_filter=... because of speed. See also
# build_tools/rocksptest.sh
#
# Hardened version of a simple `make <bin> && ./<bin>` helper:
#  * AUTO_CLEAN=1 so the Makefile automatically runs a clean when the build
#    parameters (DEBUG_LEVEL, sanitizers, ASSERT_STATUS_CHECKED, RTTI, etc.)
#    have changed since the last build, preventing stale/mixed object files.
#  * Parallel build with -j<NCORES>, computed the same way the Makefile does.
#  * `set -euo pipefail` so any failure stops the script.
#
# Run from the repository root.
#
# Example usage:
#   build_tools/rockstest.sh db_test --gtest_filter=*MixedSlowdown*
#   build_tools/rockstest.sh env_test # Slow to run many tests serially
#
# Install mode:
#   build_tools/rockstest.sh install
#     Creates ~/bin/rockstest and ~/bin/rocksptest shims that defer to
#     build_tools/rockstest.sh / rocksptest.sh in whatever directory you run
#     them from, so you can just type `rockstest db_test` from any rocksdb
#     source root.

set -euo pipefail

# Install mode: write thin ~/bin shims that defer to the build_tools scripts in
# the current directory.
if [ "${1:-}" = "install" ]; then
  mkdir -p "$HOME/bin"
  for name in rockstest rocksptest; do
    dest="$HOME/bin/$name"
    cat > "$dest" <<EOF
#!/usr/bin/env bash
# Auto-generated by 'build_tools/rockstest.sh install'. Defers to
# build_tools/$name.sh in the current rocksdb source root.
if [ -x build_tools/$name.sh ]; then
  exec build_tools/$name.sh "\$@"
else
  echo "build_tools/$name.sh not found (Not in a rocksdb source root directory?)" >&2
  exit 1
fi
EOF
    chmod +x "$dest"
    echo "Installed $dest"
  done
  exit 0
fi

if [ "$#" -lt 1 ]; then
  echo "usage: $0 <test_binary> [test args...]" >&2
  echo "       $0 install   # create ~/bin/rockstest and ~/bin/rocksptest shims" >&2
  echo "example: $0 db_test --gtest_filter=*MixedSlowdown*" >&2
  exit 1
fi

# First argument must be a test binary, not an option (catches a forgotten name).
if [ "${1#-}" != "$1" ]; then
  echo "$0: first argument must be a test binary name, not an option ('$1')" >&2
  exit 1
fi

BIN=$1
shift

# Compute parallelism the same way the Makefile computes NCORES.
NCORES=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)

make AUTO_CLEAN=1 -j"$NCORES" "$BIN"
./"$BIN" "$@"
