6464 default : 120
6565 type : string
6666 description : test case execution timeout period,default:120 minutes
67+ aop_single_enabled :
68+ required : false
69+ type : boolean
70+ default : false
71+ description : enable AOP hooks (capture / classify / skip-or-process)
6772 secrets :
6873 OBS_ACCESS_KEY_ID :
6974 required : false
@@ -220,6 +225,7 @@ jobs:
220225 fi
221226
222227 - name: Run Pytest (py-driven)
228+ id: pytest-driven
223229 if: ${{ inputs.tests != '' }}
224230 env:
225231 VLLM_WORKER_MULTIPROC_METHOD: spawn
@@ -229,10 +235,14 @@ jobs:
229235 run: |
230236 export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
231237 echo "Running pytest with tests path: ${{ inputs.tests }}"
238+ mkdir -p /tmp/test-logs
239+ set -o pipefail
232240 pytest -sv "${{ inputs.tests }}" \
233- --ignore=tests/e2e/nightly/single_node/ops/singlecard_ops/test_fused_moe.py
241+ --ignore=tests/e2e/nightly/single_node/ops/singlecard_ops/test_fused_moe.py \
242+ 2>&1 | tee /tmp/test-logs/pytest-driven.log
234243
235244 - name: Run Pytest (YAML-driven)
245+ id: yaml-test
236246 if: ${{ always() && inputs.config_file_path != '' }}
237247 env:
238248 VLLM_WORKER_MULTIPROC_METHOD: spawn
@@ -246,7 +256,125 @@ jobs:
246256 export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
247257 echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib" >> ~/.bashrc
248258 echo "Running YAML-driven test with config: ${{ inputs.config_file_path }}"
249- pytest -sv tests/e2e/nightly/single_node/models/scripts/test_single_node.py
259+ mkdir -p /tmp/test-logs
260+ set -o pipefail
261+ pytest -sv tests/e2e/nightly/single_node/models/scripts/test_single_node.py \
262+ 2>&1 | tee /tmp/test-logs/yaml-test.log
263+
264+ - name: Update good_table.csv on success
265+ if: >-
266+ ${{ always() &&
267+ (steps.pytest-driven.outcome == 'success' || steps.pytest-driven.outcome == 'skipped') &&
268+ (steps.yaml-test.outcome == 'success' || steps.yaml-test.outcome == 'skipped') &&
269+ (steps.pytest-driven.outcome == 'success' || steps.yaml-test.outcome == 'success') }}
270+ working-directory: /vllm-workspace/vllm-ascend
271+ env:
272+ TEST_NAME: ${{ inputs.name || inputs.config_file_path || inputs.tests }}
273+ TEST_PATH: ${{ inputs.config_file_path || inputs.tests }}
274+ CONFIG_BASE_PATH: ${{ inputs.config_base_path }}
275+ RUN_LINK: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
276+ VLLM_ASCEND_VERSION: ${{ env.VLLM_ASCEND_VERSION }}
277+ run: |
278+ python3 tests/e2e/nightly/scripts/update_good_table.py \
279+ --cache-csv "/root/.cache/vllm-ascend/${{ inputs.vllm_ascend_branch }}/nightly/good_table.csv" \
280+ --test-name "$TEST_NAME" \
281+ --test-path "$TEST_PATH" \
282+ --config-base-path "$CONFIG_BASE_PATH" \
283+ --run-link "$RUN_LINK" \
284+ --vllm-dir "/vllm-workspace/vllm" \
285+ --vllm-ascend-dir "/vllm-workspace/vllm-ascend" \
286+ --vllm-ascend-version "$VLLM_ASCEND_VERSION"
287+
288+ # ============================================
289+ # AOP hooks: intercept test results uniformly
290+ # ============================================
291+
292+ - name: Capture test result
293+ id: test-result
294+ if: ${{ always() && inputs.aop_single_enabled && (inputs.config_file_path != '' || inputs.tests != '') }}
295+ working-directory: /vllm-workspace/vllm-ascend
296+ run: |
297+ bash tests/e2e/nightly/scripts/aop_capture.sh \
298+ "${{ steps.yaml-test.outcome }}" \
299+ "${{ steps.pytest-driven.outcome }}"
300+
301+ - name: Classify failure
302+ id: classify
303+ if: ${{ always() && inputs.aop_single_enabled && steps.test-result.outputs.result == 'failure' }}
304+ working-directory: /vllm-workspace/vllm-ascend
305+ run: |
306+ bash tests/e2e/nightly/scripts/aop_classify.sh \
307+ "${{ steps.test-result.outputs.failed_test }}"
308+
309+ # ============================================================
310+ # Decision gate:
311+ # env_failure → Skip directly (no need to check age)
312+ # not_env_failure → Check commit age → old? Skip : Process
313+ # ============================================================
314+
315+ - name: Skip - env issue
316+ if: >-
317+ ${{ always() && inputs.aop_single_enabled &&
318+ steps.classify.outputs.failure_type == 'env_failure' }}
319+ working-directory: /vllm-workspace/vllm-ascend
320+ run: |
321+ bash tests/e2e/nightly/scripts/aop_skip.sh \
322+ "env_failure" "" "" "" \
323+ "${{ steps.test-result.outputs.pytest_summary }}" \
324+ "${{ steps.test-result.outputs.yaml_summary }}"
325+
326+ - name: Check commit age
327+ id: commit-age
328+ if: ${{ always() && inputs.aop_single_enabled && steps.classify.outputs.failure_type == 'not_env_failure' }}
329+ working-directory: /vllm-workspace/vllm-ascend
330+ run: |
331+ bash tests/e2e/nightly/scripts/aop_commit_age.sh \
332+ "${{ inputs.name || inputs.config_file_path || inputs.tests }}" \
333+ "/root/.cache/vllm-ascend/${{ inputs.vllm_ascend_branch }}/nightly/good_table.csv"
334+
335+ - name: Skip - old commit
336+ if: >-
337+ ${{ always() && inputs.aop_single_enabled &&
338+ steps.classify.outputs.failure_type == 'not_env_failure' &&
339+ steps.commit-age.outputs.is_old == 'true' }}
340+ working-directory: /vllm-workspace/vllm-ascend
341+ run: |
342+ bash tests/e2e/nightly/scripts/aop_skip.sh \
343+ "not_env_failure" \
344+ "${{ steps.commit-age.outputs.last_status }}" \
345+ "${{ steps.commit-age.outputs.last_date }}" \
346+ "${{ steps.commit-age.outputs.commit_age_days }}" \
347+ "${{ steps.test-result.outputs.pytest_summary }}" \
348+ "${{ steps.test-result.outputs.yaml_summary }}"
349+
350+ - name: Process - recent real failure
351+ if: >-
352+ ${{ always() && inputs.aop_single_enabled &&
353+ steps.classify.outputs.failure_type == 'not_env_failure' &&
354+ steps.commit-age.outputs.is_old == 'false' }}
355+ working-directory: /vllm-workspace/vllm-ascend
356+ env:
357+ GOOD_TABLE: /root/.cache/vllm-ascend/${{ inputs.vllm_ascend_branch }}/nightly/good_table.csv
358+ run: |
359+ bash tests/e2e/nightly/scripts/aop_process.sh \
360+ "${{ steps.classify.outputs.failure_type }}" \
361+ "${{ steps.commit-age.outputs.commit_age_days }}" \
362+ "${{ inputs.runner }}" \
363+ "${{ inputs.tests }}" \
364+ "${{ inputs.config_file_path }}" \
365+ "${{ steps.test-result.outputs.pytest_summary }}" \
366+ "${{ steps.test-result.outputs.yaml_summary }}" \
367+ "single_node" \
368+ "HEAD" \
369+ "" \
370+ "${{ inputs.name }}"
371+
372+ - name: On success
373+ if: ${{ always() && inputs.aop_single_enabled && steps.test-result.outputs.result == 'success' }}
374+ run: |
375+ echo ">>> All tests passed!"
376+
377+ # ============================================
250378
251379 - name: Set benchmark artifact timestamp
252380 if: ${{ always() && inputs.config_file_path != '' }}
0 commit comments