feat: Update testing documentation and introduce comprehensive report for IPSExtractor campaign. Add sections for executive summary, objectives, environment details, and methodology. Enhance README with compilation instructions and data sources for metrics analysis.

This commit is contained in:
erik
2026-07-13 21:10:43 -05:00
parent 6bf413c4ce
commit 311a4bd6d3
39 changed files with 1641 additions and 67 deletions
@@ -32,28 +32,31 @@ func NewProcessor(predictor *model.Predictor, ocrEngine *ocr.Engine, opts Option
func (p *Processor) ProcessPDF(filename string, pdfData []byte) domain.PDFResult {
start := time.Now()
result := domain.PDFResult{Filename: filename, Status: domain.StatusOK}
var renderDur, ocrDur, clusterDur, inferDur time.Duration
tRender := time.Now()
img, pageW, pageH, err := ocr.RenderPage(pdfData, p.opts.DPI)
renderDur := time.Since(tRender)
renderDur = time.Since(tRender)
if err != nil {
result.Status = domain.StatusError
result.Error = err.Error()
p.finishTiming(&result, renderDur, 0, 0, 0, time.Since(start))
return result
}
tOCR := time.Now()
boxes, err := p.ocrEngine.OCRImage(img)
ocrDur := time.Since(tOCR)
ocrDur = time.Since(tOCR)
if err != nil {
result.Status = domain.StatusError
result.Error = err.Error()
p.finishTiming(&result, renderDur, ocrDur, 0, 0, time.Since(start))
return result
}
if len(boxes) == 0 {
result.ServiceCount = 0
result.Services = []domain.ServiceRow{}
p.logTiming(filename, renderDur, ocrDur, 0, 0, time.Since(start))
p.finishTiming(&result, renderDur, ocrDur, 0, 0, time.Since(start))
return result
}
@@ -65,11 +68,11 @@ func (p *Processor) ProcessPDF(filename string, pdfData []byte) domain.PDFResult
ClusterRows(indexed, p.opts.DBSCANEps, p.opts.DBSCANMinSamples)
rows := buildFeatureRows(indexed, pageW, pageH)
clusterDur := time.Since(tCluster)
clusterDur = time.Since(tCluster)
if len(rows) == 0 {
result.ServiceCount = 0
result.Services = []domain.ServiceRow{}
p.logTiming(filename, renderDur, ocrDur, clusterDur, 0, time.Since(start))
p.finishTiming(&result, renderDur, ocrDur, clusterDur, 0, time.Since(start))
return result
}
@@ -84,7 +87,7 @@ func (p *Processor) ProcessPDF(filename string, pdfData []byte) domain.PDFResult
}
result.Services = services
result.ServiceCount = len(rows)
p.logTiming(filename, renderDur, ocrDur, clusterDur, 0, time.Since(start))
p.finishTiming(&result, renderDur, ocrDur, clusterDur, 0, time.Since(start))
return result
}
@@ -95,10 +98,11 @@ func (p *Processor) ProcessPDF(filename string, pdfData []byte) domain.PDFResult
tInfer := time.Now()
probs, err := p.predictor.PredictProba(features)
inferDur := time.Since(tInfer)
inferDur = time.Since(tInfer)
if err != nil {
result.Status = domain.StatusError
result.Error = fmt.Sprintf("inference: %v", err)
p.finishTiming(&result, renderDur, ocrDur, clusterDur, inferDur, time.Since(start))
return result
}
@@ -128,16 +132,21 @@ func (p *Processor) ProcessPDF(filename string, pdfData []byte) domain.PDFResult
result.Services = services
result.ServiceCount = serviceCount
p.logTiming(filename, renderDur, ocrDur, clusterDur, inferDur, time.Since(start))
p.finishTiming(&result, renderDur, ocrDur, clusterDur, inferDur, time.Since(start))
return result
}
func (p *Processor) logTiming(filename string, render, ocr, cluster, infer, total time.Duration) {
func (p *Processor) finishTiming(result *domain.PDFResult, render, ocrD, cluster, infer, total time.Duration) {
result.RenderMs = render.Milliseconds()
result.OCRMs = ocrD.Milliseconds()
result.ClusterMs = cluster.Milliseconds()
result.InferMs = infer.Milliseconds()
result.TotalMs = total.Milliseconds()
if !p.opts.LogPipelineTiming {
return
}
log.Printf(
"pipeline filename=%s ocr_render=%s ocr_tesseract=%s cluster=%s infer=%s total=%s",
filename, render, ocr, cluster, infer, total,
result.Filename, render, ocrD, cluster, infer, total,
)
}