Testing Toolkit Phil Koopman, Jr
Total Page:16
File Type:pdf, Size:1020Kb
Forth-83 TESTING TOOLKIT PHIL KOOPMAN, JR. - WEXFORD,- PENNSYLVANIA One ofForth's strong points is its sup port of interactive development and test \ Forth testing support ing. Sometimes, however, interactive test \ By Philip Koopman Jr., for Harris Semiconductor \ Derived from test ing is not enough. code used for the RTX chip family During the development · \ Developed on F-TZ (an F-PC and F-83 derivative) version 3.Xll of low-level software for the RTX family, we wanted a method to create a permanent VARIABLE #STACK -1 #STACK! \ Saves number of stack elements for testing record of test cases for Forth words. This CRE.ATE R-SAVE 8 ALLOT \Note: F-TZ u·ses 32-bit return addresses! record serves as documentation for users and maintainers. In addition, a full suite of GET-DEPTH ( .. stack.stuff •• - .. stack.stuff .. ) DEPTH #STACK test cases for a program provides a way to @ -- #STACK ! ; be sure that a changein one part of the OS (. ( -- $BAD1 $BAD2 ) program does not disturb other parts of the \ !nit RS to -1 so that '-' will know it is a OS input program. \ Uses hex OBADi and hex OBAD2 as sentinel values for OS -1 #STACK ! $BAD1 $BAD2 ; How to Use It Each test case consists of code that RS ( ( -- $BAD3 $BAD4 ) \ Uses hex OBAD3 and hex OBAD4 as sent·inel va1ues for RS places elements on the data and return DEPTH #STACK ! $BAb3 $BAD4 ; stacks, creates and executes a test defini tion, then verifies that ihe correct results ( nl n2 n3 n.n - nl n2 n3 •• n.n sentinel ) were piaced on both stacks. For example, a #STACK @ O< NOT IF ( if RS( ) GET-DEPTH THEN test case for the word DUP would be: ?DATA ( nl n2 -- = NOT ABORT" DATA STACK ERROR" ?RETURN ( nl n2 -- ) The test case can be =. NOT ABORT" RETURN STACK ERROR" any sequence ofForth ( --) words. DEPTH #STACK PERCOIATE ( rl n.n .. nl -- n.n .. nl rl #STACK @ ROLL -1 #STACK +! DS ( 1111 - RS ( -- ) RS ( r. n • • r3 r2 r. 1 nl n2 n3 n. n -- TEST: DUP ;DONE GET-DEPTH #STACK @ ) RS IF BEGIN PERCOIATE ?RETURN #STACK @ O= UNTIL THEN $BAD4 ?RETURN $BAD3 -- 1111 1111 )DS ?RETURN -1 #STACK )OS ( r.n .. r3 r2 r.1 nl n2 n3 n.n -- ) . The first line of the test case specifies that GET-DEPTH #STACK @ the data stack input to the test is the number IF BEGIN PERCOIATE ?DATA #STACK @ O= UNTIL THEN 1111. The second line specifies that no $BAD2 ?DATA $BAD1 ?DATA -1 #STACK elements are to be placed onto· the return stack. The third line creates and executes a REVERSE ( n.1 n.2 .• n.n n -- n.n n.2 n.1 DUP O> IF 0 DO I ROLL LOOP ELSE temporary Forth word with a body of DUP, DROP THEN ; carefully handling the data and return stack !NIT-TEST ( •• OS.stuff.. • .RS.stuff.. -- •. OS.stuff •• contents before and after the test. The ( RS: -- .. RS. stuff •• ) fourth line specifies that no values- should Volume XII, Number 3 31 Forth Dimensions be left on the return stack, and generates an error message if this is not the case. The . CR ." TEST-" fSTACK @ O< ABORT" You Imlst specify both OS( and RS(." fifth line specifies that two values of the R> R-SAVE ! R> R-SAVE 2+ \ Save return address number 1111 should be returned from the fSTACK @ REVERSE test, again generating an error message if BEGIN fSTACK @ O> WHILE >R -1 #STACK + ! REPEAT this is not the case. It is very important that R-SAVE 2+ @ >R R-SAVE @ >R \ Restore return address the test cases be written in exactly this : FINISH-TEST ( .. OS.stuff .. -- .. OS.stuff ...• reversed.RS.stuff •. order, with no missing items, for proper ( RS: .. RS.stuff .. -- ) operation. R> R-SAVE ! R> R-SAVE 2+ ! \ Save return address The body of the test case between \ Transfer return stack contents onto data stack for later compare 0 >R TE T : and ; DONE can be any sequence of s BEGIN R> R> SWAP 1+ >R DUP $BAD3 = UNTIL Forth words, including primitives that ma R> REVERSE nipulate the return stack. The words R-SAVE 2+@ >R R-SAVE@ >R \.Restore return address INIT-TEST and FINISH-TEST are ." -DONE" -1 fSTACK ! automatically compiled with the test case to handle the data and return stacks for proper \ TEST and DONE use F-TZ specific words to compile a short execution. \ definition containing the word to be tested, execute that \ definition, then FORGET it from the dictionary. In order to be sure that a word is working \ This borrows a compilation idea from Rick van Norman's RTX test code properly, it is not enough to simply place CREATE MARKER 4 ALLOT the required number of parameters on the · · TESTER ; stack and then see if the correct results are TEST: ( --) XHERE 2DUP MARKER 2 ! PARAGRAPH + OUP XDPSEG 0 XDP returned. The problem is that a word may XSEG @ -- [ '] TESTER >BODY cause unexpected side effects (such as cor COMPILE !NIT-TEST ] ; ruption of elements on the data and return stacks) that are not detected immediately. ;DONE In order to handle this case, the test words COMPILE FINISH-TEST COMPILE EXIT place two "sentinel values" onto both the STATE OFF TESTER MARKER 2@ XDP XDPSEG data stack and the return stack, then check ;IMMEDIATE to ensure that no corruption has occurred. \ Test ROT for proper operation While side effects are usually not a problem OS( 1111 2222 3333 in high-level code, they can easily create RS( -- problems when dealing with assembly lan TEST: ROT ; DONE guage or microcode word implementa )RS tions. -- 2222 3333 1111 )OS Ideas for Further Refinements \ Test >R for proper operation The test capability presented here is OS( 5555 -- rather simple, in order to keep the code RS( -- (somewhat) understandable. Features that TEST: >R ;DONE 5555 )RS could be added to improve its usability -- )OS include: allowing RS ( ) RS to be optional, so tests that deal only with data stack opera tions could automatically generate and test \ Any combination may go between TEST: and ;DONE OS( 1111 2222 3333 -- return stack sentinel values; more sophisti RS( 7777 2222 9999 -- cated error messages that show exactly TEST: SWAP R> ROT >R ; DONE what is wrong with a stack when an error 7777 2222 3333 )RS does occur; methods to ensure that only -- 1111 2222 9999 )OS desired memory locations are modified for words that perform fetches and stores; and \ Null test to be sure it works methods to ensure that only desired on-chip OS( -- registers are modified for assembly lan RS( -- guage. definitions. TEST: ;DONE The code is written for F-1Z, a version )RS ofF-PC, developed by Tom Zimmer. F-PC -- )OS is a descendent of F-83, but allows using a dictionary space of greater than 64K bytes. The code presented should be relatively (Continued on page 41.) Forth Dimensions 32 Volume Xl/, Number 3 ...- International Forth BBS' s (Continuedfrompage 32.) (Continued from page 38.) • Melbourne FIG Chapter (03) 809-178Tin Australia portable to other 83-Standard Forths, as the current one. Malloc(), callocO, tal 6 l -3c809-1787 international long as the return-address-save sequences loc(), free() andfriendsall come down SysOp: Lance Collins in INIT-TEST and FINISH-TEST are to brk() and sbrk() in the end; So there • Forth BBS JEDI changed to save and restore only a single are "most primitive possible" func Paris, France return stack element for most other Forths. tions. So primitive in fact that nobody 33 364315 15 Also, TEST: and ; DONE should be rede in their right mind wants to use them if 7 data bits, 1 stop, even parity fined for use with other dictionary struc malloc() or something like it is avail • Max BBS (ForthNet link*) tures. able. United Kingdom Interactive testing is important and use 0905 754157 ful (and, in fact, there is no reason why Note that, while thisis true in Unix, it is SysOp: Jon Brooks these tools cannot be used as an interactive not necessarily true in other operating sys • Sky Port (ForthNet link*) testing format). However, once initial test tems. Consequently, while sbrk() is cer United Kmgdom ing is done, it is often useful to have a tainly the .primitive memory allocation 44-1-294-1006 permanent test suite in a consistent and operation for Unix, it does not necessarily SysOp: Andy Brimson readable format. Portions of many -pro even exist on all C implementations. In • _SweFIG grams are so crucial to system operation particular, I would expect that it would be Per Alm Sweden that they merit a full validation suite to difficult to properly implement sbrkO on 46-8~ 71-35751 prove correct operation. AtHarris, valida • NEXUS Servicios de Informacion, the Amiga (probably the Amiga C library S.L. tion suites are being used on the instruction simulates it with some restrictions). sbrkO Travesera de Dalt, 104-106, Entlo. sets of some of the RTX processors. The assumes that each process ~as its own ad 4_:_5 too ls presented here provide a starting point dress space, which is not generally tnie. Use 08024 Barcelona, Spain for creating a validation suite for a variety of sbrk() is not necessarily portable. _ +34 3 2103355 (voice) of applications. By the way, since brk() can be imple + 343 2147262 (modem) mented in terms of sbrk(), sbrk() is the true S ysOps: Jesus Consuegra, J uanma primitive on Unix systems. In mariy Unix Barranquero PhilipKoopmanJr. is a senior scien implementations, sbrk() is the true system [email protected] (preferred) tist at Harris Semiconductor and an call, and brk() is implemented as a library - [email protected] adjunct professor at Carnegie Mel routine,athin veneer around sbrk().