EuroAssembler Index Manual Download Source Macros


Sitemap Links Forum Tests Projects

testman.htm
Data
EraseTemporaryFiles
Header
Main
RunTest

Project Test manager is the source text of compiled 32bit Windows executable program testman.exe used to run EuroAssembler tests.

This utility is an alternative to the script version of Test Manager.


Format
PE 32bit FLAT CON
Platform
MS Windows 32bit and 64bit.
Build
Compile in prowin32 subdirectory with command euroasm testman.htm.
Output
Built target executable file is ..\eatests\testman.exe
Run
Execute testman.exe in ..\eatests\ subdirectory with command testman t1234, t13*, testman * etc.
        EUROASM Unicode=off
testman PROGRAM Format=PE, Width=32, Entry=Start:, OutFile="..\eatests\testman.exe"
          INCLUDEHEAD1 wins.htm, winscon.htm, winssec.htm, winsfile.htm, winfile.htm, winapi.htm, \
                       status32.htm, cpuext.htm, cpuext32.htm, stdcal32.htm, string32.htm
          ; Specification of files which might be created during the test.
%TemporaryFilesExtensions %SET .asm, .i.asm, .j.asm, .k.asm, \ explicit sources,
                               .exp.lst, .htm.lst, .asm.lst, \ expected and obtained listing,
                               .exp.msg, .msg,               \ expected and obtained messages,
                               .exp.hex, .hex,               \ expected and obtained hexadecimal dump,
                               .ext                          ; object file expected extension specification.
Data
Statically declared and initialized memory variables are defined in segment [.data] , uninitialized memory variables in segment [.bss].
[.data]
StartupInfo        DS STARTUP_INFO        ; Windows API structures for running the test.
ProcessInformation DS PROCESS_INFORMATION
SecurityAttributes DS SECURITY_ATTRIBUTES
Errorlevel: DD 0 ; 0=all tests passed, 2=some test failed, 4=file access error, 8=syntax error.
ArgCnt:     DD 0 ; Number of remaining testman.exe command-line arguments.
ArgNr:      DD 0 ; Ordinal number of testman.exe argument.
PassedCnt:  DD 0 ; Number of passed tests.
FailedCnt:  DD 0 ; Number of failed tests.
StartTime:  DD 0 ; Milliseconds since Windows boot.
test.htm:   DS FILE ; FILE structures for files created during testing.
mask.htm:   DS FILE
tempfile:   DS FILE
euroasm.ini DS FILE
ext %FOR %TemporaryFilesExtensions
test%ext:   DS FILE
    %ENDFOR ext
HelpText:
 DB 13,10
 DB 'Program "testman.exe" will check EuroAssembler functionality using test files.',13,10
 DB 'It should be run in EuroAssembler subdirectory "eatests".',13,10
 DB '"testman.exe" erases configuration files "..\easource\euroasm.ini"',13,10
 DB 'and "..\eatests\euroasm.ini".',13,10
 DB 'The checked version of EuroAssembler is "..\easource\euroasm.exe".',13,10
 DB 13,10
 DB '"testman.exe" will extract temporary files from the test file',13,10
 DB 'and then it will compile and link the extracted source.',13,10
 DB 'Finally it compares obtained listing, messages and object file',13,10
 DB 'with expected templates stored in the test file',13,10
 DB 'and claim the test as "passed" if they match.',13,10
 DB 'Temporary files are erased only if the test has succesfully passed.',13,10
 DB 13,10
 DB 'Tests may be specified as file mask(s), for instance',13,10
 DB '  testman.exe t1234.htm t1235.htm t42??.htm"',13,10
 DB 'File extension ".htm" as well as prefix "t" may be omitted, for instance',13,10
 DB '  testman.exe 7??? 8???   or  testman * (launch all tests).',13,10
 DB 0
