Skip to content

ci(tests): fuzz testing workflow for REST API #25

ci(tests): fuzz testing workflow for REST API

ci(tests): fuzz testing workflow for REST API #25

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
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
- name: Print Docker Compose logs
if: always()
run: |
docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml logs