|
|
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.