test:        DB "t????",0
mask:        DB "t????.htm",0
command:     DB "..\easource\euroasm.exe ",0 ; The tested version of EuroAssembler.
params:      DB ", TIMESTAMP=0, NOWARN=0010..0170, NOWARN=0980, NOWARN=1160",0
Error:       DB "Internal error 0x"
ErrCode:     DB "???????? accessing file ",0
AllPassed:   DB 'All '
AllTests:    DB '???? tests passed',0
PassedTests: DB '???? tests passed,'
FailedTests: DB '???? tests failed',0
Duration:    DB ' in'
Seconds:     DB '???? seconds.',13,10,0
;;
[.bss]       ; Reserved, not initialized memory.
DumpAddr:    D DWORD
DumpLine:    D  64 * BYTE
CmdLine:     D 128 * BYTE
Ext:         D  12 * BYTE  ; Extension of object file, e.g. ".lib".
Status:      D DWORD       ; Status flags in following encoding:
stFailed     = 1  ; Test failed.
stListing    = 2  ; Listing are different.
stMessages   = 4  ; Messages are different.
stObject     = 8  ; Object dumps are different.
stA          = 16 ; Assembler source <!--A--> is present in test file.
stB          = 32 ; Object dump <!--B--> is present in test file.
Main
This is the program code entry which reads command-line arguments and calls subprocedure RunTest for each resolved test file.
[.text]
Start::
  WinAPI GetTickCount
  MOV [StartTime],EAX
  GetArgCount ; Macro from library winapi.htm.
  JNC ArgCountOK:
Help:         ; When testman.exe was provided with none or wrong test number.
  StdOutput HelpText
  ORB [Errorlevel],8
  JMP End:
ArgCountOK:
  MOV [ArgCnt],ECX
  JECXZ Help:    ; If run without arguments.
  FileAssign euroasm.ini,=B"..\easource\",=B"euroasm.ini"
  FileDelete euroasm.ini  ; Make sure that no global or local euroasm.ini will interfere.
  FileAssign euroasm.ini,=B"..\eatests\",=B"euroasm.ini"
  FileDelete euroasm.ini
NextArg:  ; Parse command-line arguments.
  MOV EAX,[ArgNr]
  INC EAX
  MOV [ArgNr],EAX
  GetArg EAX
  JC Help:
  ; ESI,ECX is now one command-line argument, e.g. "t1234" or "/?".
  LEA EDX,[ESI+ECX] ; EDX points to the end of input string.
  CMPB [ESI],'/'
  JE Help:
  CMPB [ESI],'-'
  JE Help:
  MOV EDI,mask:
  MOVD [EDI+1],'????' ; Reinitialize the test name mask with wildcards.
  MOV AL,'t'
NextChar:
  CMP EDI,mask: + 5
  JAE Mask3:
  STOSB
SkipChar:
  CMP ESI,EDX
  JNB Mask3: ; If no more characters to parse.
  LODSB
  CMP AL,'?'
  JE NextChar:
  CMP AL,'*'
  JE Mask3:
  CMP AL,'0'
  JB SkipChar:
  CMP AL,'9'
  JA SkipChar: ; Skip nondigit and nonwild characters.
  JMP NextChar:
Mask3:
  FileAssign mask.htm:, mask:
  FileEach mask.htm:, RunTest ; Perform RunTest with all wildcard-resolved files.
  DEC [ArgCnt]
  JNZ NextArg: ; If provided with more than one argument.
  WinAPI GetTickCount
  SUB EAX,[StartTime] ; EAX is now duration af all tests in miliseconds.
  JC Report1:
  MOV ECX,1000
  SUB EDX,EDX
  DIV ECX
  StoD Seconds, Size=4, Align=right
Report1:
  MOV EAX,[PassedCnt]
  StoD PassedTests, Size=4, Align=right
  StoD AllTests, Size=4, Align=right
  MOV EAX,[FailedCnt]
  StoD FailedTests, Size=4, Align=right
  MOV ESI,PassedTests:
  TEST EAX ; Did any test fail?
  JNZ Report2:
  MOV ESI,AllPassed:
