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
14 from zeroinstall
import NeedDownload
15 from zeroinstall
.injector
import model
, basedir
, autopolicy
, gpg
, iface_cache
, namespaces
, reader
19 foo_iface_uri
= 'http://foo'
21 logger
= logging
.getLogger()
23 class TestAutoPolicy(unittest
.TestCase
):
25 os
.mkdir(config_home
, 0700)
26 os
.mkdir(cache_home
, 0700)
27 if os
.environ
.has_key('DISPLAY'):
28 del os
.environ
['DISPLAY']
29 self
.gnupg_home
= tempfile
.mktemp()
30 os
.environ
['GNUPGHOME'] = self
.gnupg_home
31 os
.mkdir(self
.gnupg_home
, 0700)
32 stream
= tempfile
.TemporaryFile()
33 stream
.write(data
.thomas_key
)
35 gpg
.import_key(stream
)
36 iface_cache
.iface_cache
._interfaces
= {}
39 shutil
.rmtree(config_home
)
40 shutil
.rmtree(cache_home
)
41 shutil
.rmtree(self
.gnupg_home
)
43 def cache_iface(self
, name
, data
):
44 cached_ifaces
= basedir
.save_cache_path('0install.net',
47 f
= file(os
.path
.join(cached_ifaces
, model
.escape(name
)), 'w')
51 def testNoNeedDl(self
):
52 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
53 download_only
= False)
55 assert policy
.need_download()
56 self
.cache_iface(foo_iface_uri
,
57 """<?xml version="1.0" ?>
58 <interface last-modified="1110752708"
60 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
62 <summary>Foo</summary>
63 <description>Foo</description>
64 </interface>""" % foo_iface_uri
)
65 iface_cache
.iface_cache
._interfaces
= {}
66 assert not policy
.need_download()
68 def testDownload(self
):
69 tmp
= tempfile
.NamedTemporaryFile()
71 """<?xml version="1.0" ?>
73 main='ThisBetterNotExist'
74 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
76 <summary>Foo</summary>
77 <description>Foo</description>
78 <implementation version='1.0' id='/bin'/>
81 policy
= autopolicy
.AutoPolicy(tmp
.name
, False, False)
83 policy
.download_and_execute(['Hello'])
85 except model
.SafeException
, ex
:
86 assert "ThisBetterNotExist" in str(ex
)
90 tmp
= tempfile
.NamedTemporaryFile()
92 """<?xml version="1.0" ?>
94 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
96 <summary>Foo</summary>
97 <description>Foo</description>
98 <implementation version='1.0' id='/bin'/>
101 policy
= autopolicy
.AutoPolicy(tmp
.name
, False, False)
103 policy
.download_and_execute(['Hello'])
105 except model
.SafeException
, ex
:
106 assert "library" in str(ex
)
109 def testNeedDL(self
):
110 policy
= autopolicy
.AutoPolicy(foo_iface_uri
, False, False)
112 policy
.network_use
= model
.network_full
113 self
.cache_iface(foo_iface_uri
,
114 """<?xml version="1.0" ?>
115 <interface last-modified="0"
117 main='ThisBetterNotExist'
118 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
120 <summary>Foo</summary>
121 <description>Foo</description>
122 <implementation version='1.0' id='sha1=123'/>
123 </interface>""" % foo_iface_uri
)
124 assert policy
.need_download()
126 def testBinding(self
):
127 tmp
= tempfile
.NamedTemporaryFile()
129 """<?xml version="1.0" ?>
131 main='testautopolicy.py'
132 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
134 <summary>Bar</summary>
135 <description>Bar</description>
137 <requires interface='%s'>
138 <environment name='FOO_PATH' insert='.'/>
139 <environment name='BAR_PATH' insert='.' default='/a:/b'/>
140 <environment name='XDG_DATA_DIRS' insert='.'/>
142 <implementation version='1.0' id='%s'/>
144 </interface>""" % (foo_iface_uri
, os
.path
.dirname(os
.path
.abspath(__file__
))))
146 self
.cache_iface(foo_iface_uri
,
147 """<?xml version="1.0" ?>
148 <interface last-modified="0"
150 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
152 <summary>Foo</summary>
153 <description>Foo</description>
154 <implementation version='1.0' id='sha1=123'/>
155 </interface>""" % foo_iface_uri
)
156 cached_impl
= basedir
.save_cache_path('0install.net',
159 policy
= autopolicy
.AutoPolicy(tmp
.name
, False,
161 policy
.network_use
= model
.network_offline
162 os
.environ
['FOO_PATH'] = "old"
163 old
, sys
.stdout
= sys
.stdout
, StringIO()
165 policy
.download_and_execute(['Hello'])
168 self
.assertEquals(cached_impl
+ '/.:old',
169 os
.environ
['FOO_PATH'])
170 self
.assertEquals(cached_impl
+ '/.:/a:/b',
171 os
.environ
['BAR_PATH'])
173 del os
.environ
['FOO_PATH']
174 if 'XDG_DATA_DIRS' in os
.environ
:
175 del os
.environ
['XDG_DATA_DIRS']
176 os
.environ
['BAR_PATH'] = '/old'
177 old
, sys
.stdout
= sys
.stdout
, StringIO()
179 policy
.download_and_execute(['Hello'])
182 self
.assertEquals(cached_impl
+ '/.',
183 os
.environ
['FOO_PATH'])
184 self
.assertEquals(cached_impl
+ '/.:/old',
185 os
.environ
['BAR_PATH'])
186 self
.assertEquals(cached_impl
+ '/.:/usr/local/share:/usr/share',
187 os
.environ
['XDG_DATA_DIRS'])
190 self
.cache_iface(foo_iface_uri
,
191 """<?xml version="1.0" ?>
192 <interface last-modified="0"
194 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
196 <summary>Foo</summary>
197 <description>Foo</description>
198 <feed src='http://bar'/>
199 </interface>""" % foo_iface_uri
)
200 self
.cache_iface('http://bar',
201 """<?xml version="1.0" ?>
202 <interface last-modified="0"
204 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
205 <feed-for interface='%s'/>
207 <summary>Bar</summary>
208 <description>Bar</description>
209 <implementation version='1.0' id='sha1=123'/>
210 </interface>""" % foo_iface_uri
)
211 policy
= autopolicy
.AutoPolicy(foo_iface_uri
, False,
214 policy
.network_use
= model
.network_full
217 foo_iface
= policy
.get_interface(foo_iface_uri
)
218 self
.assertEquals('sha1=123', policy
.implementation
[foo_iface
].id)
220 def testBadConfig(self
):
221 path
= basedir
.save_config_path(namespaces
.config_site
,
222 namespaces
.config_prog
)
223 glob
= os
.path
.join(path
, 'global')
224 assert not os
.path
.exists(glob
)
225 stream
= file(glob
, 'w')
226 stream
.write('hello!')
229 logger
.setLevel(logging
.ERROR
)
230 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
231 download_only
= False)
232 logger
.setLevel(logging
.WARN
)
234 def testRanking(self
):
235 self
.cache_iface('http://bar',
236 """<?xml version="1.0" ?>
237 <interface last-modified="1110752708"
239 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
241 <summary>Bar</summary>
242 <description>Bar</description>
243 <implementation id='sha1=125' version='1.0' arch='odd-weird' stability='buggy'/>
244 <implementation id='sha1=126' version='1.0'/>
246 self
.cache_iface(foo_iface_uri
,
247 """<?xml version="1.0" ?>
248 <interface last-modified="1110752708"
250 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
252 <summary>Foo</summary>
253 <description>Foo</description>
254 <feed src='http://example.com' arch='odd-unknown'/>
255 <feed src='http://bar'/>
256 <implementation id='sha1=123' version='1.0' arch='odd-strange'/>
257 <implementation id='sha1=124' version='1.0' arch='odd-weird'/>
258 </interface>""" % foo_iface_uri
)
259 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
260 download_only
= False)
261 policy
.network_use
= model
.network_full
263 impls
= policy
.get_ranked_implementations(
264 policy
.get_interface(policy
.root
))
265 assert len(impls
) == 4
267 logger
.setLevel(logging
.ERROR
)
268 policy
.network_use
= model
.network_offline
# Changes sort order tests
269 policy
.recalculate() # Triggers feed-for warning
270 logger
.setLevel(logging
.WARN
)
272 def testNoLocal(self
):
273 self
.cache_iface(foo_iface_uri
,
274 """<?xml version="1.0" ?>
275 <interface last-modified="1110752708"
277 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
279 <summary>Foo</summary>
280 <description>Foo</description>
281 <feed src='/etc/passwd'/>
282 </interface>""" % foo_iface_uri
)
283 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
284 download_only
= False)
285 policy
.network_use
= model
.network_offline
287 policy
.get_interface(foo_iface_uri
)
289 except reader
.InvalidInterface
, ex
:
290 assert 'Invalid feed URL' in str(ex
)
292 def testDLfeed(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 <feed src='http://example.com'/>
302 </interface>""" % foo_iface_uri
)
303 policy
= autopolicy
.AutoPolicy(foo_iface_uri
, dry_run
= True)
304 policy
.network_use
= model
.network_full
310 except NeedDownload
, ex
:
313 iface
= policy
.get_interface(foo_iface_uri
)
314 iface
.feeds
= [model
.Feed('/BadFeed', None, False)]
316 logger
.setLevel(logging
.ERROR
)
317 policy
.recalculate() # Triggers warning
318 logger
.setLevel(logging
.WARN
)
320 def testBestUnusable(self
):
321 self
.cache_iface(foo_iface_uri
,
322 """<?xml version="1.0" ?>
323 <interface last-modified="1110752708"
325 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
327 <summary>Foo</summary>
328 <description>Foo</description>
329 <implementation id='sha1=123' version='1.0' arch='odd-weird'/>
330 </interface>""" % foo_iface_uri
)
331 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
332 download_only
= False)
334 assert not policy
.ready
337 self
.cache_iface(foo_iface_uri
,
338 """<?xml version="1.0" ?>
339 <interface last-modified="1110752708"
341 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
343 <summary>Foo</summary>
344 <description>Foo</description>
346 <requires interface='%s'/>
347 <implementation id='sha1=123' version='1.0'/>
349 </interface>""" % (foo_iface_uri
, foo_iface_uri
))
350 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
351 download_only
= False)
354 def testConstraints(self
):
355 self
.cache_iface('http://bar',
356 """<?xml version="1.0" ?>
357 <interface last-modified="1110752708"
359 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
361 <summary>Bar</summary>
362 <description>Bar</description>
363 <implementation id='sha1=100' version='1.0'/>
364 <implementation id='sha1=150' stability='developer' version='1.5'/>
365 <implementation id='sha1=200' version='2.0'/>
367 self
.cache_iface(foo_iface_uri
,
368 """<?xml version="1.0" ?>
369 <interface last-modified="1110752708"
371 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
373 <summary>Foo</summary>
374 <description>Foo</description>
376 <requires interface='http://bar'>
379 <implementation id='sha1=123' version='1.0'/>
381 </interface>""" % foo_iface_uri
)
382 policy
= autopolicy
.AutoPolicy(foo_iface_uri
,
383 download_only
= False)
384 policy
.network_use
= model
.network_full
386 #logger.setLevel(logging.DEBUG)
388 #logger.setLevel(logging.WARN)
389 foo_iface
= policy
.get_interface(foo_iface_uri
)
390 bar_iface
= policy
.get_interface('http://bar')
391 assert policy
.implementation
[bar_iface
].id == 'sha1=200'
393 dep
= policy
.implementation
[foo_iface
].dependencies
['http://bar']
394 assert len(dep
.restrictions
) == 1
395 restriction
= dep
.restrictions
[0]
397 restriction
.before
= [2, 0]
399 assert policy
.implementation
[bar_iface
].id == 'sha1=100'
401 restriction
.not_before
= [1, 5]
403 assert policy
.implementation
[bar_iface
].id == 'sha1=150'
405 suite
= unittest
.makeSuite(TestAutoPolicy
)
406 if __name__
== '__main__':
407 sys
.argv
.append('-v')