package main import ( "bytes" "os" "runtime" "testing" pdflib "github.com/ledongthuc/pdf" ) // A DIAGNOSTIC, not an assertion. It answers one question about the document that OOM killed the extractor: // does memory accumulate across pages, which a bound can fix, or does one page explode inside the library, // which a bound cannot. The answer decides the shape of the fix. func TestTE6DiagnoseWhereTheMemoryGoes(t *testing.T) { path := os.Getenv("MM_TEST_TE6_PDF") if path == "" { t.Skip("set MM_TEST_TE6_PDF to run") } raw, err := os.ReadFile(path) if err != nil { t.Skipf("fixture unreadable: %v", err) } heapMB := func() uint64 { var m runtime.MemStats runtime.ReadMemStats(&m) return m.HeapAlloc / (1 << 20) } defer func() { if rec := recover(); rec != nil { t.Logf("panicked: %v", rec) } }() t.Logf("heap before NewReader: %d MB", heapMB()) rd, err := pdflib.NewReader(bytes.NewReader(raw), int64(len(raw))) if err != nil { t.Fatalf("NewReader: %v", err) } t.Logf("heap after NewReader: %d MB, NumPage=%d", heapMB(), rd.NumPage()) for i := 1; i <= rd.NumPage() && i <= 12; i++ { p := rd.Page(i) if p.V.IsNull() { t.Logf("page %d null, heap %d MB", i, heapMB()) continue } txt, e := p.GetPlainText(nil) t.Logf("page %d: text=%d bytes err=%v heap=%d MB", i, len(txt), e, heapMB()) if heapMB() > 400 { t.Logf("STOP: heap passed 400 MB at page %d, so growth is PER PAGE and a bound can fix it", i) return } } }