diff --git a/.github/scripts/alioss/run-int.sh b/.github/scripts/alioss/run-int.sh new file mode 100755 index 0000000..140c7b3 --- /dev/null +++ b/.github/scripts/alioss/run-int.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_dir="$( cd "$(dirname "${0}")" && pwd )" +repo_root="$(cd "${script_dir}/../../.." && pwd)" + +: "${access_key_id:?}" +: "${access_key_secret:?}" +: "${test_name:=general}" +: "${region:=eu-central-1}" + +export ACCESS_KEY_ID="${access_key_id}" +export ACCESS_KEY_SECRET="${access_key_secret}" +export ENDPOINT="oss-${region}.aliyuncs.com" + +pushd "${script_dir}" > /dev/null + source utils.sh + bucket_name="$(read_bucket_name_from_file "${test_name}")" + : "${bucket_name:?}" + export BUCKET_NAME="${bucket_name}" +popd > /dev/null + +pushd "${repo_root}" > /dev/null + echo -e "\n running tests with $(go version)..." + ginkgo -r alioss/integration/ +popd > /dev/null + diff --git a/.github/scripts/alioss/setup.sh b/.github/scripts/alioss/setup.sh new file mode 100755 index 0000000..c13308a --- /dev/null +++ b/.github/scripts/alioss/setup.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_dir="$( cd "$(dirname "${0}")" && pwd )" +repo_root="$(cd "${script_dir}/../../.." && pwd)" + + + +: "${access_key_id:?}" +: "${access_key_secret:?}" +: "${test_name:=general}" +: "${region:=eu-central-1}" + + +export ALI_ACCESS_KEY_ID="${access_key_id}" +export ALI_ACCESS_KEY_SECRET="${access_key_secret}" +export ALI_REGION="${region}" + + + +pushd "${script_dir}" + source utils.sh + generate_bucket_name "${test_name}" + aliyun_configure + create_bucket "${test_name}" +popd diff --git a/.github/scripts/alioss/teardown.sh b/.github/scripts/alioss/teardown.sh new file mode 100755 index 0000000..31c1c02 --- /dev/null +++ b/.github/scripts/alioss/teardown.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_dir="$( cd "$(dirname "${0}")" && pwd )" +repo_root="$(cd "${script_dir}/../../.." && pwd)" + + +: "${access_key_id:?}" +: "${access_key_secret:?}" +: "${test_name:=general}" +: "${region:=eu-central-1}" + +export ALI_ACCESS_KEY_ID="${access_key_id}" +export ALI_ACCESS_KEY_SECRET="${access_key_secret}" +export ALI_REGION="${region}" + + + +pushd "${script_dir}" + source utils.sh + aliyun_configure + if delete_bucket "${test_name}" ; then + delete_bucket_name_file "${test_name}" + else + exit 1 + fi +popd diff --git a/.github/scripts/alioss/utils.sh b/.github/scripts/alioss/utils.sh new file mode 100755 index 0000000..891aa2b --- /dev/null +++ b/.github/scripts/alioss/utils.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +TMP_DIR="/tmp/storage-cli-alioss-${GITHUB_RUN_ID:-${USER}}" + +# generate a random bucket name with "alioss-" prefix +function random_name { + echo "alioss-$(openssl rand -hex 20)" +} + + +# create a file with .lock suffix and store the bucket name inside it +function generate_bucket_name { + local file_name="${1}.lock" + local bucket_name="$(random_name)" + mkdir -p "${TMP_DIR}" + echo "${bucket_name}" > "${TMP_DIR}/${file_name}" +} + + +# retrieve the bucket name from the .lock file +function read_bucket_name_from_file { + local file_name="$1" + cat "${TMP_DIR}/${file_name}.lock" +} + +# delete the .lock file +function delete_bucket_name_file { + local file_name="$1" + rm -f "${TMP_DIR}/${file_name}.lock" +} + + +function aliyun_configure { + aliyun configure set --access-key-id "$ALI_ACCESS_KEY_ID" \ + --access-key-secret "$ALI_ACCESS_KEY_SECRET" \ + --region "$ALI_REGION" +} + +function bucket_exists { + local bucket_name="$1" + if aliyun oss ls | grep -w "oss://${bucket_name}" > /dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +function create_bucket { + local bucket_name="$(read_bucket_name_from_file "$1")" + + if aliyun oss mb "oss://$bucket_name" 2>/dev/null; then + echo "Bucket ${bucket_name} created successfully" + else + if bucket_exists "${bucket_name}"; then + echo "Bucket ${bucket_name} already exists" + return 0 + else + echo "Failed to create bucket ${bucket_name}" + return 1 + fi + fi + +} + + +function delete_bucket { + local bucket_name="$(read_bucket_name_from_file "$1")" + + if aliyun oss rm "oss://${bucket_name}" -b -r -f 2>/dev/null; then + echo "Bucket ${bucket_name} deleted successfully" + else + if bucket_exists "${bucket_name}"; then + echo "ERROR: Failed to delete bucket ${bucket_name}" + return 1 + else + echo "Bucket ${bucket_name} already deleted or doesn't exist" + fi + fi + return 0 +} \ No newline at end of file diff --git a/.github/workflows/alioss-integration.yml b/.github/workflows/alioss-integration.yml new file mode 100644 index 0000000..928bc6d --- /dev/null +++ b/.github/workflows/alioss-integration.yml @@ -0,0 +1,42 @@ +name: Alioss Integration Tests + +on: + workflow_dispatch: + pull_request: + paths: + - ".github/workflows/alioss-integration.yml" + - "alioss/**" + push: + branches: + - main +jobs: + alioss-general-integration-tests: + name: Alioss General Integration Tests + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - name: Set up Aliyun CLI + uses: aliyun/setup-aliyun-cli-action@v1 + - name: Install Ginkgo + run: go install github.com/onsi/ginkgo/v2/ginkgo@latest + - name: Setup Alioss Test Environment + run: | + export access_key_id="${{ secrets.ALI_ACCESS_KEY_ID }}" + export access_key_secret="${{ secrets.ALI_ACCESS_KEY_SECRET }}" + ./.github/scripts/alioss/setup.sh + - name: Run Tests + run: | + export access_key_id="${{ secrets.ALI_ACCESS_KEY_ID }}" + export access_key_secret="${{ secrets.ALI_ACCESS_KEY_SECRET }}" + ./.github/scripts/alioss/run-int.sh + - name: Teardown Alioss Test Environment + if: always() + run: | + export access_key_id="${{ secrets.ALI_ACCESS_KEY_ID }}" + export access_key_secret="${{ secrets.ALI_ACCESS_KEY_SECRET }}" + ./.github/scripts/alioss/teardown.sh \ No newline at end of file diff --git a/alioss/README.md b/alioss/README.md index 18c17fe..a8f401a 100644 --- a/alioss/README.md +++ b/alioss/README.md @@ -1,7 +1,7 @@ # Ali Storage CLI The Ali Storage CLI is for uploading, fetching and deleting content to and from an Ali OSS. -It is highly inspired by the https://github.com/cloudfoundry/bosh-s3cli. +It is highly inspired by the [storage-cli/s3](https://github.com/cloudfoundry/storage-cli/blob/6058f516e9b81471b64a50b01e228158a05731f0/s3) ## Usage @@ -47,14 +47,36 @@ curl -X PUT -T path/to/file # Downloading a blob: curl -X GET ``` -## Running integration tests - -To run the integration tests: -- Export the following variables into your environment: - ``` bash - export ACCESS_KEY_ID= - export ACCESS_KEY_SECRET= - export ENDPOINT= - export BUCKET_NAME= - ``` -- go build && go test ./integration/... +## Running Tests + +### Unit Tests +**Note:** Run the following commands from the repository root directory. + +```bash +go install github.com/onsi/ginkgo/v2/ginkgo + +ginkgo --skip-package=integration --randomize-all --cover -v -r ./alioss/... +``` +### Integration Tests + +- To run the integration tests with your existing bucket: + 1. Export the following variables into your environment: + ``` bash + export ACCESS_KEY_ID= + export ACCESS_KEY_SECRET= + export ENDPOINT= + export BUCKET_NAME= + ``` + 1. Navigate to project's root folder and run the command below: + ``` bash + go build -o ./alioss ./alioss && go test ./alioss/integration/... + ``` +- To run it from scratch; create a new bucket, run tests, delete the bucket + 1. Create a user in your ali account and add policy `AliyunOSSFullAccess`, or restrict the users with more granular policies like `oss:CreateBucket`, `oss:DeleteBucket` etc. + 1. Create access key for the user. + 1. Export `AccessKeyId` with command `export access_key_id=`. + 1. Export `AccessKeySecret` with command `export access_key_secret=`. + 1. Navigate to project's root folder. + 1. Run environment setup script to create bucket `./.github/scripts/alioss/setup.sh`. + 1. Run tests `./.github/scripts/alioss/run-int.sh`. + 1. Run environment teardown script to delete test resources `./.github/scripts/alioss/teardown.sh`.