Annotation of hatari/tests/tosboot/tos-tester.py, revision 1.1

1.1     ! root        1: #!/usr/bin/env python
        !             2: #
        !             3: # This script tests that all given TOS image files boot under
        !             4: # Hatari with several different HW configurations and saves
        !             5: # verification screenshots into current directory.
        !             6: # 
        !             7: # Copyright (C) 2012 by Eero Tamminen <oak at helsinkinet fi>
        !             8: #
        !             9: # This program is free software; you can redistribute it and/or modify
        !            10: # it under the terms of the GNU General Public License as published by
        !            11: # the Free Software Foundation; either version 2 of the License, or
        !            12: # (at your option) any later version.
        !            13: #
        !            14: # This program is distributed in the hope that it will be useful,
        !            15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            17: # GNU General Public License for more details.
        !            18: 
        !            19: import os, sys
        !            20: 
        !            21: # add most likely hconsole locations to module import path,
        !            22: # prefer the devel version in Hatari sources, if it's found
        !            23: def add_hconsole_paths():
        !            24:     subdirs = len(os.path.abspath(os.curdir).split(os.path.sep))-1
        !            25:     for level in range(subdirs):
        !            26:         f = level*(".." + os.path.sep) + "tools/hconsole/hconsole.py"
        !            27:         if os.path.isfile(f):
        !            28:             f = os.path.dirname(f)
        !            29:             sys.path.append(f)
        !            30:             print "Added local hconsole path: %s" % f
        !            31:             break
        !            32:     sys.path += ["/usr/local/share/hatari/hconsole",
        !            33:                  "/usr/share/hatari/hconsole"]
        !            34: 
        !            35: add_hconsole_paths()
        !            36: import hconsole
        !            37: 
        !            38: def warning(msg):
        !            39:     sys.stderr.write("WARNING: %s\n" % msg)
        !            40: def error_exit(msg):
        !            41:     scriptname = os.path.basename(sys.argv[0])
        !            42:     sys.stderr.write("""
        !            43: usage: %s <TOS image files>
        !            44: 
        !            45: Boots the given TOS versions under Hatari with a selection
        !            46: of machine and monitor types and memory sizes supported by
        !            47: the given TOS version.
        !            48: 
        !            49: Verification screenshot is taken of the booted TOS desktop
        !            50: before proceeding to booting the next combination.
        !            51: 
        !            52: Screenshot name indicates the used combination, for example:
        !            53:         etos512k-falcon-rgb-14M.png
        !            54:         etos512k-st-mono-1M.png
        !            55: 
        !            56: 
        !            57: NOTE: If you want to test the latest, uninstalled version of Hatari,
        !            58: you need to set PATH to point to your Hatari binary directory, like
        !            59: this:
        !            60:        PATH=../../build/src:$PATH %s <TOS images>
        !            61: 
        !            62: If hconsole isn't installed to one of the standard locations (under
        !            63: /usr or /usr/local), or you don't run this from within Hatari sources,
        !            64: you also need to specify hconsole.py location with:
        !            65:        export PYTHONPATH=/path/to/hconsole
        !            66: 
        !            67: 
        !            68: ERROR: %s!
        !            69: """ % (scriptname, scriptname, msg))
        !            70:     sys.exit(1)
        !            71: 
        !            72: 
        !            73: class TOS:
        !            74:     def __init__(self, images):
        !            75:         "check & store given list of TOS image file names"
        !            76:         self.images = []
        !            77:         if len(images) < 1:
        !            78:             error_exit("no TOS image files given")
        !            79:         for img in images:
        !            80:             self.add_image(img)
        !            81:         if not self.images:
        !            82:             error_exit("no (valid) TOS image files given")
        !            83: 
        !            84:     def files(self):
        !            85:         "return list of stored, valid TOS image file names"
        !            86:         return self.images
        !            87:     
        !            88:     def image_machines(self, img):
        !            89:         "return tuple of (IsEmuTOS, <tuple of supported machine types>) for given TOS image"
        !            90:         (version, is_etos) = self.image_version(img)
        !            91:         if is_etos:
        !            92:             if version > 0x200:
        !            93:                 return (is_etos, ("st", "ste", "tt", "falcon"))
        !            94:             else:
        !            95:                 return (is_etos, ("st", "ste", "tt"))
        !            96:         elif version < 0x160:
        !            97:             return (is_etos, ("st",))
        !            98:         elif version < 0x200:
        !            99:             return (is_etos, ("ste",))
        !           100:         elif version < 0x300:
        !           101:             return (is_etos, ("st", "ste", "tt"))
        !           102:         elif version < 0x400:
        !           103:             return (is_etos, ("tt",))
        !           104:         else:
        !           105:             return (is_etos, ("falcon",))
        !           106:     
        !           107:     def image_version(self, img):
        !           108:         "return tuple of (TOSversion, IsEmuTOS) for given TOS image"
        !           109:         f = open(img)
        !           110:         f.seek(0x2, 0)
        !           111:         version = (ord(f.read(1)) << 8) + ord(f.read(1))
        !           112:         f.seek(0x2C, 0)
        !           113:         etos = f.read(4)
        !           114:         return (version, etos == "ETOS")
        !           115:     
        !           116:     def add_image(self, img):
        !           117:         "check and store given, valid TOS image to internal list"
        !           118:         if not os.path.isfile(img):
        !           119:             warning("'%s' isn't a file")
        !           120:             return
        !           121:         size = os.stat(img).st_size
        !           122:         tossizes = (196608, 262144, 524288)
        !           123:         if size not in tossizes:
        !           124:             warning("image '%s' size not one of TOS sizes %s" % (img, repr(tossizes)))
        !           125:             return
        !           126:         basename = os.path.basename(img)
        !           127:         (version, is_etos) = self.image_version(img)
        !           128:         if is_etos:
        !           129:             print "%s is EmuTOS v%x" % (basename, version)
        !           130:         elif version >= 0x100 and version < 0x500:
        !           131:             print "%s is normal TOS v%x" % (basename, version)
        !           132:         else:
        !           133:             warning("'%s' with TOS version 0x%x isn't valid" % (basename, version))
        !           134:             return
        !           135:         self.images.append(img)
        !           136: 
        !           137: 
        !           138: class Tester:
        !           139:     # dummy config file to force suitable default options
        !           140:     dummycfg = "dummy.cfg"
        !           141:     defaults = [sys.argv[0], "--configfile", dummycfg]
        !           142:     hdtestdir = "gemdos"
        !           143:     
        !           144:     def __init__(self):
        !           145:         "test setup initialization"
        !           146:         self.images = TOS(sys.argv[1:])
        !           147:         # write specific configuration to:
        !           148:         # - avoid user's own config
        !           149:         # - get rid of the dialogs
        !           150:         # - disable GEMDOS emu by default
        !           151:         # - use empty blank disk to avoid TOS error when no disks
        !           152:         # - limit Videl zooming to same sizes as ST screen zooming
        !           153:         # - get rid of statusbar and borders in TOS screenshots
        !           154:         #   to make them smaller & more consistent
        !           155:         dummy = open(self.dummycfg, "w")
        !           156:         dummy.write("[Log]\nnAlertDlgLogLevel = 0\nbConfirmQuit = FALSE\n")
        !           157:         dummy.write("[HardDisk]\nbUseHardDiskDirectory = FALSE\n")
        !           158:         dummy.write("[Floppy]\nszDiskAFileName = blank-a.st.gz\n")
        !           159:         dummy.write("[Screen]\nnMaxWidth=832\nnMaxHeight=576\nbCrop = TRUE\nbAllowOverscan=FALSE\n")
        !           160:         dummy.close()
        !           161:         # directory for GEMDOS emu testing
        !           162:         if not os.path.isdir(self.hdtestdir):
        !           163:             os.mkdir(self.hdtestdir)
        !           164:         # remove left over screenshots
        !           165:         if os.path.isfile("grab0001.png"):
        !           166:             os.remove("grab0001.png")
        !           167:         if os.path.isfile("grab0001.bmp"):
        !           168:             os.remove("grab0001.bmp")
        !           169: 
        !           170:     def test(self, identity, testargs, bootwait, deskwait):
        !           171:         "run single boot test for TOS image"
        !           172:         sys.argv = self.defaults + testargs
        !           173:         instance = hconsole.Main()
        !           174:         # pass memory test
        !           175:         instance.run("sleep %d" % bootwait)
        !           176:         instance.run("keypress %s" % hconsole.Scancode.Space)
        !           177:         # wait until in desktop, TOS3 is slower in color
        !           178:         instance.run("sleep %d" % deskwait)
        !           179:         # screenshot of desktop
        !           180:         instance.run("screenshot")
        !           181:         if os.path.isfile("grab0001.png"):
        !           182:             os.rename("grab0001.png", identity+".png")
        !           183:         elif os.path.isfile("grab0001.bmp"):
        !           184:             os.rename("grab0001.bmp", identity+".bmp")
        !           185:         else:
        !           186:             warning("failed to locate screenshot grab0001.{png,bmp}")
        !           187:         # get rid of this Hatari instance
        !           188:         instance.run("kill")
        !           189: 
        !           190:     def run(self):
        !           191:         "run all TOS boot tests"
        !           192:         for tos in self.images.files():
        !           193: 
        !           194:             name = os.path.basename(tos)
        !           195:             name = name[:name.rfind('.')]
        !           196:             print
        !           197:             print "***** TESTING: %s *****" % name
        !           198:             print
        !           199:             
        !           200:             (is_etos, machines) = self.images.image_machines(tos)
        !           201:             for machine in machines:
        !           202: 
        !           203:                 if machine in ("st", "ste"):
        !           204:                     bootwait = 1
        !           205:                     deskwait = 3
        !           206:                     if is_etos:
        !           207:                         # EmuTOS is slower than TOS 1.x
        !           208:                         deskwait += 2
        !           209:                     if machine == "st":
        !           210:                         memories = (0, 2)
        !           211:                         monitors = ("tv", "mono", "vdi1", "vdi4")
        !           212:                     else:
        !           213:                         memories = (1, 4)
        !           214:                         monitors = ("rgb", "mono", "vdi1", "vdi4")
        !           215:                 else:
        !           216:                     bootwait = 2
        !           217:                     # e.g. TOS3 is quite slow in color modes
        !           218:                     deskwait = 5
        !           219:                     if machine == "tt" or is_etos:
        !           220:                         memories = (2, 10)
        !           221:                         monitors = ("vga", "mono", "vdi1", "vdi4")
        !           222:                     else:
        !           223:                         # VDI modes don't work with TOS4
        !           224:                         memories = (4, 14)
        !           225:                         monitors = ("rgb", "vga", "mono")
        !           226: 
        !           227:                 for monitor in monitors:
        !           228:                     for memory in memories:
        !           229:                         # e.g. TOS4 is slower with more mem
        !           230:                         bootwait += memory//8
        !           231:                         deskwait += memory//8
        !           232:                         for gemdos in (False, True):
        !           233:                             identity = "%s-%s-%s-%sM" % (name, machine, monitor, memory)
        !           234:                             testargs = ["--memsize", str(memory), "--machine", machine, "--tos", tos]
        !           235:                             if monitor[:3] == "vdi":
        !           236:                                 planes = monitor[-1]
        !           237:                                 if planes == "1":
        !           238:                                     testargs += ["--vdi-width", "640", "--vdi-height", "480", "--vdi-planes", planes]
        !           239:                                 else:
        !           240:                                     testargs += ["--vdi-width", "320", "--vdi-height", "240", "--vdi-planes", planes]
        !           241:                             else:
        !           242:                                 testargs += ["--monitor", monitor]
        !           243:                             if gemdos:
        !           244:                                 identity += "-gemdos"
        !           245:                                 testargs += ["--harddrive", self.hdtestdir]
        !           246:                             self.test(identity, testargs, bootwait, deskwait)
        !           247: 
        !           248: 
        !           249: 
        !           250: if __name__ == "__main__":
        !           251:     tests = Tester()
        !           252:     tests.run()

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.