Stress test for hash resizing.
[m4.git] / tests / modules.at
blob0d81848187c8a5cf659f4c3fcf1d4c16cf940e65
1 # Hand crafted tests for GNU M4.                               -*- Autotest -*-
2 # Copyright (C) 2001, 2006, 2007, 2008 Free Software Foundation, Inc.
4 # This file is part of GNU M4.
6 # GNU M4 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 3 of the License, or
9 # (at your option) any later version.
11 # GNU M4 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.
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 AT_BANNER([Module support.])
23 ## --------- ##
24 ## modfreeze ##
25 ## --------- ##
27 AT_SETUP([Freezing modules])
28 AT_KEYWORDS([frozen])
29 AT_CHECK_DYNAMIC_MODULE
31 AT_DATA([[frozen.m4]],
32 [[divert(1)dnl
33 define(`test', `local::`test'')dnl
34 define(`test1', defn(`test'))dnl
35 ->test
36 load(`modtest')
37 define(`test2', defn(`test'))dnl
38 ->test
39 load(`shadow')
40 define(`test3', defn(`test'))dnl
41 ->test
42 ]])
44 AT_DATA([[unfrozen.m4]],
45 [[undivert(1)dnl
46 test1
47 test2
48 test3
49 ]])
51 # First generate the `expout' ouput by running over the sources before
52 # freezing.
53 AT_CHECK_M4([-M "$abs_builddir" -m load frozen.m4 unfrozen.m4],
54             [0], [stdout], [stderr])
56 mv stdout expout
57 mv stderr experr
59 # Now freeze the first source file.
60 AT_CHECK_M4([-M "$abs_builddir" -m load -F frozen.m4f frozen.m4],
61             [0], [], [ignore])
63 # Now rerun the original sequence, but using the frozen file.
64 AT_CHECK_M4([-M "$abs_builddir" -R frozen.m4f unfrozen.m4],
65             [0], [expout], [experr])
67 AT_CLEANUP([frozen.m4f])
70 ## ------------------ ##
71 ## module test macros ##
72 ## ------------------ ##
74 AT_SETUP([module test macros])
75 AT_CHECK_DYNAMIC_MODULE
76 AT_CHECK_GMP
78 AT_DATA([in], [[load(`mpeval')
79 -__load__-__mpeval__-
80 unload(`mpeval')
81 -__load__-__mpeval__-
82 unload(`load')
83 -__load__-__mpeval__-
84 ]])
86 AT_CHECK_M4([-m load in], [0], [[
87 ---
89 --__mpeval__-
91 -__load__-__mpeval__-
92 ]])
94 AT_CLEANUP
97 ## ---------------------------- ##
98 ## Exercising the test module.  ##
99 ## ---------------------------- ##
101 # AT_CHECK_M4_MODTEST(TITLE, ENV-VARS, M4-OPTIONS)
102 # ------------------------------------------------
103 # Add a test named TITLE, running m4 with either ENV-VARS in the environment
104 # or M4-OPTIONS set to pick up test modules.
105 m4_define([AT_CHECK_M4_MODTEST],
106 [AT_SETUP([$1])
107 AT_CHECK_DYNAMIC_MODULE
109 AT_DATA([input.m4],
110 [[load(`modtest')
111 test
112 Dumpdef: dumpdef(`test').
113 unload(`modtest')
114 test
115 Dumpdef: dumpdef(`test').
118 dnl Fortunately, all tests within AT_SETUP are in the same subshell, so
119 dnl setting the environment now will impact the AT_CHECK_M4, but not
120 dnl carry over to the next AT_SETUP.
121 m4_ifval([$2], [$2
122 export m4_substr([$2], [0], m4_index([$2], [=]))])
124 AT_CHECK_M4([-m load $3 input.m4], [0],
126 Test module called.
127 Dumpdef: .
129 test
130 Dumpdef: .
132 [[Test module loaded.
133 test:   <test>
134 Test module unloaded.
135 m4:input.m4:6: Warning: dumpdef: undefined macro `test'
138 AT_CLEANUP
143 AT_CHECK_M4_MODTEST([--module-directory: absolute path],
144                     [], [-M "$abs_builddir"])
146 AT_CHECK_M4_MODTEST([--module-directory: relative path],
147                     [], [-M "$top_build_prefix/tests"])
149 AT_CHECK_M4_MODTEST([M4MODPATH: absolute path],
150                     [M4MODPATH="$abs_builddir"], [])
152 AT_CHECK_M4_MODTEST([M4MODPATH: relative path],
153                     [M4MODPATH="$top_build_prefix/tests"], [])
155 AT_CHECK_M4_MODTEST([LTDL_LIBRARY_PATH: absolute path],
156                     [LTDL_LIBRARY_PATH="$abs_builddir"], [])
158 AT_CHECK_M4_MODTEST([LTDL_LIBRARY_PATH: relative path],
159                     [LTDL_LIBRARY_PATH="$top_build_prefix/tests"], [])
164 ## ------ ##
165 ## shadow ##
166 ## ------ ##
168 AT_SETUP([modules: shadow])
169 AT_CHECK_DYNAMIC_MODULE
171 AT_DATA([[input.m4]],
172 [[# no modules loaded yet
173 test
174 shadow
176 # define our own macros for `test' and `shadow'
177 define(`test', `local::`test'')
178 define(`shadow', `local::`shadow'')
179 test
180 shadow
182 # module Shadow defines `shadow' and `test' macros
183 load(`shadow')
184 dumpdef(`test')
185 dumpdef(`shadow')
186 test
187 shadow
189 # save the definition of `test' from the Shadow module
190 define(`Shadow::test', defn(`test'))
192 # module Modtest also defines a `test' macro
193 load(`modtest')
194 dumpdef(`test')
195 dumpdef(`shadow')
196 test
197 shadow
199 # Reloading Shadow shouldn't affect anything
200 load(`shadow')
201 dumpdef(`test')
202 dumpdef(`shadow')
203 test
204 shadow
206 # Unloading Modtest will unshadow the test definition in Shadow
207 unload(`modtest')
208 dumpdef(`test')
209 dumpdef(`shadow')
210 test
211 shadow
213 # Unloading Shadow once has no effect (we loaded it twice)
214 unload(`shadow')
215 dumpdef(`test')
216 dumpdef(`shadow')
217 test
218 shadow
220 # Unloading Shadow again will revert to copying `test' and the local
221 # `shadow' macro.
222 unload(`shadow')
223 test
224 shadow
227 AT_DATA([[expout]],
228 [[# no modules loaded yet
229 test
230 shadow
232 # define our own macros for `test' and `shadow'
235 local::test
236 local::shadow
238 # module Shadow defines `shadow' and `test' macros
239 Shadow module loaded.
242 Shadow::test called.
243 Shadow::shadow called.
245 # save the definition of `test' from the Shadow module
248 # module Modtest also defines a `test' macro
252 Test module called.
253 Shadow::shadow called.
255 # Reloading Shadow shouldn't affect anything
259 Test module called.
260 Shadow::shadow called.
262 # Unloading Modtest will unshadow the test definition in Shadow
266 Shadow::test called.
267 Shadow::shadow called.
269 # Unloading Shadow once has no effect (we loaded it twice)
273 Shadow::test called.
274 Shadow::shadow called.
276 # Unloading Shadow again will revert to copying `test' and the local
277 # `shadow' macro.
279 local::test
280 local::shadow
283 AT_DATA([[experr]],
284 [[test: <test>
285 shadow: <shadow>
286 Test module loaded.
287 test:   <test>
288 shadow: <shadow>
289 test:   <test>
290 shadow: <shadow>
291 Test module unloaded.
292 test:   <test>
293 shadow: <shadow>
294 test:   <test>
295 shadow: <shadow>
298 AT_CHECK_M4([-M "$abs_builddir" -m load input.m4], [0],
299             [expout], [experr])
301 AT_CLEANUP
305 ## ------ ##
306 ## unload ##
307 ## ------ ##
309 AT_SETUP([modules: unload])
310 AT_CHECK_DYNAMIC_MODULE
312 AT_DATA([[input.m4]],
313 [[test
314 __test__
315 load(`modtest')
316 test
317 __test__
318 load(`shadow')
319 test
320 __test__
321 unload(`modtest')
322 test
323 __test__
324 load(`modtest')
325 test
326 __test__
327 unload(`modtest')
328 test
329 __test__
330 unload(`shadow')
331 test
332 __test__
335 AT_DATA([[expout]],
336 [[test
337 __test__
339 Test module called.
340 modtest
341 Shadow module loaded.
342 Shadow::test called.
343 shadow
345 Shadow::test called.
346 shadow
348 Test module called.
349 modtest
351 Shadow::test called.
352 shadow
354 test
355 __test__
358 AT_DATA([[experr]],
359 [[Test module loaded.
360 Test module unloaded.
361 Test module loaded.
362 Test module unloaded.
366 AT_CHECK_M4([-M "$abs_builddir" -m load input.m4],
367             [0], [expout], [experr])
369 AT_CLEANUP
373 ## ----------------------- ##
374 ## module symbol importing ##
375 ## ----------------------- ##
377 # Importing a symbol from a not yet loaded module
379 # This test is ugly, because we need to canonicalize strerror strings
380 # to match our test.  So we save STDERR to a file, and run another check
381 # which edits that file and compares it to the canonical STDERR output
382 # from the first command:
384 AT_SETUP([modules: importing])
385 AT_CHECK_DYNAMIC_MODULE
387 AT_DATA([[input.m4]],
388 [[import
389 load(`import')
390 import
391 unload(`modtest')
392 import
393 symbol_fail
394 module_fail
397 AT_DATA([[expout]],
398 [[import
400 import::import called.
402 import::import called.
403 import::symbol_fail called.
406 AT_DATA([[experr]],
407 [[Test module loaded.
409 TRUE
410 Test module unloaded.
411 Test module loaded.
413 TRUE
414 m4:input.m4:6: cannot load symbol `no_such' from module `modtest'
415 m4:input.m4:7: cannot open module `no_such'
418 AT_CHECK_M4([-M "$abs_builddir" -m load input.m4],
419             [1], [expout], [experr])
421 AT_CLEANUP
425 ## ------------------- ##
426 ## text module symbols ##
427 ## ------------------- ##
429 # Support text macros with requested numbers of parameters.
431 AT_SETUP([modules: text])
432 AT_CHECK_DYNAMIC_MODULE
434 AT_DATA([input.m4],
435 [[__test__
436 __test__(1)
437 __test__(1,2)
438 onearg
439 onearg(1)
440 onearg(1,2)
441 manyargs
442 manyargs(1)
443 manyargs(1,2)
446 AT_CHECK_M4([-M "$abs_builddir" -m modtest input.m4], [0],
447 [[modtest
448 modtest
449 modtest
456 ]], [[Test module loaded.
457 m4:input.m4:2: Warning: __test__: extra arguments ignored: 1 > 0
458 m4:input.m4:3: Warning: __test__: extra arguments ignored: 2 > 0
459 m4:input.m4:4: Warning: onearg: too few arguments: 0 < 1
460 m4:input.m4:6: Warning: onearg: extra arguments ignored: 2 > 1
461 Test module unloaded.
464 AT_CLEANUP
467 ## -------------------- ##
468 ## trace module symbols ##
469 ## -------------------- ##
471 # The trace bit should not be lost if a builtin is unloaded from
472 # memory and then redefined by a subsequent load.
474 AT_SETUP([modules: trace])
475 AT_CHECK_DYNAMIC_MODULE
477 AT_DATA([[input.m4]],
478 [[test
479 load(`shadow')
480 test
481 unload(`shadow')
482 test
483 load(`shadow')
484 test
487 AT_DATA([[expout]],
488 [[test
489 Shadow module loaded.
490 Shadow::test called.
492 test
493 Shadow module loaded.
494 Shadow::test called.
497 AT_DATA([[experr]],
498 [[m4trace: -1- test -> `Shadow::`test' called.'
499 m4trace: -1- test -> `Shadow::`test' called.'
503 AT_CHECK_M4([-M "$abs_builddir" -m load -t test input.m4],
504             [0], [expout], [experr])
506 AT_CLEANUP
509 ## ----------------- ##
510 ## unload gnu module ##
511 ## ----------------- ##
513 AT_SETUP([unload gnu module])
514 AT_CHECK_DYNAMIC_MODULE
516 dnl Ensure that the gnu module does not leak memory.  I don't know how
517 dnl to portably artificially limit the heap to cause an out-of-memory
518 dnl condition in the case of a leak, but examining the run of this test
519 dnl in a debugger can show whether it is leaking.
520 AT_DATA([input.m4], [[divert(-1)
521 define(`forloop',
522   `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
523 define(`_forloop',
524   `$4`'ifelse($1, `$3', `',
525     `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
526 forloop(`i', `1', `5000', `unload(`gnu')load(`gnu')regexp(`123', `\(4\)?2')')
529 AT_CHECK_M4([-m load input.m4], [0])
531 AT_CLEANUP
534 ## ------------------ ##
535 ## unload load module ##
536 ## ------------------ ##
538 AT_SETUP([unload load module])
539 AT_CHECK_DYNAMIC_MODULE
541 dnl Ensure that the load module can be unloaded and reloaded (obviously,
542 dnl it can't reload itself; the reload occurs on the command line).  Since
543 dnl the module must be resident (after all, the `unload' builtin had better
544 dnl not unmap the memory for the code it is currently executing), make sure
545 dnl that resident modules are handled gracefully.
546 AT_DATA([in1.m4], [[__load__ 1
547 unload(`load') 2
548 __load__ 3
551 AT_DATA([in2.m4], [[__load__ 4
552 load(`load') 5
553 __load__ 6
554 unload(`load') 7
555 __load__ 8
556 unload(`load') 9
557 __load__ 10
560 AT_CHECK_M4([-m load in1.m4 -m load in2.m4], [0],
561 [[ 1
563 __load__ 3
570 __load__ 10
573 AT_CLEANUP