Release 0.9
[0test.git] / 0test
blob7e5a5e3ba352930face078ee5cacf2b68637969f
1 #!/usr/bin/env python
2 # Copyright (C) 2010, Thomas Leonard
3 # Visit http://0install.net for details.
5 import os, traceback, sys
6 from optparse import OptionParser
8 zi = os.environ.get("0TEST_ZEROINSTALL", None)
9 if zi is not None:
10 sys.path.insert(0, zi)
11 # (else using distro version)
13 from zeroinstall import SafeException
14 from zeroinstall.injector import model, handler, policy
16 import test_spec, runner, reporting
18 version = '0.9'
20 parser = OptionParser(usage="usage: %prog [INTERFACE VERSION ...] ... [-- ARGS]\n\n"
21 "For example, to test two versions of 0compile against two versions of Zero Install:\n\n"
22 "0test http://0install.net/2006/interfaces/0compile.xml 0.19 0.20 \\\n"
23 " http://0install.net/2007/interfaces/ZeroInstall.xml 0.47 0.48\n\n"
24 "The ARGS, if any, are passed through to the program's test script.")
26 parser.add_option("", "--html", help="write results as HTML", action='store', metavar='OUTPUT')
27 parser.add_option("-c", "--command", help="the <command> to select", action='store', metavar='CMD')
28 parser.add_option("-o", "--offline", help="run in off-line mode", action='store_true')
29 parser.add_option("-s", "--skip-ok", help="skipping tests is not an error", action='store_true')
30 parser.add_option("-t", "--test-command", help="specify a custom shell command", action='store', metavar='CMD')
31 parser.add_option("-v", "--verbose", help="more verbose output", action='count')
32 parser.add_option("-V", "--version", help="display version information", action='store_true')
33 parser.disable_interspersed_args()
35 (options, args) = parser.parse_args()
37 if options.version:
38 print "0test (zero-install) " + version
39 print "Copyright (C) 2011 Thomas Leonard"
40 print "This program comes with ABSOLUTELY NO WARRANTY,"
41 print "to the extent permitted by law."
42 print "You may redistribute copies of this program"
43 print "under the terms of the GNU General Public License."
44 print "For more information about these matters, see the file named COPYING."
45 sys.exit(0)
47 if not args:
48 parser.print_help()
49 sys.exit(1)
51 if options.verbose:
52 import logging
53 logger = logging.getLogger()
54 if options.verbose == 1:
55 logger.setLevel(logging.INFO)
56 else:
57 logger.setLevel(logging.DEBUG)
58 logging.info("Starting 0test %s", version)
60 try:
61 if os.isatty(1):
62 h = handler.ConsoleHandler()
63 else:
64 h = handler.Handler()
65 config = policy.load_config(handler = h)
67 if options.offline:
68 config.network_use = model.network_offline
70 spec = test_spec.parse_arguments(options, args)
72 if options.html and len(spec.test_ifaces) < 2:
73 print >>sys.stderr, "Need versions for at least two interfaces for --html mode."
74 possible_deps = set()
75 for impl in config.iface_cache.get_feed(spec.test_iface).implementations.values():
76 for dep in impl.requires:
77 if dep.interface not in spec.test_matrix:
78 possible_deps.add(dep.interface)
79 if possible_deps:
80 print "Suggestions:"
81 for url in possible_deps:
82 print "-", url
84 sys.exit(1)
86 if 'DISPLAY' in os.environ and not spec.test_wrapper and not options.command:
87 del os.environ['DISPLAY']
89 results = runner.run_test_combinations(config, spec)
91 reporting.print_summary(results)
93 html_file = options.html
95 if html_file:
96 doc = reporting.format_html(results)
97 stream = open(html_file, 'w')
98 doc.writexml(stream, encoding = 'utf8')
99 stream.close()
100 except SafeException, ex:
101 if options.verbose: raise
102 try:
103 print >>sys.stderr, unicode(ex)
104 except:
105 print >>sys.stderr, repr(ex)
106 sys.exit(1)
107 except KeyboardInterrupt as ex:
108 if options.verbose: raise
109 print >>sys.stderr, "Interrupted"
110 sys.exit(1)
112 if results.by_status['failed']:
113 sys.exit(1)
115 if results.by_status['skipped'] and not options.skip_ok:
116 sys.exit(2)