Reject URIs without a path component (e.g. http://host)
[zeroinstall/zeroinstall-mseaborn.git] / tests / testlaunch.py
blob806804d1c14382dfb5c02a62e8b8c1361e40c374
1 #!/usr/bin/env python2.4
2 from basetest import BaseTest
3 import sys, tempfile, os, shutil, imp
4 from StringIO import StringIO
5 import unittest
6 import logging
8 foo_iface_uri = 'http://foo'
10 sys.path.insert(0, '..')
11 from zeroinstall.injector import trust, autopolicy, namespaces, model, iface_cache, cli
12 from zeroinstall.zerostore import Store; Store._add_with_helper = lambda *unused: False
13 from zeroinstall.support import basedir
15 class SilenceLogger(logging.Filter):
16 def filter(self, record):
17 return 0
18 silenceLogger = SilenceLogger()
20 class TestLaunch(BaseTest):
21 def cache_iface(self, name, data):
22 cached_ifaces = basedir.save_cache_path('0install.net',
23 'interfaces')
25 f = file(os.path.join(cached_ifaces, model.escape(name)), 'w')
26 f.write(data)
27 f.close()
29 def run_0launch(self, args):
30 sys.argv = ['0launch'] + args
31 old_stdout = sys.stdout
32 old_stderr = sys.stderr
33 try:
34 sys.stdout = StringIO()
35 sys.stderr = StringIO()
36 ex = None
37 try:
38 imp.load_source('launch', '../0launch')
39 print "Finished"
40 except NameError:
41 raise
42 except SystemExit:
43 pass
44 except TypeError:
45 raise
46 except AttributeError:
47 raise
48 except AssertionError:
49 raise
50 except Exception, ex:
51 pass
52 out = sys.stdout.getvalue()
53 err = sys.stderr.getvalue()
54 if ex is not None:
55 err += str(ex.__class__)
56 finally:
57 sys.stdout = old_stdout
58 sys.stderr = old_stderr
59 return (out, err)
61 def testHelp(self):
62 out, err = self.run_0launch([])
63 assert out.lower().startswith("usage:")
64 assert not err
66 def testList(self):
67 out, err = self.run_0launch(['--list'])
68 assert not err
69 self.assertEquals("Finished\n", out)
70 cached_ifaces = os.path.join(self.cache_home,
71 '0install.net', 'interfaces')
73 os.makedirs(cached_ifaces)
74 file(os.path.join(cached_ifaces, 'file%3a%2f%2ffoo'), 'w').close()
76 out, err = self.run_0launch(['--list'])
77 assert not err
78 self.assertEquals("file://foo\nFinished\n", out)
80 out, err = self.run_0launch(['--list', 'foo'])
81 assert not err
82 self.assertEquals("file://foo\nFinished\n", out)
84 out, err = self.run_0launch(['--list', 'bar'])
85 assert not err
86 self.assertEquals("Finished\n", out)
88 out, err = self.run_0launch(['--list', 'one', 'two'])
89 assert not err
90 assert out.lower().startswith("usage:")
92 def testVersion(self):
93 out, err = self.run_0launch(['--version'])
94 assert not err
95 assert out.startswith("0launch (zero-install)")
97 def testInvalid(self):
98 a = tempfile.NamedTemporaryFile()
99 out, err = self.run_0launch(['-q', a.name])
100 assert err
102 def testOK(self):
103 out, err = self.run_0launch(['--dry-run', 'http://foo/d'])
104 self.assertEquals("Would download 'http://foo/d'\nFinished\n", out)
105 self.assertEquals("", err)
107 def testOffline(self):
108 out, err = self.run_0launch(['--offline', 'http://foo/d'])
109 self.assertEquals("Can't find all required implementations:\n- <Interface http://foo/d> -> None\n", err)
110 self.assertEquals("", out)
112 def testDisplay(self):
113 os.environ['DISPLAY'] = ':foo'
114 out, err = self.run_0launch(['--dry-run', 'http://foo/d'])
115 # Uses local copy of GUI
116 assert out.startswith("Would execute: ")
117 assert 'basetest.py' in out
118 self.assertEquals("", err)
120 del os.environ['DISPLAY']
121 out, err = self.run_0launch(['--gui', '--dry-run'])
122 self.assertEquals("", err)
123 self.assertEquals("Finished\n", out)
125 def testRefreshDisplay(self):
126 os.environ['DISPLAY'] = ':foo'
127 out, err = self.run_0launch(['--dry-run', '--refresh', 'http://foo/d'])
128 assert out.startswith("Would execute: ")
129 assert 'basetest.py' in out
130 self.assertEquals("", err)
132 def testNeedDownload(self):
133 policy = autopolicy.AutoPolicy(foo_iface_uri)
134 policy.save_config()
135 os.environ['DISPLAY'] = ':foo'
136 out, err = self.run_0launch(['--download-only', '--dry-run', 'Foo.xml'])
137 self.assertEquals("", err)
138 self.assertEquals("Finished\n", out)
140 def testHello(self):
141 out, err = self.run_0launch(['--dry-run', 'Foo.xml'])
142 self.assertEquals("", err)
143 assert out.startswith("Would execute: ")
145 out, err = self.run_0launch(['Foo.xml'])
146 # (Foo.xml tries to run a directory; plash gives a different error)
147 assert "Permission denied" in err or "Is a directory" in err
149 def testSource(self):
150 out, err = self.run_0launch(['--dry-run', '--source', 'Source.xml'])
151 self.assertEquals("", err)
152 assert 'Compiler.xml' in out
154 def testRanges(self):
155 out, err = self.run_0launch(['--dry-run', '--before=1', '--not-before=0.2', 'Foo.xml'])
156 assert 'tests/two' in err, err
157 self.assertEquals("", out)
159 def testLogging(self):
160 log = logging.getLogger()
161 log.addFilter(silenceLogger)
163 out, err = self.run_0launch(['-v', '--list', 'UNKNOWN'])
164 self.assertEquals(logging.INFO, log.level)
166 out, err = self.run_0launch(['-vv', '--version'])
167 self.assertEquals(logging.DEBUG, log.level)
169 log.removeFilter(silenceLogger)
170 log.setLevel(logging.WARN)
172 def testHelp(self):
173 out, err = self.run_0launch(['--help'])
174 self.assertEquals("", err)
175 assert 'options:' in out.lower()
177 out, err = self.run_0launch([])
178 self.assertEquals("", err)
179 assert 'options:' in out.lower()
181 def testBadFD(self):
182 copy = os.dup(1)
183 try:
184 os.close(1)
185 cli.main(['--list', 'UNKNOWN'])
186 finally:
187 os.dup2(copy, 1)
189 suite = unittest.makeSuite(TestLaunch)
190 if __name__ == '__main__':
191 sys.argv.append('-v')
192 unittest.main()