Report2:
  ADD EAX,[PassedCnt]
  CMP EAX,1
  JNA End: ; Skip report if only one test was performed.
  StdOutput ESI,Duration
End:TerminateProgram [Errorlevel]
RunTest
This is a callback procedure which executes one test assigned in file mask.htm, and compares test results.
It continuously reports test name and result on standard output.
Input
ESI= is pointer to zero-terminated, wildcard-resolved test file name, e.g. t1234.htm.
Called from
FileEach macro invoked at Main.Mask3:.
RunTest PROC
    MOV EDI,test:
    MOV ECX,5
    REP MOVSB
    StdOutput test:, =B" ... "
ext %FOR %TemporaryFilesExtensions
      FileAssign test%ext:, test:, =B"%ext"
    %ENDFOR ext
    CALL EraseTemporaryFiles
    XOR EAX,EAX
    MOV [Status],EAX
    FileAssign  test.htm, test:, =B".htm"
    FileStreamOpen test.htm
    JC .Error:
.NextLine:
    FileStreamReadLn test.htm ; Parse test file and write its divisions to temporary files.
    JC .Error:
    JZ .CloseWrittenFiles: ; If no more lines.
    MOV ECX,EAX
    StripSpaces ESI,ECX
    CMPB [ESI],'<'                                                                                        ; >
    JE .Marker?:
    MOV EBX,test.exp.lst
    CMP [EBX+FILE.Handle],INVALID_HANDLE_VALUE ; Is the file already open?
    JNZ .StoreLstLine:
    FileStreamCreate EBX
    JC .Error:
.StoreLstLine:
    FileStreamWriteLn EBX,ESI,ECX
    JC .Error:
    JMP .NextLine:
.Marker?:
    CMPD [ESI],'      ; Is it the marker beginning with <!-- ?
    JNE .NextLine:
    MOV EAX,[ESI+4]
    MOV EDX,EAX
    SHR EDX,8
    CMP EDX,'-->'     ; Is it the marker ending with --> ?
    JNE .NextLine:
    ADD ESI,8 ; Size of marker.
    SUB ECX,8
    JB .Error:
    Dispatch AL, 'M','A','I','J','K','E','B'
    JMP .NextLine: ; Ignore other markers.
.StoreDivisionLine:
    CMP [EBX+FILE.Handle],INVALID_HANDLE_VALUE ; It the file already open?
    JNE .StoreLine:
    FileStreamCreate EBX
    JC .Error:
.StoreLine:
    FileStreamWriteLn EBX,ESI,ECX
    JC .Error:
    JMP .NextLine:
.M: MOV EBX,test.exp.msg
    JMP .StoreDivisionLine:
.A: SetSt [Status],stA
    MOV EBX,test.asm
    JMP .StoreDivisionLine:
.I: MOV EBX,test.i.asm
    JMP .StoreDivisionLine:
.J: MOV EBX,test.j.asm
    JMP .StoreDivisionLine:
.K: MOV EBX,test.k.asm
    JMP .StoreDivisionLine:
.E: SetSt [Status],stB
    MOV EBX,test.ext
    JMP .StoreDivisionLine:
.B: SetSt [Status],stB
    MOV EBX,test.exp.hex
    CMP ECX,53
    JBE .B5:
    MOV ECX,53 ; Trim off the character column of the dump.
.B5:StripSpaces ESI,ECX
    JMP .StoreDivisionLine:
.CloseWrittenFiles:
    FileClose test.htm, test.asm, test.i.asm, test.j.asm, test.k.asm, test.ext, test.exp.lst, test.exp.msg, test.exp.hex
    JNSt [Status],stB,.ExecTest: ; If output object file won't be checked in this test.
    FileLoad test.ext ; File exists if  marker specified output extension.
    JNC .ObjExt:
    SetSt [Status],stFailed+stObject
    JMP .ExecTest:
.ObjExt:
    MOV ECX,EAX ; File size.
    StripSpaces ESI,ECX
    MOV AL,'.'
    MOV EDI,Ext:
    CMP [ESI],AL
    JE .StoreExt:
    STOSB
