When using an app, allow the app to update
[0test.git] / test_spec.py
blobe807909e88c68fc0cd2f0ee2fc173604eac4145d
1 # Copyright (C) 2010, Thomas Leonard
2 # Visit http://0install.net for details.
4 from zeroinstall import SafeException
5 from zeroinstall.injector import model
6 import logging
8 class TestSpec:
9 def __init__(self):
10 self.test_iface = None # The URI of the program being tested
12 self.test_ifaces = [] # [Interface] - list of interfaces with specified versions
13 self.test_matrix = {} # {URI: [version]} - versions of each interface to test
14 # (test_ifaces is needed because we care about the order)
16 self.command = None
17 self.test_wrapper = None # Command to execute to perform tests
18 self.test_args = [] # Arguments to pass to test script
20 # Yield a sequence of set((uri, version)), one for each combination to test
21 def get_combos(self, ifaces):
22 if not ifaces:
23 yield {}
24 return
25 for version in self.test_matrix[ifaces[0]]:
26 for combo in self.get_combos(ifaces[1:]):
27 combo[ifaces[0]] = version
28 yield combo.copy()
30 def parse_arguments(config, options, args):
31 spec = TestSpec()
33 if '--' in args:
34 i = args.index('--')
35 spec.test_args = args[i + 1:]
36 args = args[:i]
38 if options.test_command:
39 spec.test_wrapper = options.test_command + ' #'
40 if spec.test_args:
41 raise SafeException("Can't specify arguments with --test-command")
43 spec.command = 'run'
44 else:
45 spec.command = 'test'
47 if options.command == '':
48 spec.command = None
49 elif options.command:
50 spec.command = options.command
52 if spec.command:
53 logging.info("Test command is '{command}'".format(command = spec.command))
54 else:
55 logging.info("Test command is None")
57 iface = None
59 # Check if we've been given an app name
60 app = config.app_mgr.lookup_app(args[0], missing_ok = True)
61 if app is not None:
62 # Yes. Get the URI from the app's requirements.
63 r = app.get_requirements()
64 iface = r.interface_uri
65 args = args[1:]
66 spec.test_ifaces.append(iface)
68 if not args:
69 # If the user didn't specify any versions, make sure we use the app's
70 # current selections.
71 sels = app.get_selections(may_update = True)
72 for iface, impl in sels.selections.items():
73 spec.test_matrix[iface] = [impl.version]
74 if iface != r.interface_uri:
75 spec.test_ifaces.append(iface)
76 else:
77 spec.test_matrix[iface] = []
79 for x in args:
80 if (x[0].isdigit() or x[0] in ',%.!') and iface and '/' not in x:
81 spec.test_matrix[iface].append(x)
82 else:
83 assert x not in spec.test_matrix, "Interface %s given twice!" % x
84 iface = model.canonical_iface_uri(x)
85 spec.test_matrix[iface] = []
86 spec.test_ifaces.append(iface)
88 # We don't need to specify the version of the interface under test.
89 spec.test_iface = spec.test_ifaces[0]
90 if not spec.test_matrix[spec.test_iface]:
91 del spec.test_matrix[spec.test_iface]
92 del spec.test_ifaces[0]
94 # We do need a version for all the others (else what was the point of listing them?)
95 for iface in spec.test_ifaces:
96 if not spec.test_matrix[iface]:
97 raise SafeException("No versions given for interface %s" % iface)
99 return spec