Files
solution-erp/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-test-k1.md
2026-07-31 15:01:40 +07:00

6.8 KiB
Raw Blame History

test K1

Tiến độ

§0 Baseline ĐO TƯƠI trước khi viết (không tin số đề bài) — XONG

Lệnh: dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1

Domain: Failed 0, Passed 45,  Total 45
Infra : Failed 1, Passed 544, Total 545

baseline 590 test = 589 PASS / 1 FAIL. Đề bài ghi "590/590" — LỆCH 1. 🔴 FAIL KHÔNG liên quan K1: Forms.DocxRendererTests.RenderAsync_UnknownPlaceholder_KeepsLiteralToken_NoCrashSystem.OutOfMemoryException tại WordprocessingDocument.AddMainDocumentPart() (DocxRendererTests.cs:26). Nghi flake do áp lực RAM (fan-out nhiều agent chạy song song), KHÔNG phải regression code. Sẽ đo lại RIÊNG test đó ở §3 để phân biệt flake ⟂ vỡ thật.

§1 Đọc nguồn — XONG

  • sub-invest-fable-b2-cum1.md:59-75 §K1.e (5 case) + §K1.f (checklist acceptance)
  • Code THẬT (test theo CODE, không theo spec): · Domain/Master/Catalogs/ContractCatalogEntry.cs:13-25 — 10 cột · Persistence/Configurations/ContractCatalogEntryConfiguration.cs:27-29 — UNIQUE filtered [IsDeleted] = 0 + index ApprovalGroup + query filter · DbInitializer.cs:3163-3324 SeedContractCatalogAsync(ApplicationDbContext, ILogger) private static → gọi qua REFLECTION (khuôn S67) · DbInitializer.cs:3293-3296IgnoreQueryFilters() khi dò existing (né #75/#76) · Application/Master/Catalogs/ContractCatalogFeatures.cs — List/Get/Create/Update/Delete + 2 validator InclusiveBetween(1,8) · Api/Controllers/ContractCatalogController.cs:20-23[Authorize] class + Roles="Admin" cho 3 verb ghi (0 policy key) · MenuKeys.cs:28-32 + :173 — const ContractCatalog VÀO All; DbInitializer.cs:1776 menu row parent Catalogs

PHẦN 2 (relaunch)

§2 Tiền-đề đề bài SAI — file ĐÃ LAND trên đĩa (đo, không suy)

Đề bài relaunch nói "lượt trước chết sau khi đọc contract, CHƯA viết test". ĐĨA nói khác:

?? tests/SolutionErp.Infrastructure.Tests/Application/ContractCatalogTests.cs   (git status: untracked)
-rw-r--r-- 25005 Jul 31 14:49 ContractCatalogTests.cs      # sub-test-k1.md sửa lần cuối 14:46

⇒ lượt-1 VIẾT XONG file lúc 14:49 rồi chết trước khi cập nhật sub-md/return (đúng hình #53: việc land, vết mất). Sub-md dừng ở "(ĐANG LÀM)" nên lead đọc thành "chưa làm". 🔴 Bài: git status 1 lệnh phân biệt "chưa-làm" ⟂ "làm-rồi-mất-vết" — KHÔNG viết đè, sẽ mất 7 test.

Khác 2 điểm so với lệnh (lượt-1 tự chốt, ghi rõ ở header file :41-42 + :29-39):

  • Đường dẫn Application/ (không Services/) — Services/ là chỗ code-generator + workflow-service; hàng xóm đúng nghĩa = MasterCatalogFilteredUniqueTests.cs / *SeedTests.csApplication/.
  • 7 test (không 6): tách thêm T1b Seed_AfterSoftDeleteOfOneCode_DoesNotResurrectIt — phép đo riêng cho IgnoreQueryFilters() @DbInitializer.cs:3294 (né #75/#76).

§3 Việc CÒN LẠI của lượt này = CHẠY (file chưa từng được biên dịch/chạy)

Rủi ro thật: file 25KB viết xong mà chưa build lần nào ⇒ có thể sai chữ ký API (skeleton nấc-2). Đo: build + chạy filter ContractCatalogTests trước, rồi full-suite.

Kết quả filter (build SẠCH ngay lần đầu — không sai chữ ký API nào):

dotnet test tests/SolutionErp.Infrastructure.Tests/... --filter "FullyQualifiedName~ContractCatalogTests"
Passed!  - Failed: 0, Passed: 7, Skipped: 0, Total: 7, Duration: 8 s

7 test (không 6): T1 idempotent-86 · T1b không-hồi-sinh · T2 phân bố · T3 unique-filtered 2-chiều · T4 validator 1..8 · T5 vòng đời handler + xoá mềm · T6 menu-key/policy/grant.

§4 Probe VI-PHÂN — chứng T1b có RĂNG (không đụng production)

File tạm Application/_TempProbeK1.cs (đã XOÁ) tái lập ĐÚNG biểu thức dò-tồn-tại của seeder DbInitializer.cs:3293-3296 nhưng bỏ IgnoreQueryFilters(), chạy trên chính DB thật sau khi xoá mềm A1-01:

(A) CÓ IgnoreQueryFilters   → 86 mã, CÓ "A1-01"   ⇒ seeder skip ⇒ không hồi sinh
(B) BỎ IgnoreQueryFilters   → 85 mã, THIẾU "A1-01" ⇒ seeder Add lại ⇒ tổng 87 ⇒ T1b ĐỎ
Passed! - Failed: 0, Passed: 1, Total: 1

⇒ 2 tập KHÁC NHAU ⇒ T1b phân biệt được 2 thế giới, không phải assert rỗng nghĩa. Zero-risk: không mimic production, gọi seeder THẬT, chỉ đổi 1 toán tử ở phía test. Dọn dẹp verify 2 chiều: ls → No such file · git status --short tests/ → chỉ còn đúng 1 dòng ?? ContractCatalogTests.cs (không sót file tạm).

§5 FULL SUITE — đo tươi, 0 FAIL

dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1
Domain: Failed 0, Passed  45, Total  45   (54 ms)
Infra : Failed 0, Passed 552, Total 552   (59 s)

TỔNG 597 test / 0 FAIL (45 + 552).

Đối chiếu với §0 baseline đo tươi đầu lượt-1:

Domain Infra Tổng Fail
§0 baseline 45 545 590 1
§5 sau K1 45 552 597 0
delta 0 +7 +7 1
  • +7 Infra khớp ĐÚNG 7 [Fact] của ContractCatalogTests.cs — không test nào bị nuốt/trùng tên.
  • 🟢 1 FAIL của §0 TỰ KHỎI: Forms.DocxRendererTests.RenderAsync_UnknownPlaceholder_KeepsLiteralToken_NoCrash (OutOfMemoryException @DocxRendererTests.cs:26) nay XANH khi máy rảnh ⇒ xác nhận FLAKE do áp lực RAM lúc fan-out chạy song song, KHÔNG phải regression. Nghi ngờ §0 đóng bằng phép đo, không bằng đoán.
  • ⚠️ Số đề bài ("590/590 → 596") sai cả 2 vế: baseline có 1 fail, và K1 là 7 test chứ không 6. THẬT = 597/0.

§6 Không đụng production — không có bug cần báo

  • File duy nhất thêm: tests/SolutionErp.Infrastructure.Tests/Application/ContractCatalogTests.cs (untracked).
  • git status --short tests/ cuối lượt: đúng 1 dòng ?? đó. _TempProbeK1.cs đã xoá sạch.
  • KHÔNG commit (theo lệnh). KHÔNG sửa src/Backend/**.
  • Đọc code K1 lượt này KHÔNG thấy bug. 2 điểm CỐ Ý đáng ghi (đã khoá thành invariant có răng): · DbInitializer.cs:3293-3296 dùng IgnoreQueryFilters()khác khuôn :2970 (Projects) và ĐÚNG hơn khuôn đó (#75/#76); T1b khoá lại để ai "chuẩn hoá về khuôn cũ" là ĐỎ. · Dup-check handler (ContractCatalogFeatures.cs:131,193) chạy trên active-set ⇒ khớp index filtered [IsDeleted]=0 ⇒ mã của dòng đã xoá tái dùng được (T3 khoá tầng DB, T5 khoá tầng handler).

END test-k1 — +7 test · 597 PASS / 0 FAIL