2 from basetest
import BaseTest
3 import sys
, tempfile
, os
, logging
4 from StringIO
import StringIO
7 sys
.path
.insert(0, '..')
9 from zeroinstall
.injector
import model
, gpg
, namespaces
, reader
, run
, fetch
10 from zeroinstall
.injector
.policy
import Policy
11 from zeroinstall
.support
import basedir
14 foo_iface_uri
= 'http://foo'
16 logger
= logging
.getLogger()
18 def recalculate(policy
):
19 policy
.need_download()
21 def download_and_execute(policy
, prog_args
, main
= None, dry_run
= True):
22 downloaded
= policy
.solve_and_download_impls()
24 policy
.config
.handler
.wait_for_blocker(downloaded
)
25 run
.execute_selections(policy
.solver
.selections
, prog_args
, stores
= policy
.config
.stores
, main
= main
, dry_run
= dry_run
)
27 class TestAutoPolicy(BaseTest
):
30 stream
= tempfile
.TemporaryFile()
31 stream
.write(data
.thomas_key
)
33 gpg
.import_key(stream
)
35 def cache_iface(self
, name
, data
):
36 cached_ifaces
= basedir
.save_cache_path('0install.net',
39 f
= file(os
.path
.join(cached_ifaces
, model
.escape(name
)), 'w')
43 def testNoNeedDl(self
):
44 policy
= Policy(foo_iface_uri
, config
= self
.config
)
46 assert policy
.need_download()
48 policy
= Policy(os
.path
.abspath('Foo.xml'), config
= self
.config
)
49 assert not policy
.need_download()
52 def testUnknownAlg(self
):
53 self
.cache_iface(foo_iface_uri
,
54 """<?xml version="1.0" ?>
57 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
59 <summary>Foo</summary>
60 <description>Foo</description>
61 <implementation main='.' id='unknown=123' version='1.0'>
62 <archive href='http://foo/foo.tgz' size='100'/>
64 </interface>""" % foo_iface_uri
)
65 self
.config
.fetcher
= fetch
.Fetcher(self
.config
.handler
)
66 policy
= Policy(foo_iface_uri
, config
= self
.config
)
69 assert policy
.need_download()
70 download_and_execute(policy
, [])
71 except model
.SafeException
, ex
:
72 assert 'Unknown digest algorithm' in str(ex
)
74 def testDownload(self
):
75 tmp
= tempfile
.NamedTemporaryFile()
77 """<?xml version="1.0" ?>
79 main='ThisBetterNotExist'
80 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
82 <summary>Foo</summary>
83 <description>Foo</description>
84 <implementation version='1.0' id='/bin'/>
87 policy
= Policy(tmp
.name
, config
= self
.config
)
89 download_and_execute(policy
, ['Hello'])
91 except model
.SafeException
, ex
:
92 assert "ThisBetterNotExist" in str(ex
)
96 tmp
= tempfile
.NamedTemporaryFile()
98 """<?xml version="1.0" ?>
100 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
102 <summary>Foo</summary>
103 <description>Foo</description>
104 <implementation version='1.0' id='/bin'/>
107 policy
= Policy(tmp
.name
, config
= self
.config
)
109 download_and_execute(policy
, ['Hello'])
111 except model
.SafeException
, ex
:
112 assert "library" in str(ex
), ex
115 def testNeedDL(self
):
116 self
.cache_iface(foo_iface_uri
,
117 """<?xml version="1.0" ?>
118 <interface last-modified="0"
120 main='ThisBetterNotExist'
121 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
123 <summary>Foo</summary>
124 <description>Foo</description>
125 <implementation version='1.0' id='sha1=123'>
126 <archive href='http://foo/foo.tgz' size='100'/>
128 </interface>""" % foo_iface_uri
)
129 policy
= Policy(foo_iface_uri
, config
= self
.config
)
131 policy
.network_use
= model
.network_full
133 assert policy
.need_download()
136 def testBinding(self
):
137 local_impl
= os
.path
.dirname(os
.path
.abspath(__file__
))
138 tmp
= tempfile
.NamedTemporaryFile()
140 """<?xml version="1.0" ?>
142 main='testautopolicy.py'
143 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
145 <summary>Bar</summary>
146 <description>Bar</description>
148 <requires interface='%s'>
149 <environment name='FOO_PATH' insert='.'/>
150 <environment name='BAR_PATH' insert='.' default='/a:/b'/>
151 <environment name='XDG_DATA_DIRS' insert='.'/>
153 <environment name='SELF_GROUP' insert='group' mode='replace'/>
154 <implementation version='1.0' id='%s'>
155 <environment name='SELF_IMPL' insert='impl' mode='replace'/>
158 </interface>""" % (foo_iface_uri
, local_impl
))
160 self
.cache_iface(foo_iface_uri
,
161 """<?xml version="1.0" ?>
162 <interface last-modified="0"
164 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
166 <summary>Foo</summary>
167 <description>Foo</description>
168 <implementation version='1.0' id='sha1=123'/>
169 </interface>""" % foo_iface_uri
)
170 cached_impl
= basedir
.save_cache_path('0install.net',
173 policy
= Policy(tmp
.name
, config
= self
.config
)
174 policy
.network_use
= model
.network_offline
175 os
.environ
['FOO_PATH'] = "old"
176 old
, sys
.stdout
= sys
.stdout
, StringIO()
178 download_and_execute(policy
, ['Hello'])
181 self
.assertEquals(cached_impl
+ '/.:old',
182 os
.environ
['FOO_PATH'])
183 self
.assertEquals(cached_impl
+ '/.:/a:/b',
184 os
.environ
['BAR_PATH'])
186 self
.assertEquals(os
.path
.join(local_impl
, 'group'), os
.environ
['SELF_GROUP'])
187 self
.assertEquals(os
.path
.join(local_impl
, 'impl'), os
.environ
['SELF_IMPL'])
189 del os
.environ
['FOO_PATH']
190 if 'XDG_DATA_DIRS' in os
.environ
:
191 del os
.environ
['XDG_DATA_DIRS']
192 os
.environ
['BAR_PATH'] = '/old'
193 old
, sys
.stdout
= sys
.stdout
, StringIO()
195 download_and_execute(policy
, ['Hello'])
198 self
.assertEquals(cached_impl
+ '/.',
199 os
.environ
['FOO_PATH'])
200 self
.assertEquals(cached_impl
+ '/.:/old',
201 os
.environ
['BAR_PATH'])
202 self
.assertEquals(cached_impl
+ '/.:/usr/local/share:/usr/share',
203 os
.environ
['XDG_DATA_DIRS'])
206 self
.cache_iface(foo_iface_uri
,
207 """<?xml version="1.0" ?>
208 <interface last-modified="0"
210 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
212 <summary>Foo</summary>
213 <description>Foo</description>
214 <feed src='http://bar'/>
215 </interface>""" % foo_iface_uri
)
216 self
.cache_iface('http://bar',
217 """<?xml version="1.0" ?>
218 <interface last-modified="0"
220 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
221 <feed-for interface='%s'/>
223 <summary>Bar</summary>
224 <description>Bar</description>
225 <implementation version='1.0' id='sha1=123' main='dummy'>
226 <archive href='foo' size='10'/>
228 </interface>""" % foo_iface_uri
)
229 policy
= Policy(foo_iface_uri
, config
= self
.config
)
231 policy
.network_use
= model
.network_full
234 foo_iface
= self
.config
.iface_cache
.get_interface(foo_iface_uri
)
235 self
.assertEquals('sha1=123', policy
.implementation
[foo_iface
].id)
237 def testBadConfig(self
):
238 path
= basedir
.save_config_path(namespaces
.config_site
,
239 namespaces
.config_prog
)
240 glob
= os
.path
.join(path
, 'global')
241 assert not os
.path
.exists(glob
)
242 stream
= file(glob
, 'w')
243 stream
.write('hello!')
246 logger
.setLevel(logging
.ERROR
)
247 Policy(foo_iface_uri
, config
= self
.config
)
248 logger
.setLevel(logging
.WARN
)
250 def testNoLocal(self
):
251 self
.cache_iface(foo_iface_uri
,
252 """<?xml version="1.0" ?>
253 <interface last-modified="1110752708"
255 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
257 <summary>Foo</summary>
258 <description>Foo</description>
259 <feed src='/etc/passwd'/>
260 </interface>""" % foo_iface_uri
)
261 self
.config
.network_use
= model
.network_offline
263 self
.config
.iface_cache
.get_interface(foo_iface_uri
)
265 except reader
.InvalidInterface
, ex
:
266 assert 'Invalid feed URL' in str(ex
)
268 def testDLfeed(self
):
269 self
.cache_iface(foo_iface_uri
,
270 """<?xml version="1.0" ?>
271 <interface last-modified="1110752708"
273 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
275 <summary>Foo</summary>
276 <description>Foo</description>
277 <feed src='http://example.com'/>
278 </interface>""" % foo_iface_uri
)
279 policy
= Policy(foo_iface_uri
, config
= self
.config
)
280 policy
.network_use
= model
.network_full
283 assert policy
.need_download()
285 feed
= self
.config
.iface_cache
.get_feed(foo_iface_uri
)
286 feed
.feeds
= [model
.Feed('/BadFeed', None, False)]
288 logger
.setLevel(logging
.ERROR
)
289 assert policy
.need_download() # Triggers warning
290 logger
.setLevel(logging
.WARN
)
292 def testBestUnusable(self
):
293 self
.cache_iface(foo_iface_uri
,
294 """<?xml version="1.0" ?>
295 <interface last-modified="1110752708"
297 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
299 <summary>Foo</summary>
300 <description>Foo</description>
301 <implementation id='sha1=123' version='1.0' arch='odd-weird' main='dummy'/>
302 </interface>""" % foo_iface_uri
)
303 policy
= Policy(foo_iface_uri
, config
= self
.config
)
304 policy
.network_use
= model
.network_offline
306 assert not policy
.ready
, policy
.implementation
308 download_and_execute(policy
, [])
310 except model
.SafeException
, ex
:
311 assert "has no usable implementations" in str(ex
), ex
313 def testNoArchives(self
):
314 self
.cache_iface(foo_iface_uri
,
315 """<?xml version="1.0" ?>
316 <interface last-modified="1110752708"
318 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
320 <summary>Foo</summary>
321 <description>Foo</description>
322 <implementation id='sha1=123' version='1.0' main='dummy'/>
323 </interface>""" % foo_iface_uri
)
324 policy
= Policy(foo_iface_uri
, config
= self
.config
)
327 assert not policy
.ready
330 self
.cache_iface(foo_iface_uri
,
331 """<?xml version="1.0" ?>
332 <interface last-modified="1110752708"
334 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
336 <summary>Foo</summary>
337 <description>Foo</description>
339 <requires interface='%s'/>
340 <implementation id='sha1=123' version='1.0'>
341 <archive href='foo' size='10'/>
344 </interface>""" % (foo_iface_uri
, foo_iface_uri
))
345 policy
= Policy(foo_iface_uri
, config
= self
.config
)
349 def testConstraints(self
):
350 self
.cache_iface('http://bar',
351 """<?xml version="1.0" ?>
352 <interface last-modified="1110752708"
354 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
356 <summary>Bar</summary>
357 <description>Bar</description>
358 <implementation id='sha1=100' version='1.0'>
359 <archive href='foo' size='10'/>
361 <implementation id='sha1=150' stability='developer' version='1.5'>
362 <archive href='foo' size='10'/>
364 <implementation id='sha1=200' version='2.0'>
365 <archive href='foo' size='10'/>
368 self
.cache_iface(foo_iface_uri
,
369 """<?xml version="1.0" ?>
370 <interface last-modified="1110752708"
372 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
374 <summary>Foo</summary>
375 <description>Foo</description>
377 <requires interface='http://bar'>
380 <implementation id='sha1=123' version='1.0'>
381 <archive href='foo' size='10'/>
384 </interface>""" % foo_iface_uri
)
385 policy
= Policy(foo_iface_uri
, config
= self
.config
)
386 policy
.network_use
= model
.network_full
388 #logger.setLevel(logging.DEBUG)
390 #logger.setLevel(logging.WARN)
391 foo_iface
= self
.config
.iface_cache
.get_interface(foo_iface_uri
)
392 bar_iface
= self
.config
.iface_cache
.get_interface('http://bar')
393 assert policy
.implementation
[bar_iface
].id == 'sha1=200'
395 dep
= policy
.implementation
[foo_iface
].dependencies
['http://bar']
396 assert len(dep
.restrictions
) == 1
397 restriction
= dep
.restrictions
[0]
399 restriction
.before
= model
.parse_version('2.0')
401 assert policy
.implementation
[bar_iface
].id == 'sha1=100'
403 restriction
.not_before
= model
.parse_version('1.5')
405 assert policy
.implementation
[bar_iface
].id == 'sha1=150'
407 if __name__
== '__main__':