|
|
@@ -168,6 +168,16 @@ for k, v in cur.items():
|
|
|
elif pcat == 'BIZ_OK' and cat != 'BIZ_OK':
|
|
|
regressed.append((k, pcat, cat))
|
|
|
|
|
|
+# CONN_ERR 参与的翻转不算真实修复/劣化:CONN_ERR 是连接中断/超时,
|
|
|
+# 长耗时 AI 接口(如 portrait 族)本身耗时在数秒到数十秒间抖动,会骑在客户端
|
|
|
+# 超时阈值上反复翻转,同一接口每轮 fix/reg 互换但后端实际一直是 200。
|
|
|
+# 故单列 flaky 计数,并在报告与 commit message 中标注,避免被误读成业绩/劣化。
|
|
|
+flaky_fix = [x for x in fixed if x[1] == 'CONN_ERR']
|
|
|
+flaky_reg = [x for x in regressed if x[2] == 'CONN_ERR']
|
|
|
+flaky_note = ''
|
|
|
+if flaky_fix or flaky_reg:
|
|
|
+ flaky_note = f"(其中 CONN_ERR 翻转 fix={len(flaky_fix)}/reg={len(flaky_reg)} 属口径抖动,非真实修复/劣化)"
|
|
|
+
|
|
|
def top(cat, n=20):
|
|
|
return [(k[0], k[1], v[3], v[4]) for k, v in cur.items() if v[4] == cat][:n]
|
|
|
|
|
|
@@ -182,12 +192,17 @@ lines.append("")
|
|
|
if fixed:
|
|
|
lines.append(f"## ✅ 回归修复({len(fixed)} 个,之前失败现已通过)")
|
|
|
for (m,p),pc,_ in fixed[:30]:
|
|
|
- lines.append(f"- `{m} {p}` (原 {pc})")
|
|
|
+ _tag = ' ← CONN_ERR 恢复,疑为口径抖动而非真实修复,需直连复核' if pc == 'CONN_ERR' else ''
|
|
|
+ lines.append(f"- `{m} {p}` (原 {pc}){_tag}")
|
|
|
lines.append("")
|
|
|
if regressed:
|
|
|
lines.append(f"## ⚠️ 回归劣化({len(regressed)} 个,之前通过现失败)")
|
|
|
for (m,p),_,c in regressed[:30]:
|
|
|
- lines.append(f"- `{m} {p}` (现 {c})")
|
|
|
+ _tag = ' ← CONN_ERR(连接中断/超时),多为耗时抖动,需直连复核再判劣化' if c == 'CONN_ERR' else ''
|
|
|
+ lines.append(f"- `{m} {p}` (现 {c}){_tag}")
|
|
|
+ lines.append("")
|
|
|
+if flaky_note:
|
|
|
+ lines.append(f"> {flaky_note}")
|
|
|
lines.append("")
|
|
|
lines.append(f"## 需开发团队关注的契约缺口 (NOT_FOUND={cats.get('NOT_FOUND',0)})")
|
|
|
for m,p,b,c in top('NOT_FOUND'):
|
|
|
@@ -263,6 +278,7 @@ with open(trend, 'a', encoding='utf-8') as f:
|
|
|
_metrics_path = os.path.join(os.path.dirname(trend), 'interface_test_metrics.env')
|
|
|
with open(_metrics_path, 'w', encoding='utf-8') as _mf:
|
|
|
_mf.write(f"RATE={rate}\nFIXED_COUNT={len(fixed)}\nREGRESSED_COUNT={len(regressed)}\n"
|
|
|
+ f"FLAKY_FIX_COUNT={len(flaky_fix)}\nFLAKY_REG_COUNT={len(flaky_reg)}\n"
|
|
|
f"TOTAL={total}\nOK_COUNT={ok}\nNON_JSON_COUNT={non_json}\n"
|
|
|
f"SERVER_ERR_COUNT={server_err}\nCONN_ERR_COUNT={conn_err}\n"
|
|
|
f"HTTP_502_COUNT={http_502}\nINVALID={1 if INVALID else 0}\n"
|
|
|
@@ -508,9 +524,16 @@ fi
|
|
|
# 不提交、不推送、不更新回归基线,避免污染趋势与开发侧闭环
|
|
|
# ---------------------------------------------------------------------------
|
|
|
INVALID=0; INVALID_REASON=""
|
|
|
-RATE="?"; FIXED_COUNT=0; REGRESSED_COUNT=0
|
|
|
+RATE="?"; FIXED_COUNT=0; REGRESSED_COUNT=0; FLAKY_FIX_COUNT=0; FLAKY_REG_COUNT=0
|
|
|
METRICS_ENV="$REPO_DIR/interface_test_metrics.env"
|
|
|
[ -f "$METRICS_ENV" ] && . "$METRICS_ENV"
|
|
|
+# CONN_ERR 参与的翻转标 flaky:该类别是连接中断/超时,长耗时 AI 接口会骑在客户端
|
|
|
+# 超时阈值上反复翻转(后端实际一直 200),写进 commit 标题需显式区分,避免 fix/reg
|
|
|
+# 被当成真实业绩或真实劣化。
|
|
|
+FLAKY_TAG=""
|
|
|
+if [ "${FLAKY_FIX_COUNT:-0}" -gt 0 ] || [ "${FLAKY_REG_COUNT:-0}" -gt 0 ]; then
|
|
|
+ FLAKY_TAG=" [CONN_ERR翻转标flaky: fix=${FLAKY_FIX_COUNT:-0} reg=${FLAKY_REG_COUNT:-0}]"
|
|
|
+fi
|
|
|
if [ "${INVALID:-0}" -eq 1 ]; then
|
|
|
log "⚠️ 守卫触发 INVALID:本轮结果不提交 / 不推送 / 不更新回归基线"
|
|
|
log " 原因: ${INVALID_REASON}"
|
|
|
@@ -571,7 +594,7 @@ if git diff --cached --quiet; then
|
|
|
log "无测试结果变更,跳过提交"
|
|
|
COMMIT_OK=2
|
|
|
else
|
|
|
- if git commit -m "test(interface): 接口冒烟闭环 $(date '+%Y-%m-%d %H:%M') — 通过率 ${RATE}% (fix=${FIXED_COUNT} reg=${REGRESSED_COUNT}); 测试用例 ${TC_DONE:-?}/${TC_E2E_TOTAL:-?} 完成(文档化${TC_DOC:-?})" \
|
|
|
+ if git commit -m "test(interface): 接口冒烟闭环 $(date '+%Y-%m-%d %H:%M') — 通过率 ${RATE}% (fix=${FIXED_COUNT} reg=${REGRESSED_COUNT})${FLAKY_TAG}; 测试用例 ${TC_DONE:-?}/${TC_E2E_TOTAL:-?} 完成(文档化${TC_DOC:-?})" \
|
|
|
>>"$LOG_DIR/interface_cron.log" 2>&1; then
|
|
|
HEAD_AFTER=$(git rev-parse HEAD)
|
|
|
if [ "$HEAD_BEFORE" = "$HEAD_AFTER" ]; then
|