1 # Copyright (C) 2010, Thomas Leonard
2 # Visit http://0install.net for details.
4 import os
, sys
, logging
5 from zeroinstall
.injector
import policy
, model
, run
, arch
, requirements
6 from reporting
import format_combo
8 class VersionRestriction(model
.Restriction
):
9 def __init__(self
, version
):
10 self
.version
= version
12 def meets_restriction(self
, impl
):
13 return impl
.get_version() == self
.version
16 return "version = %s" % self
.version
18 class TestingArchitecture(arch
.Architecture
):
19 use
= frozenset([None, "testing"])
21 def __init__(self
, child_arch
):
22 arch
.Architecture
.__init
__(self
, child_arch
.os_ranks
, child_arch
.machine_ranks
)
23 self
.child_arch
= child_arch
25 def run_tests(config
, tested_iface
, sels
, spec
):
26 def _get_implementation_path(impl
):
27 return impl
.local_path
or config
.iface_cache
.stores
.lookup_any(impl
.digests
)
29 main_command
= sels
.commands
[0] if sels
.commands
else None
31 root_impl
= sels
.selections
[tested_iface
.uri
]
36 # $1 is the main executable, or the root of the package if there isn't one
37 # We have to add the slash because otherwise 0launch interprets the path
38 # relative to itself...
39 if main_command
and main_command
.path
:
40 test_main
= "/" + main_command
.path
44 if main_command
is None:
45 print >>sys
.stderr
, "No <command> requested and no test command either!"
50 if main_command
.path
is None:
51 tests_dir
= _get_implementation_path(root_impl
)
53 main_abs
= os
.path
.join(_get_implementation_path(root_impl
), main_command
.path
)
54 if not os
.path
.exists(main_abs
):
55 print >>sys
.stderr
, "Test executable does not exist:", main_abs
58 tests_dir
= os
.path
.dirname(main_abs
)
63 pid
, status
= os
.waitpid(child
, 0)
65 print "Status:", hex(status
)
74 if spec
.test_wrapper
is None:
76 run
.execute_selections(sels
, spec
.test_args
, main
= test_main
, wrapper
= spec
.test_wrapper
)
78 except model
.SafeException
, ex
:
80 print >>sys
.stderr
, unicode(ex
)
82 print >>sys
.stderr
, repr(ex
)
92 def __init__(self
, spec
):
94 self
.by_combo
= {} # { set((uri, version)) : status }
95 self
.by_status
= { # status -> [ selections ]
101 def run_test_combinations(config
, spec
):
102 r
= requirements
.Requirements(spec
.test_iface
)
103 r
.command
= spec
.command
104 ap
= policy
.Policy(config
= config
, requirements
= r
)
105 ap
.target_arch
= TestingArchitecture(ap
.target_arch
)
107 # Explore all combinations...
109 tested_iface
= config
.iface_cache
.get_interface(spec
.test_iface
)
110 results
= Results(spec
)
111 for combo
in spec
.get_combos(spec
.test_ifaces
):
115 for (uri
, version
) in combo
.iteritems():
116 iface
= config
.iface_cache
.get_interface(uri
)
117 selections
[iface
] = version
120 not_before
, before
= [model
.parse_version(v
) if v
!= "" else None for v
in version
.split(',')]
121 if (not_before
and before
) and not_before
>= before
:
122 raise model
.SafeException("Low version >= high version in %s!" % version
)
123 restrictions
[iface
] = [model
.VersionRangeRestriction(before
, not_before
)]
125 model
.parse_version(version
) # Check format
126 restrictions
[iface
] = [VersionRestriction(version
)]
127 key
.add((uri
, version
))
129 ap
.solver
.extra_restrictions
= restrictions
130 solve
= ap
.solve_with_downloads()
131 ap
.handler
.wait_for_blocker(solve
)
133 logging
.info("Can't select combination %s: %s", combo
, ap
.solver
.get_failure_reason())
135 for uri
, impl
in ap
.solver
.selections
.iteritems():
137 selections
[uri
] = selections
.get(uri
, None) or '?'
139 selections
[uri
] = impl
.get_version()
142 for iface
, impl
in ap
.solver
.selections
.iteritems():
144 version
= impl
.get_version()
147 selections
[iface
] = version
148 download
= ap
.download_uncached_implementations()
150 config
.handler
.wait_for_blocker(download
)
152 tested_impl
= ap
.implementation
[tested_iface
]
154 print format_combo(selections
)
156 result
= run_tests(config
, tested_iface
, ap
.solver
.selections
, spec
)
158 results
.by_status
[result
].append(selections
)
159 results
.by_combo
[frozenset(key
)] = (result
, selections
)