3 from __future__
import print_function
5 from basetest
import BaseTest
, StringIO
, BytesIO
6 import sys
, tempfile
, os
, imp
10 foo_iface_uri
= 'http://foo'
12 sys
.path
.insert(0, '..')
13 from zeroinstall
import SafeException
14 from zeroinstall
.support
import tasks
15 from zeroinstall
.injector
import run
, cli
, namespaces
, qdom
, selections
16 from zeroinstall
.zerostore
import Store
; Store
._add
_with
_helper
= lambda *unused
: False
17 from zeroinstall
.injector
.requirements
import Requirements
18 from zeroinstall
.injector
.driver
import Driver
20 mydir
= os
.path
.abspath(os
.path
.dirname(__file__
))
22 class SilenceLogger(logging
.Filter
):
23 def filter(self
, record
):
25 silenceLogger
= SilenceLogger()
27 class TestLaunch(BaseTest
):
28 def run_0launch(self
, args
):
29 old_stdout
= sys
.stdout
30 old_stderr
= sys
.stderr
32 sys
.stdout
= StringIO()
33 sys
.stderr
= StringIO()
44 except AttributeError:
46 except AssertionError:
48 except Exception as ex2
:
50 out
= sys
.stdout
.getvalue()
51 err
= sys
.stderr
.getvalue()
53 err
+= str(ex
.__class
__)
55 sys
.stdout
= old_stdout
56 sys
.stderr
= old_stderr
60 out
, err
= self
.run_0launch([])
61 assert out
.lower().startswith("usage:")
65 out
, err
= self
.run_0launch(['--list'])
67 self
.assertEqual("Finished\n", out
)
68 cached_ifaces
= os
.path
.join(self
.cache_home
,
69 '0install.net', 'interfaces')
71 os
.makedirs(cached_ifaces
)
72 open(os
.path
.join(cached_ifaces
, 'file%3a%2f%2ffoo'), 'w').close()
74 out
, err
= self
.run_0launch(['--list'])
76 self
.assertEqual("file://foo\nFinished\n", out
)
78 out
, err
= self
.run_0launch(['--list', 'foo'])
80 self
.assertEqual("file://foo\nFinished\n", out
)
82 out
, err
= self
.run_0launch(['--list', 'bar'])
84 self
.assertEqual("Finished\n", out
)
86 out
, err
= self
.run_0launch(['--list', 'one', 'two'])
88 assert out
.lower().startswith("usage:")
90 def testVersion(self
):
91 out
, err
= self
.run_0launch(['--version'])
93 assert out
.startswith("0launch (zero-install)")
95 def testInvalid(self
):
96 a
= tempfile
.NamedTemporaryFile()
97 out
, err
= self
.run_0launch(['-q', a
.name
])
101 out
, err
= self
.run_0launch(['--dry-run', 'http://foo/d'])
102 self
.assertEqual("Would download 'http://foo/d'\nFinished\n", out
)
103 self
.assertEqual("", err
)
106 out
, err
= self
.run_0launch(['Local.xml'])
107 self
.assertEqual("", out
)
108 assert "test-echo' does not exist" in err
, err
110 def testAbsMain(self
):
111 with tempfile
.NamedTemporaryFile(prefix
= 'test-', delete
= False) as tmp
:
113 """<?xml version="1.0" ?>
114 <interface last-modified="1110752708"
116 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
118 <summary>Foo</summary>
119 <description>Foo</description>
120 <group main='/bin/sh'>
121 <implementation id='.' version='1'/>
123 </interface>""" % foo_iface_uri
).encode('utf-8'))
125 driver
= Driver(requirements
= Requirements(tmp
.name
), config
= self
.config
)
127 downloaded
= driver
.solve_and_download_impls()
129 tasks
.wait_for_blocker(downloaded
)
130 run
.execute_selections(driver
.solver
.selections
, [], stores
= self
.config
.stores
)
132 except SafeException
as ex
:
133 assert 'Command path must be relative' in str(ex
), ex
135 def testOffline(self
):
136 out
, err
= self
.run_0launch(['--offline', 'http://foo/d'])
137 self
.assertEqual("Interface 'http://foo/d' has no usable implementations in the cache (and 0install is in off-line mode)\n", err
)
138 self
.assertEqual("", out
)
140 def testDisplay(self
):
141 os
.environ
['DISPLAY'] = ':foo'
142 out
, err
= self
.run_0launch(['--dry-run', 'http://foo/d'])
143 # Uses local copy of GUI
144 assert out
.startswith("Would execute: "), repr((out
, err
))
145 assert 'basetest.py' in out
146 self
.assertEqual("", err
)
148 del os
.environ
['DISPLAY']
149 out
, err
= self
.run_0launch(['--gui'])
150 self
.assertEqual("Can't use GUI because $DISPLAY is not set\n", err
)
151 self
.assertEqual("", out
)
153 def testRefreshDisplay(self
):
154 os
.environ
['DISPLAY'] = ':foo'
155 out
, err
= self
.run_0launch(['--dry-run', '--refresh', 'http://foo/d'])
156 assert out
.startswith("Would execute: ")
157 assert 'basetest.py' in out
158 self
.assertEqual("", err
)
160 def testNeedDownload(self
):
161 os
.environ
['DISPLAY'] = ':foo'
162 out
, err
= self
.run_0launch(['--download-only', '--dry-run', 'Foo.xml'])
163 self
.assertEqual("", err
)
164 self
.assertEqual("Finished\n", out
)
166 def testSelectOnly(self
):
167 os
.environ
['DISPLAY'] = ':foo'
168 out
, err
= self
.run_0launch(['--get-selections', '--select-only', 'Hello.xml'])
169 self
.assertEqual("", err
)
171 assert out
.endswith("Finished\n")
172 out
= out
[:-len("Finished\n")]
174 root
= qdom
.parse(BytesIO(str(out
).encode('utf-8')))
175 self
.assertEqual(namespaces
.XMLNS_IFACE
, root
.uri
)
176 sels
= selections
.Selections(root
)
177 sel
,= sels
.selections
.values()
178 self
.assertEqual("sha1=3ce644dc725f1d21cfcf02562c76f375944b266a", sel
.id)
181 out
, err
= self
.run_0launch(['--dry-run', 'Foo.xml'])
182 self
.assertEqual("", err
)
183 assert out
.startswith("Would execute: ")
185 out
, err
= self
.run_0launch(['Foo.xml'])
186 # (Foo.xml tries to run a directory; plash gives a different error)
187 assert "Permission denied" in err
or "Is a directory" in err
189 def testSource(self
):
190 out
, err
= self
.run_0launch(['--dry-run', '--source', '--not-before=1', 'Source.xml'])
191 self
.assertEqual("", err
)
192 assert 'Compiler.xml' in out
194 def testRanges(self
):
195 out
, err
= self
.run_0launch(['--get-selections', '--before=1', '--not-before=0.2', 'Foo.xml'])
196 assert 'tests/rpm' in out
, out
197 self
.assertEqual("", err
)
199 def testLogging(self
):
200 log
= logging
.getLogger()
201 log
.addFilter(silenceLogger
)
203 out
, err
= self
.run_0launch(['-v', '--list', 'UNKNOWN'])
204 self
.assertEqual(logging
.INFO
, log
.level
)
206 out
, err
= self
.run_0launch(['-vv', '--version'])
207 self
.assertEqual(logging
.DEBUG
, log
.level
)
209 log
.removeFilter(silenceLogger
)
210 log
.setLevel(logging
.WARN
)
213 out
, err
= self
.run_0launch(['--help'])
214 self
.assertEqual("", err
)
215 assert 'options:' in out
.lower()
217 out
, err
= self
.run_0launch([])
218 self
.assertEqual("", err
)
219 assert 'options:' in out
.lower()
225 cli
.main(['--list', 'UNKNOWN'])
230 command_feed
= os
.path
.join(mydir
, 'Command.xml')
231 out
, err
= self
.run_0launch(['--show', command_feed
])
232 self
.assertEqual("", err
)
233 assert 'Local.xml' in out
, out
235 def testExecutables(self
):
236 # Check top-level scripts are readable (detects white-space errors)
237 for script
in ['0launch', '0alias', '0store', '0desktop', '0install']:
238 path
= os
.path
.join('..', script
)
240 old_stdout
= sys
.stdout
241 old_stderr
= sys
.stderr
244 sys
.argv
= [script
, '--help']
245 sys
.stderr
= sys
.stdout
= StringIO()
247 imp
.load_source(script
, path
)
248 except SystemExit as ex
:
249 out
= sys
.stdout
.getvalue()
250 assert 'Usage: ' in out
, (script
, out
)
254 sys
.stdout
= old_stdout
255 sys
.stderr
= old_stderr
259 if __name__
== '__main__':