guardians.test 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. ;;;; guardians.test --- test suite for Guile Guardians -*- scheme -*-
  2. ;;;; Jim Blandy <jimb@red-bean.com> --- July 1999
  3. ;;;;
  4. ;;;; Copyright (C) 1999, 2001, 2006 Free Software Foundation, Inc.
  5. ;;;;
  6. ;;;; This program is free software; you can redistribute it and/or modify
  7. ;;;; it under the terms of the GNU General Public License as published by
  8. ;;;; the Free Software Foundation; either version 2, or (at your option)
  9. ;;;; any later version.
  10. ;;;;
  11. ;;;; This program is distributed in the hope that it will be useful,
  12. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;;; GNU General Public License for more details.
  15. ;;;;
  16. ;;;; You should have received a copy of the GNU General Public License
  17. ;;;; along with this software; see the file COPYING. If not, write to
  18. ;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. ;;;; Boston, MA 02110-1301 USA
  20. ;;; These tests make some questionable assumptions.
  21. ;;; - They assume that a GC will find all dead objects, so they
  22. ;;; will become flaky if we have a generational GC.
  23. ;;; - They assume that objects won't be saved by the guardian until
  24. ;;; they explicitly invoke GC --- in other words, they assume that GC
  25. ;;; won't happen too often.
  26. (define-module (test-guardians)
  27. :use-module (test-suite lib)
  28. :use-module (ice-9 documentation)
  29. :use-module (ice-9 weak-vector))
  30. ;;;
  31. ;;; miscellaneous
  32. ;;;
  33. (define (documented? object)
  34. (not (not (object-documentation object))))
  35. (gc)
  36. ;;; Who guards the guardian?
  37. (gc)
  38. (define g2 (make-guardian))
  39. (g2 (list 'g2-garbage))
  40. (define g3 (make-guardian))
  41. (g3 (list 'g3-garbage))
  42. (g3 g2)
  43. (pass-if "g2-garbage not collected yet" (equal? (g2) #f))
  44. (pass-if "g3-garbage not collected yet" (equal? (g3) #f))
  45. (set! g2 #f)
  46. (gc)
  47. (let ((seen-g3-garbage #f)
  48. (seen-g2 #f)
  49. (seen-something-else #f))
  50. (let loop ()
  51. (let ((saved (g3)))
  52. (if saved
  53. (begin
  54. (cond
  55. ((equal? saved '(g3-garbage)) (set! seen-g3-garbage #t))
  56. ((procedure? saved) (set! seen-g2 saved))
  57. (else (pk saved) (set! seen-something-else #t)))
  58. (loop)))))
  59. (pass-if "g3-garbage saved" (or seen-g3-garbage (throw 'unresolved)))
  60. (pass-if "g2-saved" (or (procedure? seen-g2) (throw 'unresolved)))
  61. (pass-if "nothing else saved" (not seen-something-else))
  62. (pass-if "g2-garbage saved" (or (and (procedure? seen-g2)
  63. (equal? (seen-g2) '(g2-garbage)))
  64. (throw 'unresolved))))
  65. (with-test-prefix "standard guardian functionality"
  66. (with-test-prefix "make-guardian"
  67. (pass-if "documented?"
  68. (documented? make-guardian))
  69. (pass-if "returns procedure"
  70. (procedure? (make-guardian)))
  71. (pass-if "returns new procedure each time"
  72. (not (equal? (make-guardian) (make-guardian)))))
  73. (with-test-prefix "empty guardian"
  74. (pass-if "returns #f"
  75. (eq? ((make-guardian)) #f))
  76. (pass-if "returns always #f"
  77. (let ((g (make-guardian)))
  78. (and (eq? (g) #f)
  79. (begin (gc) (eq? (g) #f))
  80. (begin (gc) (eq? (g) #f))))))
  81. (with-test-prefix "guarding independent objects"
  82. (pass-if "guarding immediate"
  83. (let ((g (make-guardian)))
  84. (g #f)
  85. (and (eq? (g) #f)
  86. (begin (gc) (eq? (g) #f))
  87. (begin (gc) (eq? (g) #f)))))
  88. (pass-if "guarding non-immediate"
  89. (let ((g (make-guardian)))
  90. (gc)
  91. (g (cons #f #f))
  92. (if (not (eq? (g) #f))
  93. (throw 'unresolved)
  94. (begin
  95. (gc)
  96. (if (not (equal? (g) (cons #f #f)))
  97. (throw 'unresolved)
  98. (eq? (g) #f))))))
  99. (pass-if "guarding two non-immediates"
  100. (let ((g (make-guardian)))
  101. (gc)
  102. (g (cons #f #f))
  103. (g (cons #t #t))
  104. (if (not (eq? (g) #f))
  105. (throw 'unresolved)
  106. (begin
  107. (gc)
  108. (let ((l (list (g) (g))))
  109. (if (not (or (equal? l (list (cons #f #f) (cons #t #t)))
  110. (equal? l (list (cons #t #t) (cons #f #f)))))
  111. (throw 'unresolved)
  112. (eq? (g) #f)))))))
  113. (pass-if "re-guarding non-immediates"
  114. (let ((g (make-guardian)))
  115. (gc)
  116. (g (cons #f #f))
  117. (if (not (eq? (g) #f))
  118. (throw 'unresolved)
  119. (begin
  120. (gc)
  121. (let ((p (g)))
  122. (if (not (equal? p (cons #f #f)))
  123. (throw 'unresolved)
  124. (begin
  125. (g p)
  126. (set! p #f)
  127. (gc)
  128. (if (not (equal? (g) (cons #f #f)))
  129. (throw 'unresolved)
  130. (eq? (g) #f)))))))))
  131. (pass-if "guarding living non-immediate"
  132. (let ((g (make-guardian))
  133. (p (cons #f #f)))
  134. (g p)
  135. (if (not (eq? (g) #f))
  136. (throw 'fail)
  137. (begin
  138. (gc)
  139. (not (eq? (g) p)))))))
  140. (with-test-prefix "guarding weakly referenced objects"
  141. (pass-if "guarded weak vector element gets returned from guardian"
  142. (let ((g (make-guardian))
  143. (v (weak-vector #f)))
  144. (gc)
  145. (let ((p (cons #f #f)))
  146. (g p)
  147. (vector-set! v 0 p))
  148. (if (not (eq? (g) #f))
  149. (throw 'unresolved)
  150. (begin
  151. (gc)
  152. (if (not (equal? (g) (cons #f #f)))
  153. (throw 'unresolved)
  154. (eq? (g) #f))))))
  155. (pass-if "guarded element of weak vector gets eventually removed from weak vector"
  156. (let ((g (make-guardian))
  157. (v (weak-vector #f)))
  158. (gc)
  159. (let ((p (cons #f #f)))
  160. (g p)
  161. (vector-set! v 0 p))
  162. (begin
  163. (gc)
  164. (if (not (equal? (g) (cons #f #f)))
  165. (throw 'unresolved)
  166. (begin
  167. (gc)
  168. (or (not (vector-ref v 0))
  169. (throw 'unresolved))))))))
  170. (with-test-prefix "guarding weak containers"
  171. (pass-if "element of guarded weak vector gets collected"
  172. (let ((g (make-guardian))
  173. (v (weak-vector (cons #f #f))))
  174. (g v)
  175. (gc)
  176. (if (equal? (vector-ref v 0) (cons #f #f))
  177. (throw 'unresolved)
  178. #t))))
  179. (with-test-prefix "guarding guardians"
  180. #t)
  181. (with-test-prefix "guarding dependent objects"
  182. ;; We don't make any guarantees about the order objects are
  183. ;; returned from guardians and therefore we skip the following
  184. ;; test.
  185. (if #f
  186. (pass-if "guarding vector and element"
  187. (let ((g (make-guardian)))
  188. (gc)
  189. (let ((p (cons #f #f)))
  190. (g p)
  191. (g (vector p)))
  192. (if (not (eq? (g) #f))
  193. (throw 'unresolved)
  194. (begin
  195. (gc)
  196. (if (not (equal? (g) (vector (cons #f #f))))
  197. (throw 'unresolved)
  198. (if (not (eq? (g) #f))
  199. (throw 'unresolved)
  200. (begin
  201. (gc)
  202. (if (not (equal? (g) (cons #f #f)))
  203. (throw 'unresolved)
  204. (eq? (g) #f)))))))))))
  205. (with-test-prefix "guarding objects more than once"
  206. (pass-if "guarding twice in one guardian"
  207. (let ((g (make-guardian)))
  208. (gc)
  209. (let ((p (cons #f #f)))
  210. (g p)
  211. (g p))
  212. (if (not (eq? (g) #f))
  213. (throw 'unresolved)
  214. (begin
  215. (gc)
  216. (or (and (and=> (g) (lambda (o) (equal? o (cons #f #f))))
  217. (and=> (g) (lambda (o) (equal? o (cons #f #f)))))
  218. (throw 'unresolved))))))
  219. (pass-if "guarding twice in two guardians"
  220. (let ((g (make-guardian))
  221. (h (make-guardian)))
  222. (gc)
  223. (let ((p (cons #f #f)))
  224. (g p)
  225. (h p))
  226. (if (not (eq? (g) #f))
  227. (throw 'unresolved)
  228. (begin
  229. (gc)
  230. (or (and (and=> (g) (lambda (o) (equal? o (cons #f #f))))
  231. (and=> (h) (lambda (o) (equal? o (cons #f #f)))))
  232. (throw 'unresolved)))))))
  233. (with-test-prefix "guarding cyclic dependencies"
  234. #t)
  235. )