1 #!/usr/bin/env python2.3
2 import sys
, tempfile
, os
, shutil
, logging
3 from StringIO
import StringIO
5 from logging
import getLogger
, DEBUG
, INFO
7 sys
.path
.insert(0, '..')
9 config_home
= tempfile
.mktemp()
10 cache_home
= tempfile
.mktemp()
11 os
.environ
['XDG_CONFIG_HOME'] = config_home
12 os
.environ
['XDG_CACHE_HOME'] = cache_home
13 os
.environ
['XDG_CACHE_DIRS'] = ''
15 from zeroinstall
import NeedDownload
16 from zeroinstall
.injector
import model
, basedir
, autopolicy
, gpg
, iface_cache
, namespaces
, reader
20 foo_iface_uri
= 'http://foo'
22 logger
= logging
.getLogger()
24 class TestAutoPolicy(unittest
.TestCase
):
26 os
.mkdir(config_home
, 0700)
27 os
.mkdir(cache_home
, 0700)
28 if os
.environ
.has_key('DISPLAY'):
29 del os
.environ
['DISPLAY']
30 self
.gnupg_home
= tempfile
.mktemp()
31 os
.environ
['GNUPGHOME'] = self
.gnupg_home
32 os
.mkdir(self
.gnupg_home
, 0700)
33 stream
= tempfile
.TemporaryFile()
34 stream
.write(data
.thomas_key
)
36 gpg
.import_key(stream
)
37 iface_cache
.iface_cache
._interfaces
= {}
40 shutil
.rmtree(config_home
)
41 shutil
.rmtree(cache_home
)
42 shutil
.rmtree(self
.gnupg_home
)
44 def cache_iface(self
, name
, data
):
45 cached_ifaces
= basedir
.save_cache_path('0install.net',
48 f
= file(os
.path
.join(cached_ifaces
, model
.escape(name
)), 'w')
52 def testNoNeedDl(self
):
53 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
54 download_only
= False)
56 assert policy
.need_download()
57 self
.cache_iface(foo_iface_uri
,
58 """<?xml version="1.0" ?>
59 <interface last-modified="1110752708"
61 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
63 <summary>Foo</summary>
64 <description>Foo</description>
65 </interface>""" % foo_iface_uri
)
66 iface_cache
.iface_cache
._interfaces
= {}
67 assert not policy
.need_download()
69 def testDownload(self
):
70 tmp
= tempfile
.NamedTemporaryFile()
72 """<?xml version="1.0" ?>
74 main='ThisBetterNotExist'
75 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
77 <summary>Foo</summary>
78 <description>Foo</description>
79 <implementation version='1.0' id='/bin'/>
82 policy
= autopolicy
.AutoPolicy(tmp
.name
, False, False)
84 policy
.download_and_execute(['Hello'])
86 except model
.SafeException
, ex
:
87 assert "ThisBetterNotExist" in str(ex
)
91 tmp
= tempfile
.NamedTemporaryFile()
93 """<?xml version="1.0" ?>
95 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
97 <summary>Foo</summary>
98 <description>Foo</description>
99 <implementation version='1.0' id='/bin'/>
102 policy
= autopolicy
.AutoPolicy(tmp
.name
, False, False)
104 policy
.download_and_execute(['Hello'])
106 except model
.SafeException
, ex
:
107 assert "library" in str(ex
)
110 def testNeedDL(self
):
111 self
.cache_iface(foo_iface_uri
,
112 """<?xml version="1.0" ?>
113 <interface last-modified="0"
115 main='ThisBetterNotExist'
116 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
118 <summary>Foo</summary>
119 <description>Foo</description>
120 <implementation version='1.0' id='sha1=123'>
121 <archive href='http://foo/foo.tgz' size='100'/>
123 </interface>""" % foo_iface_uri
)
124 policy
= autopolicy
.AutoPolicy(foo_iface_uri
, False, True)
126 policy
.network_use
= model
.network_full
128 assert policy
.need_download()
130 policy
.start_downloading_impls()
132 except NeedDownload
, ex
:
135 def testBinding(self
):
136 tmp
= tempfile
.NamedTemporaryFile()
138 """<?xml version="1.0" ?>
140 main='testautopolicy.py'
141 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
143 <summary>Bar</summary>
144 <description>Bar</description>
146 <requires interface='%s'>
147 <environment name='FOO_PATH' insert='.'/>
148 <environment name='BAR_PATH' insert='.' default='/a:/b'/>
149 <environment name='XDG_DATA_DIRS' insert='.'/>
151 <implementation version='1.0' id='%s'/>
153 </interface>""" % (foo_iface_uri
, os
.path
.dirname(os
.path
.abspath(__file__
))))
155 self
.cache_iface(foo_iface_uri
,
156 """<?xml version="1.0" ?>
157 <interface last-modified="0"
159 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
161 <summary>Foo</summary>
162 <description>Foo</description>
163 <implementation version='1.0' id='sha1=123'/>
164 </interface>""" % foo_iface_uri
)
165 cached_impl
= basedir
.save_cache_path('0install.net',
168 policy
= autopolicy
.AutoPolicy(tmp
.name
, False,
170 policy
.network_use
= model
.network_offline
171 os
.environ
['FOO_PATH'] = "old"
172 old
, sys
.stdout
= sys
.stdout
, StringIO()
174 policy
.download_and_execute(['Hello'])
177 self
.assertEquals(cached_impl
+ '/.:old',
178 os
.environ
['FOO_PATH'])
179 self
.assertEquals(cached_impl
+ '/.:/a:/b',
180 os
.environ
['BAR_PATH'])
182 del os
.environ
['FOO_PATH']
183 if 'XDG_DATA_DIRS' in os
.environ
:
184 del os
.environ
['XDG_DATA_DIRS']
185 os
.environ
['BAR_PATH'] = '/old'
186 old
, sys
.stdout
= sys
.stdout
, StringIO()
188 policy
.download_and_execute(['Hello'])
191 self
.assertEquals(cached_impl
+ '/.',
192 os
.environ
['FOO_PATH'])
193 self
.assertEquals(cached_impl
+ '/.:/old',
194 os
.environ
['BAR_PATH'])
195 self
.assertEquals(cached_impl
+ '/.:/usr/local/share:/usr/share',
196 os
.environ
['XDG_DATA_DIRS'])
199 self
.cache_iface(foo_iface_uri
,
200 """<?xml version="1.0" ?>
201 <interface last-modified="0"
203 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
205 <summary>Foo</summary>
206 <description>Foo</description>
207 <feed src='http://bar'/>
208 </interface>""" % foo_iface_uri
)
209 self
.cache_iface('http://bar',
210 """<?xml version="1.0" ?>
211 <interface last-modified="0"
213 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
214 <feed-for interface='%s'/>
216 <summary>Bar</summary>
217 <description>Bar</description>
218 <implementation version='1.0' id='sha1=123'/>
219 </interface>""" % foo_iface_uri
)
220 policy
= autopolicy
.AutoPolicy(foo_iface_uri
, False,
223 policy
.network_use
= model
.network_full
226 foo_iface
= policy
.get_interface(foo_iface_uri
)
227 self
.assertEquals('sha1=123', policy
.implementation
[foo_iface
].id)
229 def testBadConfig(self
):
230 path
= basedir
.save_config_path(namespaces
.config_site
,
231 namespaces
.config_prog
)
232 glob
= os
.path
.join(path
, 'global')
233 assert not os
.path
.exists(glob
)
234 stream
= file(glob
, 'w')
235 stream
.write('hello!')
238 logger
.setLevel(logging
.ERROR
)
239 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
240 download_only
= False)
241 logger
.setLevel(logging
.WARN
)
243 def testRanking(self
):
244 self
.cache_iface('http://bar',
245 """<?xml version="1.0" ?>
246 <interface last-modified="1110752708"
248 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
250 <summary>Bar</summary>
251 <description>Bar</description>
252 <implementation id='sha1=125' version='1.0' arch='odd-weird' stability='buggy'/>
253 <implementation id='sha1=126' version='1.0'/>
255 self
.cache_iface(foo_iface_uri
,
256 """<?xml version="1.0" ?>
257 <interface last-modified="1110752708"
259 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
261 <summary>Foo</summary>
262 <description>Foo</description>
263 <feed src='http://example.com' arch='odd-unknown'/>
264 <feed src='http://bar'/>
265 <implementation id='sha1=123' version='1.0' arch='odd-strange'/>
266 <implementation id='sha1=124' version='1.0' arch='odd-weird'/>
267 </interface>""" % foo_iface_uri
)
268 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
269 download_only
= False)
270 policy
.network_use
= model
.network_full
272 impls
= policy
.get_ranked_implementations(
273 policy
.get_interface(policy
.root
))
274 assert len(impls
) == 4
276 logger
.setLevel(logging
.ERROR
)
277 policy
.network_use
= model
.network_offline
# Changes sort order tests
278 policy
.recalculate() # Triggers feed-for warning
279 logger
.setLevel(logging
.WARN
)
281 def testNoLocal(self
):
282 self
.cache_iface(foo_iface_uri
,
283 """<?xml version="1.0" ?>
284 <interface last-modified="1110752708"
286 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
288 <summary>Foo</summary>
289 <description>Foo</description>
290 <feed src='/etc/passwd'/>
291 </interface>""" % foo_iface_uri
)
292 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
293 download_only
= False)
294 policy
.network_use
= model
.network_offline
296 policy
.get_interface(foo_iface_uri
)
298 except reader
.InvalidInterface
, ex
:
299 assert 'Invalid feed URL' in str(ex
)
301 def testDLfeed(self
):
302 self
.cache_iface(foo_iface_uri
,
303 """<?xml version="1.0" ?>
304 <interface last-modified="1110752708"
306 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
308 <summary>Foo</summary>
309 <description>Foo</description>
310 <feed src='http://example.com'/>
311 </interface>""" % foo_iface_uri
)
312 policy
= autopolicy
.AutoPolicy(foo_iface_uri
, dry_run
= True)
313 policy
.network_use
= model
.network_full
319 except NeedDownload
, ex
:
322 iface
= policy
.get_interface(foo_iface_uri
)
323 iface
.feeds
= [model
.Feed('/BadFeed', None, False)]
325 logger
.setLevel(logging
.ERROR
)
326 policy
.recalculate() # Triggers warning
327 logger
.setLevel(logging
.WARN
)
329 def testBestUnusable(self
):
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>
338 <implementation id='sha1=123' version='1.0' arch='odd-weird'/>
339 </interface>""" % foo_iface_uri
)
340 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
341 download_only
= False)
342 policy
.network_use
= model
.network_offline
344 assert not policy
.ready
346 policy
.download_and_execute([])
348 except model
.SafeException
, ex
:
349 assert "Can't find all required implementations" in str(ex
)
351 def testNoArchives(self
):
352 self
.cache_iface(foo_iface_uri
,
353 """<?xml version="1.0" ?>
354 <interface last-modified="1110752708"
356 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
358 <summary>Foo</summary>
359 <description>Foo</description>
360 <implementation id='sha1=123' version='1.0'/>
361 </interface>""" % foo_iface_uri
)
362 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
363 download_only
= False)
368 policy
.download_and_execute([])
370 except model
.SafeException
, ex
:
371 assert 'no download locations' in str(ex
)
374 self
.cache_iface(foo_iface_uri
,
375 """<?xml version="1.0" ?>
376 <interface last-modified="1110752708"
378 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
380 <summary>Foo</summary>
381 <description>Foo</description>
383 <requires interface='%s'/>
384 <implementation id='sha1=123' version='1.0'/>
386 </interface>""" % (foo_iface_uri
, foo_iface_uri
))
387 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
388 download_only
= False)
391 def testConstraints(self
):
392 self
.cache_iface('http://bar',
393 """<?xml version="1.0" ?>
394 <interface last-modified="1110752708"
396 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
398 <summary>Bar</summary>
399 <description>Bar</description>
400 <implementation id='sha1=100' version='1.0'/>
401 <implementation id='sha1=150' stability='developer' version='1.5'/>
402 <implementation id='sha1=200' version='2.0'/>
404 self
.cache_iface(foo_iface_uri
,
405 """<?xml version="1.0" ?>
406 <interface last-modified="1110752708"
408 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
410 <summary>Foo</summary>
411 <description>Foo</description>
413 <requires interface='http://bar'>
416 <implementation id='sha1=123' version='1.0'/>
418 </interface>""" % foo_iface_uri
)
419 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
420 download_only
= False)
421 policy
.network_use
= model
.network_full
423 #logger.setLevel(logging.DEBUG)
425 #logger.setLevel(logging.WARN)
426 foo_iface
= policy
.get_interface(foo_iface_uri
)
427 bar_iface
= policy
.get_interface('http://bar')
428 assert policy
.implementation
[bar_iface
].id == 'sha1=200'
430 dep
= policy
.implementation
[foo_iface
].dependencies
['http://bar']
431 assert len(dep
.restrictions
) == 1
432 restriction
= dep
.restrictions
[0]
434 restriction
.before
= model
.parse_version('2.0')
436 assert policy
.implementation
[bar_iface
].id == 'sha1=100'
438 restriction
.not_before
= model
.parse_version('1.5')
440 assert policy
.implementation
[bar_iface
].id == 'sha1=150'
442 suite
= unittest
.makeSuite(TestAutoPolicy
)
443 if __name__
== '__main__':
444 sys
.argv
.append('-v')