Got tests working again
[zeroinstall.git] / tests / testsolver.py
blobac515f7492fe6dc540309242b1a220c8d3e3b26f
1 #!/usr/bin/env python
2 from basetest import BaseTest
3 import sys, os, locale
4 import ConfigParser
5 import unittest
7 sys.path.insert(0, '..')
8 from zeroinstall.zerostore import Stores
9 from zeroinstall.injector import solver, reader, arch, model
11 import logging
12 logger = logging.getLogger()
13 #logger.setLevel(logging.DEBUG)
15 class TestSolver(BaseTest):
16 def testSimple(self):
17 iface_cache = self.config.iface_cache
18 s = solver.DefaultSolver(self.config)
20 foo = iface_cache.get_interface('http://foo/Binary.xml')
21 reader.update(foo, 'Binary.xml')
22 foo_src = iface_cache.get_interface('http://foo/Source.xml')
23 reader.update(foo_src, 'Source.xml')
24 compiler = iface_cache.get_interface('http://foo/Compiler.xml')
25 reader.update(compiler, 'Compiler.xml')
27 binary_arch = arch.Architecture({None: 1}, {None: 1})
28 assert str(binary_arch).startswith("<Arch")
29 s.solve('http://foo/Binary.xml', binary_arch)
31 assert s.ready
32 assert s.feeds_used == set([foo.uri]), s.feeds_used
33 assert s.selections[foo].id == 'sha1=123'
35 # Now ask for source instead
36 s.solve('http://foo/Binary.xml',
37 arch.SourceArchitecture(binary_arch),
38 command_name = 'compile')
39 assert s.ready, s.get_failure_reason()
40 assert s.feeds_used == set([foo.uri, foo_src.uri, compiler.uri]), s.feeds_used
41 assert s.selections[foo].id == 'sha1=234' # The source
42 assert s.selections[compiler].id == 'sha1=345' # A binary needed to compile it
44 assert not s.details
46 def testDetails(self):
47 iface_cache = self.config.iface_cache
48 s = solver.DefaultSolver(self.config)
50 foo = iface_cache.get_interface('http://foo/Binary.xml')
51 reader.update(foo, 'Binary.xml')
52 foo_src = iface_cache.get_interface('http://foo/Source.xml')
53 reader.update(foo_src, 'Source.xml')
54 compiler = iface_cache.get_interface('http://foo/Compiler.xml')
55 reader.update(compiler, 'Compiler.xml')
57 binary_arch = arch.Architecture({None: 1}, {None: 1})
58 s.record_details = True
59 s.solve('http://foo/Binary.xml', arch.SourceArchitecture(binary_arch), command_name = 'compile')
60 assert s.ready, s.get_failure_reason()
62 foo_src_impls = iface_cache.get_feed(foo_src.uri).implementations
63 foo_impls = iface_cache.get_feed(foo.uri).implementations
64 compiler_impls = iface_cache.get_feed(compiler.uri).implementations
66 assert len(s.details) == 2
67 self.assertEquals([(foo_src_impls['sha1=234'], None),
68 (foo_impls['sha1=123'], 'Unsupported machine type')],
69 sorted(s.details[foo]))
70 assert s.details[compiler] == [(compiler_impls['sha1=345'], None)]
72 def testRecursive(self):
73 iface_cache = self.config.iface_cache
74 s = solver.DefaultSolver(self.config)
76 foo = iface_cache.get_interface('http://foo/Recursive.xml')
77 reader.update(foo, 'Recursive.xml')
79 binary_arch = arch.Architecture({None: 1}, {None: 1})
80 s.record_details = True
81 s.solve('http://foo/Recursive.xml', binary_arch)
82 assert s.ready
84 foo_impls = iface_cache.get_feed(foo.uri).implementations
86 assert len(s.details) == 1
87 assert s.details[foo] == [(foo_impls['sha1=abc'], None)]
89 def testMultiArch(self):
90 iface_cache = self.config.iface_cache
91 s = solver.DefaultSolver(self.config)
93 foo = iface_cache.get_interface('http://foo/MultiArch.xml')
94 reader.update(foo, 'MultiArch.xml')
95 lib = iface_cache.get_interface('http://foo/MultiArchLib.xml')
96 reader.update(lib, 'MultiArchLib.xml')
98 # On an i686 system we can only use the i486 implementation
100 binary_arch = arch.get_architecture('Linux', 'i686')
101 s.solve('http://foo/MultiArch.xml', binary_arch)
102 assert s.ready
103 assert s.selections[foo].machine == 'i486'
104 assert s.selections[lib].machine == 'i486'
106 # On an 64 bit system we could use either, but we prefer the 64
107 # bit implementation. The i486 version of the library is newer,
108 # but we must pick one that is compatible with the main binary.
110 binary_arch = arch.get_architecture('Linux', 'x86_64')
111 s.solve('http://foo/MultiArch.xml', binary_arch)
112 assert s.ready
113 assert s.selections[foo].machine == 'x86_64'
114 assert s.selections[lib].machine == 'x86_64'
116 def testArch(self):
117 host_arch = arch.get_host_architecture()
118 host_arch2 = arch.get_architecture(None, None)
119 self.assertEquals(host_arch.os_ranks, host_arch2.os_ranks)
120 self.assertEquals(host_arch.machine_ranks, host_arch2.machine_ranks)
122 other = arch.get_architecture('FooBar', 'i486')
123 self.assertEquals(2, len(other.os_ranks))
125 assert 'FooBar' in other.os_ranks
126 assert None in other.os_ranks
127 assert 'i486' in other.machine_ranks
128 assert 'ppc' not in other.machine_ranks
130 def testRanking(self):
131 iface_cache = self.config.iface_cache
132 s = solver.DefaultSolver(self.config)
133 ranking = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'Ranking.xml')
134 iface = iface_cache.get_interface(ranking)
136 binary_arch = arch.get_architecture('Linux', 'x86_64')
137 selected = []
138 while True:
139 s.solve(ranking, binary_arch)
140 if not s.ready:
141 break
142 impl = s.selections[iface]
143 selected.append(impl.get_version() + ' ' + impl.arch)
144 impl.arch = 'Foo-odd' # prevent reselection
145 self.assertEquals([
146 '0.2 Linux-i386', # poor arch, but newest version
147 '0.1 Linux-x86_64', # 64-bit is best match for host arch
148 '0.1 Linux-i686', '0.1 Linux-i586', '0.1 Linux-i486'], # ordering of x86 versions
149 selected)
151 def testLangs(self):
152 iface_cache = self.config.iface_cache
153 try:
154 locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
156 s = solver.DefaultSolver(self.config)
157 iface = iface_cache.get_interface('http://foo/Langs.xml')
158 reader.update(iface, 'Langs.xml')
160 # 1 is the oldest, but the only one in our language
161 binary_arch = arch.get_architecture(None, 'arch_1')
162 s.solve('http://foo/Langs.xml', binary_arch)
163 assert s.ready
164 self.assertEquals('sha1=1', s.selections[iface].id)
166 # 6 is the newest, and close enough, even though not
167 # quite the right locale
168 binary_arch = arch.get_architecture(None, 'arch_2')
169 s.solve('http://foo/Langs.xml', binary_arch)
170 assert s.ready
171 self.assertEquals('sha1=6', s.selections[iface].id)
173 # 9 is the newest, although 7 is a closer match
174 binary_arch = arch.get_architecture(None, 'arch_3')
175 s.solve('http://foo/Langs.xml', binary_arch)
176 assert s.ready
177 self.assertEquals('sha1=9', s.selections[iface].id)
179 # 11 is the newest we understand
180 binary_arch = arch.get_architecture(None, 'arch_4')
181 s.solve('http://foo/Langs.xml', binary_arch)
182 assert s.ready
183 self.assertEquals('sha1=11', s.selections[iface].id)
185 # 13 is the newest we understand
186 binary_arch = arch.get_architecture(None, 'arch_5')
187 s.solve('http://foo/Langs.xml', binary_arch)
188 assert s.ready
189 self.assertEquals('sha1=13', s.selections[iface].id)
191 def check(target_arch, langs, expected):
192 s.langs = langs
193 binary_arch = arch.get_architecture(None, target_arch)
194 s.solve('http://foo/Langs.xml', binary_arch)
195 assert s.ready
196 self.assertEquals(expected, s.selections[iface].id)
198 # We don't understand any, so pick the newest
199 check('arch_2', ['es_ES'], 'sha1=6')
201 # These two have the same version number. Choose the
202 # one most appropriate to our country
203 check('arch_6', ['zh_CN'], 'sha1=15')
204 check('arch_6', ['zh_TW'], 'sha1=16')
206 # Same, but one doesn't have a country code
207 check('arch_7', ['bn'], 'sha1=17')
208 check('arch_7', ['bn_IN'], 'sha1=18')
209 finally:
210 locale.setlocale(locale.LC_ALL, '')
212 if __name__ == '__main__':
213 unittest.main()