Integration Tests #68
This file contains hidden or 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: Integration Tests | |
| on: | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| schedule: | |
| - cron: "0 18 * * *" | |
| jobs: | |
| pr-lightweight: | |
| if: github.event_name == 'pull_request' | |
| runs-on: macos-14 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.21" | |
| cache-dependency-path: dpi_bridge/go.sum | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Check DM secrets availability | |
| id: dm_ready | |
| run: | | |
| if [ -n "${{ secrets.DM_TEST_HOST }}" ] && [ -n "${{ secrets.DM_TEST_PORT }}" ] && [ -n "${{ secrets.DM_TEST_USER }}" ] && [ -n "${{ secrets.DM_TEST_PASSWORD }}" ]; then | |
| echo "available=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "available=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Decode DPI headers | |
| if: steps.dm_ready.outputs.available == 'true' | |
| env: | |
| DPI_HEADERS_TAR_B64: ${{ secrets.DPI_HEADERS_TAR_B64 }} | |
| run: | | |
| mkdir -p dpi_include | |
| echo "$DPI_HEADERS_TAR_B64" | base64 -d | tar xzf - -C dpi_include/ | |
| - name: Build Go bridge library | |
| if: steps.dm_ready.outputs.available == 'true' | |
| run: | | |
| cd dpi_bridge && go build -buildmode=c-shared -o libdmdpi.dylib . | |
| install_name_tool -id @rpath/libdmdpi.dylib libdmdpi.dylib | |
| - name: Build extension and run P0/P1 | |
| if: steps.dm_ready.outputs.available == 'true' | |
| env: | |
| DYLD_LIBRARY_PATH: ${{ github.workspace }}/dpi_bridge | |
| DM_TEST_HOST: ${{ secrets.DM_TEST_HOST }} | |
| DM_TEST_PORT: ${{ secrets.DM_TEST_PORT }} | |
| DM_TEST_USER: ${{ secrets.DM_TEST_USER }} | |
| DM_TEST_PASSWORD: ${{ secrets.DM_TEST_PASSWORD }} | |
| DM_TEST_BOUNDARY_SIZES: ${{ secrets.DM_TEST_BOUNDARY_SIZES }} | |
| run: | | |
| python -m pip install pytest pytest-timeout pytest-cov | |
| python setup.py build_ext --inplace | |
| python -m pytest -q tests/integration -m "p0_stability or p1_contract" --junitxml=pytest-pr.xml --cov=. --cov-report=term-missing --cov-report=xml:coverage.xml | |
| - name: Upload coverage report (PR) | |
| if: steps.dm_ready.outputs.available == 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-pr | |
| path: | | |
| coverage.xml | |
| pytest-pr.xml | |
| - name: Skip lightweight integration tests | |
| if: steps.dm_ready.outputs.available != 'true' | |
| run: | | |
| echo "::notice::SKIP_DM_INTEGRATION: PR integration tests are skipped because DM secrets are not configured." | |
| full-regression: | |
| if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' | |
| runs-on: macos-14 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.21" | |
| cache-dependency-path: dpi_bridge/go.sum | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Check DM secrets availability | |
| id: dm_ready | |
| run: | | |
| if [ -n "${{ secrets.DM_TEST_HOST }}" ] && [ -n "${{ secrets.DM_TEST_PORT }}" ] && [ -n "${{ secrets.DM_TEST_USER }}" ] && [ -n "${{ secrets.DM_TEST_PASSWORD }}" ]; then | |
| echo "available=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "available=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Decode DPI headers | |
| if: steps.dm_ready.outputs.available == 'true' | |
| env: | |
| DPI_HEADERS_TAR_B64: ${{ secrets.DPI_HEADERS_TAR_B64 }} | |
| run: | | |
| mkdir -p dpi_include | |
| echo "$DPI_HEADERS_TAR_B64" | base64 -d | tar xzf - -C dpi_include/ | |
| - name: Build Go bridge library | |
| if: steps.dm_ready.outputs.available == 'true' | |
| run: | | |
| cd dpi_bridge && go build -buildmode=c-shared -o libdmdpi.dylib . | |
| install_name_tool -id @rpath/libdmdpi.dylib libdmdpi.dylib | |
| - name: Build extension and run P0/P1/P2 | |
| if: steps.dm_ready.outputs.available == 'true' | |
| env: | |
| DYLD_LIBRARY_PATH: ${{ github.workspace }}/dpi_bridge | |
| DM_TEST_HOST: ${{ secrets.DM_TEST_HOST }} | |
| DM_TEST_PORT: ${{ secrets.DM_TEST_PORT }} | |
| DM_TEST_USER: ${{ secrets.DM_TEST_USER }} | |
| DM_TEST_PASSWORD: ${{ secrets.DM_TEST_PASSWORD }} | |
| DM_TEST_BOUNDARY_SIZES: ${{ secrets.DM_TEST_BOUNDARY_SIZES }} | |
| DM_TEST_STRESS_ROWS: ${{ secrets.DM_TEST_STRESS_ROWS }} | |
| DM_TEST_STRESS_WORKERS: ${{ secrets.DM_TEST_STRESS_WORKERS }} | |
| DM_TEST_CHURN_LOOPS: ${{ secrets.DM_TEST_CHURN_LOOPS }} | |
| DM_TEST_GC_LOOPS: ${{ secrets.DM_TEST_GC_LOOPS }} | |
| run: | | |
| python -m pip install pytest pytest-timeout pytest-cov | |
| python setup.py build_ext --inplace | |
| start_ts=$(date +%s) | |
| python -m pytest -q tests/integration -m "p0_stability or p1_contract or p2_scale" --junitxml=pytest-full.xml --cov=. --cov-report=term-missing --cov-report=xml:coverage.xml | |
| end_ts=$(date +%s) | |
| duration=$((end_ts - start_ts)) | |
| python - <<PY | |
| import json | |
| import xml.etree.ElementTree as ET | |
| root = ET.parse("pytest-full.xml").getroot() | |
| attrs = root.attrib | |
| trend = { | |
| "tests": int(float(attrs.get("tests", "0"))), | |
| "failures": int(float(attrs.get("failures", "0"))), | |
| "errors": int(float(attrs.get("errors", "0"))), | |
| "skipped": int(float(attrs.get("skipped", "0"))), | |
| "pytest_reported_seconds": float(attrs.get("time", "0")), | |
| "wall_clock_seconds": int(${duration}), | |
| } | |
| with open("trend-full-regression.json", "w", encoding="utf-8") as f: | |
| json.dump(trend, f, indent=2, ensure_ascii=False) | |
| print(trend) | |
| PY | |
| - name: Upload coverage report (full) | |
| if: steps.dm_ready.outputs.available == 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-full | |
| path: | | |
| coverage.xml | |
| pytest-full.xml | |
| trend-full-regression.json | |
| - name: Skip full integration tests | |
| if: steps.dm_ready.outputs.available != 'true' | |
| run: | | |
| echo "::notice::SKIP_DM_INTEGRATION: Full regression is skipped because DM secrets are not configured." |