From 9d986fd7d60d705c523e3d8c331fa286dda9e2c0 Mon Sep 17 00:00:00 2001 From: Luke McCrone Date: Fri, 7 Aug 2026 13:53:22 -0300 Subject: [PATCH] test: install script improvements --- .github/workflows/system-macos-15-intel.yml | 38 +- .github/workflows/system-macos-15.yml | 38 +- .github/workflows/system-ubuntu-arm.yml | 33 +- .github/workflows/system.yml | 33 +- tests/Dockerfile_test_bats | 60 +- tests/README.md | 8 +- tests/install_base_dependencies.sh | 607 ++++++++++++++++---- tests/tags/get_tests.sh | 2 +- 8 files changed, 520 insertions(+), 299 deletions(-) diff --git a/.github/workflows/system-macos-15-intel.yml b/.github/workflows/system-macos-15-intel.yml index ae684568..ef2817db 100644 --- a/.github/workflows/system-macos-15-intel.yml +++ b/.github/workflows/system-macos-15-intel.yml @@ -13,42 +13,6 @@ jobs: run: | ./tests/install_base_dependencies.sh - - name: Set up Go - uses: actions/setup-go@v7 - with: - go-version: "stable" - id: go - - - name: Get Dependencies - run: | - go get -v -t -d ./... - - - name: Upgrade bash - run: | - brew install bash - echo "$(brew --prefix)/bin" >> "$GITHUB_PATH" - - - name: Install BATS - run: | - git clone https://github.com/bats-core/bats-core.git - cd bats-core && ./install.sh ${{ github.workspace }} - git clone https://github.com/bats-core/bats-support.git ${{ github.workspace }}/tests/bats-support - git clone https://github.com/ztombol/bats-assert.git ${{ github.workspace }}/tests/bats-assert - - # disable mc tests due to dl.min.io instability - # - name: Install mc - # run: | - # curl https://dl.min.io/client/mc/release/linux-amd64/mc --create-dirs -o /usr/local/bin/mc - # chmod 755 /usr/local/bin/mc - - # see https://github.com/versity/versitygw/issues/1034 - - name: Install AWS cli - run: | - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-2.22.35.zip" -o "awscliv2.zip" - unzip -o awscliv2.zip - ./aws/install -i ${{ github.workspace }}/aws-cli -b ${{ github.workspace }}/bin - echo "${{ github.workspace }}/bin" >> $GITHUB_PATH - - name: Create test user run: | sudo sysadminctl -addUser tester -shell /bin/bash -home /Users/tester -createHome @@ -190,7 +154,7 @@ jobs: if [[ $RECREATE_BUCKETS == "false" ]]; then $BREW_BASH ${{ github.workspace }}/tests/setup_static.sh fi - $BREW_BASH ${{ github.workspace }}/bin/bats ${{ github.workspace }}/$RUN_SET + $BREW_BASH bats ${{ github.workspace }}/$RUN_SET if [ -e "$COVERAGE_LOG" ]; then cat $COVERAGE_LOG diff --git a/.github/workflows/system-macos-15.yml b/.github/workflows/system-macos-15.yml index 8b3e6b98..6a16269f 100644 --- a/.github/workflows/system-macos-15.yml +++ b/.github/workflows/system-macos-15.yml @@ -13,42 +13,6 @@ jobs: run: | ./tests/install_base_dependencies.sh - - name: Set up Go - uses: actions/setup-go@v7 - with: - go-version: "stable" - id: go - - - name: Get Go Dependencies - run: | - go get -v -t -d ./... - - - name: Upgrade bash - run: | - brew install bash - echo "$(brew --prefix)/bin" >> "$GITHUB_PATH" - - - name: Install BATS - run: | - git clone https://github.com/bats-core/bats-core.git - cd bats-core && ./install.sh ${{ github.workspace }} - git clone https://github.com/bats-core/bats-support.git ${{ github.workspace }}/tests/bats-support - git clone https://github.com/ztombol/bats-assert.git ${{ github.workspace }}/tests/bats-assert - - # disable mc tests due to dl.min.io instability - # - name: Install mc - # run: | - # curl https://dl.min.io/client/mc/release/linux-amd64/mc --create-dirs -o /usr/local/bin/mc - # chmod 755 /usr/local/bin/mc - - # see https://github.com/versity/versitygw/issues/1034 - - name: Install AWS cli - run: | - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-2.22.35.zip" -o "awscliv2.zip" - unzip -o awscliv2.zip - ./aws/install -i ${{ github.workspace }}/aws-cli -b ${{ github.workspace }}/bin - echo "${{ github.workspace }}/bin" >> $GITHUB_PATH - - name: Create test user run: | sudo sysadminctl -addUser tester -shell /bin/bash -home /Users/tester -createHome @@ -190,7 +154,7 @@ jobs: if [[ $RECREATE_BUCKETS == "false" ]]; then $BREW_BASH ${{ github.workspace }}/tests/setup_static.sh fi - $BREW_BASH ${{ github.workspace }}/bin/bats ${{ github.workspace }}/$RUN_SET + $BREW_BASH bats ${{ github.workspace }}/$RUN_SET if [ -e "$COVERAGE_LOG" ]; then cat $COVERAGE_LOG diff --git a/.github/workflows/system-ubuntu-arm.yml b/.github/workflows/system-ubuntu-arm.yml index 007e8335..b0e3996d 100644 --- a/.github/workflows/system-ubuntu-arm.yml +++ b/.github/workflows/system-ubuntu-arm.yml @@ -13,37 +13,6 @@ jobs: run: | ./tests/install_base_dependencies.sh - - name: Set up Go - uses: actions/setup-go@v7 - with: - go-version: "stable" - id: go - - - name: Get Go Dependencies - run: | - go get -v -t -d ./... - - - name: Install BATS - run: | - git clone https://github.com/bats-core/bats-core.git - cd bats-core && ./install.sh ${{ github.workspace }} - git clone https://github.com/bats-core/bats-support.git ${{ github.workspace }}/tests/bats-support - git clone https://github.com/ztombol/bats-assert.git ${{ github.workspace }}/tests/bats-assert - - # disable mc tests due to dl.min.io instability - # - name: Install mc - # run: | - # curl https://dl.min.io/client/mc/release/linux-amd64/mc --create-dirs -o /usr/local/bin/mc - # chmod 755 /usr/local/bin/mc - - # see https://github.com/versity/versitygw/issues/1034 - - name: Install AWS cli - run: | - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-2.22.35.zip" -o "awscliv2.zip" - unzip -o awscliv2.zip - ./aws/install -i ${{ github.workspace }}/aws-cli -b ${{ github.workspace }}/bin - echo "${{ github.workspace }}/bin" >> $GITHUB_PATH - - name: Create test user run: | sudo useradd -m -s /bin/bash tester @@ -169,7 +138,7 @@ jobs: if [[ $RECREATE_BUCKETS == "false" ]]; then BYPASS_ENV_FILE=true bash ${{ github.workspace }}/tests/setup_static.sh fi - BYPASS_ENV_FILE=true ${{ github.workspace }}/bin/bats ${{ github.workspace }}/$RUN_SET + BYPASS_ENV_FILE=true bats ${{ github.workspace }}/$RUN_SET if [ -e "$COVERAGE_LOG" ]; then cat $COVERAGE_LOG diff --git a/.github/workflows/system.yml b/.github/workflows/system.yml index 40fc14c2..379bf283 100644 --- a/.github/workflows/system.yml +++ b/.github/workflows/system.yml @@ -32,37 +32,6 @@ jobs: run: | ./tests/install_base_dependencies.sh - - name: Set up Go - uses: actions/setup-go@v7 - with: - go-version: "stable" - id: go - - - name: Get Go Dependencies - run: | - go get -v -t -d ./... - - - name: Install BATS - run: | - git clone https://github.com/bats-core/bats-core.git - cd bats-core && ./install.sh ${{ github.workspace }} - git clone https://github.com/bats-core/bats-support.git ${{ github.workspace }}/tests/bats-support - git clone https://github.com/ztombol/bats-assert.git ${{ github.workspace }}/tests/bats-assert - -# disable mc tests due to dl.min.io instability -# - name: Install mc -# run: | -# curl https://dl.min.io/client/mc/release/linux-amd64/mc --create-dirs -o /usr/local/bin/mc -# chmod 755 /usr/local/bin/mc - - # see https://github.com/versity/versitygw/issues/1034 - - name: Install AWS cli - run: | - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-2.22.35.zip" -o "awscliv2.zip" - unzip -o awscliv2.zip - ./aws/install -i ${{ github.workspace }}/aws-cli -b ${{ github.workspace }}/bin - echo "${{ github.workspace }}/bin" >> $GITHUB_PATH - - name: Create test user run: | sudo useradd -m -s /bin/bash tester @@ -190,7 +159,7 @@ jobs: if [[ $RECREATE_BUCKETS == "false" ]]; then BYPASS_ENV_FILE=true bash ${{ github.workspace }}/tests/setup_static.sh fi - BYPASS_ENV_FILE=true ${{ github.workspace }}/bin/bats ${{ github.workspace }}/$RUN_SET + BYPASS_ENV_FILE=true bats ${{ github.workspace }}/$RUN_SET if [ -e "$COVERAGE_LOG" ]; then cat $COVERAGE_LOG diff --git a/tests/Dockerfile_test_bats b/tests/Dockerfile_test_bats index ae10364f..b8127c42 100644 --- a/tests/Dockerfile_test_bats +++ b/tests/Dockerfile_test_bats @@ -8,53 +8,21 @@ ARG GO_LIBRARY=go1.21.13.linux-${TARGETARCH}.tar.gz ARG MC_FOLDER=linux-${TARGETARCH} ENV TZ=Etc/UTC -WORKDIR /tmp - -COPY ./tests/install_base_dependencies.sh . -RUN ./install_base_dependencies.sh - -RUN update-ca-certificates && rm -rf /var/lib/apt/lists/* - -RUN case "$TARGETARCH" in \ - amd64) echo 'DOWNLOAD_ARCH=x86_64' > ./arch.env ;; \ - arm64) echo 'DOWNLOAD_ARCH=aarch64' > ./arch.env ;; \ - *) echo "Unsupported TARGETARCH: $TARGETARCH" && exit 1 ;; \ - esac - -# Install AWS cli -RUN . ./arch.env && curl "https://awscli.amazonaws.com/awscli-exe-linux-${DOWNLOAD_ARCH}.zip" -o "awscliv2.zip" && unzip awscliv2.zip && ./aws/install - -# Install mc -RUN curl -fL https://dl.min.io/client/mc/release/${MC_FOLDER}/mc \ - --create-dirs \ - -o /usr/local/minio-binaries/mc && \ -chmod -R 755 /usr/local/minio-binaries -ENV PATH=/usr/local/minio-binaries:${PATH} - -# Download Go 1.21 (adjust the version and platform as needed) -RUN wget https://golang.org/dl/${GO_LIBRARY} - -# Extract the downloaded archive -RUN tar -xvf $GO_LIBRARY -C /usr/local - -# Set Go environment variables -ENV PATH="/usr/local/go/bin:${PATH}" -ENV GOPATH="/go" -ENV GOBIN="$GOPATH/bin" - -# Make the directory for Go packages -RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" # Create tester user RUN groupadd -r tester && useradd -r -g tester tester RUN mkdir /home/tester && chown tester:tester /home/tester ENV HOME=/home/tester +WORKDIR /home/tester -# install bats -RUN git clone https://github.com/bats-core/bats-core.git && \ - cd bats-core && \ - ./install.sh /home/tester -ENV PATH="/home/tester/bin:${PATH}" +USER tester +COPY --chown=tester:tester . /home/tester + +USER root +RUN INSTALL_MC=true /home/tester/tests/install_base_dependencies.sh + +WORKDIR /tmp +RUN update-ca-certificates && rm -rf /var/lib/apt/lists/* # Create a shared venv & install Python deps there ENV VENV=/opt/venv @@ -65,17 +33,11 @@ RUN python3 -m venv "$VENV" \ # Make the venv the default Python for all subsequent RUN/CMD/ENTRYPOINT ENV PATH="$VENV/bin:${PATH}" -USER tester -COPY --chown=tester:tester . /home/tester - -# add bats support libraries -RUN git clone https://github.com/bats-core/bats-support.git && rm -rf /home/tester/tests/bats-support && mv bats-support /home/tester/tests -RUN git clone https://github.com/ztombol/bats-assert.git && rm -rf /home/tester/tests/bats-assert && mv bats-assert /home/tester/tests - WORKDIR /home/tester -RUN go mod download RUN make +USER tester + RUN . $SECRETS_FILE && \ export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION AWS_PROFILE && \ aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID --profile $AWS_PROFILE && \ diff --git a/tests/README.md b/tests/README.md index d64f0341..d0b0145e 100644 --- a/tests/README.md +++ b/tests/README.md @@ -20,6 +20,12 @@ > **Note**: many of the required libraries, and a good rundown of the installation procedure, can be found in the `Dockerfile_test_bats` dockerfile in the root folder. +#### Automatic + +Run `tests/install_base_dependencies.sh` to automatically run steps 1 through 5 below. Then proceed with manual setup. + +#### Manual + 1. Build the `versitygw` binary. 2. Install the command-line interface(s) you want to test if unavailable on your machine. * **aws cli**: Instructions are [here](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). @@ -81,7 +87,7 @@ To communicate directly with s3, in order to compare the gateway results to dire 1. Copy `.secrets.default` to `.secrets` in the `tests` folder and change the parameters and add the additional s3 fields explained in the **S3 Backend** section above if running with the s3 backend. 2. By default, the dockerfile uses the **arm** architecture (usually modern Mac). If using **amd** (usually earlier Mac or Linux), you can either replace the corresponding `ARG` values directly, or with `arg="="` Also, you can determine which is used by your OS with `uname -a`. -3. Build and run the `Dockerfile_test_bats` file. Change the `SECRETS_FILE` and `CONFIG_FILE` parameters to point to your secrets and config file, respectively, if not using the defaults. Example: `docker build -t --build-arg="SECRETS_FILE=" --build-arg="CONFIG_FILE=" -f tests/Dockerfile_test_bats .`. +3. Build and run the `Dockerfile_test_bats` file. Change the `SECRETS_FILE` and `CONFIG_FILE` parameters to point to your secrets and config file, respectively, if not using the defaults. Example: `docker build -t --build-arg="SECRETS_FILE=" --build-arg="CONFIG_FILE=" -f tests/Dockerfile_test_bats .`. Also, default docker parameters, such as `TARGETARCH`, at the top of the Dockerfile can be changed by the user if needed. 4. To run the entire suite, run `docker run -it `. This is not recommended due to the sheer amount of tests. To run an individual suite, pass in the name of the suite as defined in `tests/run.sh` (e.g. REST bucket tests -> `docker run -it rest-bucket`). Also, multiple specific suites can be run, if separated by comma. 5. To list all suites available, the `-h` tag can be passed. Example: `docker run -t -h`. 6. By default, the config is placed in the `/home/tester/config` folder inside the container. Logs are printed to `/home/tester/log`. To overwrite the config, an `.env` folder can be placed in a mounted host folder, and to view the logs, a mounted folder can also be used. Example: `docker run -v $PWD/runtime/config:/home/tester/config -v $PWD/runtime/log:/home/tester/log -t bats_test s3` diff --git a/tests/install_base_dependencies.sh b/tests/install_base_dependencies.sh index 89fe4297..c87da0c1 100755 --- a/tests/install_base_dependencies.sh +++ b/tests/install_base_dependencies.sh @@ -1,8 +1,64 @@ #!/usr/bin/env bash +pre_install_report() { + local os arch cwd detected_pkg_manager xcode_clt cmd + + os=$(uname -s) + arch=$(uname -m) + cwd=$(pwd) + detected_pkg_manager="$(detect_linux_package_manager)" + + echo "=== Pre-install report ===" + printf "OS: %s\n" "$os" + printf "Architecture: %s\n" "$arch" + printf "Working directory: %s\n" "$cwd" + printf "Current user: %s (uid=%s)\n" "$(id -un)" "$(id -u)" + printf "Root user: %s\n" "$(is_root && echo yes || echo no)" + printf "CI: %s\n" "${CI:-false}" + printf "PATH: %s\n" "$PATH" + printf "Home: %s\n" "$HOME" + + if [ "$os" = "Linux" ]; then + printf "Detected Linux package manager: %s\n" "$detected_pkg_manager" + elif [ "$os" = "Darwin" ]; then + if command -v xcode-select >/dev/null 2>&1 && xcode-select -p >/dev/null 2>&1; then + xcode_clt=$(xcode-select -p) + printf "Xcode CLT: %s\n" "$xcode_clt" + else + printf "Xcode CLT: not installed\n" + fi + fi + + for cmd in bash brew go aws bats git make curl wget unzip jq python3 xmllint xmlstarlet s3cmd uuidgen xxd; do + if command -v "$cmd" >/dev/null 2>&1; then + printf "%-10s %s\n" "$cmd:" "$(command -v "$cmd")" + else + printf "%-10s %s\n" "$cmd:" "missing" + fi + done + + if command -v bash >/dev/null 2>&1; then + printf "Bash version: %s\n" "$BASH_VERSION" + fi + if command -v go >/dev/null 2>&1; then + printf "Go version: %s\n" "$(go version)" + fi + if command -v aws >/dev/null 2>&1; then + printf "AWS CLI version: %s\n" "$(aws --version 2>&1)" + fi + if command -v bats >/dev/null 2>&1; then + printf "BATS version: %s\n" "$(bats --version 2>&1)" + fi + echo "==========================" + return 0 +} + check_for_xcode() { + local xcode_tools + if xcode-select -p >/dev/null 2>&1; then - echo "Xcode Command Line Tools already installed: $(xcode-select -p)" + xcode_tools=$(xcode-select -p) + printf "Xcode Command Line Tools already installed: %s\n" "$xcode_tools" return 0 fi @@ -23,6 +79,70 @@ check_for_xcode() { return 1 } +install_managed_libraries() { + if [ "$#" -ne 1 ]; then + echo "install_managed_libraries requires OS type" >&2 + return 1 + fi + local os="$1" + case "$os" in + Darwin) + if ! install_mac_libraries; then + echo "error installing mac libraries" >&2 + return 1 + fi + ;; + Linux) + if ! install_linux_libraries; then + echo "error installing linux libraries" >&2 + return 1 + fi + ;; + *) + echo "unrecognized os: $os" >&2 + return 1 + ;; + esac + return 0 +} + +install_linux_libraries() { + local package_manager + + package_manager="$(detect_linux_package_manager)" + case "$package_manager" in + apt) + if ! install_apt_libraries; then + echo "error installing apt libraries" >&2 + return 1 + fi + ;; + dnf) + if ! install_dnf_libraries; then + echo "error installing dnf libraries" >&2 + return 1 + fi + ;; + yum) + if ! install_yum_libraries; then + echo "error installing yum libraries" >&2 + return 1 + fi + ;; + apk) + if ! install_apk_libraries; then + echo "error installing apk libraries" >&2 + return 1 + fi + ;; + *) + echo "unrecognized package manager: '$package_manager'" >&2 + return 1 + ;; + esac + return 0 +} + install_mac_libraries() { if ! check_for_xcode; then return 1 @@ -39,7 +159,15 @@ install_mac_libraries() { s3cmd libxml2 xmlstarlet + jq + go + bats-core ) + if command -v aws >/dev/null 2>&1; then + printf "AWS CLI already installed: %s\n" "$(aws --version 2>&1)" + else + packages+=(awscli) + fi local package for package in "${packages[@]}"; do @@ -53,6 +181,11 @@ install_mac_libraries() { return 1 fi done + + if ! upgrade_bash_on_mac; then + echo "error upgrading bash" >&2 + return 1 + fi return 0 } @@ -87,106 +220,118 @@ detect_linux_package_manager() { return 0 } -install_linux_libraries() { - local pkg_manager - pkg_manager="$(detect_linux_package_manager)" +install_apt_libraries() { + local libraries=(git + make \ + wget \ + curl \ + unzip \ + tzdata \ + s3cmd \ + jq \ + bc \ + libxml2-utils \ + xmlstarlet \ + python3-pip \ + python3-venv \ + xxd \ + uuid-runtime \ + ca-certificates \ + build-essential \ + libc6-dev \ + bats) + if command -v go >/dev/null 2>&1; then + printf "Go already installed: %s\n" "$(go version)" + else + libraries+=(golang-go) + fi + run_as_root env DEBIAN_FRONTEND=noninteractive apt-get update || return 1 + run_as_root env DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y "${libraries[@]}" +} - echo "Package manager: $pkg_manager" +install_dnf_libraries() { + local libraries=(git \ + make \ + wget \ + curl \ + unzip \ + tzdata \ + s3cmd \ + jq \ + bc \ + libxml2 \ + xmlstarlet \ + python3-pip \ + python3-virtualenv \ + vim-common \ + util-linux \ + ca-certificates \ + bats) + if command -v go >/dev/null 2>&1; then + printf "Go already installed: %s\n" "$(go version)" + else + libraries+=(golang) + fi + run_as_root dnf install -y "${libraries[@]}" +} - case "$pkg_manager" in - apt) - run_as_root env DEBIAN_FRONTEND=noninteractive apt-get update || return 1 - run_as_root env DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC \ - apt-get install -y \ - git \ - make \ - wget \ - curl \ - unzip \ - tzdata \ - s3cmd \ - jq \ - bc \ - libxml2-utils \ - xmlstarlet \ - python3-pip \ - python3-venv \ - xxd \ - uuid-runtime \ - ca-certificates || return 1 - ;; +install_yum_libraries() { + local libraries=(git \ + make \ + wget \ + curl \ + unzip \ + tzdata \ + s3cmd \ + jq \ + bc \ + libxml2 \ + xmlstarlet \ + python3-pip \ + python3-virtualenv \ + vim-common \ + util-linux \ + ca-certificates \ + bats) + if command -v go >/dev/null 2>&1; then + printf "Go already installed: %s\n" "$(go version)" + else + libraries+=(golang) + fi + run_as_root yum install -y "${libraries[@]}" +} - dnf) - run_as_root dnf install -y \ - git \ - make \ - wget \ - curl \ - unzip \ - tzdata \ - s3cmd \ - jq \ - bc \ - libxml2 \ - xmlstarlet \ - python3-pip \ - python3-virtualenv \ - vim-common \ - util-linux \ - ca-certificates || return 1 - ;; - - yum) - run_as_root yum install -y \ - git \ - make \ - wget \ - curl \ - unzip \ - tzdata \ - s3cmd \ - jq \ - bc \ - libxml2 \ - xmlstarlet \ - python3-pip \ - python3-virtualenv \ - vim-common \ - util-linux \ - ca-certificates || return 1 - ;; - - apk) - run_as_root apk add --no-cache \ - git \ - make \ - wget \ - curl \ - unzip \ - tzdata \ - s3cmd \ - jq \ - bc \ - libxml2-utils \ - xmlstarlet \ - py3-pip \ - python3 \ - py3-virtualenv \ - xxd \ - util-linux \ - ca-certificates || return 1 - ;; - - *) - echo "error: unsupported Linux package manager" >&2 - return 1 - ;; - esac - return 0 +install_apk_libraries() { + local libraries=(git \ + make \ + wget \ + curl \ + unzip \ + tzdata \ + s3cmd \ + jq \ + bc \ + libxml2-utils \ + xmlstarlet \ + py3-pip \ + python3 \ + py3-virtualenv \ + xxd \ + util-linux \ + ca-certificates \ + bats) + if command -v go >/dev/null 2>&1; then + printf "Go already installed: %s\n" "$(go version)" + else + libraries+=(go) + fi + run_as_root apk add --no-cache "${libraries[@]}" } check_required_commands() { local commands=( + aws + go git make wget @@ -202,6 +347,10 @@ check_required_commands() { xxd ) + if [ "${INSTALL_MC:-false}" = "true" ]; then + commands+=(mc) + fi + local cmd for cmd in "${commands[@]}"; do if ! command -v "$cmd" >/dev/null 2>&1; then @@ -212,26 +361,264 @@ check_required_commands() { return 0 } +upgrade_bash_on_mac() { + local bash_major brew_bash bash_path + + bash_major="${BASH_VERSINFO[0]:-0}" + if [ "$bash_major" -ge 4 ]; then + printf "Bash already modern enough: %s\n" "$BASH_VERSION" + return 0 + fi + + if ! command -v brew >/dev/null 2>&1; then + echo "error: Homebrew is required to upgrade Bash on macOS" >&2 + return 1 + fi + + echo "Upgrading bash with Homebrew..." + if ! brew install bash; then + echo "error: failed to install bash with Homebrew" >&2 + return 1 + fi + + if brew --prefix >/dev/null 2>&1; then + brew_bash="$(brew --prefix)/bin/bash" + if [ -x "$brew_bash" ]; then + bash_path="$brew_bash" + fi + fi + if [ -z "$bash_path" ] && command -v bash >/dev/null 2>&1; then + bash_path="$(command -v bash)" + fi + + if [ -n "$bash_path" ] && [ -x "$bash_path" ]; then + printf "Installed newer bash: %s\n" "$bash_path" + printf "Use this shell explicitly if needed: %s\n" "$bash_path" + return 0 + fi + + echo "error: bash install completed but upgraded bash path could not be found" >&2 + return 1 +} + +install_aws_from_url() { + if [ "$#" -ne 2 ]; then + echo "install_aws_from_url requires download url, archive name" >&2 + return 1 + fi + local download_url="$1" archive_name="$2" + local tmp_dir install_dir bin_dir + + tmp_dir=$(mktemp -d) || return 1 + install_dir="/usr/local/aws-cli" + bin_dir="/usr/local/bin" + + echo "Downloading AWS CLI from $download_url..." + if ! curl -fsSL "$download_url" -o "$tmp_dir/$archive_name"; then + echo "error: failed to download AWS CLI" >&2 + rm -rf "$tmp_dir" + return 1 + fi + if ! unzip -q "$tmp_dir/$archive_name" -d "$tmp_dir"; then + echo "error: failed to unzip AWS CLI archive" >&2 + rm -rf "$tmp_dir" + return 1 + fi + if ! run_as_root "$tmp_dir/aws/install" -i "$install_dir" -b "$bin_dir" --update; then + echo "error: failed to install AWS CLI" >&2 + rm -rf "$tmp_dir" + return 1 + fi + rm -rf "$tmp_dir" +} + +install_linux_aws_command_line_tools() { + if command -v aws >/dev/null 2>&1; then + printf "AWS CLI already installed: %s\n" "$(aws --version 2>&1)" + return 0 + fi + local response tmp_dir archive_name download_url + + archive_name="awscliv2.zip" + case "$(uname -m)" in + x86_64|amd64) + download_url="https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" + ;; + aarch64|arm64) + download_url="https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" + ;; + *) + echo "error: unsupported Linux architecture for AWS CLI: $(uname -m)" >&2 + rm -rf "$tmp_dir" + return 1 + ;; + esac + if ! install_aws_from_url "$download_url" "$archive_name"; then + echo "error installing AWS from download url '$download_url'" + return 1 + fi + + if ! command -v aws >/dev/null 2>&1; then + echo "error: AWS CLI still not found after installation" >&2 + return 1 + fi + + if ! response=$(aws --version 2>&1); then + echo "error: failed to run installed AWS CLI" >&2 + return 1 + fi + printf "Installed AWS CLI: %s\n" "$response" + return 0 +} + +get_mc_download_link() { + if [ $# -ne 1 ]; then + echo "get_mc_download_link requires os" >&2 + return 1 + fi + local os="$1" + local arch download_url + + arch=$(uname -m) + case "$os" in + Darwin) + case "$arch" in + x86_64|amd64) + download_url="https://dl.min.io/client/mc/release/darwin-amd64/mc" + ;; + arm64|aarch64) + download_url="https://dl.min.io/client/mc/release/darwin-arm64/mc" + ;; + *) + echo "error: unsupported macOS architecture for mc: $arch" >&2 + return 1 + ;; + esac + ;; + Linux) + case "$arch" in + x86_64|amd64) + download_url="https://dl.min.io/client/mc/release/linux-amd64/mc" + ;; + arm64|aarch64) + download_url="https://dl.min.io/client/mc/release/linux-arm64/mc" + ;; + *) + echo "error: unsupported Linux architecture for mc: $arch" >&2 + return 1 + ;; + esac + ;; + *) + echo "error: unsupported OS type for installing mc: $os" >&2 + return 1 + ;; + esac + printf '%s\n' "$download_url" + return 0 +} + +install_mc() { + if [ "$#" -ne 1 ]; then + echo "install_mc requires os" >&2 + return 1 + fi + local os="$1" + local download_url tmp_dir target_path response + + if command -v mc >/dev/null 2>&1; then + printf "MinIO mc already installed: %s\n" "$(mc --version 2>&1 | head -n 1)" + return 0 + fi + + if ! response=$(get_mc_download_link "$os" 2>&1); then + echo "error getting mc download link: $response" >&2 + return 1 + fi + download_url="$response" + + tmp_dir=$(mktemp -d) || return 1 + target_path="/usr/local/bin/mc" + echo "Downloading mc from $download_url..." + if ! curl -fsSL "$download_url" -o "$tmp_dir/mc"; then + echo "error: failed to download mc" >&2 + rm -rf "$tmp_dir" + return 1 + fi + + if ! chmod 755 "$tmp_dir/mc"; then + echo "error: failed to mark mc executable" >&2 + rm -rf "$tmp_dir" + return 1 + fi + + if ! run_as_root install "$tmp_dir/mc" "$target_path"; then + echo "error: failed to install mc to $target_path" >&2 + rm -rf "$tmp_dir" + return 1 + fi + rm -rf "$tmp_dir" + + if ! command -v mc >/dev/null 2>&1; then + echo "error: mc still not found after installation" >&2 + return 1 + fi + + if ! response=$(mc --version 2>&1 | head -n 1); then + echo "error: failed to run installed mc" >&2 + return 1 + fi + printf "Installed MinIO mc: %s\n" "$response" + return 0 +} + os=$(uname -s) -case "$os" in - Darwin) - if ! install_mac_libraries; then - echo "error installing MacOS packages" >&2 - exit 1 - fi - ;; +pre_install_report - Linux) - if ! install_linux_libraries; then - echo "error installing Linux packages" >&2 - exit 1 - fi - ;; +if ! install_managed_libraries "$os"; then + echo "error installing package-managed libraries" >&2 + exit 1 +fi - *) - echo "unsupported os type: $os" >&2 +if ! response=$(go get -v -t -d ./... 2>&1); then + printf "error installing go dependencies: %s\n" "$response" + exit 1 +fi + +if [ "$os" == "Linux" ] && ! install_linux_aws_command_line_tools; then + exit 1 +fi + +if [ "${INSTALL_MC:-false}" = "true" ]; then + if ! install_mc "$os"; then exit 1 -esac + fi +else + echo "Skipping mc installation (set INSTALL_MC=true to enable)" +fi +tests_folder="$(dirname "${BASH_SOURCE[0]}")" +if [ -d "${tests_folder}/bats-support" ]; then + echo "bats-support already installed" +else + if ! git clone https://github.com/bats-core/bats-support.git "${tests_folder}/bats-support"; then + echo "error getting bats-support library" >&2 + exit 1 + fi +fi +if [ -d "${tests_folder}/bats-assert" ]; then + echo "bats-assert already installed" +else + if ! git clone https://github.com/ztombol/bats-assert.git "${tests_folder}/bats-assert"; then + echo "error getting bats-assert library" >&2 + exit 1 + fi +fi + +if ! check_required_commands; then + exit 1 +fi + +echo "Install complete" exit 0 diff --git a/tests/tags/get_tests.sh b/tests/tags/get_tests.sh index 56be239d..62604177 100755 --- a/tests/tags/get_tests.sh +++ b/tests/tags/get_tests.sh @@ -81,7 +81,7 @@ run_tests() { file="${files[$j]}" name="${names[$j]}" name_re="$(escape_regex "$name")" - cmd=("$HOME/bin/bats" -f "$name_re" "$file") + cmd=(bats -f "$name_re" "$file") if ! VERSITYGW_TEST_ENV=$VERSITYGW_TEST_ENV "${cmd[@]}"; then echo "error running test" exit 1