| Index | Manual | Download | Source | Macros | Embedded word Case ins.
Sitemap | Links | Forum | Tests | Projects

# testman.htm
Data
EraseTemporaryFiles
Header
Main
RunTest

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

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

Format
  PE 32-bit FLAT CON
Platform
  MS Windows 32-bit and 64-bit.
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.exe t1234, t13*`, `testman *` etc.

Header

  The header defines program format, imported libraries, used temporary files.

  > As this program only uses core WinAPI functions from kernel32.dll , no import library is linked.

            EUROASM Unicode=off
    testman PROGRAM Format=PE, Width=32, Entry=Start:, OutFile="..\eatests\testman.exe"
              INCLUDEHEAD1 wins.htm, winscon.htm, winssec.htm, winsfile.htm, winf32.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 the segment `[.data]` , uninitialized memory variables in the 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.
    FirstFILE:
    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
    LastFILE:
    HelpText:
     DB 13,10
     DB 'File "testman.exe" is the Windows version of program "testman"',13,10
     DB ' which will check the functionality of EuroAssembler with test files.',13,10
     DB 'Testman should be run in EuroAssembler subdirectory "eatests".',13,10
     DB 'It erases option files "..\easource\euroasm.ini"',13,10
     DB ' and "..\eatests\euroasm.ini" in order to guarantee a stable configuration.',13,10
     DB 'The checked version of EuroAssembler is "..\easource\euroasm.exe" in MS Windows.',13,10
     DB 13,10
     DB 'The program testman 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 '"%%test.htm.lst", "%%test.msg" and "%%test.bin"',13,10
     DB ' with expected templates stored in the files',13,10
     DB ' "%%test.exp.lst", "%%test.exp.msg" and "%%test.exp.hex".',13,10
     DB 'The output binary file is converted to hexa format before comparison.',13,10
     DB 'The test is claimed as "passed" if listing, messages and object all match.',13,10
     DB 'Temporary files are erased only when 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???  or  testman.exe * (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                            ; Returns miliseconds since Windows was started.
      MOV [StartTime],EAX
      GetArgCount                                    ; A macro from the 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,FirstFILE
    NextFILE:
      MOV [EDI+FILE.Handle],INVALID_HANDLE_VALUE
      ADD EDI,SIZE# FILE
      CMP EDI,LastFILE
      JB NextFILE:
      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 the 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 the 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 the file mask.htm and then compares the test results.
  It continuously reports test name and results on the standard output.
Input
  ESI= is pointer to a 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 the 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 the  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
        XOR EAX,EAX
        STOSB
        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 the 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 the 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. Temporary files remain when the test failed.

    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▲