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