|
1 | | -#lang racket/base |
| 1 | +#lang at-exp racket/base |
2 | 2 |
|
3 | | -(require rackunit |
4 | | - racket/system |
5 | | - racket/port |
| 3 | +(require recspecs |
| 4 | + recspecs/shell |
| 5 | + racket/runtime-path |
| 6 | + racket/format |
6 | 7 | racket/string) |
7 | 8 |
|
8 | | -;; Test that gcstats runs and produces expected output format |
9 | | -(define output |
10 | | - (with-output-to-string |
11 | | - (lambda () |
12 | | - (parameterize ([current-error-port (current-output-port)]) |
13 | | - ;; Run a simple program that allocates memory to trigger GC |
14 | | - (system "racket -l gcstats -e '(for ([i 100000]) (cons i i))'"))))) |
15 | | - |
16 | | -;; Check that output contains expected sections |
17 | | -(check-true (string-contains? output "bytes allocated in the heap") |
18 | | - "Output should contain allocation info") |
19 | | -(check-true (string-contains? output "bytes collected by GC") |
20 | | - "Output should contain collection info") |
21 | | -(check-true (string-contains? output "bytes max heap size") |
22 | | - "Output should contain max heap size") |
23 | | -(check-true (string-contains? output "INIT time") |
24 | | - "Output should contain init time") |
25 | | -(check-true (string-contains? output "MUT time") |
26 | | - "Output should contain mutator time") |
27 | | -(check-true (string-contains? output "GC time") |
28 | | - "Output should contain GC time") |
29 | | -(check-true (string-contains? output "TOTAL time") |
30 | | - "Output should contain total time") |
31 | | -(check-true (string-contains? output "Alloc rate") |
32 | | - "Output should contain allocation rate") |
| 9 | +;; Test script that allocates memory to trigger GC |
| 10 | +(define-runtime-path test-script "test-script.rkt") |
| 11 | + |
| 12 | +(define cmd (~a "racket -l gcstats -t " test-script)) |
| 13 | + |
| 14 | +;; Helper to extract a number from a line matching a pattern |
| 15 | +(define (extract-number pattern output) |
| 16 | + (define m (regexp-match pattern output)) |
| 17 | + (and m (string->number (regexp-replace* #rx"," (cadr m) "")))) |
| 18 | + |
| 19 | +;; Test that gcstats produces expected output format |
| 20 | +;; We use recspecs-output-filter to normalize numeric values and whitespace |
| 21 | +;; AND validate that key metrics are sane |
| 22 | +(parameterize ([recspecs-output-filter |
| 23 | + (lambda (s) |
| 24 | + ;; Validate numeric values before normalizing |
| 25 | + (define allocated (extract-number #px"([0-9,]+) bytes allocated" s)) |
| 26 | + (define collected (extract-number #px"([0-9,]+) bytes collected" s)) |
| 27 | + (define max-heap (extract-number #px"([0-9,]+) bytes max heap" s)) |
| 28 | + (define gc-pct (extract-number #px"%GC time +([0-9.]+)" s)) |
| 29 | + |
| 30 | + (unless (and allocated (> allocated 0)) |
| 31 | + (error 'gcstats-test "bytes allocated should be positive, got ~a" allocated)) |
| 32 | + (unless (and collected (>= collected 0)) |
| 33 | + (error 'gcstats-test "bytes collected should be non-negative, got ~a" collected)) |
| 34 | + (unless (and max-heap (> max-heap 0)) |
| 35 | + (error 'gcstats-test "max heap should be positive, got ~a" max-heap)) |
| 36 | + (unless (and gc-pct (<= gc-pct 100)) |
| 37 | + (error 'gcstats-test "GC percentage should be <= 100, got ~a" gc-pct)) |
| 38 | + |
| 39 | + ;; Replace numbers (with optional commas/decimals) with # |
| 40 | + (define no-nums (regexp-replace* #px"[0-9][0-9,]*\\.?[0-9]*" s "#")) |
| 41 | + ;; Collapse multiple spaces to single space |
| 42 | + (regexp-replace* #px" +" no-nums " "))]) |
| 43 | + @expect/shell[cmd]{ |
| 44 | + |
| 45 | + # bytes allocated in the heap |
| 46 | + # bytes collected by GC |
| 47 | + # bytes max heap size |
| 48 | + # bytes max slop |
| 49 | + # bytes peak total memory use |
| 50 | + |
| 51 | +Generation #: # collections, #ms, #ms elapsed |
| 52 | + |
| 53 | +INIT time # ms |
| 54 | +MUT time # ms ( # ms elapsed) |
| 55 | +GC time # ms ( # ms elapsed) |
| 56 | +TOTAL time # ms ( # ms elapsed) |
| 57 | + |
| 58 | +Max pause time: # ms |
| 59 | +%GC time # % ( # % elapsed) |
| 60 | + |
| 61 | +Alloc rate # bytes per MUT second |
| 62 | + |
| 63 | +}) |
0 commit comments