From 3afda064e5cb2b2178dfb2d3d37d435213e08a37 Mon Sep 17 00:00:00 2001 From: Luis Remis Date: Thu, 23 Apr 2026 03:54:47 -0700 Subject: [PATCH 1/4] Add robots.md --- robots.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 robots.md diff --git a/robots.md b/robots.md new file mode 100644 index 00000000..26b73a42 --- /dev/null +++ b/robots.md @@ -0,0 +1,69 @@ +# ApertureDB Python Testing Guide + +This guide is designed for automated agents and LLMs to quickly understand how to build and run the test suite for `py-aperturedb` locally. + +## Prerequisites +The integration tests rely on local `aperturedb` + `lenz` containers orchestrated by Docker Compose. The environment runs a client container to execute the `pytest` suite against these spun-up backends. + +--- + +## 1. Building the Test Environment Image + +To run the tests locally, you first need to build the `aperturedb-python-tests:latest` Docker image. From the workspace root (`/home/remis/src/ad/py-aperturedb`), populate the expected context directory and execute `docker build`: + +```bash +# 1. Provide the expected context data for the test Dockerfile +mkdir -p test/aperturedb/logs/runner_state +mkdir -p docker/tests/aperturedata + +# 2. Copy the Python source and configurations over +cp -r aperturedb pyproject.toml README.md docker/tests/aperturedata +mkdir -m 777 -p docker/tests/aperturedata/test/aperturedb + +# 3. Copy test inputs and test scripts over +cp -r test/*.py test/*.sh test/input docker/tests/aperturedata/test + +# 4. Build the test image locally +docker build -t aperturedata/aperturedb-python-tests:latest -f docker/tests/Dockerfile . +``` + +--- + +## 2. Running the Complete Test Suite + +Once the test image is built, use the `run_test_container.sh` wrapper script located in the `test/` directory to coordinate the backend integration environment and run the test suite. + +```bash +cd test +set -a && source .env && set +a +bash run_test_container.sh +``` + +This script: +1. Orchestrates spinning up `aperturedb`, `nginx`, `lenz` containers using `docker-compose.yml` on temporary networking bridges. +2. Starts two parallel test suites (HTTP and non-HTTP modes). +3. Checks exit codes for successes or failures and cleans up. + +--- + +## 3. Running tests and bypassing AWS/GCP API requirements + +A subset of the `pytest` tests interact with external objects, such as fetching blob configurations directly from cloud providers (AWS S3, Google Storage - GS). If your local environment or the automated agent lacks valid AWS/GCP credentials (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `GCP_SERVICE_ACCOUNT_KEY`), you will hit authentication validation errors when resolving `storage.Client()` architectures or boto3 structures during execution. + +To dynamically skip external storage tests, you should inform `pytest` running inside the Docker sequence to skip functions interacting with S3 and Google Storage. + +Before running the test script, manually modify the `pytest` invocation inside `test/run_test.sh` to explicitly add `-k "not S3 and not GS"` to exclude any specific loading functions targeting S3 or GS, along with keeping away tests appropriately marked with `@pytest.mark.remote_credentials`. + +Use this quick `sed` command to patch the exclusion: + +```bash +cd test +# Modify the pytest invocation to ignore AWS/GCP specific loaders and remotely constrained mark configurations +sed -i 's/pytest -m "$FILTER"/pytest -k "not test_S3ImageLoader and not test_GSImageLoader and not test_S3VideoLoader and not test_GSVideoLoader" -m "$FILTER and not remote_credentials and not external_network"/' run_test.sh + +# Then run the tests as usual +set -a && source .env && set +a +bash run_test_container.sh +``` + +By applying this change, any LLM/agent can successfully execute internal `aperturedb` connector + python-centric API tests without raising failures tied strictly to external cloud requirements. From 9b28a7435806f6e50f7c502bbe78ce3d33ef0891 Mon Sep 17 00:00:00 2001 From: ad-claw000 Date: Thu, 23 Apr 2026 08:33:28 -0700 Subject: [PATCH 2/4] ci: use amazon/aws-cli docker image to avoid host dependency (#662) --- ci.sh | 4 ++-- test/run_test.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci.sh b/ci.sh index 3b41ffdc..083a262b 100755 --- a/ci.sh +++ b/ci.sh @@ -186,9 +186,9 @@ push_aws_ecr(){ PREFIX="aperturedata/" docker tag ${SRC_IMAGE} \ 684446431133.dkr.ecr.${REGION}.amazonaws.com/${DST_IMAGE} - aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin 684446431133.dkr.ecr.${REGION}.amazonaws.com + docker run --rm -e AWS_ACCESS_KEY_ID -e AWS_DEFAULT_REGION -e AWS_SECRET_ACCESS_KEY amazon/aws-cli ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin 684446431133.dkr.ecr.${REGION}.amazonaws.com - aws ecr create-repository --repository-name ${ECR_REPO_NAME} --region us-west-2 || true + docker run --rm -e AWS_ACCESS_KEY_ID -e AWS_DEFAULT_REGION -e AWS_SECRET_ACCESS_KEY amazon/aws-cli ecr create-repository --repository-name ${ECR_REPO_NAME} --region us-west-2 || true docker push 684446431133.dkr.ecr.${REGION}.amazonaws.com/${DST_IMAGE} } diff --git a/test/run_test.sh b/test/run_test.sh index 93af1096..a4921090 100755 --- a/test/run_test.sh +++ b/test/run_test.sh @@ -43,7 +43,7 @@ if [[ $RESULT != 0 ]]; then ARCHIVE_NAME=logs.tar.gz DESTINATION="s3://${BUCKET}/aperturedb-${NOW}-${FILTER// /_}.tgz" tar czf ${ARCHIVE_NAME} ${APERTUREDB_LOG_PATH}/.. - aws s3 cp ${ARCHIVE_NAME} $DESTINATION + docker run --rm -v $(pwd):/workspace -w /workspace -e AWS_ACCESS_KEY_ID -e AWS_DEFAULT_REGION -e AWS_SECRET_ACCESS_KEY amazon/aws-cli s3 cp ${ARCHIVE_NAME} $DESTINATION echo "Log output to $DESTINATION" else echo "Unable to output log, APERTUREDB_LOG_PATH not set." From bdb2af2316bb45c6f280b9d258c4b338d1a27a2e Mon Sep 17 00:00:00 2001 From: ad-claw000 Date: Thu, 23 Apr 2026 10:04:36 -0700 Subject: [PATCH 3/4] ci: split HTTP and non-HTTP tests into GitHub Actions matrix to reduce CI duration (Closes #659) (#663) --- .github/workflows/develop.yml | 6 +- .github/workflows/main.yml | 5 ++ .github/workflows/pr.yaml | 7 ++- .github/workflows/release.yaml | 8 ++- test/run_test_container.sh | 100 ++++++++++++++++++++------------- 5 files changed, 84 insertions(+), 42 deletions(-) diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index cae2c7fe..0b778352 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -7,6 +7,10 @@ on: jobs: build-test: + strategy: + fail-fast: false + matrix: + protocol: [http, non_http] runs-on: - benchmark @@ -30,6 +34,7 @@ jobs: - name: Build and Run Tests env: + TEST_PROTOCOL: ${{ matrix.protocol }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -66,4 +71,3 @@ jobs: LENZ_TAG: dev run: BUILD_COMPLETE=true ./ci.sh shell: bash - diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 55ed1f1a..dabbdbf0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,10 @@ on: jobs: build_and_test: + strategy: + fail-fast: false + matrix: + protocol: [http, non_http] runs-on: - benchmark @@ -30,6 +34,7 @@ jobs: - name: Build and Run Tests env: + TEST_PROTOCOL: ${{ matrix.protocol }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 924ffc88..284be9dc 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -7,6 +7,10 @@ on: jobs: run_test: + strategy: + fail-fast: false + matrix: + protocol: [http, non_http] runs-on: - gcp @@ -34,11 +38,12 @@ jobs: - name: Build and Run Tests env: + TEST_PROTOCOL: ${{ matrix.protocol }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} GCP_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} - RUNNER_NAME: ${{ runner.name }} + RUNNER_NAME: ${{ runner.name }}_${{ matrix.protocol }} RUN_TESTS: true NO_PUSH: true BRANCH_NAME: ${{ github.event.pull_request.head.ref }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c903f5d5..d604b4c1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,6 +7,10 @@ on: jobs: build-test: + strategy: + fail-fast: false + matrix: + protocol: [http, non_http] runs-on: - self-hosted @@ -35,10 +39,12 @@ jobs: - name: Build and Run Tests env: + TEST_PROTOCOL: ${{ matrix.protocol }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} GCP_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} + RUNNER_NAME: ${{ runner.name }}_${{ matrix.protocol }} run: RUN_TESTS=true NO_PUSH=true UPDATE_BRANCH=true ./ci.sh shell: bash @@ -64,4 +70,4 @@ jobs: - name: Build Notebook Docker run: BUILD_COMPLETE=true NO_PUSH=true ./ci.sh - shell: bash \ No newline at end of file + shell: bash diff --git a/test/run_test_container.sh b/test/run_test_container.sh index c51c792f..99e23725 100755 --- a/test/run_test_container.sh +++ b/test/run_test_container.sh @@ -30,8 +30,16 @@ function run_aperturedb_instance(){ IP_REGEX='[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' -GATEWAY_HTTP=$(run_aperturedb_instance "${RUNNER_NAME}_http" | grep $IP_REGEX ) -GATEWAY_NON_HTTP=$(run_aperturedb_instance "${RUNNER_NAME}_non_http" | grep $IP_REGEX ) +# Check if TEST_PROTOCOL is set, otherwise default to both +TEST_PROTOCOL=${TEST_PROTOCOL:-"both"} + +if [ "$TEST_PROTOCOL" == "http" ] || [ "$TEST_PROTOCOL" == "both" ]; then + GATEWAY_HTTP=$(run_aperturedb_instance "${RUNNER_NAME}_http" | grep $IP_REGEX ) +fi + +if [ "$TEST_PROTOCOL" == "non_http" ] || [ "$TEST_PROTOCOL" == "both" ]; then + GATEWAY_NON_HTTP=$(run_aperturedb_instance "${RUNNER_NAME}_non_http" | grep $IP_REGEX ) +fi # The LOG_PATH and RUNNER_INFO_PATH are set to the current working directory LOG_PATH="$(pwd)/aperturedb/logs" @@ -48,42 +56,57 @@ fi sleep 20 # wait for the containers to be up and running -echo "running tests on docker image $REPOSITORY with $GATEWAY_HTTP and $GATEWAY_NON_HTTP" -docker run \ - -v $(pwd)/output:/aperturedata/test/output \ - -v $(pwd)/${RUNNER_NAME}_http_ca:/ca \ - --network=${RUNNER_NAME}_http_default \ - -v "$LOG_PATH":"${TESTING_LOG_PATH}" \ - -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ - -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \ - -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ - -e GCP_SERVICE_ACCOUNT_KEY="$GCP_SERVICE_ACCOUNT_KEY" \ - -e APERTUREDB_LOG_PATH="${TESTING_LOG_PATH}" \ - -e GATEWAY="nginx" \ - -e FILTER="http" \ - $REPOSITORY & - -pid1=$! -docker run \ - -v $(pwd)/output:/aperturedata/test/output \ - -v $(pwd)/${RUNNER_NAME}_non_http_ca:/ca \ - --network=${RUNNER_NAME}_non_http_default \ - -v "$LOG_PATH":"${TESTING_LOG_PATH}" \ - -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ - -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \ - -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ - -e GCP_SERVICE_ACCOUNT_KEY="$GCP_SERVICE_ACCOUNT_KEY" \ - -e APERTUREDB_LOG_PATH="${TESTING_LOG_PATH}" \ - -e GATEWAY="lenz" \ - -e FILTER="not http" \ - $REPOSITORY & - -pid2=$! - -wait $pid1 -exit_code1=$? -wait $pid2 -exit_code2=$? +pid1=0 +pid2=0 + +if [ "$TEST_PROTOCOL" == "http" ] || [ "$TEST_PROTOCOL" == "both" ]; then + echo "running tests on docker image $REPOSITORY with $GATEWAY_HTTP" + docker run \ + -v $(pwd)/output:/aperturedata/test/output \ + -v $(pwd)/${RUNNER_NAME}_http_ca:/ca \ + --network=${RUNNER_NAME}_http_default \ + -v "$LOG_PATH":"${TESTING_LOG_PATH}" \ + -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ + -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \ + -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ + -e GCP_SERVICE_ACCOUNT_KEY="$GCP_SERVICE_ACCOUNT_KEY" \ + -e APERTUREDB_LOG_PATH="${TESTING_LOG_PATH}" \ + -e GATEWAY="nginx" \ + -e FILTER="http" \ + $REPOSITORY & + pid1=$! +fi + +if [ "$TEST_PROTOCOL" == "non_http" ] || [ "$TEST_PROTOCOL" == "both" ]; then + echo "running tests on docker image $REPOSITORY with $GATEWAY_NON_HTTP" + docker run \ + -v $(pwd)/output:/aperturedata/test/output \ + -v $(pwd)/${RUNNER_NAME}_non_http_ca:/ca \ + --network=${RUNNER_NAME}_non_http_default \ + -v "$LOG_PATH":"${TESTING_LOG_PATH}" \ + -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ + -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \ + -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ + -e GCP_SERVICE_ACCOUNT_KEY="$GCP_SERVICE_ACCOUNT_KEY" \ + -e APERTUREDB_LOG_PATH="${TESTING_LOG_PATH}" \ + -e GATEWAY="lenz" \ + -e FILTER="not http" \ + $REPOSITORY & + pid2=$! +fi + +exit_code1=0 +exit_code2=0 + +if [ "$pid1" != "0" ]; then + wait $pid1 + exit_code1=$? +fi + +if [ "$pid2" != "0" ]; then + wait $pid2 + exit_code2=$? +fi if [ $exit_code1 -ne 0 ]; then echo "Tests failed for HTTP" @@ -94,7 +117,6 @@ if [ $exit_code2 -ne 0 ]; then exit $exit_code2 fi - echo "Tests completed" echo " --- Runner name: ${RUNNER_NAME} ---" check_containers_networks From 83c07f11d158af7ef942b6196dde90209caa3a9a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:53:07 +0000 Subject: [PATCH 4/4] Version bump: 0.4.57 to 0.4.58 --- aperturedb/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aperturedb/__init__.py b/aperturedb/__init__.py index 07631782..0b008225 100644 --- a/aperturedb/__init__.py +++ b/aperturedb/__init__.py @@ -10,7 +10,7 @@ import signal import sys -__version__ = "0.4.57" +__version__ = "0.4.58" logger = logging.getLogger(__name__)