Generalise mirror fallback code.
[zeroinstall/zeroinstall-mseaborn.git] / tests / testmodel.py
blobeb31f581eadfab17ae1f743d95922f1baa9ec0c2
1 #!/usr/bin/env python2.4
2 # -*- coding: utf-8 -*-
3 from basetest import BaseTest, empty_feed
4 import sys, tempfile, os, shutil
5 import unittest
6 from StringIO import StringIO
8 sys.path.insert(0, '..')
9 from zeroinstall.injector import model, qdom
11 class TestModel(BaseTest):
12 def testLevels(self):
13 assert model.network_offline in model.network_levels
14 assert model.network_minimal in model.network_levels
15 assert model.network_full in model.network_levels
17 def testStabilities(self):
18 assert 'insecure' in model.stability_levels
19 assert 'buggy' in model.stability_levels
20 assert 'developer' in model.stability_levels
21 assert 'testing' in model.stability_levels
22 assert 'stable' in model.stability_levels
23 assert 'preferred' in model.stability_levels
24 str(model.insecure)
26 def testEscape(self):
27 self.assertEquals("", model.escape(""))
28 self.assertEquals("hello", model.escape("hello"))
29 self.assertEquals("%20", model.escape(" "))
31 self.assertEquals("file%3a%2f%2ffoo%7ebar",
32 model.escape("file://foo~bar"))
33 self.assertEquals("file%3a%2f%2ffoo%25bar",
34 model.escape("file://foo%bar"))
36 self.assertEquals("file:##foo%7ebar",
37 model._pretty_escape("file://foo~bar"))
38 self.assertEquals("file:##foo%25bar",
39 model._pretty_escape("file://foo%bar"))
41 def testUnescape(self):
42 self.assertEquals("", model.unescape(""))
43 self.assertEquals("hello", model.unescape("hello"))
44 self.assertEquals(" ", model.unescape("%20"))
46 self.assertEquals("file://foo~bar",
47 model.unescape("file%3a%2f%2ffoo%7ebar"))
48 self.assertEquals("file://foo%bar",
49 model.unescape("file%3a%2f%2ffoo%25bar"))
51 self.assertEquals("file://foo",
52 model.unescape("file:##foo"))
53 self.assertEquals("file://foo~bar",
54 model.unescape("file:##foo%7ebar"))
55 self.assertEquals("file://foo%bar",
56 model.unescape("file:##foo%25bar"))
58 def testEscaping(self):
59 def check(str):
60 self.assertEquals(str, model.unescape(model.escape(str)))
61 self.assertEquals(str, model.unescape(model._pretty_escape(str)))
63 check(u'http://example.com')
64 check(u'http://example%46com')
65 check(u'http:##example#com')
66 check(u'http://example.com/foo/bar.xml')
67 check(u'%20%21~&!"£ :@;,./{}$%^&()')
69 def testBadInterface(self):
70 try:
71 model.Interface('foo')
72 assert 0
73 except model.SafeException:
74 pass
76 def testInterface(self):
77 i = model.Interface('http://foo')
78 self.assertEquals('(foo)', i.get_name())
79 feed = model.ZeroInstallFeed(empty_feed, local_path = '/foo')
80 i._main_feed = feed
81 self.assertEquals('Empty', i.get_name())
82 repr(i)
84 def testMetadata(self):
85 i = model.Interface('http://foo')
86 i._main_feed = model.ZeroInstallFeed(empty_feed, local_path = '/foo')
87 e = qdom.parse(StringIO('<ns:b xmlns:ns="a" foo="bar"/>'))
88 i._main_feed.metadata = [e]
89 assert i.get_metadata('a', 'b') == [e]
90 assert i.get_metadata('b', 'b') == []
91 assert i.get_metadata('a', 'a') == []
92 assert e.getAttribute('foo') == 'bar'
94 def testStabPolicy(self):
95 i = model.Interface('http://foo')
96 self.assertEquals(None, i.stability_policy)
97 i.set_stability_policy(model.buggy)
98 self.assertEquals(model.buggy, i.stability_policy)
100 def testGetImpl(self):
101 i = model.Interface('http://foo')
102 feed = model.ZeroInstallFeed(empty_feed, local_path = '/foo')
103 a = feed._get_impl('foo')
104 b = feed._get_impl('bar')
105 c = feed._get_impl('foo')
106 assert a and b and c
107 assert a is c
108 assert a is not b
109 assert isinstance(a, model.ZeroInstallImplementation)
111 def testImpl(self):
112 i = model.Interface('http://foo')
113 a = model.ZeroInstallImplementation(i, 'foo')
114 assert a.id == 'foo'
115 assert a.size == a.version == a.user_stability == None
116 assert a.arch == a.upstream_stability == None
117 assert a.dependencies == {}
118 assert a.download_sources == []
119 assert a.get_stability() is model.testing
120 a.upstream_stability = model.stable
121 assert a.get_stability() is model.stable
122 a.user_stability = model.buggy
123 assert a.get_stability() is model.buggy
124 a.version = model.parse_version('1.2.3')
125 self.assertEquals('1.2.3', a.get_version())
126 a.version = model.parse_version('1.2.3-rc2-post')
127 self.assertEquals('1.2.3-rc2-post', a.get_version())
128 assert str(a) == 'foo'
130 b = model.ZeroInstallImplementation(i, 'foo')
131 b.version = [1,2,1]
132 assert b > a
134 def testDownloadSource(self):
135 f = model.ZeroInstallFeed(empty_feed, local_path = '/foo')
136 a = model.ZeroInstallImplementation(f, 'foo')
137 a.add_download_source('ftp://foo', 1024, None)
138 a.add_download_source('ftp://foo.tgz', 1025, 'foo')
139 assert a.download_sources[0].url == 'ftp://foo'
140 assert a.download_sources[0].size == 1024
141 assert a.download_sources[0].extract == None
142 assert a.feed is f
144 def testEnvBind(self):
145 a = model.EnvironmentBinding('PYTHONPATH', 'path')
146 assert a.name == 'PYTHONPATH'
147 assert a.insert == 'path'
148 str(a)
150 def testEnvModes(self):
151 prepend = model.EnvironmentBinding('PYTHONPATH', 'lib', None, model.EnvironmentBinding.PREPEND)
152 assert prepend.name == 'PYTHONPATH'
153 assert prepend.insert == 'lib'
154 assert prepend.mode is model.EnvironmentBinding.PREPEND
156 self.assertEquals('/impl/lib:/usr/lib', prepend.get_value('/impl', '/usr/lib'))
157 self.assertEquals('/impl/lib', prepend.get_value('/impl', None))
159 append = model.EnvironmentBinding('PYTHONPATH', 'lib', '/opt/lib', model.EnvironmentBinding.APPEND)
160 assert append.name == 'PYTHONPATH'
161 assert append.insert == 'lib'
162 assert append.mode is model.EnvironmentBinding.APPEND
164 self.assertEquals('/usr/lib:/impl/lib', append.get_value('/impl', '/usr/lib'))
165 self.assertEquals('/opt/lib:/impl/lib', append.get_value('/impl', None))
167 append = model.EnvironmentBinding('PYTHONPATH', 'lib', None, model.EnvironmentBinding.REPLACE)
168 assert append.name == 'PYTHONPATH'
169 assert append.insert == 'lib'
170 assert append.mode is model.EnvironmentBinding.REPLACE
172 self.assertEquals('/impl/lib', append.get_value('/impl', '/usr/lib'))
173 self.assertEquals('/impl/lib', append.get_value('/impl', None))
175 assert model.EnvironmentBinding('PYTHONPATH', 'lib').mode == model.EnvironmentBinding.PREPEND
178 def testDep(self):
179 b = model.InterfaceDependency('http://foo')
180 assert not b.restrictions
181 assert not b.bindings
182 str(b)
184 def testFeed(self):
185 f = model.Feed('http://feed', arch = None, user_override = False)
186 assert f.uri == 'http://feed'
187 assert f.os == None
188 assert f.machine == None
189 assert f.arch == None
190 assert f.user_override == False
192 f = model.Feed('http://feed', arch = 'Linux-*', user_override = True)
193 assert f.uri == 'http://feed'
194 assert f.os == 'Linux'
195 assert f.machine == None
196 assert f.arch == 'Linux-*'
197 assert f.user_override == True
199 f = model.Feed('http://feed', arch = '*-i386', user_override = True)
200 assert f.uri == 'http://feed'
201 assert f.os == None
202 assert f.machine == 'i386'
203 assert f.arch == '*-i386'
204 assert f.user_override == True
205 assert str(f).startswith('<Feed from')
207 try:
208 f = model.Feed('http://feed', arch = 'i386', user_override = True)
209 assert False
210 except model.SafeException, ex:
211 assert 'Malformed arch' in str(ex)
213 def testCanonical(self):
214 self.assertEquals('http://foo',
215 model.canonical_iface_uri('http://foo'))
216 try:
217 model.canonical_iface_uri('bad-name')
218 assert False
219 except model.SafeException, ex:
220 assert 'Bad interface name' in str(ex)
222 def testVersions(self):
223 def pv(v):
224 parsed = model.parse_version(v)
225 assert model.format_version(parsed) == v
226 return parsed
228 assert pv('1.0') > pv('0.9')
229 assert pv('1.0') > pv('1')
230 assert pv('1.0') == pv('1.0')
231 assert pv('0.9.9') < pv('1.0')
233 def invalid(v):
234 try:
235 pv(v)
236 assert False
237 except model.SafeException, ex:
238 pass
239 invalid('hello')
240 invalid('2./1')
241 invalid('.1')
242 invalid('')
244 # Check parsing
245 assert pv('1') == [[1], 0]
246 assert pv('1.0') == [[1,0], 0]
247 assert pv('1.0-pre5') == [[1,0], -2, [5], 0]
248 assert pv('1.0-rc5') == [[1,0], -1, [5], 0]
249 assert pv('1.0-5') == [[1,0], 0, [5], 0]
250 assert pv('1.0-post5') == [[1,0], 1, [5], 0]
251 assert pv('1.0-post') == [[1,0], 1]
252 assert pv('1-rc2.0-pre2-post') == [[1], -1, [2,0], -2, [2], 1]
253 assert pv('1-rc2.0-pre-post') == [[1], -1, [2,0], -2, [], 1]
255 assert pv('1.0-0') > pv('1.0')
256 assert pv('1.0-1') > pv('1.0-0')
257 assert pv('1.0-0') < pv('1.0-1')
259 assert pv('1.0-pre99') > pv('1.0-pre1')
260 assert pv('1.0-pre99') < pv('1.0-rc1')
261 assert pv('1.0-rc1') < pv('1.0')
262 assert pv('1.0') < pv('1.0-0')
263 assert pv('1.0-0') < pv('1.0-post')
264 assert pv('2.1.9-pre-1') > pv('2.1.9-pre')
266 assert pv('2-post999') < pv('3-pre1')
268 suite = unittest.makeSuite(TestModel)
269 if __name__ == '__main__':
270 sys.argv.append('-v')
271 unittest.main()