Start development series 0.7-post
[0test.git] / 0test
blob6c465042b6faf328206c08342ea6e83d38271e37
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.7'
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("-t", "--test-command", help="specify a custom shell command", action='store', metavar='CMD')
30 parser.add_option("-v", "--verbose", help="more verbose output", action='count')
31 parser.add_option("-V", "--version", help="display version information", action='store_true')
32 parser.disable_interspersed_args()
34 (options, args) = parser.parse_args()
36 if options.version:
37 print "0test (zero-install) " + version
38 print "Copyright (C) 2011 Thomas Leonard"
39 print "This program comes with ABSOLUTELY NO WARRANTY,"
40 print "to the extent permitted by law."
41 print "You may redistribute copies of this program"
42 print "under the terms of the GNU General Public License."
43 print "For more information about these matters, see the file named COPYING."
44 sys.exit(0)
46 if not args:
47 parser.print_help()
48 sys.exit(1)
50 if options.verbose:
51 import logging
52 logger = logging.getLogger()
53 if options.verbose == 1:
54 logger.setLevel(logging.INFO)
55 else:
56 logger.setLevel(logging.DEBUG)
57 logging.info("Starting 0test %s", version)
59 try:
60 if os.isatty(1):
61 h = handler.ConsoleHandler()
62 else:
63 h = handler.Handler()
64 config = policy.load_config(handler = h)
66 if options.offline:
67 config.network_use = model.network_offline
69 spec = test_spec.parse_arguments(options, args)
71 if options.html and len(spec.test_ifaces) < 2:
72 print >>sys.stderr, "Need versions for at least two interfaces for --html mode."
73 possible_deps = set()
74 for impl in config.iface_cache.get_feed(spec.test_iface).implementations.values():
75 for dep in impl.requires:
76 if dep.interface not in spec.test_matrix:
77 possible_deps.add(dep.interface)
78 if possible_deps:
79 print "Suggestions:"
80 for url in possible_deps:
81 print "-", url
83 sys.exit(1)
85 if 'DISPLAY' in os.environ and not spec.test_wrapper and not options.command:
86 del os.environ['DISPLAY']
88 results = runner.run_test_combinations(config, spec)
90 reporting.print_summary(results)
92 html_file = options.html
94 if html_file:
95 doc = reporting.format_html(results)
96 stream = open(html_file, 'w')
97 doc.writexml(stream, encoding = 'utf8')
98 stream.close()
99 except SafeException, ex:
100 if options.verbose: raise
101 try:
102 print >>sys.stderr, unicode(ex)
103 except:
104 print >>sys.stderr, repr(ex)
105 sys.exit(1)
108 if results.by_status['failed']:
109 sys.exit(1)
111 if results.by_status['skipped']:
112 sys.exit(2)