ci(tests): fuzz testing workflow for REST API #26
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: REST API Fuzz Test | |
on: | |
workflow_dispatch: | |
pull_request: # Pushing a new commit to the HEAD ref of a pull request will trigger the “synchronize” event | |
paths: | |
- .yarnrc.yml . | |
- .yarn | |
- package.json | |
- '.github/workflows/rest-api-fuzzer.yml' | |
- 'packages/server/**/*' | |
- 'packages/shared/**/*' | |
env: | |
BUILD_CONFIGURATION: Release | |
BUILD_PLATFORM: 'Any CPU' | |
RESTLER_VERSION: '9.2.4' | |
PYTHON_VERSION: '3.8' | |
DOTNET_VERSION: '6.0.x' | |
jobs: | |
build-restler-fuzzer: | |
name: Fuzz test speckle-server REST API | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
steps: | |
- uses: actions/checkout@v4 | |
name: Checkout RESTler Fuzzer | |
with: | |
repository: microsoft/restler-fuzzer | |
ref: v${{ env.RESTLER_VERSION }} | |
path: 'restler-fuzzer' # The path to clone the repository within the {{ github.workspace }} directory | |
- name: Setup .NET ${{ env.DOTNET_VERSION }} | |
uses: actions/setup-dotnet@v4 | |
with: | |
dotnet-version: ${{ env.DOTNET_VERSION }} | |
cache: true | |
cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/src/Restler.sln | |
- name: Restore NuGet packages | |
run: dotnet restore ${{ github.workspace }}/restler-fuzzer/src/Restler.sln | |
- name: Set up Python ${{ env.PYTHON_VERSION }} | |
uses: actions/setup-python@v4 | |
with: | |
python-version: ${{ env.PYTHON_VERSION }} | |
cache: 'pip' | |
cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt | |
- name: Install engine (Python) dependencies | |
run: | | |
pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt | |
- name: Build RESTler | |
run: | | |
python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin | |
- name: Debug the built output | |
run: | | |
ls -la ${{ github.workspace }}/bin/restler | |
ls -la ${{ github.workspace }}/bin/restler/Restler | |
- uses: actions/checkout@v4 | |
name: Checkout speckle-server | |
with: | |
path: 'speckle-server' | |
- name: Restore cached Grammar | |
id: cache-grammar-restore | |
uses: actions/cache/restore@v4 | |
with: | |
path: | | |
${{ github.workspace }}/Compile | |
key: restler-grammar-${{ hashFiles('speckle-server/utils/specifications/speckle-server.openapi.json') }} | |
- name: Compile RESTler grammar from OpenAPI specification | |
if: steps.cache-grammar-restore.outputs.cache-hit != 'true' | |
run: | | |
${{ github.workspace }}/bin/restler/Restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json | |
- name: Print the Restler configuration | |
run: | | |
ls -la ${{ github.workspace }}/Compile | |
echo "" | |
echo "Engine settings:" | |
cat ${{ github.workspace }}/Compile/engine_settings.json | |
echo "" | |
echo "Config:" | |
cat ${{ github.workspace }}/Compile/config.json | |
echo "" | |
echo "Dictionary:" | |
cat ${{ github.workspace }}/Compile/dict.json | |
- name: Save Grammar | |
id: cache-grammar-save | |
uses: actions/cache/save@v4 | |
with: | |
path: | | |
${{ github.workspace }}/Compile | |
key: ${{ steps.cache-grammar-restore.outputs.cache-primary-key }} | |
- name: Docker Compose up | |
run: | | |
docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml up --detach | |
- name: Install Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 22 | |
cache: 'yarn' | |
cache-dependency-path: ${{ github.workspace }}/speckle-server/yarn.lock | |
- name: Install dependencies | |
working-directory: ${{ github.workspace }}/speckle-server/packages/server | |
run: yarn install | |
- name: Build public packages | |
working-directory: ${{ github.workspace }}/speckle-server/packages/server | |
run: yarn build:public | |
- name: Build speckle-server | |
working-directory: ${{ github.workspace }}/speckle-server/packages/server | |
run: yarn build | |
- name: Configure speckle-server | |
working-directory: ${{ github.workspace }}/speckle-server/packages/server | |
run: | | |
cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzz-test-example .env | |
- name: Run speckle-server | |
working-directory: ${{ github.workspace }}/speckle-server/packages/server | |
timeout-minutes: 1 | |
run: | | |
yarn start & | |
until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do | |
echo "Waiting a further 3 seconds for speckle-server to start..." | |
sleep 3 | |
done | |
- name: Run RESTler coverage test | |
run: | | |
curl --head --fail http://127.0.0.1:3000/readiness | |
${{ github.workspace }}/bin/restler/Restler test \ | |
--grammar_file "${{ github.workspace }}/Compile/grammar.py" \ | |
--dictionary_file "${{ github.workspace }}/Compile/dict.json" \ | |
--settings "${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json" \ | |
--no_ssl \ | |
--target_ip "127.0.0.1" \ | |
--target_port "3000" | |
- name: Print the results | |
if: always() | |
run: | | |
ls -la ${{ github.workspace }}/Test | |
echo "" | |
echo "############################################" | |
echo "# Engine stderr #" | |
echo "############################################" | |
echo "" | |
cat ${{ github.workspace }}/Test/EngineStdErr.txt || true | |
echo "" | |
echo "############################################" | |
echo "# Engine stdout #" | |
echo "############################################" | |
echo "" | |
cat ${{ github.workspace }}/Test/EngineStdOut.txt || true | |
echo "" | |
echo "############################################" | |
echo "# Results analyzer stderr #" | |
echo "############################################" | |
echo "" | |
cat ${{ github.workspace }}/Test/ResultsAnalyzerStdErr.txt || true | |
echo "" | |
echo "############################################" | |
echo "# Results analyzer stdout #" | |
echo "############################################" | |
echo "" | |
cat ${{ github.workspace }}/Test/ResultsAnalyzerStdOut.txt || true | |
echo "" | |
echo "############################################" | |
echo "# Coverage failures to investigate #" | |
echo "############################################" | |
echo "" | |
cat ${{ github.workspace }}/Test/coverage_failures_to_investigate.txt || true | |
echo "" | |
echo "############################################" | |
echo "# Restler logs #" | |
echo "############################################" | |
echo "" | |
cat ${{ github.workspace }}/Test/restler-*.log || true | |
echo "" | |
echo "############################################" | |
echo "# Coverage report #" | |
echo "############################################" | |
echo "" | |
cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" || true | |
echo "" | |
echo "############################################" | |
echo "# Network testing logs #" | |
echo "############################################" | |
echo "" | |
cat "$(find ${{ github.workspace }}/Test -type f -name "network.testing.*.txt")" || true | |
- name: Print Docker Compose logs | |
if: always() | |
run: | | |
docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml logs |