AI-Stack Selenium 自動化測試

INTERNAL 安裝與測試指南 · 冷啟動 + CI/CD 功能測試 · v1 (2026-06-25)

AI-Stack Selenium 自動化測試 — 安裝與測試指南

版本:v1 (2026-06-25) · repo gitlab.infinitix.co:jefflinux/aistack-testautomation 對象:在「已安裝好的 AI-Stack」上,用 Selenium 做平台設定 + fixture 備齊 + 全覆蓋功能測試,並可串接 CI/CD。 範圍邊界:L0 安裝 + L1 平台設定(安裝後 5 步)由安裝器(ansible/install-tui)備好,不在本套件範圍;本套件從「裝好且設定好的站」開始 → check-assert L1 → 補 L2 test fixture → 功能測試。


1. 總覽

項目
套件 jefflinux/aistack-testautomation(deterministic Selenium,純 UI 驅動)
規模 69 test 檔 / 53 page object / 999 test collected(canonical;pytest tests/ == pytest 無 path 一致)。
被測站 AI-Stack v4.27.2-HA(web tier = docker-compose ai-stack-web,:8080;workload = k8s)
Runner VM80 Linux(google-chrome 149 + venv),禁本機 Windows 跑(flaky)
紀律 操控 AIS 只走 Selenium/UI;k8s/API/DB 一律 read-only

分層模型(artifact manifest):

L0 平台      = k8s + AI-Stack 已裝好          ← 安裝器(ansible/install-tui),套件只 check
L1 平台設定  = 超管/License/CloudProvider+    ← 安裝器「安裝後系統設定 5 步」/install-tui auto
              skyport/CloudRegion/Harbor         套件只 check-assert(2026-06-26 修正:非 Selenium)
L2 應用 fixture = golden01/測試專案/sel-* 規格 ← preflight ensure() 自動補(Selenium 真責任)
                 樣板/LDAP/MailHog/容器/cupy
功能測試     = 454+ QA case(opui/portal/...) ← pytest marker 分流跑
hw 物理硬體  = 單卡限制(ETHPC 多 worker≥2GPU) ← pending-hardware,標 reason 不偽造

2. 安裝(套件本身)

跑測試的機器 = VM80(已備好,通常不用重裝);以下為從零建環境的步驟。

2.1 前置

2.2 取得 + 建環境(VM80)

ssh 80
cd ~ && git clone git@gitlab.infinitix.co:jefflinux/aistack-testautomation.git
cd aistack-testautomation
python3 -m venv .venv
./.venv/bin/pip install -r requirements.txt

deps pin(requirements.txt,權威):selenium==4.27.1 / pytest==8.3.4 / pytest-html==4.1.1。 ⚠️ VM80 已有專屬 .venv;勿污染 ixCSP 的 .venv-smoke。(註:現有 VM80 venv 的 runtime 版本可能高於 pin,以 requirements.txt 為安裝基準。)

2.3 設定(config.py / 環境變數)

變數 預設 說明
BASE_URL https://10.20.12.80:8080 被測站;CI 參數化指向目標 AIS
SUPERUSER / SUPERUSER_PW superuser / P@ssw0rd123 OP UI 管理者
PORTAL_USER / PORTAL_USER_PW golden01 / P@ssw0rd123 User Portal(一般登入)
LDAP_USER / LDAP_USER_PW testuser01 / password1 User Portal(LDAP)
DEFAULT_TIMEOUT 10 元素等待秒數

3. Artifact / Fixture 安裝步驟與內容

「artifact」= 跑測試前該站必須具備的狀態(設定 / fixture)。原則:在就複用、缺就補到好、唯一非綠=實體硬體缺。落地 = preflight.py registry(manifest as data)+ conftest.pyensure(artifact) fixture(依 deps 拓樸排序,check→缺則 provision→recheck)。

3.1 preflight 狀態檢視(read-only)

ssh 80 'cd ~/aistack-testautomation && PREFLIGHT_ON_VM80=1 ./.venv/bin/python -c "import preflight; preflight.check_all()"'
# 每個 artifact 印 ok / MISSING / ?(needs WebTerminal);read-only,不改站

