|
|
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()
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.