Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ jobs:

- run:
name: Run CircleCI tests (long)
command: VORTEX_DEV_VOLUMES_MOUNTED=0 VORTEX_DEV_TEST_COVERAGE_DIR=/tmp/artifacts/coverage .vortex/tests/test.postbuild.sh
command: VORTEX_DEV_VOLUMES_SKIP_MOUNT=1 VORTEX_DEV_TEST_COVERAGE_DIR=/tmp/artifacts/coverage .vortex/tests/test.postbuild.sh

- store_test_results:
path: *test_results
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/vortex-test-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_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_MOUNTED: 0
VORTEX_DEV_VOLUMES_SKIP_MOUNT: 1
VORTEX_DEV_TEST_COVERAGE_DIR: /tmp/.vortex-coverage-html

steps:
Expand Down Expand Up @@ -109,7 +109,7 @@ jobs:
TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_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_MOUNTED: 0
VORTEX_DEV_VOLUMES_SKIP_MOUNT: 1
VORTEX_DEV_TEST_COVERAGE_DIR: /tmp/.vortex-coverage-html
TEST_NODE_INDEX: ${{ matrix.batch }}

Expand Down Expand Up @@ -169,7 +169,7 @@ jobs:
TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_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_MOUNTED: 0
VORTEX_DEV_VOLUMES_SKIP_MOUNT: 1
VORTEX_DEV_TEST_COVERAGE_DIR: /tmp/.vortex-coverage-html
TEST_NODE_INDEX: ${{ matrix.batch }}

Expand Down
9 changes: 6 additions & 3 deletions .vortex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
This directory contains development files for Vortex itself.
This directory is removed by the installer or can be deleted manually.

FAQ:
Q: Pipeline fails with "PHPUnit\Framework\Exception: Error: Differences between directories"
A: Run `ahoy update-fixtures` from .vortex folder
- [`docs`](docs) - documentation for Vortex published to https://vortex.drevops.com
- [`installer`](installer) - self-contained Symfony console application used to install Vortex
- [`tests`](tests) - unit and functional tests for Vortex

For convenience, the commands are available via `ahoy` wrapper.
Run `ahoy --help` to see the list of available commands.
93 changes: 93 additions & 0 deletions .vortex/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Vortex Testing Framework

This directory contains the comprehensive testing system for the Vortex project
to ensure the quality and reliability of Vortex workflows and scripts.

## Overview

The Vortex testing framework is designed to validate:

- Core Vortex functionality and scripts
- Installation and deployment workflows
- Integration scenarios
- CI/CD pipeline components

## Testing Technologies

### PHPUnit

PHPUnit handles functional testing of Vortex user's **workflows**: processes
and commands are ran in the context of a Vortex installation, simulating
real-world scenarios.

### Bats (Bash Automated Testing System)

