77 lines
3.3 KiB
Racket
77 lines
3.3 KiB
Racket
#lang racket/base
|
|
|
|
(require rackunit
|
|
racket/file
|
|
"../flac-decoder.rkt"
|
|
"../flac-encoder.rkt")
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Tests for module flac-decoder.rkt
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; Generate a small native FLAC fixture without external programs or test data.
|
|
(let* ((directory (make-temporary-file "flac-lifecycle-~a" 'directory))
|
|
(file (build-path directory "silence.flac"))
|
|
(format (hasheq 'sample-rate 44100 'channels 2 'bits-per-sample 24)))
|
|
(dynamic-wind
|
|
void
|
|
(λ ()
|
|
(let ((encoder (flac-encoder-open file (hasheq) format))
|
|
(samples (make-bytes (* 256 2 3))))
|
|
(flac-encoder-write encoder format samples (bytes-length samples))
|
|
(flac-encoder-finish encoder))
|
|
|
|
(test-case "repeated stop before reading is harmless"
|
|
(let ((handle (flac-open file void void)))
|
|
(check-not-exn (λ () (flac-stop handle)))
|
|
(check-not-exn (λ () (flac-stop handle)))))
|
|
|
|
(test-case "stop after decoder EOF is harmless"
|
|
(let ((handle (flac-open file void void)))
|
|
(flac-read handle)
|
|
(check-false (flac-handle-reading handle))
|
|
(check-not-exn (λ () (flac-stop handle)))))
|
|
|
|
(test-case "callback failure releases the decoder and allows stop"
|
|
(let ((handle (flac-open file void
|
|
(λ (_header _samples _size)
|
|
(error 'test "audio consumer failed")))))
|
|
(check-exn #rx"audio consumer failed" (λ () (flac-read handle)))
|
|
(check-false (flac-handle-reading handle))
|
|
(let ((stopper (thread (λ () (flac-stop handle)))))
|
|
(dynamic-wind
|
|
void
|
|
(λ () (check-not-false (sync/timeout 2 stopper)))
|
|
(λ () (unless (thread-dead? stopper) (kill-thread stopper)))))))
|
|
|
|
(test-case "invalid FLAC data reports failure and remains stoppable"
|
|
(let ((broken (build-path directory "broken.flac")))
|
|
(display-to-file #"fLaC" broken)
|
|
(let ((handle (flac-open broken void void)))
|
|
(check-exn #rx"Could not decode FLAC frame"
|
|
(λ () (flac-read handle)))
|
|
(check-false (flac-handle-reading handle))
|
|
(check-not-exn (λ () (flac-stop handle))))))
|
|
|
|
(test-case "a stop request waits for active decoder cleanup"
|
|
(letrec ((entered (make-semaphore 0))
|
|
(handle
|
|
(flac-open file void
|
|
(λ (_header _samples _size)
|
|
(semaphore-post entered)
|
|
(let loop ()
|
|
(unless (flac-handle-stop-reading handle)
|
|
(sleep 0.001)
|
|
(loop))))))
|
|
(reader (thread (λ () (flac-read handle)))))
|
|
(dynamic-wind
|
|
void
|
|
(λ ()
|
|
(check-not-false (sync/timeout 2 entered))
|
|
(flac-stop handle)
|
|
(check-false (flac-handle-reading handle))
|
|
(check-not-false (sync/timeout 2 reader))
|
|
(check-not-exn (λ () (flac-stop handle))))
|
|
(λ () (unless (thread-dead? reader) (kill-thread reader)))))))
|
|
(λ () (delete-directory/files directory))))
|