3.2 目前 preflight.py ARTIFACTS(實況,17 keys — 與 source 對齊)

以下是 preflight.pyARTIFACTS registry 實際 keys 與 provisioner 狀態(Codex 對齊 source 查核 2026-06-25)。✅自動=prov_ 已實作;⏳TODO=prov_ raise ProvisionTODO;手動=prov=None(缺則 RuntimeError,須手動 OpUI)。

artifact key 內容 provision 狀態
platform_up L0 AIS web 200 + k8s nodes Ready prov_installer(raise ProvisionTODO:L0 外部安裝,套件只 check) check-only(範圍外)
superuser L1 OP UI 超管可登入 prov_superuser ⏳ TODO(待建 page object;僅 fresh 站可驗)
cloudregion L1 sys_cloudregioninfo 有 region(check 僅查存在,驗 skyport/:443) prov=None 手動 OpUI
gpu_node L1/HW GPU worker node Ready prov=None 手動
mls_spec_1gpu L1 MLS 1-GPU 規格存在 prov=None 手動 OpUI
mls_template L1 MLS 樣板存在 prov=None 手動 OpUI
ixgpu_webhook L1 ixgpu-scheduler endpoint up prov=None 手動
golden01 L2 Portal 用戶 golden01 prov_golden01(seed_golden01.py 冪等) ✅ 自動
project_golden L2 專案 golden-gpu-demo prov_project ⏳ TODO
ldap_server L2 osixia/openldap 容器 prov_ldap(docker run 冪等) ✅ 自動
mailhog_sink L2 MailHog SMTP sink prov_mailhog(docker run 冪等) ✅ 自動
rcs_spec_hermes L2 GPU-off hermes-spec prov_rcs_spec_hermes(create_hermes_spec.py 冪等) ✅ 自動
hermes_image L2 Harbor hermes-agent:official-0.15.2 prov_hermes_image ⏳ TODO
container_seltestmls01 / container_seltfgpu01 / container_selgpu01 L2 MLS 容器 1/1 Running(seltfgpu01=canonical tensorflow+WebTerminal;另二為 back-compat,多讀 MISSING) prov_container(mls-creator 精靈;需 free GPU) ✅ 自動(gated on free GPU)
cupy_in_container L2 容器內裝 cupy(GPU 負載) prov_cupy ⏳ TODO(需容器 WT_URL)

3.2b L1/L2 責任分工(2026-06-26 修正:L1 是安裝器的,不是 Selenium)

🚨 修正:先前把 L1 平台設定列成「Selenium 待建 provisioner」是 scope 錯。官方 ansible installer「安裝後系統設定 5 步」+ install-tui auto 就是 L1 owner;Selenium 不重做,只 check-assert。

L1 = 安裝器責任(ansible 安裝後 5 步 / install-tui auto)— Selenium 只 check-assert,不 provision:

L1 項目 安裝器來源
超管建立 ansible 安裝後 step1(/operation/super-admin-creating)/ install-tui auto
License 上傳 ansible 安裝後 step2
CloudProvider + skyport key + :6443 測試 ansible 安裝後 step3(skyport key 來自 cluster-21)
CloudRegion + serviceTypes ansible 安裝後 step4
Harbor Registry ansible 安裝後 step5 + cluster-10
gpu_node / ixgpu_webhook ansible cluster-13/14/15/20/21/22(infra)

L2 = Selenium/preflight 真要 provision 的 test fixture:

L2 fixture 狀態 可在 VM80 開發?
golden01 用戶 / LDAP / MailHog / rcs_spec_hermes ✅ 已自動
project_golden(測試專案) ⏳ TODO
測試專用 spec/template(sel-mls-1gpu/frac4、tensorflow+WebTerminal) ⏳ 待建(有 script 雛形)
auto-approve(測試前置開啟) ⏳ 待建
測試容器 / cupy container ✅自動 / cupy ⏳TODO
hermes_image / harbor 測試鏡像 ⏳(infra docker push,非 UI)