.StoreExt:
    REP MOVSB
    FileDelete test.ext
    FileAssign test.ext, test:, Ext: ; Reassign with the extension depending on program format.
.ExecTest:; Execute the test.
    MOV ESI,=B".htm"
    MOV EBX,test.htm.lst
    JNSt [Status],stA,.CmdLine:
    MOV ESI,=B".asm"
    MOV EBX,test.asm.lst
.CmdLine:
    Concat$ CmdLine:, command:, test:, ESI, params:
    MOV ECX,SIZE# SecurityAttributes
    XOR EAX,EAX
    MOV [SecurityAttributes.nLength],ECX
    MOV [SecurityAttributes.lpSecurityDescriptor],EAX
    INC EAX
    MOV [SecurityAttributes.bInheritHandle],EAX
    MOV ESI,test.msg.Name ; Filename to capture standard output messages.
    WinAPI CreateFileA,ESI,FILE_APPEND_DATA,FILE_SHARE_WRITE|FILE_SHARE_READ, \
           SecurityAttributes,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
    CMP EAX,INVALID_HANDLE_VALUE
    JE .Error:
    MOV [test.msg.Handle],EAX
    MOV ECX,SIZE# StartupInfo
    MOV EDX,STARTF_USESTDHANDLES
    MOV [StartupInfo.cb],ECX
    MOV [StartupInfo.hStdOutput],EAX
    MOV [StartupInfo.dwFlags],EDX
    WinAPI CreateProcess,0,CmdLine:,0,0,1,0,0,0,StartupInfo,ProcessInformation
    TEST EAX
    JZ .Error:
    WinAPI WaitForSingleObject,[ProcessInformation.hProcess],10k ; Until euroasm.exe finishes the test.
    WinAPI CloseHandle,[test.msg.Handle]
    ; Compare listing.
    MOV EBX,test.htm.lst
    JNSt [Status],stA,.LstLoad
    MOV EBX,test.asm.lst
.LstLoad:
    FileLoad EBX ; Obtained listing.
    JC .LstFail:
    FileLoad test.exp.lst ; Expected listing.
    JC .LstFail:
    MOV ESI,[EBX+FILE.BufPtr]
    MOV ECX,[EBX+FILE.BufSize]
    MOV EDI,[test.exp.lst.BufPtr]
    CMP ECX,[test.exp.lst.BufSize]
    JNE .LstFail:
    REPE CMPSB
    JE .CmpMsg:
.LstFail:
    SetSt [Status],stFailed + stListing
.CmpMsg:; Compare messages.
    FileLoad test.msg ; Obtained messages.
    JC .MsgFail:
    FileLoad test.exp.msg ; Expected messages.
    JC .MsgFail:
    MOV ESI,[test.msg.BufPtr]
    MOV ECX,[test.msg.BufSize]
    MOV EDI,[test.exp.msg.BufPtr]
    CMP ECX,[test.exp.msg.BufSize]
    JNE .MsgFail:
    REPE CMPSB
    JE .MsgOK:
.MsgFail:
    SetSt [Status],stFailed + stMessages
.MsgOK:
    JNSt [Status],stB,.ObjOK:
    ; Compare target object executable file.
    ; Convert output file test.ext to hexadecimal dump test.hex.
    FileStreamCreate test.hex
    JC .ObjFail:
    FileLoad test.ext ; Obtained target binary output file.
    JC .ObjFail:
    MOV ESI,[test.ext.BufPtr]
    MOV EDX,[test.ext.BufSize]
    ADD EDX,ESI ; End of dumped data.
    MOV [DumpAddr],-16
.NextDumpLine: ; Prepare one dump row into DumpLine.
    MOV EDI,DumpLine
    MOV EAX,[DumpAddr]
    ADD EAX,16
    MOV [DumpAddr],EAX
    AND EAX,0x0000FFFF
    StoH EDI,Size=4
    MOV AL,':'
    STOSB
    MOV ECX,16 ; Prepare max. 16 hex bytes.
