Skip to content

Integration Tests

Integration Tests #68

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."