Skip to content

Commit

Permalink
[O2B-1313] Local parallelisation (#1649)
Browse files Browse the repository at this point in the history
* Local parallelisation

* Local parallelisation

* package lock fix

* [O2B-1300] Logging added

* Custom logging, no-console now warning not error

* Cleaner code

* Remove rejects

* Formatting

* Add time

* Test CI no port

* Review comments implemented

* Bump default numberOfWorkers to 3

* Single docker image and small fixes

* Removed unnecessary workersCompleted

* Technical doc + review comments implemented

* Make workers env configurable, use storage path env in mocha-reporter. Update doc
  • Loading branch information
AnoeBanoe authored Jul 18, 2024
1 parent db8d76d commit bef4063
Show file tree
Hide file tree
Showing 12 changed files with 714 additions and 46 deletions.
12 changes: 8 additions & 4 deletions .github/workflows/bookkeeping.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,24 @@ jobs:
- name: Build and Start Test Database
run: |
docker-compose \
-f docker-compose.test-parallel.yml \
-f docker-compose.test-parallel-base.yml \
-f docker-compose.test-parallel-ci.yml \
up --detach test_db
env:
TEST_TYPE: ${{ matrix.test_type }}
- name: Build Test Container
run: |
docker-compose \
-f docker-compose.test-parallel.yml \
-f docker-compose.test-parallel-base.yml \
-f docker-compose.test-parallel-ci.yml \
build test_app
env:
TEST_TYPE: ${{ matrix.test_type }}
- name: Run Tests
run: |
docker-compose \
-f docker-compose.test-parallel.yml \
-f docker-compose.test-parallel-base.yml \
-f docker-compose.test-parallel-ci.yml \
run test_app
env:
TEST_TYPE: ${{ matrix.test_type }}
Expand All @@ -74,7 +77,8 @@ jobs:
- name: Clean Up
run: |
docker-compose \
-f docker-compose.test-parallel.yml \
-f docker-compose.test-parallel-base.yml \
-f docker-compose.test-parallel-ci.yml \
down
env:
TEST_TYPE: ${{ matrix.test_type }}
Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,20 @@ jobs:
-f docker-compose.yml \
-f docker-compose.coverage.yml \
config --quiet
- name: Validate docker-compose.test-parallel.yml
- name: Validate docker-compose.test-parallel-base.yml
run: |
docker compose \
-f docker-compose.test-parallel.yml \
-f docker-compose.test-parallel-base.yml \
config --quiet
- name: Validate docker-compose.test-parallel-ci.yml
run: |
docker compose \
-f docker-compose.test-parallel-base.yml \
-f docker-compose.test-parallel-ci.yml \
config --quiet
- name: Validate docker-compose.test-parallel-local.yml
run: |
docker compose \
-f docker-compose.test-parallel-base.yml \
-f docker-compose.test-parallel-local.yml \
config --quiet
12 changes: 7 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ CMD [ "/opt/wait-for-it.sh", "-t", "0", "database:3306", "--", "npm", "run", "te

#
# ---- Test parallel for CI ----
FROM developmentdependencies as test_parallel

# Set ARG and ENV for TEST_TYPE
ARG TEST_TYPE
ENV TEST_TYPE=${TEST_TYPE}
FROM developmentdependencies as test_parallel_ci

CMD [ "sh", "-c", "/opt/wait-for-it.sh -t 0 test_db:3306 -- npm run test:subset" ]

#
# ---- Test parallel local ----
FROM developmentdependencies as test_parallel_local

CMD [ "sh", "-c", "/opt/wait-for-it.sh -t 0 test_db:3306 -- npm run test:subset-local" ]

#
# ---- Coverage ----
FROM developmentdependencies as coverage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ services:
build:
context: .
dockerfile: Dockerfile
target: test_parallel
args:
TEST_TYPE: ${TEST_TYPE}
environment:
TEST_TYPE: ${TEST_TYPE}
NODE_ENV: test
Expand All @@ -16,9 +13,9 @@ services:
PAGE_ITEMS_LIMIT: 100
DATABASE_HOST: test_db
ALI_ECS_GUI_URL: "${ALI_ECS_GUI_URL:-http://localhost:8080}"
FLP_INFOLOGGER_URL: "${ALI_ECS_GUI_URL:-http://localhost:8081}"
QC_GUI_URL: "${ALI_ECS_GUI_URL:-http://localhost:8082}"
ALI_FLP_INDEX_URL: "${ALI_ECS_GUI_URL:-http://localhost:80}"
FLP_INFOLOGGER_URL: "${FLP_INFOLOGGER_URL:-http://localhost:8081}"
QC_GUI_URL: "${QC_GUI_URL:-http://localhost:8082}"
ALI_FLP_INDEX_URL: "${ALI_FLP_INDEX_URL:-http://localhost:80}"
links:
- test_db
restart: "no"
Expand All @@ -30,12 +27,8 @@ services:
source: ./scripts
target: /opt
- type: bind
read_only: false
source: ./database/storage
target: /var/storage
- type: bind
source: ${GITHUB_WORKSPACE}/coverage
target: /usr/src/app/coverage/${TEST_TYPE}
read_only: false

test_db:
Expand All @@ -45,7 +38,6 @@ services:
restart: unless-stopped
volumes:
- type: volume
read_only: false
source: database-data
target: /var/lib/mysql
- type: bind
Expand All @@ -56,8 +48,6 @@ services:
read_only: true
source: ./database/populate
target: /docker-entrypoint-initdb.d
ports:
- "3306:3306"

volumes:
database-data:
11 changes: 11 additions & 0 deletions docker-compose.test-parallel-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: '3.7'

services:
test_app:
build:
target: test_parallel_ci
volumes:
- type: bind
source: ${GITHUB_WORKSPACE}/coverage
target: /usr/src/app/coverage/${TEST_TYPE}
read_only: false
7 changes: 7 additions & 0 deletions docker-compose.test-parallel-local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: '3.7'

services:
test_app:
image: test-parallel-application:latest
build:
target: test_parallel_local
77 changes: 77 additions & 0 deletions docs/parallel-testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Parallel testing

## Prerequisites

Parallel testing requires the following programs to run:
- docker ([documentation](https://docs.docker.com/engine/install/))
- npm, which is bundled with nodejs ([download](https://nodejs.org/en/download/))

# How it works
Parallel testing is implemented to decrease the time it takes to run all test suites by distributing them across multiple Docker containers.
the `child_process` module of Node.js is used to spawn worker processes. Each worker process is responsible for running a portion of the test suites.
The main.js script begins by building a Docker image using the Docker Compose files. This image is then tagged for use by the worker containers.
Before starting the workers, any existing test logs are cleaned up to ensure a fresh environment for the new test runs.

Workers are spawned based on the predefined number set in the variable `amountOfWorkers` in main.js. Each worker is a Node.js process created using the fork() method from the child_process module.
These workers are isolated in that they can execute independently and in parallel, each in their own Docker container.

Each worker initially requests a test suite to execute from the testSuites stack. Once a worker completes a test suite, it requests the next available suite from the stack.
This continues until there are no more test suites left to assign in the stack, at which point the worker will shut down.

Inside each worker, the test-runner.js script handles the execution of the test suites. This script is responsible for reaching the target in the Dockerfile which will initiate a test run based on the `TEST_TYPE` given by main.js.
Custom logging and results handling are implemented using a custom Mocha reporter (custom-mocha-reporter.js). This reporter logs the results of the test executions into separate files.
These log files are then used to create the final result output.



# How to configure
All configuration can be done in main.js:
1. Set amountOfWorkers to as many as your system can handle (default is 3)
2. Make sure the testSuites stack in main.js is populated with all necessary suites
3. Run the tests in parallel

# How to run
After configuring everything, simply run:
```sh
npm run docker-test:parallel
```
The amount of workers can also be set using the environment variable WORKERS:
```sh
WORKERS=5 npm run docker-test:parallel
```
And the path where the result logs are stored can also be set:
```sh
STORAGE_PATH='./path/of/choice' npm run docker-test:parallel
```

## Docker configuration files

### Docker Compose files

There are two Docker Compose files used in this setup:

1. `docker-compose.test-parallel-base.yml` - Sets up the base testing environment including the application and database services.
2. `docker-compose.test-parallel-local.yml` - Configures the test-specific settings like image and target.

### Dockerfile

The `Dockerfile` is structured in multiple stages:

- **Base:** Sets up the Node.js environment.
- **Development Dependencies:** Installs tools and libraries required for testing.
- **Test Parallel Local:** Runs the command to execute a subset of tests.

## Testing scripts

### npm command

- **test:subset-local**: Executes the Mocha test runner for a subset of tests specified by the `TEST_TYPE` environment variable, and uses the custom-mocha-reporter to create logs which are used in the Node.js scripts.

### Node.js scripts

- **main.js**: Handles the initialization and distribution of tests across multiple worker processes.
- **test-runner.js**: Manages the execution of tests for a given subset, handling the Docker commands and environment setup.
- **custom-mocha-reporter.js**: A custom Mocha reporter that logs test results into separate files which are used in main.js to create the final result output.

### Test suites
For every test suite that needs to be ran by one of the workers, a script is provided in the test/scripts directory named test-suiteName. The suite name is given by the Node.js scripts and used in the npm command.
88 changes: 67 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit bef4063

Please sign in to comment.