Added support for <command> element
[zeroinstall/zeroinstall-afb.git] / tests / testlaunch.py
blob3da957370270933789ec026ac45a583500cd508d
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 import autopolicy, model, cli, namespaces, qdom, selections
13 from zeroinstall.zerostore import Store; Store._add_with_helper = lambda *unused: False
14 from zeroinstall.support import basedir
16 class SilenceLogger(logging.Filter):
17 def filter(self, record):
18 return 0
19 silenceLogger = SilenceLogger()
21 class TestLaunch(BaseTest):
22 def run_0launch(self, args):
23 old_stdout = sys.stdout
24 old_stderr = sys.stderr
25 try:
26 sys.stdout = StringIO()
27 sys.stderr = StringIO()
28 ex = None
29 try:
30 cli.main(args)
31 print "Finished"
32 except NameError:
33 raise
34 except SystemExit:
35 pass
36 except TypeError:
37 raise
38 except AttributeError:
39 raise
40 except AssertionError:
41 raise
42 except Exception, ex:
43 pass
44 out = sys.stdout.getvalue()
45 err = sys.stderr.getvalue()
46 if ex is not None:
47 err += str(ex.__class__)
48 finally:
49 sys.stdout = old_stdout
50 sys.stderr = old_stderr
51 return (out, err)
53 def testHelp(self):
54 out, err = self.run_0launch([])
55 assert out.lower().startswith("usage:")
56 assert not err
58 def testList(self):
59 out, err = self.run_0launch(['--list'])
60 assert not err
61 self.assertEquals("Finished\n", out)
62 cached_ifaces = os.path.join(self.cache_home,
63 '0install.net', 'interfaces')
65 os.makedirs(cached_ifaces)
66 file(os.path.join(cached_ifaces, 'file%3a%2f%2ffoo'), 'w').close()
68 out, err = self.run_0launch(['--list'])
69 assert not err
70 self.assertEquals("file://foo\nFinished\n", out)
72 out, err = self.run_0launch(['--list', 'foo'])
73 assert not err
74 self.assertEquals("file://foo\nFinished\n", out)
76 out, err = self.run_0launch(['--list', 'bar'])
77 assert not err
78 self.assertEquals("Finished\n", out)
80 out, err = self.run_0launch(['--list', 'one', 'two'])
81 assert not err
82 assert out.lower().startswith("usage:")
84 def testVersion(self):
85 out, err = self.run_0launch(['--version'])
86 assert not err
87 assert out.startswith("0launch (zero-install)")
89 def testInvalid(self):
90 a = tempfile.NamedTemporaryFile()
91 out, err = self.run_0launch(['-q', a.name])
92 assert err
94 def testOK(self):
95 out, err = self.run_0launch(['--dry-run', 'http://foo/d'])
96 self.assertEquals("Would download 'http://foo/d'\nFinished\n", out)
97 self.assertEquals("", err)
99 def testRun(self):
100 out, err = self.run_0launch(['Local.xml'])
101 self.assertEquals("", out)
102 assert "test-echo' does not exist" in err, err
104 def testAbsMain(self):
105 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
106 tmp.write(
107 """<?xml version="1.0" ?>
108 <interface last-modified="1110752708"
109 uri="%s"
110 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
111 <name>Foo</name>
112 <summary>Foo</summary>
113 <description>Foo</description>
114 <group main='/bin/sh'>
115 <implementation id='.' version='1'/>
116 </group>
117 </interface>""" % foo_iface_uri)
118 tmp.flush()
119 policy = autopolicy.AutoPolicy(tmp.name)
120 try:
121 policy.download_and_execute([])
122 assert False
123 except SafeException, ex:
124 assert 'Command path must be relative' in str(ex), ex
126 def testOffline(self):
127 out, err = self.run_0launch(['--offline', 'http://foo/d'])
128 self.assertEquals("Interface 'http://foo/d' has no usable implementations\n", err)
129 self.assertEquals("", out)
131 def testDisplay(self):
132 os.environ['DISPLAY'] = ':foo'
133 out, err = self.run_0launch(['--dry-run', 'http://foo/d'])
134 # Uses local copy of GUI
135 assert out.startswith("Would execute: ")
136 assert 'basetest.py' in out
137 self.assertEquals("", err)
139 del os.environ['DISPLAY']
140 out, err = self.run_0launch(['--gui', '--dry-run'])
141 self.assertEquals("", err)
142 self.assertEquals("Finished\n", out)
144 def testRefreshDisplay(self):
145 os.environ['DISPLAY'] = ':foo'
146 out, err = self.run_0launch(['--dry-run', '--refresh', 'http://foo/d'])
147 assert out.startswith("Would execute: ")
148 assert 'basetest.py' in out
149 self.assertEquals("", err)
151 def testNeedDownload(self):
152 policy = autopolicy.AutoPolicy(foo_iface_uri)
153 policy.save_config()
154 os.environ['DISPLAY'] = ':foo'
155 out, err = self.run_0launch(['--download-only', '--dry-run', 'Foo.xml'])
156 self.assertEquals("", err)
157 self.assertEquals("Finished\n", out)
159 def testSelectOnly(self):
160 policy = autopolicy.AutoPolicy(foo_iface_uri)
161 policy.save_config()
162 os.environ['DISPLAY'] = ':foo'
163 out, err = self.run_0launch(['--get-selections', '--select-only', 'Hello.xml'])
164 self.assertEquals("", err)
166 assert out.endswith("Finished\n")
167 out = out[:-len("Finished\n")]
169 root = qdom.parse(StringIO(str(out)))
170 self.assertEquals(namespaces.XMLNS_IFACE, root.uri)
171 sels = selections.Selections(root)
172 sel,= sels.selections.values()
173 self.assertEquals("sha1=3ce644dc725f1d21cfcf02562c76f375944b266a", sel.id)
175 def testHello(self):
176 out, err = self.run_0launch(['--dry-run', 'Foo.xml'])
177 self.assertEquals("", err)
178 assert out.startswith("Would execute: ")
180 out, err = self.run_0launch(['Foo.xml'])
181 # (Foo.xml tries to run a directory; plash gives a different error)
182 assert "Permission denied" in err or "Is a directory" in err
184 def testSource(self):
185 out, err = self.run_0launch(['--dry-run', '--source', 'Source.xml'])
186 self.assertEquals("", err)
187 assert 'Compiler.xml' in out
189 def testRanges(self):
190 out, err = self.run_0launch(['--get-selections', '--before=1', '--not-before=0.2', 'Foo.xml'])
191 assert 'tests/rpm' in out, out
192 self.assertEquals("", err)
194 def testLogging(self):
195 log = logging.getLogger()
196 log.addFilter(silenceLogger)
198 out, err = self.run_0launch(['-v', '--list', 'UNKNOWN'])
199 self.assertEquals(logging.INFO, log.level)
201 out, err = self.run_0launch(['-vv', '--version'])
202 self.assertEquals(logging.DEBUG, log.level)
204 log.removeFilter(silenceLogger)
205 log.setLevel(logging.WARN)
207 def testHelp2(self):
208 out, err = self.run_0launch(['--help'])
209 self.assertEquals("", err)
210 assert 'options:' in out.lower()
212 out, err = self.run_0launch([])
213 self.assertEquals("", err)
214 assert 'options:' in out.lower()
216 def testBadFD(self):
217 copy = os.dup(1)
218 try:
219 os.close(1)
220 cli.main(['--list', 'UNKNOWN'])
221 finally:
222 os.dup2(copy, 1)
224 if __name__ == '__main__':
225 unittest.main()