Start development series 0.8-post
[0test.git] / 0test
blob2b1b8cb8e870f7cc2d7e56667d8cf2f356a258c7
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.8'
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)
109 if results.by_status['failed']:
110 sys.exit(1)
112 if results.by_status['skipped'] and not options.skip_ok:
113 sys.exit(2)