[Bats](https://github.com/bats-core/bats-core) is used for **unit** testing
shell scripts with coverage.

## Running Tests

### Prerequisites

- Docker and Docker Compose
- Node.js and Yarn
- PHP 8.2+
- Composer
- Git

### Setup

```bash
# Install PHP dependencies
composer install

# Install Node.js dependencies for BATS testing (BATS is distributed via npm, but does not require Node.js to run)
yarn install
```

## Running PHPUnit Tests

```bash
# Run all PHPUnit tests
./vendor/bin/phpunit

# Run specific test class
./vendor/bin/phpunit phpunit/Functional/WorkflowTest.php
```

## Running BATS tests

```bash
# Run specific Bats test file
bats bats/helpers.bats

# Run with verbose output
bats --verbose-run bats/provision.bats
```

## Running Individual Test Suites

For parallel execution, tests can be run across multiple CI nodes using the
convenience script wrappers:

- [`test.common.sh]`(test.common.sh) - Common tests for all environments
- [`test.deployment.sh`](test.deployment.sh) - Deployment tests
- [`test.postbuild.sh`](test.postbuild.sh) - Post-build tests
- [`test.workflow.sh`](test.workflow.sh) - Workflow tests
- [`lint.scripts.sh`](lint.scripts.sh) - Linting for shell scripts
- [`lint.dockerfiles.sh`](lint.dockerfiles.sh) - Linting for Dockerfiles

These scripts are designed to run in CI environments (CircleCI, GitHub Actions)
and use the `TEST_NODE_INDEX` environment variable to distribute tests across
multiple runners.

## Environment Variables

The following environment variables can be added in the environment to
customize test execution:

- `TEST_VORTEX_DEBUG=1` - Enable debug output
- `TEST_NODE_INDEX` - CI runner index for parallel execution
- `VORTEX_DEV_TEST_COVERAGE_DIR` - Coverage output directory
- `TEST_GITHUB_TOKEN` - GitHub token used for integration tests
- `TEST_VORTEX_CONTAINER_REGISTRY_USER/PASS` - Container registry credentials used for integration tests
8 changes: 4 additions & 4 deletions .vortex/tests/bats/_helper.bash
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@
local dst="${1:-.}"
# shellcheck disable=SC1090,SC1091
[ -f "./.env" ] && t=$(mktemp) && export -p >"${t}" && set -a && . "./.env" && set +a && . "${t}" && rm "${t}" && unset t
[ "${VORTEX_DEV_VOLUMES_MOUNTED-}" = "1" ] && return
[ "${VORTEX_DEV_VOLUMES_SKIP_MOUNT:-0}" != "1" ] && return
docker compose cp -L cli:/app/. "${dst}"
}

Expand All @@ -1345,7 +1345,7 @@
local src="${1:-.}"
# shellcheck disable=SC1090,SC1091
[ -f "./.env" ] && t=$(mktemp) && export -p >"${t}" && set -a && . "./.env" && set +a && . "${t}" && rm "${t}" && unset t
[ "${VORTEX_DEV_VOLUMES_MOUNTED-}" = "1" ] && return
[ "${VORTEX_DEV_VOLUMES_SKIP_MOUNT:-0}" != "1" ] && return

Check warning on line 1348 in .vortex/tests/bats/_helper.bash

View check run for this annotation

Codecov / codecov/patch

.vortex/tests/bats/_helper.bash#L1348

Added line #L1348 was not covered by tests
docker compose cp -L "${src}" cli:/app/
}

Expand All @@ -1361,7 +1361,7 @@

pushd "${VORTEX_INSTALL_DST_DIR}" >/dev/null || exit 1

if [ -f docker-compose.yml ] && [ "${VORTEX_DEV_VOLUMES_MOUNTED:-1}" != "1" ]; then
if [ -f docker-compose.yml ] && [ "${VORTEX_DEV_VOLUMES_SKIP_MOUNT:-0}" = "1" ]; then
sed -i -e "/###/d" docker-compose.yml
assert_file_not_contains docker-compose.yml "###"
sed -i -e "s/##//" docker-compose.yml
Expand Down Expand Up @@ -1419,7 +1419,7 @@
}

