2 from basetest
import BaseTest
6 sys
.path
.insert(0, '..')
7 from zeroinstall
.injector
import solver
, arch
10 logger
= logging
.getLogger()
11 #logger.setLevel(logging.DEBUG)
13 mydir
= os
.path
.dirname(os
.path
.abspath(__file__
))
14 command_dep
= os
.path
.join(mydir
, 'command-dep.xml')
16 class TestSolver(BaseTest
):
18 iface_cache
= self
.config
.iface_cache
19 s
= solver
.DefaultSolver(self
.config
)
21 foo
= iface_cache
.get_interface('http://foo/Binary.xml')
22 self
.import_feed(foo
.uri
, 'Binary.xml')
23 foo_src
= iface_cache
.get_interface('http://foo/Source.xml')
24 self
.import_feed(foo_src
.uri
, 'Source.xml')
25 compiler
= iface_cache
.get_interface('http://foo/Compiler.xml')
26 self
.import_feed(compiler
.uri
, 'Compiler.xml')
28 binary_arch
= arch
.Architecture({None: 1}, {None: 1})
29 assert str(binary_arch
).startswith("<Arch")
30 s
.solve('http://foo/Binary.xml', binary_arch
)
33 assert s
.feeds_used
== set([foo
.uri
]), s
.feeds_used
34 assert s
.selections
[foo
].id == 'sha1=123'
36 # Now ask for source instead
37 s
.solve('http://foo/Binary.xml',
38 arch
.SourceArchitecture(binary_arch
),
39 command_name
= 'compile')
40 assert s
.ready
, s
.get_failure_reason()
41 assert s
.feeds_used
== set([foo
.uri
, foo_src
.uri
, compiler
.uri
]), s
.feeds_used
42 assert s
.selections
[foo
].id == 'sha1=234' # The source
43 assert s
.selections
[compiler
].id == 'sha1=345' # A binary needed to compile it
47 def testCommand(self
):
48 s
= solver
.DefaultSolver(self
.config
)
49 binary_arch
= arch
.Architecture({None: 1}, {None: 1})
50 s
.solve(command_dep
, binary_arch
)
51 command
= s
.selections
.selections
[s
.selections
.interface
].get_command("run")
52 dep
, = command
.requires
53 dep_impl
= s
.selections
.selections
[dep
.interface
]
54 assert dep_impl
.get_command("run").path
== "test-gui"
56 def testDetails(self
):
57 iface_cache
= self
.config
.iface_cache
58 s
= solver
.DefaultSolver(self
.config
)
60 foo_binary_uri
= 'http://foo/Binary.xml'
61 foo
= iface_cache
.get_interface(foo_binary_uri
)
62 self
.import_feed(foo_binary_uri
, 'Binary.xml')
63 foo_src
= iface_cache
.get_interface('http://foo/Source.xml')
64 self
.import_feed(foo_src
.uri
, 'Source.xml')
65 compiler
= iface_cache
.get_interface('http://foo/Compiler.xml')
66 self
.import_feed(compiler
.uri
, 'Compiler.xml')
68 binary_arch
= arch
.Architecture({None: 1}, {None: 1})
69 s
.record_details
= True
70 s
.solve('http://foo/Binary.xml', arch
.SourceArchitecture(binary_arch
), command_name
= 'compile')
71 assert s
.ready
, s
.get_failure_reason()
73 foo_src_impls
= iface_cache
.get_feed(foo_src
.uri
).implementations
74 foo_impls
= iface_cache
.get_feed(foo
.uri
).implementations
75 compiler_impls
= iface_cache
.get_feed(compiler
.uri
).implementations
77 assert len(s
.details
) == 2
78 self
.assertEqual([(foo_src_impls
['sha1=234'], None),
79 (foo_impls
['sha1=123'], 'Not source code')],
80 sorted(s
.details
[foo
]))
81 assert s
.details
[compiler
] == [(compiler_impls
['sha1=345'], None)]
83 def testRecursive(self
):
84 iface_cache
= self
.config
.iface_cache
85 s
= solver
.DefaultSolver(self
.config
)
87 foo
= iface_cache
.get_interface('http://foo/Recursive.xml')
88 self
.import_feed(foo
.uri
, 'Recursive.xml')
90 binary_arch
= arch
.Architecture({None: 1}, {None: 1})
91 s
.record_details
= True
92 s
.solve('http://foo/Recursive.xml', binary_arch
)
95 foo_impls
= iface_cache
.get_feed(foo
.uri
).implementations
97 assert len(s
.details
) == 1
98 assert s
.details
[foo
] == [(foo_impls
['sha1=abc'], None)]
100 def testMultiArch(self
):
101 iface_cache
= self
.config
.iface_cache
102 s
= solver
.DefaultSolver(self
.config
)
104 foo
= iface_cache
.get_interface('http://foo/MultiArch.xml')
105 self
.import_feed(foo
.uri
, 'MultiArch.xml')
106 lib
= iface_cache
.get_interface('http://foo/MultiArchLib.xml')
107 self
.import_feed(lib
.uri
, 'MultiArchLib.xml')
109 # On an i686 system we can only use the i486 implementation
111 binary_arch
= arch
.get_architecture('Linux', 'i686')
112 s
.solve('http://foo/MultiArch.xml', binary_arch
)
114 assert s
.selections
[foo
].machine
== 'i486'
115 assert s
.selections
[lib
].machine
== 'i486'
117 # On an 64 bit system we could use either, but we prefer the 64
118 # bit implementation. The i486 version of the library is newer,
119 # but we must pick one that is compatible with the main binary.
121 binary_arch
= arch
.get_architecture('Linux', 'x86_64')
122 s
.solve('http://foo/MultiArch.xml', binary_arch
)
124 assert s
.selections
[foo
].machine
== 'x86_64'
125 assert s
.selections
[lib
].machine
== 'x86_64'
128 host_arch
= arch
.get_host_architecture()
129 host_arch2
= arch
.get_architecture(None, None)
130 self
.assertEqual(host_arch
.os_ranks
, host_arch2
.os_ranks
)
131 self
.assertEqual(host_arch
.machine_ranks
, host_arch2
.machine_ranks
)
133 other
= arch
.get_architecture('FooBar', 'i486')
134 self
.assertEqual(3, len(other
.os_ranks
))
136 assert 'POSIX' in other
.os_ranks
137 assert 'FooBar' in other
.os_ranks
138 assert None in other
.os_ranks
139 assert 'i486' in other
.machine_ranks
140 assert 'ppc' not in other
.machine_ranks
142 win
= arch
.get_architecture('Windows', 'i486')
143 self
.assertEqual(2, len(win
.os_ranks
))
144 assert 'POSIX' not in win
.os_ranks
146 def testRanking(self
):
147 iface_cache
= self
.config
.iface_cache
148 s
= solver
.DefaultSolver(self
.config
)
149 ranking
= os
.path
.join(os
.path
.abspath(os
.path
.dirname(__file__
)), 'Ranking.xml')
150 iface
= iface_cache
.get_interface(ranking
)
152 binary_arch
= arch
.get_architecture('Linux', 'x86_64')
155 s
.solve(ranking
, binary_arch
)
158 impl
= s
.selections
[iface
]
159 selected
.append(impl
.get_version() + ' ' + impl
.arch
)
160 impl
.arch
= 'Foo-odd' # prevent reselection
162 '0.2 Linux-i386', # poor arch, but newest version
163 '0.1 Linux-x86_64', # 64-bit is best match for host arch
164 '0.1 Linux-i686', '0.1 Linux-i586', '0.1 Linux-i486'], # ordering of x86 versions
168 iface_cache
= self
.config
.iface_cache
170 locale
.setlocale(locale
.LC_ALL
, 'en_US.UTF-8')
172 s
= solver
.DefaultSolver(self
.config
)
173 iface
= iface_cache
.get_interface('http://foo/Langs.xml')
174 self
.import_feed(iface
.uri
, 'Langs.xml')
176 # 1 is the oldest, but the only one in our language
177 binary_arch
= arch
.get_architecture(None, 'arch_1')
178 s
.solve('http://foo/Langs.xml', binary_arch
)
180 self
.assertEqual('sha1=1', s
.selections
[iface
].id)
182 # 6 is the newest, and close enough, even though not
183 # quite the right locale
184 binary_arch
= arch
.get_architecture(None, 'arch_2')
185 s
.solve('http://foo/Langs.xml', binary_arch
)
187 self
.assertEqual('sha1=6', s
.selections
[iface
].id)
189 # 9 is the newest, although 7 is a closer match
190 binary_arch
= arch
.get_architecture(None, 'arch_3')
191 s
.solve('http://foo/Langs.xml', binary_arch
)
193 self
.assertEqual('sha1=9', s
.selections
[iface
].id)
195 # 11 is the newest we understand
196 binary_arch
= arch
.get_architecture(None, 'arch_4')
197 s
.solve('http://foo/Langs.xml', binary_arch
)
199 self
.assertEqual('sha1=11', s
.selections
[iface
].id)
201 # 13 is the newest we understand
202 binary_arch
= arch
.get_architecture(None, 'arch_5')
203 s
.solve('http://foo/Langs.xml', binary_arch
)
205 self
.assertEqual('sha1=13', s
.selections
[iface
].id)
207 def check(target_arch
, langs
, expected
):
209 binary_arch
= arch
.get_architecture(None, target_arch
)
210 s
.solve('http://foo/Langs.xml', binary_arch
)
212 self
.assertEqual(expected
, s
.selections
[iface
].id)
214 # We don't understand any, so pick the newest
215 check('arch_2', ['es_ES'], 'sha1=6')
217 # These two have the same version number. Choose the
218 # one most appropriate to our country
219 check('arch_6', ['zh_CN'], 'sha1=15')
220 check('arch_6', ['zh_TW'], 'sha1=16')
222 # Same, but one doesn't have a country code
223 check('arch_7', ['bn'], 'sha1=17')
224 check('arch_7', ['bn_IN'], 'sha1=18')
226 locale
.setlocale(locale
.LC_ALL
, '')
228 def testDecideBug(self
):
229 s
= solver
.DefaultSolver(self
.config
)
230 watch_xml
= os
.path
.join(os
.path
.dirname(os
.path
.abspath(__file__
)), 'watchdog.xml')
231 s
.solve(watch_xml
, arch
.get_architecture(None, None), command_name
= 'test')
233 def testRecommendBug(self
):
234 s
= solver
.DefaultSolver(self
.config
)
235 optional_missing_xml
= os
.path
.join(os
.path
.dirname(os
.path
.abspath(__file__
)), 'OptionalMissing.xml')
236 s
.solve(optional_missing_xml
, arch
.get_architecture(None, None), command_name
= None)
238 if __name__
== '__main__':