Skip to content

Commit 47bd5e1

Browse files
authored
Fixed slack notification and parallel lvol case (#909)
* Adding e2e yaml and data nic param * Test: Fixing snapshot deleting uuid column * Testing: Fixing e2e tests * Testing: Fixing e2e yaml summary and adding e2e only * Testing: Fixing e2e yaml summary and adding e2e only * Testing: Fixing e2e yaml summary and adding e2e only * Adding test fixes * Adding test fixes * Adding a scheduler * Fixing deletes for lvol based on count * Fixing deletes for lvol based on count * Fixing notification and parallel lvol deletes * Parallel lvol delete clone delete * Parallel lvol delete clone delete
1 parent a8d37bb commit 47bd5e1

File tree

4 files changed

+460
-145
lines changed

4 files changed

+460
-145
lines changed

.github/workflows/e2e-bootstrap.yml

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,6 @@ jobs:
703703
--ndcs "${NDCS}" \
704704
--npcs "${NPCS}" \
705705
--run_ha true \
706-
--send_debug_notification false \
707706
2>&1 | tee output.log
708707
709708
- name: Mark test end time (always)
@@ -1125,46 +1124,84 @@ jobs:
11251124
SLACK_RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
11261125
GITHUB_REF_NAME: ${{ github.ref_name }}
11271126
SLACK_WF_NAME: "E2E (Bootstrap)"
1127+
SBCLI_BRANCH: ${{ env.SBCLI_BRANCH }}
1128+
SIMPLY_BLOCK_SPDK_ULTRA_IMAGE: ${{ env.SIMPLY_BLOCK_SPDK_ULTRA_IMAGE }}
11281129
run: |
11291130
python3 - <<'PYEOF'
11301131
import json, os, re, sys, urllib.request, urllib.error
1132+
11311133
webhook = os.environ.get("SLACK_WEBHOOK_URL", "")
11321134
if not webhook:
11331135
print("No SLACK_WEBHOOK_URL set, skipping.")
11341136
sys.exit(0)
1137+
11351138
out_log = "sbcli/e2e/output.log"
1136-
total = passed = failed = skipped = 0
1137-
if os.path.isfile(out_log):
1138-
content = open(out_log).read()
1139-
def px(pat):
1140-
m = re.search(pat, content)
1141-
return int(m.group(1)) if m else 0
1142-
total = px(r'Number of Total Cases:\s*(\d+)')
1143-
passed = px(r'Number of Passed Cases:\s*(\d+)')
1144-
failed = px(r'Number of Failed Cases:\s*(\d+)')
1145-
skipped = px(r'Number of Skipped Cases:\s*(\d+)')
1139+
content = open(out_log).read() if os.path.isfile(out_log) else ""
1140+
1141+
# --- Counts ---
1142+
def px(pat):
1143+
m = re.search(pat, content)
1144+
return int(m.group(1)) if m else 0
1145+
total = px(r'Number of Total Cases:\s*(\d+)')
1146+
passed = px(r'Number of Passed Cases:\s*(\d+)')
1147+
failed = px(r'Number of Failed Cases:\s*(\d+)')
1148+
skipped = px(r'Number of Skipped Cases:\s*(\d+)')
11461149
pass_pct = (passed * 100 // total) if total > 0 else 0
1150+
1151+
# --- Per-test results ---
1152+
ansi = re.compile(r'\x1b\[[0-9;]*m')
1153+
test_results = [] # list of (status, name)
1154+
for line in content.splitlines():
1155+
clean = ansi.sub('', line)
1156+
if not re.search(r'(PASSED|FAILED|SKIPPED) CASE', clean):
1157+
continue
1158+
m = re.search(r'Test[A-Za-z0-9_]+', clean)
1159+
if not m:
1160+
continue
1161+
name = m.group(0)
1162+
if 'PASSED CASE' in clean: test_results.append(('PASSED', name))
1163+
elif 'FAILED CASE' in clean: test_results.append(('FAILED', name))
1164+
elif 'SKIPPED CASE' in clean: test_results.append(('SKIPPED', name))
1165+
1166+
# --- Failure reason ---
1167+
failure_reason = ""
1168+
multi = [ansi.sub('', l) for l in content.splitlines() if 'MultipleExceptions:' in l]
1169+
if multi:
1170+
failure_reason = multi[0][:600]
1171+
elif content:
1172+
exc_lines = [ansi.sub('', l) for l in content.splitlines()
1173+
if re.search(r'(Exception:|AssertionError|Input/output error)', l)]
1174+
if exc_lines:
1175+
failure_reason = '\n'.join(exc_lines[-3:])[:600]
1176+
1177+
# --- Env ---
11471178
s = int(os.environ.get("TEST_START_EPOCH", "0") or "0")
11481179
e = int(os.environ.get("TEST_END_EPOCH", "0") or "0")
11491180
secs = max(0, e - s) if e >= s > 0 else 0
11501181
dur = f"{secs//3600}h {(secs%3600)//60}m {secs%60}s"
1151-
run_url = os.environ.get("SLACK_RUN_URL", "")
1152-
log_dir = os.environ.get("RUN_BASE_DIR", "N/A")
1153-
ndcs = os.environ.get("NDCS", "?")
1154-
npcs = os.environ.get("NPCS", "?")
1155-
test_cls = os.environ.get("TEST_CLASS", "") or "all"
1156-
branch = os.environ.get("GITHUB_REF_NAME", "?")
1157-
wf_name = os.environ.get("SLACK_WF_NAME", "Run")
1158-
ok = os.environ.get("JOB_STATUS", "") == "success"
1182+
run_url = os.environ.get("SLACK_RUN_URL", "")
1183+
log_dir = os.environ.get("RUN_BASE_DIR", "N/A")
1184+
ndcs = os.environ.get("NDCS", "?")
1185+
npcs = os.environ.get("NPCS", "?")
1186+
test_cls = os.environ.get("TEST_CLASS", "") or "all"
1187+
branch = os.environ.get("GITHUB_REF_NAME", "?")
1188+
sbcli_branch= os.environ.get("SBCLI_BRANCH", "?")
1189+
spdk_image = os.environ.get("SIMPLY_BLOCK_SPDK_ULTRA_IMAGE", "")
1190+
wf_name = os.environ.get("SLACK_WF_NAME", "Run")
1191+
ok = os.environ.get("JOB_STATUS", "") == "success"
1192+
11591193
icon = ":white_check_mark:" if ok else ":x:"
11601194
status = "SUCCESS" if ok else "FAILURE"
11611195
mention = "" if ok else " <!channel>"
1196+
11621197
lines = [
11631198
f"{icon} *SimplyBlock {wf_name}*{mention}",
11641199
f"*Status:* {status} | *Duration:* {dur}",
11651200
f"*Branch:* `{branch}` | *NDCS/NPCS:* `{ndcs}/{npcs}` | *Test class:* `{test_cls}`",
1201+
f"*SBCLI Branch:* `{sbcli_branch}`" + (f" | *SPDK Image:* `{spdk_image}`" if spdk_image else ""),
11661202
"",
11671203
]
1204+
11681205
if total > 0:
11691206
lines += [
11701207
f":white_check_mark: *Passed:* {passed}/{total} ({pass_pct}%)",
@@ -1173,11 +1210,23 @@ jobs:
11731210
]
11741211
else:
11751212
lines.append("_(test counts not found in log)_")
1213+
1214+
if test_results:
1215+
lines.append("")
1216+
lines.append("*Test Results:*")
1217+
icons = {'PASSED': ':white_check_mark:', 'FAILED': ':x:', 'SKIPPED': ':fast_forward:'}
1218+
for st, nm in test_results:
1219+
lines.append(f"{icons.get(st, ':grey_question:')} `{nm}`")
1220+
1221+
if failure_reason:
1222+
lines += ["", "*Failure:*", f"```{failure_reason}```"]
1223+
11761224
lines += [
11771225
"",
11781226
f":link: *Run:* <{run_url}|View on GitHub>",
11791227
f":file_folder: *Final Logs:* `{log_dir}`",
11801228
]
1229+
11811230
payload = {"text": "\n".join(lines)}
11821231
req = urllib.request.Request(
11831232
webhook,

.github/workflows/e2e-only.yml

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ jobs:
366366
"${TESTNAME_ARGS[@]}" \
367367
--ndcs "${NDCS}" \
368368
--npcs "${NPCS}" \
369-
--send_debug_notification false \
370369
2>&1 | tee output.log
371370
372371
- name: Mark test end time (always)
@@ -788,46 +787,82 @@ jobs:
788787
SLACK_RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
789788
GITHUB_REF_NAME: ${{ github.ref_name }}
790789
SLACK_WF_NAME: "E2E (No Bootstrap)"
790+
SBCLI_BRANCH: ${{ env.SBCLI_BRANCH }}
791791
run: |
792792
python3 - <<'PYEOF'
793793
import json, os, re, sys, urllib.request, urllib.error
794+
794795
webhook = os.environ.get("SLACK_WEBHOOK_URL", "")
795796
if not webhook:
796797
print("No SLACK_WEBHOOK_URL set, skipping.")
797798
sys.exit(0)
799+
798800
out_log = "sbcli/e2e/output.log"
799-
total = passed = failed = skipped = 0
800-
if os.path.isfile(out_log):
801-
content = open(out_log).read()
802-
def px(pat):
803-
m = re.search(pat, content)
804-
return int(m.group(1)) if m else 0
805-
total = px(r'Number of Total Cases:\s*(\d+)')
806-
passed = px(r'Number of Passed Cases:\s*(\d+)')
807-
failed = px(r'Number of Failed Cases:\s*(\d+)')
808-
skipped = px(r'Number of Skipped Cases:\s*(\d+)')
801+
content = open(out_log).read() if os.path.isfile(out_log) else ""
802+
803+
# --- Counts ---
804+
def px(pat):
805+
m = re.search(pat, content)
806+
return int(m.group(1)) if m else 0
807+
total = px(r'Number of Total Cases:\s*(\d+)')
808+
passed = px(r'Number of Passed Cases:\s*(\d+)')
809+
failed = px(r'Number of Failed Cases:\s*(\d+)')
810+
skipped = px(r'Number of Skipped Cases:\s*(\d+)')
809811
pass_pct = (passed * 100 // total) if total > 0 else 0
812+
813+
# --- Per-test results ---
814+
ansi = re.compile(r'\x1b\[[0-9;]*m')
815+
test_results = [] # list of (status, name)
816+
for line in content.splitlines():
817+
clean = ansi.sub('', line)
818+
if not re.search(r'(PASSED|FAILED|SKIPPED) CASE', clean):
819+
continue
820+
m = re.search(r'Test[A-Za-z0-9_]+', clean)
821+
if not m:
822+
continue
823+
name = m.group(0)
824+
if 'PASSED CASE' in clean: test_results.append(('PASSED', name))
825+
elif 'FAILED CASE' in clean: test_results.append(('FAILED', name))
826+
elif 'SKIPPED CASE' in clean: test_results.append(('SKIPPED', name))
827+
828+
# --- Failure reason ---
829+
failure_reason = ""
830+
multi = [ansi.sub('', l) for l in content.splitlines() if 'MultipleExceptions:' in l]
831+
if multi:
832+
failure_reason = multi[0][:600]
833+
elif content:
834+
exc_lines = [ansi.sub('', l) for l in content.splitlines()
835+
if re.search(r'(Exception:|AssertionError|Input/output error)', l)]
836+
if exc_lines:
837+
failure_reason = '\n'.join(exc_lines[-3:])[:600]
838+
839+
# --- Env ---
810840
s = int(os.environ.get("TEST_START_EPOCH", "0") or "0")
811841
e = int(os.environ.get("TEST_END_EPOCH", "0") or "0")
812842
secs = max(0, e - s) if e >= s > 0 else 0
813843
dur = f"{secs//3600}h {(secs%3600)//60}m {secs%60}s"
814-
run_url = os.environ.get("SLACK_RUN_URL", "")
815-
log_dir = os.environ.get("RUN_BASE_DIR", "N/A")
816-
ndcs = os.environ.get("NDCS", "?")
817-
npcs = os.environ.get("NPCS", "?")
818-
test_cls = os.environ.get("TEST_CLASS", "") or "all"
819-
branch = os.environ.get("GITHUB_REF_NAME", "?")
820-
wf_name = os.environ.get("SLACK_WF_NAME", "Run")
821-
ok = os.environ.get("JOB_STATUS", "") == "success"
844+
run_url = os.environ.get("SLACK_RUN_URL", "")
845+
log_dir = os.environ.get("RUN_BASE_DIR", "N/A")
846+
ndcs = os.environ.get("NDCS", "?")
847+
npcs = os.environ.get("NPCS", "?")
848+
test_cls = os.environ.get("TEST_CLASS", "") or "all"
849+
branch = os.environ.get("GITHUB_REF_NAME", "?")
850+
sbcli_branch= os.environ.get("SBCLI_BRANCH", "?")
851+
wf_name = os.environ.get("SLACK_WF_NAME", "Run")
852+
ok = os.environ.get("JOB_STATUS", "") == "success"
853+
822854
icon = ":white_check_mark:" if ok else ":x:"
823855
status = "SUCCESS" if ok else "FAILURE"
824856
mention = "" if ok else " <!channel>"
857+
825858
lines = [
826859
f"{icon} *SimplyBlock {wf_name}*{mention}",
827860
f"*Status:* {status} | *Duration:* {dur}",
828861
f"*Branch:* `{branch}` | *NDCS/NPCS:* `{ndcs}/{npcs}` | *Test class:* `{test_cls}`",
862+
f"*SBCLI Branch:* `{sbcli_branch}`",
829863
"",
830864
]
865+
831866
if total > 0:
832867
lines += [
833868
f":white_check_mark: *Passed:* {passed}/{total} ({pass_pct}%)",
@@ -836,11 +871,23 @@ jobs:
836871
]
837872
else:
838873
lines.append("_(test counts not found in log)_")
874+
875+
if test_results:
876+
lines.append("")
877+
lines.append("*Test Results:*")
878+
icons = {'PASSED': ':white_check_mark:', 'FAILED': ':x:', 'SKIPPED': ':fast_forward:'}
879+
for st, nm in test_results:
880+
lines.append(f"{icons.get(st, ':grey_question:')} `{nm}`")
881+
882+
if failure_reason:
883+
lines += ["", "*Failure:*", f"```{failure_reason}```"]
884+
839885
lines += [
840886
"",
841887
f":link: *Run:* <{run_url}|View on GitHub>",
842888
f":file_folder: *Final Logs:* `{log_dir}`",
843889
]
890+
844891
payload = {"text": "\n".join(lines)}
845892
req = urllib.request.Request(
846893
webhook,

0 commit comments

Comments
 (0)