diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 0e68fdd10..e6a45e7b8 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -147,7 +147,7 @@ jobs: node-version: 22.17.1 - name: Install dependencies - run: yarn install --frozen-lockfile + run: composer install working-directory: .vortex/tests - name: Install Ahoy @@ -158,85 +158,11 @@ jobs: ahoy --version - name: Run tests - run: ./tests/test.workflow.sh - working-directory: .vortex - env: - TEST_VORTEX_DEBUG: ${{ vars.TEST_VORTEX_DEBUG }} - - - name: Upload coverage report as an artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 - with: - name: ${{github.job}}-${{ matrix.batch }}-code-coverage-report - path: /tmp/.vortex-coverage-html - include-hidden-files: true - if-no-files-found: error - - - name: Upload coverage report to Codecov - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5 - with: - directory: /tmp/.vortex-coverage-html - fail_ci_if_error: false - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - vortex-test-deployment: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - batch: [0, 1] - - container: - image: drevops/ci-runner:25.10.0@sha256:03f2722e141b4939b390abad9443ed96304a8ec7bda0b2eab9dac56f9e9b7b91 - env: - # Prevent GitHub overriding the Docker config. - DOCKER_CONFIG: /root/.docker - VORTEX_DOCTOR_CHECK_MINIMAL: 1 - TEST_PACKAGE_TOKEN: ${{ secrets.TEST_PACKAGE_TOKEN }} - TEST_VORTEX_CONTAINER_REGISTRY_USER: ${{ secrets.TEST_VORTEX_CONTAINER_REGISTRY_USER }} - TEST_VORTEX_CONTAINER_REGISTRY_PASS: ${{ secrets.TEST_VORTEX_CONTAINER_REGISTRY_PASS }} - VORTEX_DEV_VOLUMES_SKIP_MOUNT: 1 - VORTEX_DEV_TEST_COVERAGE_DIR: /tmp/.vortex-coverage-html - TEST_NODE_INDEX: ${{ matrix.batch }} - - steps: - - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - with: - fetch-depth: 0 - persist-credentials: false - - - name: Setup Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6 - - - name: Adjust git config to allow running git-related tests - run: git config --global safe.directory '*' - - - name: Generate test SSH key pair used for deployment tests run: | - mkdir -p "$HOME/.ssh" - ssh-keygen -t rsa -b 4096 -m PEM -N '' -f "$HOME/.ssh/id_rsa" - chmod 600 "$HOME/.ssh/id_rsa" - ssh-agent -a "${HOME}/ssh-agent.sock" > ssh-agent-output - export SSH_AUTH_SOCK="$(grep SSH_AUTH_SOCK ssh-agent-output | cut -d';' -f1 | cut -d= -f2)" - echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK}" >> "$GITHUB_ENV" - - - name: Install dependencies - run: yarn install --frozen-lockfile + # Create an empty coverage directory to avoid errors. @see https://github.com/actions/upload-artifact/issues/255 + mkdir -p /tmp/.vortex-coverage-html && touch "/tmp/.vortex-coverage-html/.empty-$(date +%Y%m%d%H%M%S)" + php -d memory_limit=-1 vendor/bin/phpunit phpunit --group="${TEST_NODE_INDEX:-*}" working-directory: .vortex/tests - - - name: Install Ahoy - run: | - version=2.4.0 && \ - set -x && curl -L -o "/usr/local/bin/ahoy" "https://github.com/ahoy-cli/ahoy/releases/download/v${version}/ahoy-bin-$(uname -s)-amd64" && \ - chmod +x /usr/local/bin/ahoy && \ - ahoy --version - - - name: Run tests - run: ./tests/test.deployment.sh - working-directory: .vortex - timeout-minutes: 10 env: TEST_VORTEX_DEBUG: ${{ vars.TEST_VORTEX_DEBUG }} diff --git a/.vortex/tests/bats/e2e/deployment0.bats b/.vortex/tests/bats/e2e/deployment0.bats deleted file mode 100644 index 338180b87..000000000 --- a/.vortex/tests/bats/e2e/deployment0.bats +++ /dev/null @@ -1,239 +0,0 @@ -#!/usr/bin/env bats -# -# Test runner for deployment tests. -# -# shellcheck disable=SC2030,SC2031,SC2129 - -load ../_helper.bash -load ../_helper.deployment.bash - -@test "Deployment; no integration" { - pushd "${BUILD_DIR}" >/dev/null || exit 1 - - # Source directory for initialised codebase. - # If not provided - directory will be created and a site will be initialised. - # This is to facilitate local testing. - SRC_DIR="${SRC_DIR:-}" - - # "Remote" repository to deploy the artifact to. It is located in the host - # filesystem and just treated as a remote for currently installed codebase. - REMOTE_REPO_DIR=${REMOTE_REPO_DIR:-${BUILD_DIR}/deployment_remote} - - step "Starting DEPLOYMENT tests." - - # This deployment uses all 3 types. - export VORTEX_DEPLOY_TYPES="artifact,webhook,container_registry" - - if [ ! "${SRC_DIR}" ]; then - SRC_DIR="${BUILD_DIR}/deployment_src" - substep "Deployment source directory is not provided - using directory ${SRC_DIR}" - fixture_prepare_dir "${SRC_DIR}" - - # We need to use "current" directory as a place where the deployment script - # is going to run from, while "SRC_DIR" is a place where files are taken - # from for deployment. They may be the same place, but we are testing them - # if they are separate, because most likely SRC_DIR will contain code - # built on previous build stages of the CI process. - install_and_assemble_site "${CURRENT_PROJECT_DIR}" - - substep "Copying built codebase into code source directory ${SRC_DIR}." - cp -R "${CURRENT_PROJECT_DIR}/." "${SRC_DIR}/" - else - substep "Using provided SRC_DIR ${SRC_DIR}" - assert_dir_not_empty "${SRC_DIR}" - fi - - # Make sure that all files were copied out from the container or passed from - # the previous stage of the build. - - assert_files_present_common "${CURRENT_PROJECT_DIR}" - assert_files_present_deployment "${CURRENT_PROJECT_DIR}" - assert_files_present_no_integration_acquia "${CURRENT_PROJECT_DIR}" - assert_files_present_no_integration_lagoon "${CURRENT_PROJECT_DIR}" - assert_files_present_no_integration_ftp "${CURRENT_PROJECT_DIR}" - assert_git_repo "${SRC_DIR}" - - # Make sure that one of the excluded directories will be ignored in the - # deployment artifact. - mkdir -p "${SRC_DIR}"/web/themes/custom/star_wars/node_modules - touch "${SRC_DIR}"/web/themes/custom/star_wars/node_modules/test.txt - - substep "Preparing remote repo directory ${REMOTE_REPO_DIR}." - fixture_prepare_dir "${REMOTE_REPO_DIR}" - git_init 1 "${REMOTE_REPO_DIR}" - - popd >/dev/null - - pushd "${CURRENT_PROJECT_DIR}" >/dev/null - - substep "Running deployment." - - # Variables for ARTIFACT deployment. - export VORTEX_DEPLOY_ARTIFACT_GIT_REMOTE="${REMOTE_REPO_DIR}"/.git - export VORTEX_DEPLOY_ARTIFACT_ROOT="${CURRENT_PROJECT_DIR}" - export VORTEX_DEPLOY_ARTIFACT_SRC="${SRC_DIR}" - export VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL="${VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL:-testuser@example.com}" - - # Variables for WEBHOOK deployment. - export VORTEX_DEPLOY_WEBHOOK_URL=https://www.example.com - export VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS=200 - - # Variables for container registry deployment. - # @todo: Not implemented. Add here when implemented. - - # Run deployment. - run ahoy deploy - assert_success - - # - # Artifact deployment assertions. - # - - assert_output_contains "Started ARTIFACT deployment." - assert_output_contains "Installing artifact builder." - assert_output_contains "Copying git repo files meta file to the deploy code repo." - assert_output_contains "Copying deployment .gitignore as it may not exist in deploy code source files." - assert_output_contains "Running artifact builder." - - substep "ARTIFACT: Assert remote deployment files." - assert_deployment_files_present "${REMOTE_REPO_DIR}" - - # Assert Acquia integration files are absent. - assert_files_present_no_integration_acquia "${REMOTE_REPO_DIR}" - - assert_output_contains "Finished ARTIFACT deployment." - - # - # Webhook deployment assertions. - # - assert_output_contains "Started WEBHOOK deployment." - assert_output_contains "Webhook call completed." - assert_output_not_contains "[FAIL] Unable to complete webhook deployment." - assert_output_contains "Finished WEBHOOK deployment." - - # - # Container registry deployment assertions. - # - # By default, container registry deployment will not proceed if - # service-to-image map is not specified in VORTEX_DEPLOY_CONTAINER_REGISTRY_MAP - # variable and will exit normally. - assert_output_contains "Started container registry deployment." - assert_output_contains "Services map is not specified in VORTEX_DEPLOY_CONTAINER_REGISTRY_MAP variable." - assert_output_not_contains "Finished container registry deployment." - - popd >/dev/null -} - -@test "Deployment; no integration; flags" { - pushd "${BUILD_DIR}" >/dev/null || exit 1 - - # Source directory for initialised codebase. - # If not provided - directory will be created and a site will be initialised. - # This is to facilitate local testing. - SRC_DIR="${SRC_DIR:-}" - - step "Starting DEPLOYMENT tests." - - if [ ! "${SRC_DIR}" ]; then - SRC_DIR="${BUILD_DIR}/deployment_src" - substep "Deployment source directory is not provided - using directory ${SRC_DIR}" - fixture_prepare_dir "${SRC_DIR}" - - # Do not assemble - only structure. - install_and_assemble_site "${CURRENT_PROJECT_DIR}" 0 - - substep "Copying built codebase into code source directory ${SRC_DIR}." - cp -R "${CURRENT_PROJECT_DIR}/." "${SRC_DIR}/" - else - substep "Using provided SRC_DIR ${SRC_DIR}" - assert_dir_not_empty "${SRC_DIR}" - fi - - # Make sure that all files were copied out from the container or passed from - # the previous stage of the build. - - assert_files_present_common "${CURRENT_PROJECT_DIR}" - assert_files_present_deployment "${CURRENT_PROJECT_DIR}" - assert_files_present_no_integration_acquia "${CURRENT_PROJECT_DIR}" - assert_files_present_no_integration_lagoon "${CURRENT_PROJECT_DIR}" - assert_files_present_no_integration_ftp "${CURRENT_PROJECT_DIR}" - assert_git_repo "${SRC_DIR}" - - popd >/dev/null - - pushd "${CURRENT_PROJECT_DIR}" >/dev/null - - substep "Running deployment." - - export VORTEX_DEPLOY_TYPES="webhook" - - # Variables for WEBHOOK deployment. - export VORTEX_DEPLOY_WEBHOOK_URL=https://www.example.com - export VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS=200 - - # - # Test assertions. - # - - substep "Run deployment without skip flag set." - - run ahoy deploy - assert_success - assert_output_not_contains "Skipping deployment webhook." - assert_output_contains "Started WEBHOOK deployment." - assert_output_contains "Finished WEBHOOK deployment." - - step "Run deployment with skip flag set, but without per-branch or per-pr skip flags." - export VORTEX_DEPLOY_ALLOW_SKIP=1 - - run ahoy deploy - assert_success - assert_output_not_contains "Skipping deployment webhook." - assert_output_contains "Found flag to skip a deployment." - assert_output_contains "Started WEBHOOK deployment." - assert_output_contains "Finished WEBHOOK deployment." - - step "Run deployment with skip flag set and with per-branch flag set." - export VORTEX_DEPLOY_ALLOW_SKIP=1 - - export VORTEX_DEPLOY_BRANCH="feature/test" - export VORTEX_DEPLOY_SKIP_BRANCH_FEATURE_TEST=1 - - run ahoy deploy - assert_success - assert_output_contains "Found flag to skip a deployment." - assert_output_contains "Found skip variable VORTEX_DEPLOY_SKIP_BRANCH_FEATURE_TEST for branch feature/test." - assert_output_contains "Skipping deployment webhook." - assert_output_not_contains "Started WEBHOOK deployment." - assert_output_not_contains "Finished WEBHOOK deployment." - - step "Run deployment with skip flag set and with per-pr flag set." - export VORTEX_DEPLOY_ALLOW_SKIP=1 - - export VORTEX_DEPLOY_PR="123" - export VORTEX_DEPLOY_SKIP_PR_123=1 - - run ahoy deploy - assert_success - assert_output_contains "Found flag to skip a deployment." - assert_output_contains "Found skip variable VORTEX_DEPLOY_SKIP_PR_123 for PR 123." - assert_output_contains "Skipping deployment webhook." - assert_output_not_contains "Started WEBHOOK deployment." - assert_output_not_contains "Finished WEBHOOK deployment." - - step "Run deployment without skip flag set and with per-pr flag set." - unset VORTEX_DEPLOY_ALLOW_SKIP - - export VORTEX_DEPLOY_PR="123" - export VORTEX_DEPLOY_SKIP_PR_123=1 - - run ahoy deploy - assert_success - assert_output_not_contains "Found flag to skip a deployment." - assert_output_not_contains "Found skip variable VORTEX_DEPLOY_SKIP_PR_123 for PR 123." - assert_output_not_contains "Skipping deployment webhook." - assert_output_contains "Started WEBHOOK deployment." - assert_output_contains "Finished WEBHOOK deployment." - - popd >/dev/null -} diff --git a/.vortex/tests/bats/e2e/deployment1.bats b/.vortex/tests/bats/e2e/deployment1.bats deleted file mode 100644 index a1baf7012..000000000 --- a/.vortex/tests/bats/e2e/deployment1.bats +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/env bats -# -# Test runner for deployment tests. -# -# shellcheck disable=SC2030,SC2031,SC2129,SC2154 - -load ../_helper.bash -load ../_helper.deployment.bash - -@test "Deployment; Acquia integration" { - pushd "${BUILD_DIR}" >/dev/null || exit 1 - - # Source directory for initialised codebase. - # If not provided - directory will be created and a site will be initialised. - # This is to facilitate local testing. - SRC_DIR="${SRC_DIR:-}" - - # "Remote" repository to deploy the artifact to. It is located in the host - # filesystem and just treated as a remote for currently installed codebase. - REMOTE_REPO_DIR=${REMOTE_REPO_DIR:-${BUILD_DIR}/deployment_remote} - - step "Starting DEPLOYMENT tests." - - export VORTEX_INSTALLER_PROMPT_DEPLOY_TYPES="artifact" - - if [ ! "${SRC_DIR}" ]; then - SRC_DIR="${BUILD_DIR}/deployment_src" - substep "Deployment source directory is not provided - using directory ${SRC_DIR}" - fixture_prepare_dir "${SRC_DIR}" - - # Enable Acquia integration for this test to run independent deployment - # by using install auto-discovery. - export VORTEX_DB_DOWNLOAD_SOURCE="acquia" - - # Override download from Acquia with a special flag. This still allows to - # validate that download script expects credentials, but does not actually - # run the download (it would fail since there is no Acquia environment - # attached to this test). - # A demo test database will be used as actual database to provision site - # during this test. - echo "VORTEX_DB_DOWNLOAD_PROCEED=0" >>"${CURRENT_PROJECT_DIR}"/.env - - # We need to use "current" directory as a place where the deployment script - # is going to run from, while "SRC_DIR" is a place where files are taken - # from for deployment. They may be the same place, but we are testing them - # if they are separate, because most likely SRC_DIR will contain code - # built on previous build stages. - install_and_assemble_site "${CURRENT_PROJECT_DIR}" 1 "docroot" - - substep "Copying built codebase into code source directory ${SRC_DIR}" - cp -R "${CURRENT_PROJECT_DIR}/." "${SRC_DIR}/" - else - substep "Using provided SRC_DIR ${SRC_DIR}" - assert_dir_not_empty "${SRC_DIR}" - fi - - # Make sure that all files were copied out from the container or passed from - # the previous stage of the build. - assert_files_present_common "${SRC_DIR}" "" "" "" "" "docroot" - assert_files_present_deployment "${SRC_DIR}" - assert_files_present_integration_acquia "${SRC_DIR}" "sw" 1 "docroot" - assert_files_present_no_integration_lagoon "${SRC_DIR}" "" "docroot" - assert_files_present_no_integration_ftp "${SRC_DIR}" - assert_git_repo "${SRC_DIR}" - - # Make sure that one of the excluded directories will be ignored in the - # deployment artifact. - mkdir -p "${SRC_DIR}"/web/themes/custom/star_wars/node_modules - touch "${SRC_DIR}"/web/themes/custom/star_wars/node_modules/test.txt - - step "Preparing remote repo directory ${REMOTE_REPO_DIR}" - fixture_prepare_dir "${REMOTE_REPO_DIR}" - git_init 1 "${REMOTE_REPO_DIR}" - - popd >/dev/null - - pushd "${CURRENT_PROJECT_DIR}" >/dev/null - - step "Running deployment" - export VORTEX_DEPLOY_ARTIFACT_GIT_REMOTE="${REMOTE_REPO_DIR}"/.git - export VORTEX_DEPLOY_ARTIFACT_ROOT="${CURRENT_PROJECT_DIR}" - export VORTEX_DEPLOY_ARTIFACT_SRC="${SRC_DIR}" - export VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL="${VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL:-testuser@example.com}" - - run ahoy deploy - assert_success - assert_output_contains "Started ARTIFACT deployment." - - # Assert that no other deployments ran. - assert_output_not_contains "Started WEBHOOK deployment." - assert_output_not_contains "Webhook call completed." - assert_output_not_contains "[FAIL] Unable to complete webhook deployment." - assert_output_not_contains "Finished WEBHOOK deployment." - - assert_output_not_contains "Started container registry deployment." - assert_output_not_contains "Services map is not specified in VORTEX_DEPLOY_CONTAINER_REGISTRY_MAP variable." - assert_output_not_contains "Finished container registry deployment." - - assert_output_not_contains "Started LAGOON deployment." - assert_output_not_contains "Finished LAGOON deployment." - - step "Assert remote deployment files" - assert_deployment_files_present "${REMOTE_REPO_DIR}" "docroot" - - # Assert Acquia integration files are present. - assert_files_present_integration_acquia "${REMOTE_REPO_DIR}" "sw" 0 "docroot" - - popd >/dev/null -} - -@test "Deployment; Lagoon integration" { - pushd "${BUILD_DIR}" >/dev/null || exit 1 - - # Source directory for initialised codebase. - # If not provided - directory will be created and a site will be initialised. - # This is to facilitate local testing. - SRC_DIR="${SRC_DIR:-}" - - step "Starting DEPLOYMENT tests." - - export VORTEX_INSTALLER_PROMPT_DEPLOY_TYPES="lagoon" - export VORTEX_INSTALLER_PROMPT_HOSTING_PROVIDER="lagoon" - export VORTEX_INSTALLER_PROMPT_DEPLOY_TYPES="lagoon" - export VORTEX_INSTALLER_PROMPT_DATABASE_DOWNLOAD_SOURCE="lagoon" - - SRC_DIR="${BUILD_DIR}/deployment_src" - substep "Deployment source directory is not provided - using directory ${SRC_DIR}" - fixture_prepare_dir "${SRC_DIR}" - - # Do not assemble - only structure. - install_and_assemble_site "${CURRENT_PROJECT_DIR}" 0 "${answers[@]}" - - substep "Copying built codebase into code source directory ${SRC_DIR}" - cp -R "${CURRENT_PROJECT_DIR}/." "${SRC_DIR}/" - - # Make sure that all files were copied out from the container or passed from - # the previous stage of the build. - assert_files_present_common "${SRC_DIR}" - assert_files_present_deployment "${SRC_DIR}" - assert_files_present_integration_lagoon "${SRC_DIR}" - assert_files_present_no_integration_acquia "${SRC_DIR}" - assert_files_present_no_integration_ftp "${SRC_DIR}" - assert_git_repo "${SRC_DIR}" - - popd >/dev/null - - pushd "${CURRENT_PROJECT_DIR}" >/dev/null - - step "Running deployment" - # Always force installing of the Lagoon CLI binary in tests rather than using - # a local version. - export VORTEX_LAGOONCLI_FORCE_INSTALL=1 - export VORTEX_LAGOONCLI_PATH="${APP_TMP_DIR}" - export VORTEX_DEPLOY_LAGOON_INSTANCE="testlagoon" - export LAGOON_PROJECT="testproject" - export VORTEX_DEPLOY_BRANCH="testbranch" - - mock_lagoon=$(mock_command "lagoon") - - run ahoy deploy - assert_success - - assert_output_contains "Started Lagoon deployment." - assert_output_contains "Installing Lagoon CLI." - assert_output_contains "Configuring Lagoon instance." - assert_output_contains "Finished Lagoon deployment." - - # Assert lagoon binary exists and was called. - assert_file_exists "${VORTEX_LAGOONCLI_PATH}/lagoon" - - assert_equal 3 "$(mock_get_call_num "${mock_lagoon}")" - # Configure. - assert_contains "config add --force --lagoon testlagoon --graphql https://api.lagoon.amazeeio.cloud/graphql --hostname ssh.lagoon.amazeeio.cloud --port 32222" "$(mock_get_call_args "${mock_lagoon}" 1)" - # Get a list of environments. - assert_contains "--lagoon testlagoon --project testproject list environments --output-json --pretty" "$(mock_get_call_args "${mock_lagoon}" 2)" - # Trigger a deployment. - assert_contains "--lagoon testlagoon --project testproject deploy branch --branch testbranch" "$(mock_get_call_args "${mock_lagoon}" 3)" - - # Assert that no other deployments ran. - assert_output_not_contains "Started ARTIFACT deployment." - assert_output_not_contains "Finished ARTIFACT deployment." - - assert_output_not_contains "Started WEBHOOK deployment." - assert_output_not_contains "Webhook call completed." - assert_output_not_contains "[FAIL] Unable to complete webhook deployment." - assert_output_not_contains "Finished WEBHOOK deployment." - - assert_output_not_contains "Started container registry deployment." - assert_output_not_contains "Services map is not specified in VORTEX_DEPLOY_CONTAINER_REGISTRY_MAP variable." - assert_output_not_contains "Finished container registry deployment." - - popd >/dev/null -} - -@test "Deployment; Lagoon integration; PROVISION_TYPE_PROFILE; redeploy" { - pushd "${BUILD_DIR}" >/dev/null || exit 1 - - # Source directory for initialised codebase. - # If not provided - directory will be created and a site will be initialised. - # This is to facilitate local testing. - SRC_DIR="${SRC_DIR:-}" - - step "Starting DEPLOYMENT tests." - - SRC_DIR="${BUILD_DIR}/deployment_src" - substep "Deployment source directory is not provided - using directory ${SRC_DIR}" - fixture_prepare_dir "${SRC_DIR}" - - export VORTEX_INSTALLER_PROMPT_DEPLOY_TYPES="lagoon" - export VORTEX_INSTALLER_PROMPT_HOSTING_PROVIDER="lagoon" - export VORTEX_INSTALLER_PROMPT_DEPLOY_TYPES="lagoon" - export VORTEX_INSTALLER_PROMPT_DATABASE_DOWNLOAD_SOURCE="lagoon" - export VORTEX_INSTALLER_PROMPT_PROVISION_TYPE="profile" - - # Do not build - only structure. - install_and_assemble_site "${CURRENT_PROJECT_DIR}" 0 - - substep "Copying built codebase into code source directory ${SRC_DIR}" - cp -R "${CURRENT_PROJECT_DIR}/." "${SRC_DIR}/" - - # Make sure that all files were copied out from the container or passed from - # the previous stage of the build. - assert_files_present_common "${SRC_DIR}" - assert_files_present_deployment "${SRC_DIR}" - assert_files_present_integration_lagoon "${SRC_DIR}" - assert_files_present_no_integration_acquia "${SRC_DIR}" - assert_files_present_no_integration_ftp "${SRC_DIR}" - assert_git_repo "${SRC_DIR}" - - popd >/dev/null - - pushd "${CURRENT_PROJECT_DIR}" >/dev/null - - step "Running deployment" - # Always force installing of the Lagoon CLI binary in tests rather than using - # a local version. - export VORTEX_LAGOONCLI_FORCE_INSTALL=1 - export VORTEX_LAGOONCLI_PATH="${APP_TMP_DIR}" - export VORTEX_DEPLOY_LAGOON_INSTANCE="testlagoon" - export LAGOON_PROJECT="testproject" - export VORTEX_DEPLOY_BRANCH="testbranch" - - mock_lagoon=$(mock_command "lagoon") - # Configuring. - mock_set_output "${mock_lagoon}" "success" 1 - # Existing environment. - mock_set_output "${mock_lagoon}" '{"data": [{"deploytype": "branch", "environment": "development", "id": "364889", "name": "testbranch", "openshiftprojectname": "testproject-testbranch", "route": "https://nginx-php.develop.civic.au2.amazee.io"}]}' 2 - # Set variables. - mock_set_output "${mock_lagoon}" "success" 3 - # Set variables. - mock_set_output "${mock_lagoon}" "success" 4 - # Redeploying env. - mock_set_output "${mock_lagoon}" "success" 5 - # Remove variables. - mock_set_output "${mock_lagoon}" "success" 6 - - # Deployment action to override db. - export VORTEX_DEPLOY_ACTION="deploy_override_db" - - run ahoy deploy - assert_success - - assert_output_contains "Started Lagoon deployment." - assert_output_contains 'Found already deployed environment for branch "testbranch".' - assert_output_contains "Adding a DB import override flag for the current deployment." - assert_output_contains "Redeploying environment: project testproject, branch: testbranch." - assert_output_contains "Waiting for deployment to be queued." - assert_output_contains "Removing a DB import override flag for the current deployment." - assert_output_contains "Finished Lagoon deployment." - - # Assert lagoon binary exists and was called. - assert_file_exists "${VORTEX_LAGOONCLI_PATH}/lagoon" - - # Deployment script calls API several times. - assert_equal 6 "$(mock_get_call_num "${mock_lagoon}")" - - # Configure. - assert_contains "config add --force --lagoon testlagoon --graphql https://api.lagoon.amazeeio.cloud/graphql --hostname ssh.lagoon.amazeeio.cloud --port 32222" "$(mock_get_call_args "${mock_lagoon}" 1)" - # Get a list of environments. - assert_contains "--lagoon testlagoon --project testproject list environments --output-json --pretty" "$(mock_get_call_args "${mock_lagoon}" 2)" - # Explicitly set DB overwrite flag to 0 due to a bug in Lagoon. - assert_contains "--lagoon testlagoon --project testproject update variable --environment testbranch --name VORTEX_PROVISION_OVERRIDE_DB --value 0 --scope global" "$(mock_get_call_args "${mock_lagoon}" 3)" - # Override DB during re-deployment. - assert_contains "--lagoon testlagoon --project testproject update variable --environment testbranch --name VORTEX_PROVISION_OVERRIDE_DB --value 1 --scope global" "$(mock_get_call_args "${mock_lagoon}" 4)" - # Redeploy. - assert_contains "--lagoon testlagoon --project testproject deploy latest --environment testbranch" "$(mock_get_call_args "${mock_lagoon}" 5)" - # Remove a DB import override flag for the current deployment. - assert_contains "--lagoon testlagoon --project testproject update variable --environment testbranch --name VORTEX_PROVISION_OVERRIDE_DB --value 0 --scope global" "$(mock_get_call_args "${mock_lagoon}" 6)" - - # Assert that no other deployments ran. - assert_output_not_contains "Started ARTIFACT deployment." - assert_output_not_contains "Finished ARTIFACT deployment." - - assert_output_not_contains "Started WEBHOOK deployment." - assert_output_not_contains "Webhook call completed." - assert_output_not_contains "[FAIL] Unable to complete webhook deployment." - assert_output_not_contains "Finished WEBHOOK deployment." - - assert_output_not_contains "Started container registry deployment." - assert_output_not_contains "Services map is not specified in VORTEX_DEPLOY_CONTAINER_REGISTRY_MAP variable." - assert_output_not_contains "Finished container registry deployment." - - popd >/dev/null -} diff --git a/.vortex/tests/bats/e2e/workflow.storage.image_cached.bats b/.vortex/tests/bats/e2e/workflow.storage.image_cached.bats deleted file mode 100644 index 9340a7868..000000000 --- a/.vortex/tests/bats/e2e/workflow.storage.image_cached.bats +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env bats -# -# Workflows using different types of DB storage. -# -# Throughout these tests, a "drevops/vortex-dev-mariadb-drupal-data-test-11.x:latest" -# test image is used: it is seeded with content from the pre-built fixture -# "Star wars" test site. -# -# When debugging failed tests locally, make sure that there are no untagged -# "drevops/vortex-dev-mariadb-drupal-data-*" images. -# -# In some cases, shell may report platform incorrectly. Run with forced platform: -# DOCKER_DEFAULT_PLATFORM=linux/amd64 bats --tap tests/bats/workflow1.bats -# -# shellcheck disable=SC2030,SC2031,SC2129 - -load ../_helper.bash -load ../_helper.workflow.bash - -@test "Workflow: download from image, storage in container image, use cached image" { - # Note that output assertions in this test do not end with a dot on purpose - # as different versions of Docker may produce different messages. - - # Force storage in container image - the purpose of this test. - export VORTEX_DB_DOWNLOAD_SOURCE=container_registry - - # Use a test image. Image always must use a tag. - export VORTEX_DB_IMAGE="drevops/vortex-dev-mariadb-drupal-data-test-11.x:latest" - - # Do not use demo database - testing demo database discovery is another test. - export VORTEX_INSTALLER_IS_DEMO_DB_DOWNLOAD_SKIP=1 - - # Explicitly specify that we do not want to login into the public registry - # to use test image. - export VORTEX_CONTAINER_REGISTRY_USER= - export VORTEX_CONTAINER_REGISTRY_PASS= - - substep "Make sure that demo database will not be downloaded." - rm -f .data/db.sql - assert_file_not_exists .data/db.sql - - substep "Remove any existing images to download the fresh one." - docker_remove_image "${VORTEX_DB_IMAGE}" - - prepare_sut "Starting download from image, storage in container image, use cached image WORKFLOW tests in build directory ${BUILD_DIR}" - - # Assert that the database was not downloaded because VORTEX_INSTALLER_IS_DEMO_DB_DOWNLOAD_SKIP was set. - assert_file_not_exists .data/db.sql - # Remove .env.local added by the installer script. - rm .env.local >/dev/null - - assert_file_contains ".env" "VORTEX_DB_DOWNLOAD_SOURCE=container_registry" - assert_file_contains ".env" "VORTEX_DB_IMAGE=${VORTEX_DB_IMAGE}" - # Assert that demo config was removed as a part of the installation. - assert_file_not_contains ".env" "VORTEX_DB_IMAGE=drevops/vortex-dev-mariadb-drupal-data-demo-11.x:latest" - assert_file_not_contains ".env" "VORTEX_DB_DOWNLOAD_URL=" - - step "Initial build to use data image." - assert_ahoy_build - assert_output_contains "Using database data image ${VORTEX_DB_IMAGE}" - assert_output_contains "Not found ${VORTEX_DB_IMAGE}" - assert_output_contains "Not found archived database container image file ./.data/db.tar." - assert_output_contains "Finished building project" - - substep "Remove any existing or previously downloaded DB image dumps." - rm -Rf .data/db.tar - assert_file_not_exists .data/db.tar - - step "Update DB content" - # Make a change to current site, export the DB image, remove existing DB image - # and rebuild the stack - the used image should have the expected changes. - substep "Assert that used DB image has content." - assert_webpage_contains "/" "This test page is sourced from the Vortex database container image" - assert_webpage_not_contains "/" "Username" - - substep "Change homepage content and assert that the change was applied." - ahoy drush config-set system.site page.front /user -y - assert_webpage_not_contains "/" "This test page is sourced from the Vortex database container image" - assert_webpage_contains "/" "Username" - - substep "Exporting DB image to a file" - run ahoy export-db "db.tar" - assert_success - assert_output_contains "Found database service container with id" - assert_output_contains "Committing exported container image with name docker.io/${VORTEX_DB_IMAGE}" - assert_output_contains "Committed exported container image with id" - assert_output_contains "Exporting database image archive to file ./.data/db.tar." - assert_output_contains "Exported database image saved to archive file ./.data/db.tar." - assert_file_exists .data/db.tar - - substep "Remove existing image and assert that exported DB image file still exists." - ahoy clean - docker_remove_image "${VORTEX_DB_IMAGE}" - assert_file_exists .data/db.tar - - step "Re-run build to use previously exported DB image from file." - assert_ahoy_build - - assert_output_contains "Started database data container image download." - assert_output_contains "Using data image ${VORTEX_DB_IMAGE}" - assert_output_contains "Not found ${VORTEX_DB_IMAGE} on host" - assert_output_contains "Found archived database container image file ./.data/db.tar. Expanding" - assert_output_contains "Loaded image: ${VORTEX_DB_IMAGE}" - assert_output_contains "Found expanded ${VORTEX_DB_IMAGE}" - assert_output_contains "Finished database data container image download." - - assert_output_contains "Finished building project" - - step "Assert that the contents of the DB was loaded from the exported DB image file." - assert_webpage_not_contains "/" "This test page is sourced from the Vortex database container image" - assert_webpage_contains "/" "Username" - ahoy clean -} diff --git a/.vortex/tests/phpunit/Functional/DeploymentTest.php b/.vortex/tests/phpunit/Functional/DeploymentTest.php new file mode 100644 index 000000000..61e963373 --- /dev/null +++ b/.vortex/tests/phpunit/Functional/DeploymentTest.php @@ -0,0 +1,197 @@ +dockerCleanup(); + } + + #[Group('p2')] + public function testDeployment(): void { + $this->logStepStart(); + + static::$sutInstallerEnv = [ + 'VORTEX_INSTALLER_IS_DEMO' => '1', + ]; + + $this->logSubstep('Prepare SUT without full build (structure only)'); + $this->prepareSut(); + $this->createInstalledDependenciesStub(); + + $this->logSubstep('Run webhook deployment'); + $this->cmd('ahoy deploy', [ + '* Started WEBHOOK deployment.', + '* Webhook call completed.', + '! [FAIL] Unable to complete webhook deployment.', + '* Finished WEBHOOK deployment.', + ], txt: 'Webhook deployment should complete successfully', env: [ + 'VORTEX_DEPLOY_TYPES' => 'webhook', + 'VORTEX_DEPLOY_WEBHOOK_URL' => 'https://www.example.com', + 'VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS' => '200', + ]); + + $this->logStepFinish(); + } + + #[Group('p3')] + public function testDeploymentSkipFlags(): void { + $this->logStepStart(); + + static::$sutInstallerEnv = [ + 'VORTEX_INSTALLER_IS_DEMO' => '1', + ]; + + $this->logSubstep('Prepare SUT without full build (structure only)'); + $this->prepareSut(); + $this->createInstalledDependenciesStub(); + + $this->logSubstep('Subtest 1: Run deployment without skip flag set'); + $this->cmd('ahoy deploy', [ + '* Started WEBHOOK deployment.', + '* Finished WEBHOOK deployment.', + '! Skipping deployment webhook.', + ], txt: 'Deployment should proceed without skip flag', env: [ + 'VORTEX_DEPLOY_TYPES' => 'webhook', + 'VORTEX_DEPLOY_WEBHOOK_URL' => 'https://www.example.com', + 'VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS' => '200', + ]); + + $this->logSubstep('Subtest 2: Run deployment with skip flag but no per-branch skip'); + $this->cmd('ahoy deploy', [ + '* Found flag to skip a deployment.', + '* Started WEBHOOK deployment.', + '* Finished WEBHOOK deployment.', + '! Skipping deployment webhook.', + ], txt: 'Deployment should proceed with ALLOW_SKIP but no specific skip', env: [ + 'VORTEX_DEPLOY_TYPES' => 'webhook', + 'VORTEX_DEPLOY_WEBHOOK_URL' => 'https://www.example.com', + 'VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS' => '200', + 'VORTEX_DEPLOY_ALLOW_SKIP' => '1', + ]); + + $this->logSubstep('Subtest 3: Run deployment with per-branch skip flag'); + $this->cmd('ahoy deploy', [ + '* Found flag to skip a deployment.', + '* Found skip variable VORTEX_DEPLOY_SKIP_BRANCH_FEATURE_TEST', + '* Skipping deployment webhook.', + '! Started WEBHOOK deployment.', + '! Finished WEBHOOK deployment.', + ], txt: 'Deployment should be skipped for feature/test branch', env: [ + 'VORTEX_DEPLOY_TYPES' => 'webhook', + 'VORTEX_DEPLOY_WEBHOOK_URL' => 'https://www.example.com', + 'VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS' => '200', + 'VORTEX_DEPLOY_ALLOW_SKIP' => '1', + 'VORTEX_DEPLOY_BRANCH' => 'feature/test', + 'VORTEX_DEPLOY_SKIP_BRANCH_FEATURE_TEST' => '1', + ]); + + $this->logSubstep('Subtest 4: Run deployment with per-PR skip flag'); + $this->cmd('ahoy deploy', [ + '* Found flag to skip a deployment.', + '* Found skip variable VORTEX_DEPLOY_SKIP_PR_123', + '* Skipping deployment webhook.', + '! Started WEBHOOK deployment.', + '! Finished WEBHOOK deployment.', + ], txt: 'Deployment should be skipped for PR 123', env: [ + 'VORTEX_DEPLOY_TYPES' => 'webhook', + 'VORTEX_DEPLOY_WEBHOOK_URL' => 'https://www.example.com', + 'VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS' => '200', + 'VORTEX_DEPLOY_ALLOW_SKIP' => '1', + 'VORTEX_DEPLOY_PR' => '123', + 'VORTEX_DEPLOY_SKIP_PR_123' => '1', + ]); + + $this->logSubstep('Subtest 5: Run deployment without skip flag but with per-PR'); + $this->cmd('ahoy deploy', [ + '* Started WEBHOOK deployment.', + '* Finished WEBHOOK deployment.', + '! Found flag to skip a deployment.', + '! Skipping deployment webhook.', + ], txt: 'Deployment should proceed when ALLOW_SKIP is not set', env: [ + 'VORTEX_DEPLOY_TYPES' => 'webhook', + 'VORTEX_DEPLOY_WEBHOOK_URL' => 'https://www.example.com', + 'VORTEX_DEPLOY_WEBHOOK_RESPONSE_STATUS' => '200', + 'VORTEX_DEPLOY_PR' => '123', + 'VORTEX_DEPLOY_SKIP_PR_123' => '1', + ]); + + $this->logStepFinish(); + } + + #[Group('p2')] + public function testDeploymentArtifact(): void { + $this->logStepStart(); + + static::$sutInstallerEnv = [ + 'VORTEX_INSTALLER_IS_DEMO' => '1', + // Add trailing comma to simulate list input. + 'VORTEX_INSTALLER_PROMPT_DEPLOY_TYPE' => 'artifact,', + ]; + + $this->logSubstep('Prepare SUT with full build'); + $this->prepareSut(); + $this->adjustAhoyForUnmountedVolumes(); + + $this->logSubstep('Build site'); + $this->subtestAhoyBuild(); + $this->syncToHost(); + + $this->logSubstep('Prepare deployment directories'); + $src_dir = static::$workspace . '/deployment_src'; + $remote_dir = static::$workspace . '/deployment_remote'; + + $this->prepareDeploymentSource($src_dir); + $this->prepareRemoteRepository($remote_dir); + + $this->logSubstep('Copy built codebase to deployment source'); + // Copy everything including .git directory to match BATS test behavior. + // The deployment artifact script expects the source to be a git repository + // with .gitignore.artifact already present. + File::copy(static::$sut . '/.', $src_dir . '/'); + + $this->logSubstep('Create excluded directory (should be ignored in artifact)'); + File::mkdir($src_dir . '/web/themes/custom/star_wars/node_modules'); + File::dump($src_dir . '/web/themes/custom/star_wars/node_modules/test.txt', ''); + + $this->logSubstep('Run artifact deployment'); + $this->cmd('ahoy deploy', [ + '* Started ARTIFACT deployment.', + '* Installing artifact builder.', + '* Copying git repo files meta file to the deploy code repo.', + '* Copying deployment .gitignore as it may not exist in deploy code source files.', + '* Running artifact builder.', + '* Finished ARTIFACT deployment.', + ], txt: 'Artifact deployment should complete successfully', env: [ + 'VORTEX_DEPLOY_TYPES' => 'artifact', + 'VORTEX_DEPLOY_ARTIFACT_GIT_REMOTE' => $remote_dir . '/.git', + 'VORTEX_DEPLOY_ARTIFACT_ROOT' => static::$sut, + 'VORTEX_DEPLOY_ARTIFACT_SRC' => $src_dir, + 'VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL' => 'testuser@example.com', + ]); + + $this->logSubstep('Assert deployment files in remote repository'); + $this->assertDeploymentFilesPresent($remote_dir); + + $this->logStepFinish(); + } + +} diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestDeploymentTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestDeploymentTrait.php new file mode 100644 index 000000000..f4cea9fea --- /dev/null +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestDeploymentTrait.php @@ -0,0 +1,137 @@ +logNote('Preparing deployment source at: ' . $src_dir); + File::mkdir($src_dir); + } + + /** + * Prepare remote repository for artifact deployment. + */ + protected function prepareRemoteRepository(string $remote_dir): void { + $this->logNote('Preparing remote repository at: ' . $remote_dir); + File::mkdir($remote_dir); + $this->gitInitRepo($remote_dir); + // Configure git to accept pushes to the checked-out branch. + shell_exec('git -C ' . escapeshellarg($remote_dir) . ' config receive.denyCurrentBranch updateInstead'); + // Create an initial file so we can commit. + File::dump($remote_dir . '/.gitkeep', ''); + $this->gitCommitAll($remote_dir, 'Initial commit'); + } + + /** + * Assert deployment artifact files are present. + * + * These are the files that should exist in a deployment artifact after + * the build process has completed. + */ + protected function assertDeploymentFilesPresent(string $dir, string $webroot = 'web'): void { + $this->logNote('Asserting deployment files are present in: ' . $dir); + + // CI/CD directories should not exist in deployment. + $this->assertDirectoryDoesNotExist($dir . '/.circleci', 'CircleCI directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/.data', 'Data directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/.docker', 'Docker directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/.github', 'GitHub directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/.logs/screenshots', 'Screenshots directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/node_modules', 'node_modules should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/patches', 'Patches directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/tests', 'Tests directory should not exist in deployment'); + + // Development files should not exist in deployment. + $this->assertFileDoesNotExist($dir . '/.ahoy.yml', '.ahoy.yml should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/.dockerignore', '.dockerignore should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/.editorconfig', '.editorconfig should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/.eslintrc.json', '.eslintrc.json should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/.lagoon.yml', '.lagoon.yml should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/.stylelintrc.json', '.stylelintrc.json should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/LICENSE', 'LICENSE should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/README.md', 'README.md should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/behat.yml', 'behat.yml should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/composer.lock', 'composer.lock should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/docker-compose.yml', 'docker-compose.yml should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/gherkinlint.json', 'gherkinlint.json should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/phpcs.xml', 'phpcs.xml should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/phpstan.neon', 'phpstan.neon should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/renovate.json', 'renovate.json should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/.gitignore.artifact', '.gitignore.artifact should not exist in deployment'); + + // Required directories should exist. + $this->assertDirectoryExists($dir . '/scripts', 'Scripts directory should exist in deployment'); + $this->assertDirectoryExists($dir . '/vendor', 'Vendor directory should exist in deployment'); + + // .env configs should exist to allow project control. + $this->assertFileExists($dir . '/.env', '.env should exist in deployment'); + + // Site core module should be present. + $this->assertDirectoryExists($dir . '/' . $webroot . '/modules/custom/sw_base', 'sw_base module directory should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/modules/custom/sw_base/sw_base.info.yml', 'sw_base info file should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/modules/custom/sw_base/sw_base.module', 'sw_base module file should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/modules/custom/sw_base/sw_base.deploy.php', 'sw_base deploy file should exist'); + + // Site theme should be present. + $this->assertDirectoryExists($dir . '/' . $webroot . '/themes/custom/star_wars', 'star_wars theme directory should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/themes/custom/star_wars/.gitignore', 'Theme .gitignore should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/themes/custom/star_wars/star_wars.info.yml', 'Theme info file should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/themes/custom/star_wars/star_wars.libraries.yml', 'Theme libraries file should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/themes/custom/star_wars/star_wars.theme', 'Theme file should exist'); + + // Theme development files should not exist. + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/Gruntfile.js', 'Gruntfile should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/package.json', 'Theme package.json should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/yarn.lock', 'Theme yarn.lock should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/.eslintrc.json', 'Theme .eslintrc.json should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/node_modules', 'Theme node_modules should not exist in deployment'); + + // Drupal scaffold files should be present. + $this->assertFileExists($dir . '/' . $webroot . '/autoload.php', 'autoload.php should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/index.php', 'index.php should exist'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/robots.txt', 'robots.txt should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/update.php', 'update.php should not exist in deployment'); + + // Settings files should be present. + $this->assertFileExists($dir . '/' . $webroot . '/sites/default/settings.php', 'settings.php should exist'); + $this->assertFileExists($dir . '/' . $webroot . '/sites/default/services.yml', 'services.yml should exist'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/sites/default/example.settings.local.php', 'example.settings.local.php should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/sites/default/example.services.local.yml', 'example.services.local.yml should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/sites/default/default.settings.local.php', 'default.settings.local.php should not exist in deployment'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/sites/default/default.services.local.yml', 'default.services.local.yml should not exist in deployment'); + + // Only minified compiled CSS should be present. + $this->assertFileExists($dir . '/' . $webroot . '/themes/custom/star_wars/build/css/star_wars.min.css', 'Minified CSS should exist'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/build/css/star_wars.css', 'Non-minified CSS should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/scss', 'SCSS directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/css', 'CSS source directory should not exist in deployment'); + + // Only minified compiled JS should exist. + $this->assertFileExists($dir . '/' . $webroot . '/themes/custom/star_wars/build/js/star_wars.min.js', 'Minified JS should exist'); + $this->assertFileContainsString($dir . '/' . $webroot . '/themes/custom/star_wars/build/js/star_wars.min.js', '!function(Drupal){"use strict";Drupal.behaviors.star_wars', 'JS should contain expected minified content'); + $this->assertFileDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/build/js/star_wars.js', 'Non-minified JS should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/js', 'JS source directory should not exist in deployment'); + + // Other source asset files should not exist. + $this->assertDirectoryDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/fonts', 'Fonts source directory should not exist in deployment'); + $this->assertDirectoryDoesNotExist($dir . '/' . $webroot . '/themes/custom/star_wars/images', 'Images source directory should not exist in deployment'); + + // Config directory should exist. + $this->assertDirectoryExists($dir . '/config/default', 'Config directory should exist'); + + // Composer.json should exist for autoloading. + $this->assertFileExists($dir . '/composer.json', 'composer.json should exist'); + } + +} diff --git a/.vortex/tests/phpunit/Traits/SutTrait.php b/.vortex/tests/phpunit/Traits/SutTrait.php index 1a365aef4..f55335318 100644 --- a/.vortex/tests/phpunit/Traits/SutTrait.php +++ b/.vortex/tests/phpunit/Traits/SutTrait.php @@ -38,7 +38,7 @@ trait SutTrait { */ protected static $sutInstallerEnv = []; - protected function prepareSut(): void { + protected function prepareSut(string $webroot = 'web'): void { $this->logStepStart(); $this->logSubstep('Prepare global gitconfig'); @@ -48,13 +48,13 @@ protected function prepareSut(): void { $this->prepareGlobalGitignore(); $this->logSubstep('Assert that SUT does not have common files before installation'); - $this->assertCommonFilesAbsent(); + $this->assertCommonFilesAbsent($webroot); $this->logSubstep('Run the installer to initialise the project with the default settings'); $this->runInstaller(); $this->logSubstep('Assert that SUT has common files after installation'); - $this->assertCommonFilesPresent(); + $this->assertCommonFilesPresent($webroot); $this->logSubstep('Assert that created SUT is a git repository'); $this->gitAssertIsRepository(static::$sut); diff --git a/.vortex/tests/test.deployment.sh b/.vortex/tests/test.deployment.sh deleted file mode 100755 index 2d1d43f1e..000000000 --- a/.vortex/tests/test.deployment.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -## -# Run Vortex deployment tests. -# -# LCOV_EXCL_START - -set -eu -[ "${VORTEX_DEBUG-}" = "1" ] && set -x - -ROOT_DIR="$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)")" - -SCRIPTS_DIR="${ROOT_DIR}/scripts/vortex" - -TEST_DIR="${ROOT_DIR}/.vortex/tests" - -# ------------------------------------------------------------------------------ - -# Configure git username and email if it is not set. -[ "$(git config --global user.name)" = "" ] && echo "==> Configuring global test git user name" && git config --global user.name "Test user" -[ "$(git config --global user.email)" = "" ] && echo "==> Configuring global test git user email" && git config --global user.email "someone@example.com" - -# Create stub of local framework. -docker network create amazeeio-network 2>/dev/null || true - -index="${TEST_NODE_INDEX:-*}" -echo "==> Run deployment functional tests (${index})." -[ ! -d "${TEST_DIR}/node_modules" ] && echo " > Install test Node dependencies." && yarn --cwd="${TEST_DIR}" install --frozen-lockfile - -bats() { - pushd "${ROOT_DIR}" >/dev/null || exit 1 - if [ -n "${VORTEX_DEV_TEST_COVERAGE_DIR:-}" ]; then - mkdir -p "${VORTEX_DEV_TEST_COVERAGE_DIR}" - kcov --include-pattern=.sh,.bash --bash-parse-files-in-dir="${SCRIPTS_DIR}","${TEST_DIR}" --exclude-pattern=vendor,node_modules "${VORTEX_DEV_TEST_COVERAGE_DIR}" "${TEST_DIR}/node_modules/.bin/bats" "$@" - else - "${TEST_DIR}/node_modules/.bin/bats" "$@" - fi - popd >/dev/null || exit 1 -} - -# shellcheck disable=SC2086 -bats "${TEST_DIR}"/bats/e2e/deployment${index}.bats diff --git a/.vortex/tests/test.workflow.sh b/.vortex/tests/test.workflow.sh deleted file mode 100755 index b3252d744..000000000 --- a/.vortex/tests/test.workflow.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env bash -## -# Run Vortex workflow tests. -# -# LCOV_EXCL_START - -set -eu -[ "${VORTEX_DEBUG-}" = "1" ] && set -x - -ROOT_DIR="$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)")" - -SCRIPTS_DIR="${ROOT_DIR}/scripts/vortex" - -TEST_DIR="${ROOT_DIR}/.vortex/tests" - -# ------------------------------------------------------------------------------ - -# Configure git username and email if it is not set. -[ "$(git config --global user.name)" = "" ] && echo "==> Configuring global test git user name" && git config --global user.name "Test user" -[ "$(git config --global user.email)" = "" ] && echo "==> Configuring global test git user email" && git config --global user.email "someone@example.com" - -# Create stub of local framework. -docker network create amazeeio-network 2>/dev/null || true - -index="${TEST_NODE_INDEX:-*}" -echo "==> Run workflow functional tests (${index})." - -[ ! -d "${TEST_DIR}/node_modules" ] && echo " > Install test Node dependencies." && yarn --cwd="${TEST_DIR}" install --frozen-lockfile >/dev/null 2>&1 -[ ! -d "${TEST_DIR}/vendor" ] && echo " > Install test PHP dependencies." && composer --working-dir="${TEST_DIR}" install --no-interaction --no-progress --optimize-autoloader >/dev/null 2>&1 - -bats() { - pushd "${ROOT_DIR}" >/dev/null || exit 1 - if [ -n "${VORTEX_DEV_TEST_COVERAGE_DIR:-}" ]; then - mkdir -p "${VORTEX_DEV_TEST_COVERAGE_DIR}" - kcov --include-pattern=.sh,.bash --bash-parse-files-in-dir="${SCRIPTS_DIR}","${TEST_DIR}" --exclude-pattern=vendor,node_modules "${VORTEX_DEV_TEST_COVERAGE_DIR}" "${TEST_DIR}/node_modules/.bin/bats" "$@" - else - "${TEST_DIR}/node_modules/.bin/bats" "$@" - fi - popd >/dev/null || exit 1 -} - -phpunit() { - pushd "${TEST_DIR}" >/dev/null || exit 1 - php -d memory_limit=-1 "./vendor/bin/phpunit" "$@" - popd >/dev/null || exit 1 -} - -# Not every test has a coverage report, so we create an empty directory -# to avoid errors in CI. -# @see https://github.com/actions/upload-artifact/issues/255 -if [ -n "${CI}" ]; then - mkdir -p /tmp/.vortex-coverage-html - touch "/tmp/.vortex-coverage-html/.empty-$(date +%Y%m%d%H%M%S)" -fi - -# Run workflow based on index using switch-case. -case ${index} in - - 0) - phpunit "${TEST_DIR}"/phpunit --group=p0 - ;; - - 1) - phpunit "${TEST_DIR}"/phpunit --group=p1 - ;; - - 2) - phpunit "${TEST_DIR}"/phpunit --group=p2 - ;; - - 3) - phpunit "${TEST_DIR}"/phpunit --group=p3 - ;; - - 4) - phpunit "${TEST_DIR}"/phpunit --group=p4 - # Disabled due to intermittent failures. - # bats "${TEST_DIR}"/bats/e2e/workflow.storage.image_cached.bats - ;; - - *) - phpunit "${TEST_DIR}"/phpunit - # Disabled due to intermittent failures. - # bats "${TEST_DIR}"/bats/e2e/workflow.storage.image_cached.bats - ;; -esac