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