1 ;;;; miscellaneous side-effectful tests of LOAD
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; While most of SBCL is derived from the CMU CL system, the test
7 ;;;; files (like this one) were written from scratch after the fork
10 ;;;; This software is in the public domain and is provided with
11 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
12 ;;;; more information.
14 (defvar *tmp-filename
* "load-test.tmp")
16 ;;; Bug reported by Sean Ross: FASL loader set fill pointer to loaded
22 (with-open-file (s *tmp-filename
*
25 :if-does-not-exist
:create
)
26 (print '(setq *array
* #3a
(((1 2) (2 1)) ((3 4) (4 3)))) s
))
30 (setq tmp-fasl
(compile-file *tmp-filename
*))
33 (assert (arrayp *array
*))
34 (assert (= (array-rank *array
*) 3))
35 (assert (not (array-has-fill-pointer-p *array
*)))))
36 (when tmp-fasl
(delete-file tmp-fasl
))
37 (delete-file *tmp-filename
*))))
39 ;;; rudimentary external-format test
40 (dolist (ef '(:default
:ascii
:latin-1
:utf-8
))
41 (with-open-file (s *tmp-filename
*
44 :if-does-not-exist
:create
)
45 (print '(defun foo (x) (1+ x
)) s
))
50 (setq tmp-fasl
(compile-file *tmp-filename
* :external-format ef
))
52 (assert (= (foo 1) 2)))
53 (when tmp-fasl
(delete-file tmp-fasl
))
54 (delete-file *tmp-filename
*))))
56 ;;; As reported by David Tolpin *LOAD-PATHNAME* was not merged.
58 (defvar *saved-load-pathname
*)
59 (with-open-file (s *tmp-filename
*
62 :if-does-not-exist
:create
)
63 (print '(setq *saved-load-pathname
* *load-pathname
*) s
))
68 (assert (equal (merge-pathnames *tmp-filename
*) *saved-load-pathname
*)))
69 (delete-file *tmp-filename
*))))
71 ;;; Test many, many variations on LOAD.
72 (defparameter *counter
* 0)
73 (defparameter *loaded-pathname
* nil
)
74 (defparameter *loaded-truename
* nil
)
76 (defparameter *test-program-string
* (format nil
"~
78 (setf *loaded-pathname* *load-pathname*)
79 (setf *loaded-truename* *load-truename*)"))
81 (defmacro load-and-assert
(load-argument pathname truename
)
82 (let ((before (gensym)))
83 `(let ((,before
*counter
*)
84 *loaded-pathname
* *loaded-truename
*)
85 (load ,load-argument
:print t
:verbose t
)
86 (assert (and (= (1+ ,before
) *counter
*)
87 (equal ,(if pathname
`(merge-pathnames ,pathname
))
89 (equal ,(if pathname
`(merge-pathnames ,truename
))
90 *loaded-truename
*))))))
92 (defmacro with-test-program
(source fasl
&body body
)
97 (with-open-file (*standard-output
* ,src
:direction
:output
98 :if-exists
:supersede
)
99 (princ *test-program-string
*))
101 (compile-file ,src
:output-file
,fsl
))
105 (when (probe-file ,src
)
107 (when (and ,fsl
(probe-file ,fsl
))
108 (delete-file ,fsl
))))))
110 ;;; Loading from streams.
113 (with-input-from-string (s *test-program-string
*)
114 (load-and-assert s nil nil
))
116 ;; file-stream associated with a source file
117 (let ((source (pathname "load-impure-test.lisp")))
118 (with-test-program source nil
119 (with-open-file (stream source
)
120 (load-and-assert stream source source
))))
122 ;; file-stream associated with a fasl file
123 (let* ((source (pathname "load-impure-test.lisp"))
124 (fasl (compile-file-pathname source
)))
125 (with-test-program source fasl
126 (with-open-file (stream fasl
:element-type
'unsigned-byte
)
127 (load-and-assert fasl fasl fasl
))))
129 ;; Develop a simple Gray stream to test loading from.
130 (defclass load-impure-gray-stream
(fundamental-character-input-stream)
131 ((pointer :initform
0 :accessor load-impure-gray-stream-pointer
)))
133 (defmethod stream-read-char ((stream load-impure-gray-stream
))
134 (with-accessors ((pointer load-impure-gray-stream-pointer
)) stream
136 (if (>= pointer
(length *test-program-string
*))
138 (char *test-program-string
* pointer
))
141 (defmethod stream-unread-char ((stream load-impure-gray-stream
) char
)
142 (with-accessors ((pointer load-impure-gray-stream-pointer
)) stream
144 (error "fibber! you never read from this stream ~S" stream
)
148 (with-open-stream (stream (make-instance 'load-impure-gray-stream
))
149 (load-and-assert stream nil nil
))
151 ;;; Loading from things named by pathname designators.
153 ;; Test loading a source file by supplying a complete pathname.
154 (let ((source (pathname "load-impure-test.lisp")))
155 (with-test-program source nil
156 (load-and-assert source source source
)))
158 ;; Test loading a source file when supplying a partial pathname.
159 (let ((source (pathname "load-impure-test.lisp"))
160 (partial (pathname "load-impure-test")))
161 (with-test-program source nil
162 (load-and-assert partial source source
)))
164 ;; Test loading a source file whose name lacks a type when supplying a
166 (let ((source (make-pathname :type
:unspecific
167 :defaults
(pathname "load-impure-test")))
168 (partial (pathname "load-impure-test")))
169 (with-test-program source nil
170 (load-and-assert partial partial partial
)))
172 ;; Test loading a fasl
173 (let* ((source (pathname "load-impure-test.lisp"))
174 (fasl (compile-file-pathname source
)))
175 (with-test-program source fasl
176 (load-and-assert fasl fasl fasl
)))
178 ;; Test loading a fasl when supplying a partial pathname.
179 (let* ((source (pathname "load-impure-test.lisp"))
180 (fasl (compile-file-pathname source
))
181 (partial (pathname "load-impure-test")))
182 (with-test-program source fasl
183 (load-and-assert partial fasl fasl
)))
185 ;; Test loading a fasl whose name lacks a type when supplying a
187 (let* ((source (pathname "load-impure-test.lisp"))
188 (fasl (make-pathname :type
:unspecific
189 :defaults
(compile-file-pathname source
)))
190 (partial (pathname "load-impure-test")))
191 (with-test-program source fasl
192 (load-and-assert partial partial partial
)))
194 ;; Test loading a fasl with a strange type
195 (let* ((source (pathname "load-impure-test.lisp"))
196 (fasl (make-pathname :defaults
(compile-file-pathname source
)
197 :type
"compiled-lisp")))
198 (with-test-program source fasl
199 (load-and-assert fasl fasl fasl
)))
203 ;; Ensure that loading a fasl specified with a type checks for the
205 (let* ((source (pathname "load-impure-test.lisp"))
206 (fasl (compile-file-pathname source
)))
207 (with-test-program source fasl
208 (with-open-file (f fasl
:direction
:io
:if-exists
:overwrite
209 :element-type
'(unsigned-byte 8))
211 (handler-case (load fasl
)
212 (sb-fasl::fasl-header-missing
() :ok
))))
214 ;; Ensure that loading a fasl specified without a type checks for the
215 ;; header. Note: this wasn't the behavior in
216 ;; src/code/target-load.lisp v1.40 and earlier (SBCL version 1.0.12.35
217 ;; or so). If target-load.lisp is reverted to that state eventually,
218 ;; this test should be removed (or that definition of LOAD altered).
219 (let* ((source (pathname "load-impure-test.lisp"))
220 (fasl (compile-file-pathname source
))
221 (fasl-spec (make-pathname :type nil
222 :defaults
(compile-file-pathname source
))))
223 (with-test-program source fasl
224 (with-open-file (f fasl
:direction
:io
:if-exists
:overwrite
225 :element-type
'(unsigned-byte 8))
227 (handler-case (load fasl-spec
)
228 (sb-fasl::fasl-header-missing
() :ok
))))
230 ;; Ensure that we get an error when the source file is newer than the
231 ;; fasl and the supplied argument is an incomplete pathname.
232 (let* ((source (pathname "load-impure-test.lisp"))
233 (fasl (compile-file-pathname source
))
234 (spec (make-pathname :type nil
:defaults source
)))
235 (with-test-program source fasl
237 (with-open-file (*standard-output
* source
:direction
:output
239 (write-line ";;comment"))
240 (handler-case (load spec
)
241 ;; IWBNI the error signalled here were more specific than
243 (error () :|well
, we got an error
!|
))))
245 ;; Ensure that we can invoke the restart SOURCE in the above case.
246 (let* ((source (pathname "load-impure-test.lisp"))
247 (fasl (compile-file-pathname source
))
248 (spec (make-pathname :type nil
:defaults source
)))
249 (with-test-program source fasl
251 (with-open-file (*standard-output
* source
:direction
:output
253 (write-line ";;comment"))
254 (handler-bind ((error (lambda (error)
255 (declare (ignore error
))
256 (when (find-restart 'sb-fasl
::source
)
257 (invoke-restart 'sb-fasl
::source
)))))
258 (load-and-assert spec source source
))))
260 ;; Ensure that we can invoke the restart OBJECT in the above case.
261 (let* ((source (pathname "load-impure-test.lisp"))
262 (fasl (compile-file-pathname source
))
263 (spec (make-pathname :type nil
:defaults source
)))
264 (with-test-program source fasl
266 (with-open-file (*standard-output
* source
:direction
:output
268 (write-line ";;comment"))
269 (handler-bind ((error (lambda (error)
270 (declare (ignore error
))
271 (when (find-restart 'sb-fasl
::object
)
272 (invoke-restart 'sb-fasl
::object
)))))
273 (load-and-assert spec fasl fasl
))))
275 (with-test (:name
:bug-332
)
276 (flet ((stimulate-sbcl ()
277 (let ((filename (format nil
"/tmp/~A.lisp" (gensym))))
278 ;; create a file which redefines a structure incompatibly
279 (with-open-file (f filename
:direction
:output
:if-exists
:supersede
)
280 (print '(defstruct bug-332 foo
) f
)
281 (print '(defstruct bug-332 foo bar
) f
))
282 ;; compile and load the file, then invoke the continue restart on
283 ;; the structure redefinition error
284 (handler-bind ((error (lambda (c) (continue c
))))
285 (load (compile-file filename
))))))