docs/plans/p5a: 01 kind+fetch limits, 02 pdftext child + runner, 03 dcache PDF tables, 04 pdfpool, 05 pdfdoc render (map/pages/grep), 06 api, 07 digest citations, metrics, CLI, skill, unit, README. Given tests compile against a panic-only skeleton and fail there for the intended reasons; PDFs for tests are built by internal/pdftest (given), plus two qpdf-encrypted fixtures. Owner changes for the run: vendor go-pdfkit/extract v0.3.0 + reader v0.6.0 (pinned via tools.go until task 02); AGENTS.md, tools/run-plan.sh (enforces a Co-Authored-By trailer for the model), docs/implementer-log.md, `make gate`; gofmt (whitespace) on clean.go and guard; TestUnsupportedType uses a zip now that PDFs are supported; requestDeadline 90→210 s and writeTimeout 120→240 s for the PDF path's worst case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
1.3 KiB
Go
50 lines
1.3 KiB
Go
package metrics
|
|
|
|
// P5a task 07: the sift_pdf_* series.
|
|
|
|
import (
|
|
"io"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type zeroSrc struct{}
|
|
|
|
func (zeroSrc) Snapshot() Snapshot { return Snapshot{} }
|
|
|
|
func TestPDFSeries(t *testing.T) {
|
|
s := New(zeroSrc{})
|
|
s.ObservePDF("ok", 1500*time.Millisecond, 212)
|
|
s.ObservePDF("ok", 200*time.Millisecond, 3)
|
|
s.ObservePDF("no_text", 50*time.Millisecond, 0)
|
|
s.ObservePDF("blocked: evil.example", time.Millisecond, 0) // raw text never becomes a label
|
|
s.ObservePDFWait(2 * time.Second)
|
|
s.PDFCacheHit()
|
|
s.PDFCacheHit()
|
|
|
|
req := httptest.NewRequest("GET", "/metrics", nil)
|
|
req.RemoteAddr, req.Host = "127.0.0.1:9", "127.0.0.1:8890"
|
|
rec := httptest.NewRecorder()
|
|
s.Handler().ServeHTTP(rec, req)
|
|
body, _ := io.ReadAll(rec.Body)
|
|
out := string(body)
|
|
for _, want := range []string{
|
|
`sift_pdf_extract_total{outcome="ok"} 2`,
|
|
`sift_pdf_extract_total{outcome="no_text"} 1`,
|
|
`sift_pdf_extract_total{outcome="other"} 1`,
|
|
`sift_pdf_pages_total 215`,
|
|
`sift_pdf_cache_hits_total 2`,
|
|
`sift_pdf_extract_seconds_count 4`,
|
|
`sift_pdf_pool_wait_seconds_count 1`,
|
|
} {
|
|
if !strings.Contains(out, want) {
|
|
t.Errorf("metrics lack %q", want)
|
|
}
|
|
}
|
|
if strings.Contains(out, "evil.example") {
|
|
t.Error("a raw outcome string leaked into a label")
|
|
}
|
|
}
|