Start development series 1.9-post
[zeroinstall.git] / tests / testlaunch.py
blob06d331ba820c9c671b5ba2d218b03770f2b2db05
1 #!/usr/bin/env python
3 from __future__ import print_function
5 from basetest import BaseTest
6 import sys, tempfile, os
7 from StringIO import StringIO
8 import unittest
9 import logging
11 foo_iface_uri = 'http://foo'
13 sys.path.insert(0, '..')
14 from zeroinstall import SafeException
15 from zeroinstall.support import tasks
16 from zeroinstall.injector import run, cli, namespaces, qdom, selections
17 from zeroinstall.zerostore import Store; Store._add_with_helper = lambda *unused: False
18 from zeroinstall.injector.requirements import Requirements
19 from zeroinstall.injector.driver import Driver
21 mydir = os.path.abspath(os.path.dirname(__file__))
23 class SilenceLogger(logging.Filter):
24 def filter(self, record):
25 return 0
26 silenceLogger = SilenceLogger()
28 class TestLaunch(BaseTest):
29 def run_0launch(self, args):
30 old_stdout = sys.stdout
31 old_stderr = sys.stderr
32 try:
33 sys.stdout = StringIO()
34 sys.stderr = StringIO()
35 ex = None
36 try:
37 cli.main(args)
38 print("Finished")
39 except NameError:
40 raise
41 except SystemExit:
42 pass
43 except TypeError:
44 raise
45 except AttributeError:
46 raise
47 except AssertionError:
48 raise
49 except Exception as ex:
50 pass
51 out = sys.stdout.getvalue()
52 err = sys.stderr.getvalue()
53 if ex is not None:
54 err += str(ex.__class__)
55 finally:
56 sys.stdout = old_stdout
57 sys.stderr = old_stderr
58 return (out, err)
60 def testHelp(self):
61 out, err = self.run_0launch([])
62 assert out.lower().startswith("usage:")
63 assert not err
65 def testList(self):
66 out, err = self.run_0launch(['--list'])
67 assert not err
68 self.assertEqual("Finished\n", out)
69 cached_ifaces = os.path.join(self.cache_home,
70 '0install.net', 'interfaces')
72 os.makedirs(cached_ifaces)
73 open(os.path.join(cached_ifaces, 'file%3a%2f%2ffoo'), 'w').close()
75 out, err = self.run_0launch(['--list'])
76 assert not err
77 self.assertEqual("file://foo\nFinished\n", out)
79 out, err = self.run_0launch(['--list', 'foo'])
80 assert not err
81 self.assertEqual("file://foo\nFinished\n", out)
83 out, err = self.run_0launch(['--list', 'bar'])
84 assert not err
85 self.assertEqual("Finished\n", out)
87 out, err = self.run_0launch(['--list', 'one', 'two'])
88 assert not err
89 assert out.lower().startswith("usage:")
91 def testVersion(self):
92 out, err = self.run_0launch(['--version'])
93 assert not err
94 assert out.startswith("0launch (zero-install)")
96 def testInvalid(self):
97 a = tempfile.NamedTemporaryFile()
98 out, err = self.run_0launch(['-q', a.name])
99 assert err
101 def testOK(self):
102 out, err = self.run_0launch(['--dry-run', 'http://foo/d'])
103 self.assertEqual("Would download 'http://foo/d'\nFinished\n", out)
104 self.assertEqual("", err)
106 def testRun(self):
107 out, err = self.run_0launch(['Local.xml'])
108 self.assertEqual("", out)
109 assert "test-echo' does not exist" in err, err
111 def testAbsMain(self):
112 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
113 tmp.write(
114 """<?xml version="1.0" ?>
115 <interface last-modified="1110752708"
116 uri="%s"
117 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
118 <name>Foo</name>
119 <summary>Foo</summary>
120 <description>Foo</description>
121 <group main='/bin/sh'>
122 <implementation id='.' version='1'/>
123 </group>
124 </interface>""" % foo_iface_uri)
125 tmp.flush()
126 driver = Driver(requirements = Requirements(tmp.name), config = self.config)
127 try:
128 downloaded = driver.solve_and_download_impls()
129 if downloaded:
130 tasks.wait_for_blocker(downloaded)
131 run.execute_selections(driver.solver.selections, [], stores = self.config.stores)
132 assert False
133 except SafeException as ex:
134 assert 'Command path must be relative' in str(ex), ex
136 def testOffline(self):
137 out, err = self.run_0launch(['--offline', 'http://foo/d'])
138 self.assertEqual("Interface 'http://foo/d' has no usable implementations in the cache (and 0install is in off-line mode)\n", err)
139 self.assertEqual("", out)
141 def testDisplay(self):
142 os.environ['DISPLAY'] = ':foo'
143 out, err = self.run_0launch(['--dry-run', 'http://foo/d'])
144 # Uses local copy of GUI
145 assert out.startswith("Would execute: ")
146 assert 'basetest.py' in out
147 self.assertEqual("", err)
149 del os.environ['DISPLAY']
150 out, err = self.run_0launch(['--gui', '--dry-run'])
151 self.assertEqual("", err)
152 self.assertEqual("Finished\n", out)
154 def testRefreshDisplay(self):
155 os.environ['DISPLAY'] = ':foo'
156 out, err = self.run_0launch(['--dry-run', '--refresh', 'http://foo/d'])
157 assert out.startswith("Would execute: ")
158 assert 'basetest.py' in out
159 self.assertEqual("", err)
161 def testNeedDownload(self):
162 os.environ['DISPLAY'] = ':foo'
163 out, err = self.run_0launch(['--download-only', '--dry-run', 'Foo.xml'])
164 self.assertEqual("", err)
165 self.assertEqual("Finished\n", out)
167 def testSelectOnly(self):
168 os.environ['DISPLAY'] = ':foo'
169 out, err = self.run_0launch(['--get-selections', '--select-only', 'Hello.xml'])
170 self.assertEqual("", err)
172 assert out.endswith("Finished\n")
173 out = out[:-len("Finished\n")]
175 root = qdom.parse(StringIO(str(out)))
176 self.assertEqual(namespaces.XMLNS_IFACE, root.uri)
177 sels = selections.Selections(root)
178 sel,= sels.selections.values()
179 self.assertEqual("sha1=3ce644dc725f1d21cfcf02562c76f375944b266a", sel.id)
181 def testHello(self):
182 out, err = self.run_0launch(['--dry-run', 'Foo.xml'])
183 self.assertEqual("", err)
184 assert out.startswith("Would execute: ")
186 out, err = self.run_0launch(['Foo.xml'])
187 # (Foo.xml tries to run a directory; plash gives a different error)
188 assert "Permission denied" in err or "Is a directory" in err
190 def testSource(self):
191 out, err = self.run_0launch(['--dry-run', '--source', '--not-before=1', 'Source.xml'])
192 self.assertEqual("", err)
193 assert 'Compiler.xml' in out
195 def testRanges(self):
196 out, err = self.run_0launch(['--get-selections', '--before=1', '--not-before=0.2', 'Foo.xml'])
197 assert 'tests/rpm' in out, out
198 self.assertEqual("", err)
200 def testLogging(self):
201 log = logging.getLogger()
202 log.addFilter(silenceLogger)
204 out, err = self.run_0launch(['-v', '--list', 'UNKNOWN'])
205 self.assertEqual(logging.INFO, log.level)
207 out, err = self.run_0launch(['-vv', '--version'])
208 self.assertEqual(logging.DEBUG, log.level)
210 log.removeFilter(silenceLogger)
211 log.setLevel(logging.WARN)
213 def testHelp2(self):
214 out, err = self.run_0launch(['--help'])
215 self.assertEqual("", err)
216 assert 'options:' in out.lower()
218 out, err = self.run_0launch([])
219 self.assertEqual("", err)
220 assert 'options:' in out.lower()
222 def testBadFD(self):
223 copy = os.dup(1)
224 try:
225 os.close(1)
226 cli.main(['--list', 'UNKNOWN'])
227 finally:
228 os.dup2(copy, 1)
230 def testShow(self):
231 command_feed = os.path.join(mydir, 'Command.xml')
232 out, err = self.run_0launch(['--show', command_feed])
233 self.assertEqual("", err)
234 assert 'Local.xml' in out, out
236 if __name__ == '__main__':
237 unittest.main()