.NextDumpByte:
    CMP ESI,EDX
    JNB .WriteDumpLine:
    XOR EAX,EAX
    MOV AL,' ' ; Space separation.
    STOSB
    LODSB
    StoH EDI,Size=2 ; Dump one byte.
    LOOP .NextDumpByte:
.WriteDumpLine:
    SUB EDI,DumpLine ; Written line size.
    FileStreamWriteLn test.hex:, DumpLine,EDI
    CMP ESI,EDX
    JB .NextDumpLine:
    FileClose test.hex:
    ; Compare hexadecimal dumps.
    FileLoad test.hex ; Obtained dump.
    JC .ObjFail:
    FileLoad test.exp.hex ; Expected dump.
    JC .ObjFail:
    MOV ESI,[test.hex.BufPtr]
    MOV ECX,[test.hex.BufSize]
    MOV EDI,[test.exp.hex.BufPtr]
    CMP ECX,[test.exp.hex.BufSize]
    JNE .ObjFail:
    REPE CMPSB
    JE .ObjOK:
.ObjFail:
    SetSt [Status],stFailed + stObject
.ObjOK:
    MOV EBX,test.htm.lst
    JNSt [Status],stA,.CloseExpFiles:
    MOV EBX,test.asm.lst
.CloseExpFiles:
    FileClose EBX, test.exp.lst, test.msg, test.exp.msg
    JNSt [Status],stB,.Evaluate:
    FileClose test.ext, test.hex, test.exp.hex
.Evaluate:
    JSt [Status],stFailed,.Failed:
    StdOutput ="passed.", Eol=yes
    INCD [PassedCnt]
    CALL EraseTemporaryFiles
    JMP .ObjectOK:
.Error: ; EBX=^FILE
    ORB [Errorlevel],4
    WinAPI GetLastError
    StoH ErrCode,Size=8
    StdOutput Error:
    LEA ESI,[EBX+FILE.Name]
    StdOutput ESI, Eol=yes
    STC ; Break further FileEach wildcard resolving.
    JMP .EndRun:
.Failed:
    StdOutput ="failed:", Eol=yes
    INCD [FailedCnt]
    ORB [Errorlevel],2
    JNSt [Status],stListing,.ListingOK:
    LEA ESI,[EBX+FILE.Name]
    StdOutput ='Obtained listing "', ESI, ='" differs from expected "', \
              test.exp.lst.Name, ='".', Eol=yes
.ListingOK:
    JNSt [Status],stMessages,.MessagesOK:
    StdOutput ='Obtained message "', test.msg.Name, ='"     differs from expected "', \
              test.exp.msg.Name, ='".', Eol=yes
.MessagesOK:
    JNSt [Status],stObject,.ObjectOK:
    StdOutput ='Obtained  output "',test.hex.Name,='"     differs from expected "', \
              test.exp.hex.Name, ='".', Eol=yes
.ObjectOK:
    CLC ; CF=0 to continue FileEach with the next test.
.EndRun:
    RET
  ENDP RunTest
EraseTemporaryFiles
Files with extensions declared in Header are deleted.
Only the file with extension .htm (test source) survives.
Called from
RunTest before the test is performed, and after it has passed OK.
EraseTemporaryFiles PROC ; Delete all test*.* files except for test.htm.
   FileAssign tempfile, test:, =B"*.*"
   FileEach tempfile, EraseTempfile
   RET
EraseTempfile PROC ; Callback from FileEach to erase one FILE EBX whose name is at ESI.
       CMPB [ESI+9],0
       JNE .Erase:
       MOV EAX,[ESI+5]
       OR EAX,0x20202000 ; Convert the resolved file extension to lower case.
       CMP EAX,".htm"
       JE .Skip: ; Do not delete the test file itself.
.Erase:FileDelete EBX
.Skip: RET ; CF=0 to continue with FileEach.
     ENDPROC EraseTempfile
   ENDPROC EraseTemporaryFiles
 ENDPROGRAM testman

▲Back to the top▲