Merge branch 'master' into boehm-demers-weiser-gc
[bpt/guile.git] / test-suite / tests / guardians.test
CommitLineData
2e109b65
JB
1;;;; guardians.test --- test suite for Guile Guardians -*- scheme -*-
2;;;; Jim Blandy <jimb@red-bean.com> --- July 1999
3;;;;
6e7d5622 4;;;; Copyright (C) 1999, 2001, 2006 Free Software Foundation, Inc.
2e109b65
JB
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
92205699
MV
18;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19;;;; Boston, MA 02110-1301 USA
2e109b65
JB
20
21;;; These tests make some questionable assumptions.
22;;; - They assume that a GC will find all dead objects, so they
23;;; will become flaky if we have a generational GC.
24;;; - They assume that objects won't be saved by the guardian until
25;;; they explicitly invoke GC --- in other words, they assume that GC
26;;; won't happen too often.
27
2924541b
MV
28(use-modules (test-suite lib)
29 (ice-9 documentation)
6d63297b 30 (ice-9 weak-vector))
9247b5bc
DH
31
32
33;;;
34;;; miscellaneous
35;;;
36
37(define (documented? object)
38 (not (not (object-documentation object))))
39
2e109b65 40
2e109b65 41(gc)
2e109b65
JB
42
43;;; Who guards the guardian?
e13f1cbd
LC
44
45;;; Note: We use strings rather than symbols because symbols are usually
46;;; ``interned'', i.e., kept in a weakly-keyed hash table, thus making them
47;;; inappropriate for the tests below. Furthermore, we use `string-copy' in
48;;; order to make sure that no string is kept around in the interpreter
49;;; unwillingly (e.g., in the source-property weak hash table).
50
2e109b65
JB
51(gc)
52(define g2 (make-guardian))
e13f1cbd 53(g2 (list (string-copy "g2-garbage")))
2e109b65 54(define g3 (make-guardian))
e13f1cbd 55(g3 (list (string-copy "g3-garbage")))
2e109b65
JB
56(g3 g2)
57(pass-if "g2-garbage not collected yet" (equal? (g2) #f))
58(pass-if "g3-garbage not collected yet" (equal? (g3) #f))
59(set! g2 #f)
60(gc)
61(let ((seen-g3-garbage #f)
62 (seen-g2 #f)
63 (seen-something-else #f))
64 (let loop ()
65 (let ((saved (g3)))
66 (if saved
67 (begin
68 (cond
e13f1cbd
LC
69 ((equal? saved (list (string-copy "g3-garbage")))
70 (set! seen-g3-garbage #t))
2e109b65 71 ((procedure? saved) (set! seen-g2 saved))
e13f1cbd 72 (else (pk 'junk saved) (set! seen-something-else #t)))
2e109b65 73 (loop)))))
2924541b
MV
74 (pass-if "g3-garbage saved" (or seen-g3-garbage (throw 'unresolved)))
75 (pass-if "g2-saved" (or (procedure? seen-g2) (throw 'unresolved)))
2e109b65 76 (pass-if "nothing else saved" (not seen-something-else))
2924541b 77 (pass-if "g2-garbage saved" (or (and (procedure? seen-g2)
e13f1cbd
LC
78 (equal? (seen-g2)
79 (list (string-copy
80 "g2-garbage"))))
2924541b 81 (throw 'unresolved))))
9247b5bc
DH
82
83(with-test-prefix "standard guardian functionality"
84
85 (with-test-prefix "make-guardian"
86
87 (pass-if "documented?"
88 (documented? make-guardian))
89
90 (pass-if "returns procedure"
91 (procedure? (make-guardian)))
92
93 (pass-if "returns new procedure each time"
94 (not (equal? (make-guardian) (make-guardian)))))
95
96 (with-test-prefix "empty guardian"
97
98 (pass-if "returns #f"
99 (eq? ((make-guardian)) #f))
100
101 (pass-if "returns always #f"
102 (let ((g (make-guardian)))
103 (and (eq? (g) #f)
104 (begin (gc) (eq? (g) #f))
105 (begin (gc) (eq? (g) #f))))))
106
107 (with-test-prefix "guarding independent objects"
108
109 (pass-if "guarding immediate"
110 (let ((g (make-guardian)))
111 (g #f)
112 (and (eq? (g) #f)
113 (begin (gc) (eq? (g) #f))
114 (begin (gc) (eq? (g) #f)))))
115
116 (pass-if "guarding non-immediate"
117 (let ((g (make-guardian)))
118 (gc)
119 (g (cons #f #f))
120 (if (not (eq? (g) #f))
121 (throw 'unresolved)
122 (begin
123 (gc)
124 (if (not (equal? (g) (cons #f #f)))
125 (throw 'unresolved)
126 (eq? (g) #f))))))
127
128 (pass-if "guarding two non-immediates"
129 (let ((g (make-guardian)))
130 (gc)
131 (g (cons #f #f))
132 (g (cons #t #t))
133 (if (not (eq? (g) #f))
134 (throw 'unresolved)
135 (begin
136 (gc)
137 (let ((l (list (g) (g))))
138 (if (not (or (equal? l (list (cons #f #f) (cons #t #t)))
139 (equal? l (list (cons #t #t) (cons #f #f)))))
140 (throw 'unresolved)
141 (eq? (g) #f)))))))
142
143 (pass-if "re-guarding non-immediates"
144 (let ((g (make-guardian)))
145 (gc)
146 (g (cons #f #f))
147 (if (not (eq? (g) #f))
148 (throw 'unresolved)
149 (begin
150 (gc)
151 (let ((p (g)))
152 (if (not (equal? p (cons #f #f)))
153 (throw 'unresolved)
154 (begin
155 (g p)
156 (set! p #f)
157 (gc)
158 (if (not (equal? (g) (cons #f #f)))
159 (throw 'unresolved)
160 (eq? (g) #f)))))))))
161
162 (pass-if "guarding living non-immediate"
163 (let ((g (make-guardian))
164 (p (cons #f #f)))
165 (g p)
166 (if (not (eq? (g) #f))
167 (throw 'fail)
168 (begin
169 (gc)
170 (not (eq? (g) p)))))))
171
172 (with-test-prefix "guarding weakly referenced objects"
173
174 (pass-if "guarded weak vector element gets returned from guardian"
175 (let ((g (make-guardian))
176 (v (weak-vector #f)))
177 (gc)
178 (let ((p (cons #f #f)))
179 (g p)
180 (vector-set! v 0 p))
181 (if (not (eq? (g) #f))
182 (throw 'unresolved)
183 (begin
184 (gc)
185 (if (not (equal? (g) (cons #f #f)))
186 (throw 'unresolved)
187 (eq? (g) #f))))))
188
2924541b 189 (pass-if "guarded element of weak vector gets eventually removed from weak vector"
9247b5bc
DH
190 (let ((g (make-guardian))
191 (v (weak-vector #f)))
192 (gc)
193 (let ((p (cons #f #f)))
194 (g p)
195 (vector-set! v 0 p))
2924541b
MV
196 (begin
197 (gc)
198 (if (not (equal? (g) (cons #f #f)))
199 (throw 'unresolved)
200 (begin
201 (gc)
202 (or (not (vector-ref v 0))
203 (throw 'unresolved))))))))
9247b5bc
DH
204
205 (with-test-prefix "guarding weak containers"
206
207 (pass-if "element of guarded weak vector gets collected"
208 (let ((g (make-guardian))
209 (v (weak-vector (cons #f #f))))
210 (g v)
211 (gc)
212 (if (equal? (vector-ref v 0) (cons #f #f))
213 (throw 'unresolved)
214 #t))))
215
216 (with-test-prefix "guarding guardians"
2924541b 217 #t)
9247b5bc
DH
218
219 (with-test-prefix "guarding dependent objects"
220
2924541b
MV
221 ;; We don't make any guarantees about the order objects are
222 ;; returned from guardians and therefore we skip the following
223 ;; test.
224
225 (if #f
226 (pass-if "guarding vector and element"
227 (let ((g (make-guardian)))
228 (gc)
229 (let ((p (cons #f #f)))
230 (g p)
231 (g (vector p)))
232 (if (not (eq? (g) #f))
233 (throw 'unresolved)
234 (begin
235 (gc)
236 (if (not (equal? (g) (vector (cons #f #f))))
9247b5bc 237 (throw 'unresolved)
2924541b
MV
238 (if (not (eq? (g) #f))
239 (throw 'unresolved)
240 (begin
241 (gc)
242 (if (not (equal? (g) (cons #f #f)))
243 (throw 'unresolved)
244 (eq? (g) #f)))))))))))
9247b5bc
DH
245
246 (with-test-prefix "guarding objects more than once"
2924541b
MV
247
248 (pass-if "guarding twice in one guardian"
249 (let ((g (make-guardian)))
250 (gc)
251 (let ((p (cons #f #f)))
252 (g p)
253 (g p))
254 (if (not (eq? (g) #f))
255 (throw 'unresolved)
256 (begin
257 (gc)
258 (or (and (and=> (g) (lambda (o) (equal? o (cons #f #f))))
259 (and=> (g) (lambda (o) (equal? o (cons #f #f)))))
260 (throw 'unresolved))))))
261
262 (pass-if "guarding twice in two guardians"
263 (let ((g (make-guardian))
264 (h (make-guardian)))
265 (gc)
266 (let ((p (cons #f #f)))
267 (g p)
268 (h p))
269 (if (not (eq? (g) #f))
270 (throw 'unresolved)
271 (begin
272 (gc)
273 (or (and (and=> (g) (lambda (o) (equal? o (cons #f #f))))
274 (and=> (h) (lambda (o) (equal? o (cons #f #f)))))
275 (throw 'unresolved)))))))
9247b5bc
DH
276
277 (with-test-prefix "guarding cyclic dependencies"
278 #t)
279
280 )