If we need a command, mark all implementations without as unselectable
[zeroinstall/zeroinstall-afb.git] / tests / testreader.py
blob304c98290062d3dfe217508fd23e2731e579c186
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 from zeroinstall.injector.iface_cache import iface_cache
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 testNoVersion(self):
41 tmp = self.write_with_version('')
42 reader.check_readable(foo_iface_uri, tmp.name)
44 def testNewEnough(self):
45 tmp = self.write_with_version('min-injector-version="0.19"')
46 reader.check_readable(foo_iface_uri, tmp.name)
48 def testTooOld(self):
49 tmp = self.write_with_version('min-injector-version="1000"')
50 try:
51 reader.check_readable(foo_iface_uri, tmp.name)
52 except reader.InvalidInterface, ex:
53 assert "1000" in str(ex)
55 def testRequiresVersion(self):
56 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
57 tmp.write(
58 """<?xml version="1.0" ?>
59 <interface last-modified="1110752708"
60 uri="%s"
61 xmlns="http://zero-install.sourceforge.net/2004/injector/interface"
62 xmlns:my='http://my/namespace'>
63 <name>Foo</name>
64 <summary>Foo</summary>
65 <description>Foo</description>
66 <group>
67 <requires interface='%s' my:foo='test'>
68 <version not-before='2.3.4' before='3.4.5'/>
69 </requires>
70 <implementation id='sha1=123' version='1'/>
71 <requires interface='%s2'/>
72 </group>
73 </interface>""" % (foo_iface_uri, bar_iface_uri, bar_iface_uri))
74 tmp.flush()
75 iface = model.Interface(foo_iface_uri)
76 reader.update(iface, tmp.name)
77 feed = iface_cache.get_feed(foo_iface_uri)
79 impl = feed.implementations['sha1=123']
80 assert len(impl.dependencies) == 2
81 dep = impl.dependencies[bar_iface_uri]
82 assert len(dep.restrictions) == 1
83 res = dep.restrictions[0]
84 assert res.not_before == [[2, 3, 4], 0]
85 assert res.before == [[3, 4, 5], 0]
86 dep2 = impl.dependencies[bar_iface_uri + '2']
87 assert len(dep2.restrictions) == 0
88 str(dep)
89 str(dep2)
91 assert dep.metadata.get('http://my/namespace foo') == 'test'
92 assert dep.metadata.get('http://my/namespace food', None) == None
94 def testBindings(self):
95 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
96 tmp.write(
97 """<?xml version="1.0" ?>
98 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
99 <name>Foo</name>
100 <summary>Foo</summary>
101 <description>Foo</description>
102 <group>
103 <requires interface='http://example.com/foo.xml'>
104 <environment name='PATH' insert='bin'/>
105 <environment name='PATH' insert='bin' mode='prepend'/>
106 <environment name='PATH' insert='bin' default='/bin' mode='append'/>
107 <environment name='PATH' insert='bin' mode='replace'/>
108 </requires>
109 <implementation id='sha1=123' version='1'>
110 <environment name='SELF' insert='.' mode='replace'/>
111 </implementation>
112 </group>
113 </interface>""")
114 tmp.flush()
115 iface = model.Interface(foo_iface_uri)
116 reader.update(iface, tmp.name, local = True)
118 feed = iface_cache.get_feed(foo_iface_uri)
120 impl = feed.implementations['sha1=123']
122 assert len(impl.bindings) == 1
123 self.assertEquals(model.EnvironmentBinding.REPLACE, impl.bindings[0].mode)
125 assert len(impl.requires) == 1
126 dep = impl.requires[0]
128 assert len(dep.bindings) == 4
129 for b in dep.bindings:
130 self.assertEquals('PATH', b.name)
131 self.assertEquals('bin', b.insert)
132 self.assertEquals(model.EnvironmentBinding.PREPEND, dep.bindings[0].mode)
133 self.assertEquals(model.EnvironmentBinding.PREPEND, dep.bindings[1].mode)
134 self.assertEquals(model.EnvironmentBinding.APPEND, dep.bindings[2].mode)
135 self.assertEquals(model.EnvironmentBinding.REPLACE, dep.bindings[3].mode)
137 self.assertEquals(None, dep.bindings[1].default)
138 self.assertEquals('/bin', dep.bindings[2].default)
140 def testVersions(self):
141 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
142 tmp.write(
143 """<?xml version="1.0" ?>
144 <interface
145 uri="%s"
146 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
147 <name>Foo</name>
148 <summary>Foo</summary>
149 <description>Foo</description>
150 <implementation id='sha1=123' version='1.0-rc3' version-modifier='-pre'/>
151 </interface>""" % foo_iface_uri)
152 tmp.flush()
153 iface = model.Interface(foo_iface_uri)
154 reader.update(iface, tmp.name)
155 feed = iface_cache.get_feed(foo_iface_uri)
156 impl = feed.implementations['sha1=123']
157 assert impl.version == [[1, 0], -1, [3], -2]
159 def testAttrs(self):
160 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
161 tmp.write(
162 """<?xml version="1.0" ?>
163 <interface last-modified="1110752708"
164 uri="%s"
165 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
166 <name>Foo</name>
167 <summary>Foo</summary>
168 <description>Foo</description>
169 <group main='bin/sh' foo='foovalue' xmlns:bobpre='http://bob' bobpre:bob='bobvalue'>
170 <implementation id='sha1=123' version='1' bobpre:bob='newbobvalue'/>
171 <implementation id='sha1=124' version='2' main='next'/>
172 </group>
173 </interface>""" % foo_iface_uri)
174 tmp.flush()
175 iface = model.Interface(foo_iface_uri)
176 reader.update(iface, tmp.name)
178 feed = iface_cache.get_feed(foo_iface_uri)
180 assert len(feed.implementations) == 2
182 assert feed.implementations['sha1=123'].metadata['foo'] == 'foovalue'
183 assert feed.implementations['sha1=123'].metadata['main'] == 'bin/sh'
184 assert feed.implementations['sha1=123'].metadata['http://bob bob'] == 'newbobvalue'
186 assert feed.implementations['sha1=124'].metadata['http://bob bob'] == 'bobvalue'
187 assert feed.implementations['sha1=124'].metadata['main'] == 'next'
189 def testNative(self):
190 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
191 tmp.write(
192 """<?xml version="1.0" ?>
193 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
194 <name>Foo</name>
195 <summary>Foo</summary>
196 <description>Foo</description>
197 <package-implementation package='gimp'/>
198 <package-implementation package='python-bittorrent' foo='bar' main='/usr/bin/pbt'/>
199 </interface>""")
200 tmp.flush()
202 iface = model.Interface(foo_iface_uri)
203 reader.update(iface, tmp.name, True)
205 master_feed = iface_cache.get_feed(foo_iface_uri)
206 assert len(master_feed.implementations) == 0
207 distro_feed_url = master_feed.get_distro_feed()
209 feed = iface_cache.get_feed(distro_feed_url)
210 assert len(feed.implementations) == 1
212 impl = feed.implementations['package:deb:python-bittorrent:3.4.2-10:*']
213 assert impl.id == 'package:deb:python-bittorrent:3.4.2-10:*'
214 assert impl.upstream_stability == model.packaged
215 assert impl.user_stability == None
216 assert impl.requires == []
217 assert impl.main == '/usr/bin/pbt'
218 assert impl.metadata['foo'] == 'bar'
219 assert impl.feed == feed
221 def testLang(self):
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 <feed langs='fr en_GB' src='http://localhost/feed.xml'/>
230 <group>
231 <group langs='fr en_GB'>
232 <implementation id='sha1=124' version='2' langs='fr'/>
233 <implementation id='sha1=234' version='2'/>
234 </group>
235 <implementation id='sha1=345' version='2'/>
236 </group>
237 </interface>""")
238 tmp.flush()
240 feed = reader.load_feed(tmp.name, local = True)
242 assert len(feed.implementations) == 3
243 assert len(feed.feeds) == 1, feed.feeds
245 self.assertEquals('fr en_GB', feed.feeds[0].langs)
247 self.assertEquals('fr', feed.implementations['sha1=124'].langs)
248 self.assertEquals('fr en_GB', feed.implementations['sha1=234'].langs)
249 self.assertEquals('', feed.implementations['sha1=345'].langs)
251 if __name__ == '__main__':
252 unittest.main()