#lang scheme/base
(require (planet schematics/schemeunit:3))
(require (lib "etc.ss")
"benchmark.ss"
"benchmark-log.ss")
(provide benchmark-tests)
(define (factorial n)
(if (zero? n)
1
(* n (factorial (sub1 n)))))
(define fast (lambda () 499500))
(define slow (lambda () (factorial 2048)))
(define fast-times (benchmark-time* fast))
(define slow-times (benchmark-time* slow))
(define benchmark-log (this-expression-benchmark-log-file))
(define (write-benchmark-log name times)
(delete-benchmark-log)
(add-run benchmark-log name times))
(define (delete-benchmark-log)
(when (file-exists? benchmark-log)
(delete-file benchmark-log)))
(define benchmark-tests
(test-suite
"All tests for benchmark"
(test-case
"benchmark-time gives sensible results"
(let ([t (benchmark-time (slow))])
(check-pred vector? t)
(for ([time (in-vector t)])
(check-pred integer? time)
(check-true (> time 0)))))
(test-case
"faster*?"
(check-true (faster*? "fast" #(1 2 1 3 1 2 1 2 1 4)
"slow" #(2 3 4 5 3 4 2 4 5 2)
#f))
(check-false (faster*? "slow" #(2 3 4 5 3 4 2 4 5 2)
"fast" #(1 2 1 3 1 2 1 2 1 4)
#f)))
(test-case
"faster*? returns false for equal thunks"
(check-false
(faster*? "fast1" fast-times "fast2" fast-times #f)))
(test-case
"as-fast*?"
(check-true (as-fast*? "fast" #(2 1 3 1 2 1 4 1 1 2)
"fast" #(1 2 1 3 1 2 1 2 1 4)
#f))
(check-false (as-fast*? "slow" #(2 3 4 5 3 4 2 4 5 2)
"fast" #(1 2 1 3 1 2 1 2 1 4)
#f)))
(test-case
"faster?"
(check-true (faster? ["fast" (fast)]
["slow" (slow)]))
(check-false (faster? ["slow" (slow)]
["fast" (fast)])))
(test-case
"as-fast?"
(check-true (as-fast? ["fast" (fast)]
["slow" (fast)]))
(check-false (as-fast? ["slow" (slow)]
["fast" (fast)])))
(test-case
"check-faster fails when given slower thunk"
(let ([result
(run-test (delay-test
(test-case "Dummy" (check-faster "slow" slow "fast" fast))))])
(check = (length result) 1)
(check-pred test-failure? (car result))))
(test-case
"check-faster succeeds when given faster thunk"
(let ([result
(run-test (delay-test
(test-case "Dummy" (check-faster "fast" fast "slow" slow))))])
(check = (length result) 1)
(check-pred test-success? (car result))))
(test-case
"check-as-fast fails when given slower thunk"
(let ([result
(run-test (delay-test
(test-case "Dummy" (check-as-fast "slow" slow "fast" fast))))])
(check = (length result) 1)
(check-pred test-failure? (car result))))
(test-case
"check-as-fast succeeds when given equal thunks"
(let ([result
(run-test (delay-test
(test-case "Dummy" (check-as-fast "fast" fast "fast" fast))))])
(check = (length result) 1)
(check-pred test-success? (car result))))
(test-case
"check-faster-times succeeds when given faster times"
(let ([result
(run-test (delay-test
(test-case "Dummy"
(check-faster-times fast-times slow-times))))])
(check = (length result) 1)
(check-pred test-success? (car result))))
(test-case
"check-faster-times fails when given slower times"
(let ([result
(run-test (delay-test
(test-case "Dummy"
(check-faster-times slow-times fast-times))))])
(check = (length result) 1)
(check-pred test-failure? (car result))))
(benchmark-case
"benchmark-case run as usual tests when nothing is timed"
(check = 1 1))
(test-equal?
"Path to benchmark log file correct"
(this-expression-benchmark-log-file)
(build-path (this-expression-source-directory)
(string-append
(path->string
(this-expression-file-name))
".benchmark-log")))
(test-equal?
"benchmark-test-case has correct log-file"
(benchmark-test-case-log-file
(benchmark-case "foo" #t))
(this-expression-benchmark-log-file))
(test-case
"Benchmark test succeeds when no log file exists"
(around
(delete-benchmark-log)
(let ([result (run-test (benchmark-case "Dummy" #t))])
(check = (length result) 1)
(check-pred test-success? (car result)))
(delete-benchmark-log)))
(test-case
"Benchmark test fails if test expression fails"
(around
(delete-benchmark-log)
(let ([result (run-test (benchmark-case "Dummy" (check = 0 1)))])
(check = (length result) 1)
(check-pred test-failure? (car result)))
(delete-benchmark-log)))
(test-case
"Benchmark test succeeds if test is faster"
(around
(write-benchmark-log "Dummy" slow-times)
(let ([result (run-test (benchmark-case "Dummy" (fast)))])
(check = (length result) 1)
(check-pred test-success? (car result)))
(delete-benchmark-log)))
(test-case
"Benchmark test fails if test is slower"
(around
(write-benchmark-log "Dummy" fast-times)
(let ([result (run-test (benchmark-case "Dummy" (slow)))])
(check = (length result) 1)
(check-pred test-failure? (car result)))
(delete-benchmark-log)))
(test-case
"benchmark-case writes new times to log"
(around
(delete-benchmark-log)
(run-test (benchmark-case "Dummy" (slow)))
(let ([run (find-most-recent-run benchmark-log "Dummy")])
(check-not-false run)
(check string=? (run-name run) "Dummy")
(check-pred vector? (run-times run)))
(delete-benchmark-log)))
(test-case
"benchmark-case doesn't write slower times to log"
(around
(write-benchmark-log "Dummy" fast-times)
(run-test (benchmark-case "Dummy" (slow)))
(let ([run (find-most-recent-run benchmark-log "Dummy")])
(check-equal? (run-times run) fast-times))
(delete-benchmark-log)))
(test-case
"benchmark-case writes faster times to log"
(around
(write-benchmark-log "Dummy" slow-times)
(let ([result (run-test (benchmark-case "Dummy" (fast)))]
[run (find-most-recent-run benchmark-log "Dummy")])
(check-pred test-success? (car result))
(check (lambda (t1 t2) (not (equal? t1 t2)))
(run-times run) slow-times))
(delete-benchmark-log)))
))