所以 Selenium 的 P0 真正範圍只有上面 L2 那幾項(比原以為小很多);L1 缺 = 安裝器 5 步沒做完,走安裝器補,不是 Selenium 的事。

3.3 ensure 用法(測試內自動備齊前置)

# conftest 提供 ensure fixture;測試宣告依賴 → 自動 check→provision→recheck
def test_xxx(ensure, ...):
    ensure("container_seltfgpu01")   # 解 deps: project_golden→mls_template→spec→gpu_node→container
ssh 80 'sudo docker login 10.20.12.80:18080 -u admin -p Harbor12345 && \
  sudo docker pull <img> && sudo docker tag <img> 10.20.12.80:18080/library/<name>:<tag> && \
  sudo docker push 10.20.12.80:18080/library/<name>:<tag>'
# MLS/RCS 鏡像 picker 直讀 Harbor library/*(免 import-tool)

4. 測試執行步驟

4.1 Marker 分流(CI stage 對應)

pytest.ini 註冊 marker(實況 14 個):smoke login hermes opui portal v428gated batch3 gpu_load container_create rcs_deploy ethpc_cluster gpu_frac_verify gpu_shared_create gpu_mode_switch

marker 內容 CI stage
smoke 最小 gate(超管+golden01 登入) Stage 1(每 commit,<3min)
login 登入流程(op + portal + LDAP) Stage 1
opui / portal OP UI / User Portal 功能(非破壞) Stage 2(每 commit,~30min)
batch3 容器詳情功能深測(F-038~F-056) Stage 2
hermes hermes-webui app 測試 Stage 2/3
container_create / rcs_deploy / gpu_load / gpu_frac_verify / gpu_shared_create / gpu_mode_switch / ethpc_cluster opt-in DESTRUCTIVE(建容器/部署/GPU 負載/模式切換) Stage 3(nightly)
v428gated v4.28 限定 feature(4.27.2-HA 跳過) 版本相關

4.2 單檔 / 子集(前景,短)

ssh 80 'cd ~/aistack-testautomation && git pull -q && \
  BASE_URL=https://localhost:8080 ./.venv/bin/python -m pytest tests/<file>.py -o addopts="" -q'

4.3 Smoke gate

ssh 80 'cd ~/aistack-testautomation && BASE_URL=https://localhost:8080 ./.venv/bin/python -m pytest -m smoke -o addopts="" -q'
# 期望 1 passed,exit 0

4.4 全 suite(chunked,避 Chrome ~350-launch 天花板)

ssh 80 'cd ~/aistack-testautomation && bash scripts/run_full_suite_chunked.sh'
# file-by-file fresh process + 每檔 junit → scripts/aggregate_junit.py 聚合

-o addopts="" 清掉 pytest.ini 預設的 --junitxml=results.xml --html=report.html,避免並行搶檔。

4.5 收尾 cleanup(mutation 測必跑,四件套)

1. 刪測試容器(走 UI / kubectl delete pod)
2. deadletter = 0(SELECT count act_ru_deadletter_job)
3. ACL state reset(test 容器 → OWNER_ONLY)
4. hash_mapping 清(無孤兒)

5. CI/CD pipeline(5 stage)

Stage 0 PROVISION (慢/nightly) : 安裝器裝 L0+L1(ansible/install-tui)→ Selenium check-assert L1 + 補 L2 fixture
Stage 1 SMOKE     (每 commit)   : -m smoke(登入 gate),紅即 fail
Stage 2 FUNCTIONAL-READONLY     : -m "opui or portal"(非破壞)+ chunked
Stage 3 FUNCTIONAL-MUTATION     : opt-in destructive + cleanup 四件套(nightly)
Stage 4 REPORT + GATE           : aggregate_junit → 綠判準

綠判準(accounted-for,非 100% green):0 fail + 每個 skip 都有分類 reason(pending-hardware / pending-fixture / opt-in-not-selected / v428gated),無 unexplained skip。


6. 已知限制 / 邊界


7. 參考

INFINITIX 內部文件 · 由 aistack-selenium-install-test-guide.md 生成 · 操控 AIS 只走 UI/k8s·DB read-only