process_ahoyyml() {
[ "${VORTEX_DEV_VOLUMES_MOUNTED:-0}" = "1" ] && return
[ "${VORTEX_DEV_VOLUMES_SKIP_MOUNT:-0}" != "1" ] && return

# Override the provision command in .ahoy.yml to copy the database file to
# the container for when the volumes are not mounted.
Expand Down
2 changes: 1 addition & 1 deletion .vortex/tests/bats/_helper.deployment.bash
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ install_and_build_site() {
assert_git_repo

# Special treatment for cases where volumes are not mounted from the host.
if [ "${VORTEX_DEV_VOLUMES_MOUNTED:-}" != "1" ]; then
if [ "${VORTEX_DEV_VOLUMES_SKIP_MOUNT:-0}" = "1" ]; then
sed -i -e "/###/d" docker-compose.yml
assert_file_not_contains docker-compose.yml "###"
sed -i -e "s/##//" docker-compose.yml
Expand Down
8 changes: 6 additions & 2 deletions .vortex/tests/bats/_helper.workflow.bash
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ prepare_sut() {
step "Run SUT preparation: ${1}"
local webroot="${2:-web}"

VORTEX_DEV_VOLUMES_MOUNTED=${VORTEX_DEV_VOLUMES_MOUNTED:-1}
VORTEX_DEV_VOLUMES_SKIP_MOUNT=${VORTEX_DEV_VOLUMES_SKIP_MOUNT:-0}

assert_not_empty "${VORTEX_DEV_VOLUMES_MOUNTED-}"
assert_not_empty "${VORTEX_DEV_VOLUMES_SKIP_MOUNT-}"

assert_files_not_present_common "" "" "" "${webroot}"

Expand Down Expand Up @@ -523,12 +523,16 @@ assert_ahoy_test_bdd_fast() {
substep "Run all BDD tests"
run ahoy test-bdd
assert_success

sync_to_host

assert_dir_not_empty .logs/screenshots
rm -rf .logs/screenshots/*
ahoy cli rm -rf /app/.logs/screenshots/*

assert_dir_not_empty .logs/test_results
assert_file_exists .logs/test_results/behat/default.xml

rm -rf .logs/test_results/*
ahoy cli rm -rf /app/.logs/test_results/*
}
Expand Down
2 changes: 1 addition & 1 deletion .vortex/tests/bats/workflow.smoke.bats
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ load _helper.workflow.bash

# Copy DB into container for the cases when the volumes are not mounted.
# This will not be a case locally.
if [ "${VORTEX_DEV_VOLUMES_MOUNTED-}" != "1" ]; then
if [ "${VORTEX_DEV_VOLUMES_SKIP_MOUNT:-0}" = "1" ]; then
if [ -f .data/db.sql ]; then
docker compose exec cli mkdir -p .data
docker compose cp -L .data/db.sql cli:/app/.data/db.sql
Expand Down
46 changes: 43 additions & 3 deletions .vortex/tests/composer.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,56 @@
{
"name": "drevops/vortex-tests",
"description": "Tests for Vortex",
"description": "Test for the Vortex project",
"type": "project",
"authors": [
{
"name": "Alex Skrypnyk",
"email": "alex@drevops.com"
}
],
"require": {
"php": ">=8.2"
},
"require-dev": {
"alexskrypnyk/file": "^0.7.0",
"alexskrypnyk/phpunit-helpers": "^0.8.1",
"alexskrypnyk/shellvar": "^1.2",
"czproject/git-php": "^4.4",
"dealerdirect/phpcodesniffer-composer-installer": "^1",
"drupal/coder": "^8.3",
"ergebnis/composer-normalize": "^2.47",
"phpstan/phpstan": "^2",
"phpunit/phpunit": "^12.1",
"rector/rector": "^2",
"squizlabs/php_codesniffer": "^3.12"
},
"minimum-stability": "alpha",
"prefer-stable": true,
"require-dev": {
"alexskrypnyk/shellvar": "^1"
"autoload-dev": {
"psr-4": {
"DrevOps\\Vortex\\Tests\\": "phpunit/",
"AlexSkrypnyk\\File\\Tests\\": "vendor/alexskrypnyk/file/tests/"
}
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"ergebnis/composer-normalize": true
},
"discard-changes": true,
"sort-packages": true
},
"scripts": {
"lint": [
"phpcs",
"phpstan",
"rector --clear-cache --dry-run"
],
"lint-fix": [
"rector --clear-cache",
"phpcbf"
],
"reset": "rm -Rf vendor",
"test": "phpunit"
}
Comment on lines +43 to 55
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Platform-agnostic reset script

"reset": "rm -Rf vendor" breaks on Windows shells. A small PHP helper keeps it cross-platform:

-        "reset": "rm -Rf vendor",
+        "reset": "php -r \"echo shell_exec(PHP_OS_FAMILY==='Windows' ? 'rmdir /S /Q vendor' : 'rm -rf vendor');\"",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"scripts": {
"lint": [
"phpcs",
"phpstan",
"rector --clear-cache --dry-run"
],
"lint-fix": [
"rector --clear-cache",
"phpcbf"
],
"reset": "rm -Rf vendor",
"test": "phpunit"
}
"scripts": {
"lint": [
"phpcs",
"phpstan",
"rector --clear-cache --dry-run"
],
"lint-fix": [
"rector --clear-cache",
"phpcbf"
],
"reset": "php -r \"echo shell_exec(PHP_OS_FAMILY==='Windows' ? 'rmdir /S /Q vendor' : 'rm -rf vendor');\"",
"test": "phpunit"
}
🤖 Prompt for AI Agents
In .vortex/tests/composer.json around lines 43 to 55, the "reset" script uses a
Unix-specific command "rm -Rf vendor" which fails on Windows. Replace this with
a PHP script or command that deletes the vendor directory in a platform-agnostic
way, ensuring it works correctly on both Unix and Windows environments.

}
Loading