123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- (define-module (test-guardians)
- :use-module (test-suite lib)
- :use-module (ice-9 documentation)
- :use-module (ice-9 weak-vector))
- (define (documented? object)
- (not (not (object-documentation object))))
- (gc)
- (gc)
- (define g2 (make-guardian))
- (g2 (list (string-copy "g2-garbage")))
- (define g3 (make-guardian))
- (g3 (list (string-copy "g3-garbage")))
- (g3 g2)
- (pass-if "g2-garbage not collected yet" (equal? (g2) #f))
- (pass-if "g3-garbage not collected yet" (equal? (g3) #f))
- (set! g2 #f)
- (gc)
- (let ((seen-g3-garbage #f)
- (seen-g2 #f)
- (seen-something-else #f))
- (let loop ()
- (let ((saved (g3)))
- (if saved
- (begin
- (cond
- ((equal? saved (list (string-copy "g3-garbage")))
- (set! seen-g3-garbage #t))
- ((procedure? saved) (set! seen-g2 saved))
- (else (pk 'junk saved) (set! seen-something-else #t)))
- (loop)))))
- (pass-if "g3-garbage saved" (or seen-g3-garbage (throw 'unresolved)))
- (pass-if "g2-saved" (or (procedure? seen-g2) (throw 'unresolved)))
- (pass-if "nothing else saved" (not seen-something-else))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (pass-if "g2-garbage saved" (or (and (procedure? seen-g2)
- (equal? (seen-g2)
- (list (string-copy
- "g2-garbage"))))
- (throw 'unresolved))))
- (with-test-prefix "standard guardian functionality"
- (with-test-prefix "make-guardian"
- (pass-if "documented?"
- (documented? make-guardian))
- (pass-if "returns procedure"
- (procedure? (make-guardian)))
- (pass-if "returns new procedure each time"
- (not (equal? (make-guardian) (make-guardian)))))
- (with-test-prefix "empty guardian"
- (pass-if "returns #f"
- (eq? ((make-guardian)) #f))
- (pass-if "returns always #f"
- (let ((g (make-guardian)))
- (and (eq? (g) #f)
- (begin (gc) (eq? (g) #f))
- (begin (gc) (eq? (g) #f))))))
- (with-test-prefix "guarding independent objects"
- (pass-if "guarding immediate"
- (let ((g (make-guardian)))
- (g #f)
- (and (eq? (g) #f)
- (begin (gc) (eq? (g) #f))
- (begin (gc) (eq? (g) #f)))))
- (pass-if "guarding non-immediate"
- (let ((g (make-guardian)))
- (gc)
- (g (cons #f #f))
- (cons 'clear 'stack)
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (if (not (equal? (g) (cons #f #f)))
- (throw 'unresolved)
- (eq? (g) #f))))))
- (pass-if "guarding two non-immediates"
- (let ((g (make-guardian)))
- (gc)
- (g (cons #f #f))
- (g (cons #t #t))
- (cons 'clear 'stack)
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (let ((l (list (g) (g))))
- (if (not (or (equal? l (list (cons #f #f) (cons #t #t)))
- (equal? l (list (cons #t #t) (cons #f #f)))))
- (throw 'unresolved)
- (eq? (g) #f)))))))
- (pass-if "re-guarding non-immediates"
- (let ((g (make-guardian)))
- (gc)
- (g (cons #f #f))
- (cons 'clear 'stack)
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (let ((p (g)))
- (if (not (equal? p (cons #f #f)))
- (throw 'unresolved)
- (begin
- (g p)
- (set! p #f)
- (gc)
- (if (not (equal? (g) (cons #f #f)))
- (throw 'unresolved)
- (eq? (g) #f)))))))))
- (pass-if "guarding living non-immediate"
- (let ((g (make-guardian))
- (p (cons #f #f)))
- (g p)
- (if (not (eq? (g) #f))
- (throw 'fail)
- (begin
- (gc)
- (not (eq? (g) p)))))))
- (with-test-prefix "guarding weakly referenced objects"
- (pass-if "guarded weak vector element gets returned from guardian"
- (let ((g (make-guardian))
- (v (weak-vector #f)))
- (gc)
- (let ((p (cons #f #f)))
- (g p)
- (weak-vector-set! v 0 p)
- (set! p #f))
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (if (not (equal? (g) (cons #f #f)))
- (throw 'unresolved)
- (eq? (g) #f))))))
- (pass-if "guarded element of weak vector gets eventually removed from weak vector"
- (let ((g (make-guardian))
- (v (weak-vector #f)))
- (gc)
- (let ((p (cons #f #f)))
- (g p)
- (weak-vector-set! v 0 p)
- (set! p #f))
- (begin
- (gc)
- (if (not (equal? (g) (cons #f #f)))
- (throw 'unresolved)
- (begin
- (gc)
- (or (not (weak-vector-ref v 0))
- (throw 'unresolved))))))))
- (with-test-prefix "guarding weak containers"
- (pass-if "element of guarded weak vector gets collected"
- (let ((g (make-guardian))
- (v (weak-vector #f)))
-
-
- (weak-vector-set! v 0 (cons #f #f))
- (g v)
- (gc)
- (if (equal? (weak-vector-ref v 0) (cons #f #f))
- (throw 'unresolved)
- #t))))
- (with-test-prefix "guarding guardians"
- #t)
- (with-test-prefix "guarding dependent objects"
-
-
-
- (if #f
- (pass-if "guarding vector and element"
- (let ((g (make-guardian)))
- (gc)
- (let ((p (cons #f #f)))
- (g p)
- (g (vector p)))
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (if (not (equal? (g) (vector (cons #f #f))))
- (throw 'unresolved)
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (if (not (equal? (g) (cons #f #f)))
- (throw 'unresolved)
- (eq? (g) #f)))))))))))
- (with-test-prefix "guarding objects more than once"
- (pass-if "guarding twice in one guardian"
- (let ((g (make-guardian)))
- (gc)
- (let ((p (cons #f #f)))
- (g p)
- (g p)
- (set! p #f))
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (or (and (and=> (g) (lambda (o) (equal? o (cons #f #f))))
- (and=> (g) (lambda (o) (equal? o (cons #f #f)))))
- (throw 'unresolved))))))
- (pass-if "guarding twice in two guardians"
- (let ((g (make-guardian))
- (h (make-guardian)))
- (gc)
- (let ((p (cons #f #f)))
- (g p)
- (h p)
- (set! p #f))
- (if (not (eq? (g) #f))
- (throw 'unresolved)
- (begin
- (gc)
- (or (and (and=> (g) (lambda (o) (equal? o (cons #f #f))))
- (and=> (h) (lambda (o) (equal? o (cons #f #f)))))
- (throw 'unresolved)))))))
- (with-test-prefix "guarding cyclic dependencies"
- #t)
- )
|