Refactored code as required for the new 0publish
[zeroinstall/zeroinstall-limyreth.git] / tests / testreader.py
blobe8c52ba654c3a19d244e50d08784e4bf379e36c9
1 #!/usr/bin/env python
2 from basetest import BaseTest
3 import sys, tempfile, logging
4 import unittest
5 import os
7 sys.path.insert(0, '..')
9 from zeroinstall.injector import model, gpg, reader
10 import data
12 foo_iface_uri = 'http://foo'
13 bar_iface_uri = 'http://localhost/bar'
15 logger = logging.getLogger()
17 class TestReader(BaseTest):
18 def setUp(self):
19 BaseTest.setUp(self)
21 stream = tempfile.TemporaryFile()
22 stream.write(data.thomas_key)
23 stream.seek(0)
24 gpg.import_key(stream)
26 def write_with_version(self, version):
27 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
28 tmp.write(
29 """<?xml version="1.0" ?>
30 <interface last-modified="1110752708"
31 uri="%s" %s
32 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
33 <name>Foo</name>
34 <summary>Foo</summary>
35 <description>Foo</description>
36 </interface>""" % (foo_iface_uri, version))
37 tmp.flush()
38 return tmp
40 def write_with_bindings(self, bindings):
41 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
42 tmp.write(
43 """<?xml version="1.0" ?>
44 <interface last-modified="1110752708"
45 uri="%s"
46 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
47 <name>Foo</name>
48 <summary>Foo</summary>
49 <description>Foo</description>
50 <group>
51 <requires interface='%s2'>
53 </requires>
54 <implementation id='sha1=123' version='1'/>
55 </group>
56 </interface>""" % (foo_iface_uri, foo_iface_uri, bindings))
57 tmp.flush()
58 return tmp
60 def testNoVersion(self):
61 tmp = self.write_with_version('')
62 reader.check_readable(foo_iface_uri, tmp.name)
64 def testNewEnough(self):
65 tmp = self.write_with_version('min-injector-version="0.19"')
66 reader.check_readable(foo_iface_uri, tmp.name)
68 def testTooOld(self):
69 tmp = self.write_with_version('min-injector-version="1000"')
70 try:
71 reader.check_readable(foo_iface_uri, tmp.name)
72 self.fail()
73 except reader.InvalidInterface as ex:
74 assert "1000" in str(ex)
76 def testCantUseBothInsertAndValueInEnvironmentBinding(self):
77 tmp = self.write_with_bindings("""
78 <environment name="DATA" value="" insert=""/>
79 """)
80 try:
81 reader.check_readable(foo_iface_uri, tmp.name)
82 self.fail()
83 except reader.InvalidInterface as ex:
84 assert "Binding contains both 'insert' and 'value'" in str(ex)
86 def testRequiresVersion(self):
87 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
88 tmp.write(
89 """<?xml version="1.0" ?>
90 <interface last-modified="1110752708"
91 uri="%s"
92 xmlns="http://zero-install.sourceforge.net/2004/injector/interface"
93 xmlns:my='http://my/namespace'>
94 <name>Foo</name>
95 <summary>Foo</summary>
96 <description>Foo</description>
97 <group>
98 <requires interface='%s' my:foo='test'>
99 <version not-before='2.3.4' before='3.4.5'/>
100 </requires>
101 <implementation id='sha1=123' version='1'/>
102 <requires interface='%s2'/>
103 </group>
104 </interface>""" % (foo_iface_uri, bar_iface_uri, bar_iface_uri))
105 tmp.flush()
106 iface = model.Interface(foo_iface_uri)
107 reader.update(iface, tmp.name, iface_cache = self.config.iface_cache)
108 feed = self.config.iface_cache.get_feed(foo_iface_uri)
110 impl = feed.implementations['sha1=123']
111 assert len(impl.dependencies) == 2
112 dep = impl.dependencies[bar_iface_uri]
113 assert len(dep.restrictions) == 1
114 res = dep.restrictions[0]
115 assert res.not_before == [[2, 3, 4], 0]
116 assert res.before == [[3, 4, 5], 0]
117 dep2 = impl.dependencies[bar_iface_uri + '2']
118 assert len(dep2.restrictions) == 0
119 str(dep)
120 str(dep2)
122 assert dep.metadata.get('http://my/namespace foo') == 'test'
123 assert dep.metadata.get('http://my/namespace food', None) == None
125 def testBindings(self):
126 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
127 tmp.write(
128 """<?xml version="1.0" ?>
129 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
130 <name>Foo</name>
131 <summary>Foo</summary>
132 <description>Foo</description>
133 <group>
134 <requires interface='http://example.com/foo.xml'>
135 <environment name='PATH' insert='bin'/>
136 <environment name='PATH' insert='bin' mode='prepend'/>
137 <environment name='PATH' insert='bin' default='/bin' mode='append'/>
138 <environment name='PATH' insert='bin' mode='replace'/>
139 <environment name='PATH' insert='bin' separator=',' />
140 </requires>
141 <implementation id='sha1=123' version='1'>
142 <environment name='SELF' insert='.' mode='replace'/>
143 </implementation>
144 </group>
145 </interface>""")
146 tmp.flush()
147 iface = model.Interface(foo_iface_uri)
148 reader.update(iface, tmp.name, local = True, iface_cache = self.config.iface_cache)
150 feed = self.config.iface_cache.get_feed(foo_iface_uri)
152 impl = feed.implementations['sha1=123']
154 assert len(impl.bindings) == 1
155 self.assertEquals(model.EnvironmentBinding.REPLACE, impl.bindings[0].mode)
157 assert len(impl.requires) == 1
158 dep = impl.requires[0]
160 assert len(dep.bindings) == 5
161 for b in dep.bindings:
162 self.assertEquals('PATH', b.name)
163 self.assertEquals('bin', b.insert)
164 self.assertEquals(model.EnvironmentBinding.PREPEND, dep.bindings[0].mode)
165 self.assertEquals(model.EnvironmentBinding.PREPEND, dep.bindings[1].mode)
166 self.assertEquals(model.EnvironmentBinding.APPEND, dep.bindings[2].mode)
167 self.assertEquals(model.EnvironmentBinding.REPLACE, dep.bindings[3].mode)
168 self.assertEquals(model.EnvironmentBinding.PREPEND, dep.bindings[4].mode)
170 self.assertEquals(os.path.join('/impl', 'bin:current'),
171 dep.bindings[0].get_value('/impl', 'current'))
172 self.assertEquals(os.path.join('/impl', 'bin,current'),
173 dep.bindings[4].get_value('/impl', 'current'))
175 self.assertEquals(None, dep.bindings[1].default)
176 self.assertEquals('/bin', dep.bindings[2].default)
178 def testVersions(self):
179 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
180 tmp.write(
181 """<?xml version="1.0" ?>
182 <interface
183 uri="%s"
184 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
185 <name>Foo</name>
186 <summary>Foo</summary>
187 <description>Foo</description>
188 <implementation id='sha1=123' version='1.0-rc3' version-modifier='-pre'/>
189 </interface>""" % foo_iface_uri)
190 tmp.flush()
191 iface = model.Interface(foo_iface_uri)
192 reader.update(iface, tmp.name, iface_cache = self.config.iface_cache)
193 feed = self.config.iface_cache.get_feed(foo_iface_uri)
194 impl = feed.implementations['sha1=123']
195 assert impl.version == [[1, 0], -1, [3], -2]
197 def testAttrs(self):
198 iface_cache = self.config.iface_cache
199 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
200 tmp.write(
201 """<?xml version="1.0" ?>
202 <interface last-modified="1110752708"
203 uri="%s"
204 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
205 <name>Foo</name>
206 <summary>Foo</summary>
207 <description>Foo</description>
208 <group main='bin/sh' foo='foovalue' xmlns:bobpre='http://bob' bobpre:bob='bobvalue'>
209 <implementation id='sha1=123' version='1' bobpre:bob='newbobvalue'/>
210 <implementation id='sha1=124' version='2' main='next'/>
211 </group>
212 </interface>""" % foo_iface_uri)
213 tmp.flush()
214 iface = model.Interface(foo_iface_uri)
215 reader.update(iface, tmp.name, iface_cache = self.config.iface_cache)
217 feed = iface_cache.get_feed(foo_iface_uri)
219 assert len(feed.implementations) == 2
221 assert feed.implementations['sha1=123'].metadata['foo'] == 'foovalue'
222 assert feed.implementations['sha1=123'].metadata['main'] == 'bin/sh'
223 assert feed.implementations['sha1=123'].metadata['http://bob bob'] == 'newbobvalue'
225 assert feed.implementations['sha1=124'].metadata['http://bob bob'] == 'bobvalue'
226 assert feed.implementations['sha1=124'].metadata['main'] == 'next'
228 def testNative(self):
229 iface_cache = self.config.iface_cache
230 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
231 tmp.write(
232 """<?xml version="1.0" ?>
233 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
234 <name>Foo</name>
235 <summary>Foo</summary>
236 <description>Foo</description>
237 <package-implementation package='gimp'/>
238 <package-implementation package='python-bittorrent' foo='bar' main='/usr/bin/pbt'/>
239 </interface>""")
240 tmp.flush()
242 iface = model.Interface(foo_iface_uri)
243 reader.update(iface, tmp.name, True, iface_cache = self.config.iface_cache)
245 master_feed = iface_cache.get_feed(foo_iface_uri)
246 assert len(master_feed.implementations) == 0
247 distro_feed_url = master_feed.get_distro_feed()
249 feed = iface_cache.get_feed(distro_feed_url)
250 assert len(feed.implementations) == 1
252 impl = feed.implementations['package:deb:python-bittorrent:3.4.2-10:*']
253 assert impl.id == 'package:deb:python-bittorrent:3.4.2-10:*'
254 assert impl.upstream_stability == model.packaged
255 assert impl.user_stability == None
256 assert impl.requires == []
257 assert impl.main == '/usr/bin/pbt'
258 assert impl.metadata['foo'] == 'bar'
259 assert impl.feed == feed
261 def testLang(self):
262 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
263 tmp.write(
264 """<?xml version="1.0" ?>
265 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
266 <name>Foo</name>
267 <summary>Foo</summary>
268 <description>Foo</description>
269 <feed langs='fr en_GB' src='http://localhost/feed.xml'/>
270 <group>
271 <group langs='fr en_GB'>
272 <implementation id='sha1=124' version='2' langs='fr'/>
273 <implementation id='sha1=234' version='2'/>
274 </group>
275 <implementation id='sha1=345' version='2'/>
276 </group>
277 </interface>""")
278 tmp.flush()
280 feed = reader.load_feed(tmp.name, local = True)
282 assert len(feed.implementations) == 3
283 assert len(feed.feeds) == 1, feed.feeds
285 self.assertEquals('fr en-GB', feed.feeds[0].langs)
287 self.assertEquals('fr', feed.implementations['sha1=124'].langs)
288 self.assertEquals('fr en-GB', feed.implementations['sha1=234'].langs)
289 self.assertEquals('', feed.implementations['sha1=345'].langs)
291 if __name__ == '__main__':
292 unittest.main()