2 import sys
, tempfile
, os
, shutil
, tempfile
, subprocess
3 from StringIO
import StringIO
5 from zeroinstall
.injector
import model
, qdom
6 from zeroinstall
.support
import ro_rmtree
, basedir
7 from zeroinstall
.zerostore
import Stores
11 my_dir
= os
.path
.abspath(os
.path
.dirname(__file__
))
12 sys
.path
.insert(0, os
.path
.dirname(my_dir
))
15 hello_uri
= 'http://0install.net/tests/GNU-Hello.xml'
16 hello_selections
= os
.path
.realpath(os
.path
.join(os
.path
.dirname(__file__
), 'selections.xml'))
17 local_bad_version
= os
.path
.realpath(os
.path
.join(os
.path
.dirname(__file__
), 'bad-version.xml'))
18 local_hello_path
= os
.path
.realpath(os
.path
.join(os
.path
.dirname(__file__
), 'hello2', 'hello2.xml'))
19 local_cprog_command_path
= os
.path
.realpath(os
.path
.join(os
.path
.dirname(__file__
), 'cprog', 'cprog-command.xml'))
20 local_cprog_path
= os
.path
.realpath(os
.path
.join(os
.path
.dirname(__file__
), 'cprog', 'cprog.xml'))
22 compile_bin
= os
.path
.join(my_dir
, '0compile-coverage')
23 assert os
.path
.exists(compile_bin
)
25 if 'DISPLAY' in os
.environ
:
26 del os
.environ
['DISPLAY']
28 zeroinstall_dir
= os
.environ
.get('0COMPILE_ZEROINSTALL', None)
30 launch_command
= [sys
.executable
, os
.path
.join(zeroinstall_dir
, '0launch')]
31 if not os
.path
.exists(launch_command
[1]):
32 launch_command
[1] = os
.path
.join(zeroinstall_dir
, 'zeroinstall', 'scripts', 'launch.py')
34 launch_command
= ['0launch'] # Package
36 # Ensure it's cached now, to avoid extra output during the tests
37 if subprocess
.call(launch_command
+ ['--source', '-vc', '--download-only', hello_uri
]):
38 raise Exception("Failed to download hello world test program")
40 def compile(*args
, **kwargs
):
41 run(*([sys
.executable
, compile_bin
] + list(args
)), **kwargs
)
43 def run(*args
, **kwargs
):
44 if not isinstance(args
[0], basestring
):
45 args
= args
[0] + list(args
[1:])
46 child
= subprocess
.Popen(args
, stdout
= subprocess
.PIPE
, stderr
= subprocess
.STDOUT
)
47 got
, unused
= child
.communicate()
49 if code
!= kwargs
.get('expect_status', 0):
50 raise Exception("Exit status %d:\n%s" % (code
, got
))
52 expected
= kwargs
.get('expect', '')
54 if expected
.lower() not in got
.lower():
55 raise Exception("Expected '%s', got '%s'" % (expected
, got
))
57 raise Exception("Expected nothing, got '%s'" % got
)
59 # Detect accidental network access
60 os
.environ
['http_proxy'] = 'localhost:1111'
62 for x
in ['GNUPGHOME', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME']:
65 user_cache_dir
= os
.environ
['XDG_CACHE_DIRS'] = basedir
.xdg_cache_home
67 class TestCompile(unittest
.TestCase
):
70 self
.tmpdir
= tempfile
.mkdtemp(prefix
= '0compile-test-')
71 self
.hello_dir
= os
.path
.join(self
.tmpdir
, 'hello')
73 os
.environ
['HOME'] = self
.tmpdir
76 config_dir
= basedir
.save_config_path('0install.net', 'injector')
77 stream
= open(os
.path
.join(config_dir
, 'implementation-dirs'), 'w')
78 for x
in stores
.stores
:
79 stream
.write(x
.dir + '\n')
82 stream
= open(os
.path
.join(config_dir
, 'global'), 'w')
83 stream
.write('[global]\n'
85 'help_with_testing = True\n'
86 'network_use = off-line\n')
90 ro_rmtree(self
.tmpdir
)
92 def testBadCommand(self
):
93 compile('foo', expect
= 'usage: 0compile', expect_status
= 1)
94 compile('setup', hello_uri
, self
.tmpdir
, expect
= 'already exists', expect_status
= 1)
96 compile('setup', expect
= 'Run 0compile from a directory containing', expect_status
= 1)
97 compile('build', expect
= 'Run 0compile from a directory containing', expect_status
= 1)
98 compile('publish', expect
= 'Run 0compile from a directory containing', expect_status
= 1)
100 def testCompileNoDir(self
):
101 os
.chdir(self
.tmpdir
)
102 compile('setup', hello_uri
, expect
= 'Created directory')
103 os
.chdir('GNU-Hello')
105 def testCompile(self
):
106 compile('setup', hello_uri
, self
.hello_dir
, expect
= 'Created directory')
107 os
.chdir(self
.hello_dir
)
109 compile('build', expect
= 'Executing: "%s"' % os
.path
.join('$SRCDIR','configure'))
111 target_dir
= 'gnu-hello-%s' % support
.get_arch_name().lower()
112 archive_stem
= 'gnu-hello-%s-1.3' % support
.get_arch_name().lower()
113 assert os
.path
.isdir(target_dir
), '%s not a directory' % target_dir
115 run(os
.path
.join(target_dir
,'bin','hello'), expect
= 'Hello, world!')
116 run(launch_command
, os
.path
.join(target_dir
,'0install','GNU-Hello.xml'), expect
= 'Hello, world!')
117 compile('publish', 'http://localhost/downloads', expect
= "Now upload '%s.tar.bz2'" % archive_stem
)
119 def testAutocompile(self
):
120 compile('autocompile', hello_uri
, expect
= "Registering as feed for http://0install.net/tests/GNU-Hello.xml")
121 run(launch_command
, hello_uri
, expect
= 'Hello, world!')
124 compile('setup', local_hello_path
, self
.hello_dir
, expect
= 'Created directory')
125 os
.chdir(self
.hello_dir
)
126 compile('build', expect
= 'Executing: ls -l')
127 target_dir
= 'hello2-any-any'
128 assert os
.path
.isdir(target_dir
), '%s not a directory' % target_dir
130 run(launch_command
, os
.path
.join(target_dir
, '0install', 'hello2.xml'), expect
= 'ROX-Lib')
132 def testBadVersion(self
):
133 compile('setup', local_bad_version
, self
.hello_dir
, expect
= 'Created directory')
134 os
.chdir(self
.hello_dir
)
135 compile('build', expect
= 'hello2-0.1 requires 0compile >= 300000', expect_status
= 1)
137 def testCommand(self
):
138 comp_dir
= os
.path
.join(self
.tmpdir
, 'cprog-command')
139 compile('setup', local_cprog_command_path
, comp_dir
, expect
= 'Created directory')
141 compile('build', expect
= 'Hello from C!')
142 target_dir
= 'cprog-command-%s' % support
.get_arch_name().lower()
143 binary_feed
= os
.path
.join(target_dir
, '0install', 'cprog-command.xml')
144 run(launch_command
, binary_feed
, expect
= 'Hello from C!')
145 s
= open(binary_feed
, 'r')
146 feed
= model
.ZeroInstallFeed(qdom
.parse(s
), binary_feed
)
148 impl
, = feed
.implementations
.values()
149 assert impl
.arch
, "Missing arch on %s" % impl
151 def testCopySrc(self
):
152 comp_dir
= os
.path
.join(self
.tmpdir
, 'cprog')
153 compile('setup', local_cprog_path
, comp_dir
, expect
= 'Created directory')
155 compile('diff', expect
= "No local src directory to diff against", expect_status
= 1)
156 compile('diff', 'foo', expect
= 'usage', expect_status
= 1)
157 compile('copy-src', 'foo', expect
= 'usage', expect_status
= 1)
158 compile('copy-src', expect
= 'Copied as')
159 compile('copy-src', expect
= "Directory '", expect_status
= 1)
161 # 'src' exists, but no changes
163 compile('--verbose', 'build', expect
= 'Hello from C')
164 target_dir
= 'cprog-%s' % support
.get_arch_name().lower()
165 patch_file
= os
.path
.join(target_dir
, '0install', 'from-0.1.patch')
166 assert not os
.path
.exists(patch_file
)
168 # 'src' contains a change
169 prog
= file(os
.path
.join('src','main.c')).read()
170 prog
= prog
.replace('Hello', 'Goodbye')
171 stream
= file(os
.path
.join('src','main.c'), 'w')
174 compile('diff', expect
= 'diff')
175 shutil
.rmtree('build')
176 compile('build', expect
= 'Goodbye from C')
177 assert os
.path
.exists(patch_file
)
179 # Test dup-src's unlinking while we're here
180 compile('build', expect
= 'Goodbye from C')
182 # 'src' contains an error
183 stream
= file(os
.path
.join('src','main.c'), 'w')
184 stream
.write('this is not valid C!')
186 shutil
.rmtree('build')
187 compile('build', expect
= 'Build failed', expect_status
= 1)
188 assert os
.path
.exists(os
.path
.join('build', 'build-failure.log'))
190 # 'src' does not exist
192 shutil
.rmtree('build')
193 compile('build', expect
= 'Hello from C')
194 assert not os
.path
.exists(patch_file
)
196 # Check we fixed the .pc files...
197 pc_data
= open(os
.path
.join(target_dir
, 'pkgconfig', 'cprog.pc')).read()
198 assert pc_data
== "prefix=" + os
.path
.join("${pcfiledir}",os
.path
.pardir
) + "\n", `pc_data`
200 # Check we removed the bad .la files...
201 assert not os
.path
.exists(os
.path
.join(target_dir
, 'lib', 'bad.la')) # libtool - bad
202 assert os
.path
.exists(os
.path
.join(target_dir
, 'lib', 'good.la')) # Ends in .la, but not a libtool archive
203 assert os
.path
.exists(os
.path
.join(target_dir
, 'lib', 'nice.ok')) # Doesn't end in .la
205 def testInlcudeDeps(self
):
206 compile('setup', hello_uri
, self
.hello_dir
, expect
= 'Created directory')
207 os
.chdir(self
.hello_dir
)
208 os
.unlink('0compile.properties')
209 compile('setup', hello_uri
, '.')
210 compile('include-deps', expect
= 'dependencies to')
211 compile('include-deps', expect
= 'Copied 0 depend')
214 compile('setup', hello_selections
, self
.hello_dir
,
215 expect
= 'Created directory')
216 compile('setup', hello_selections
, self
.hello_dir
,
217 expect
= "Directory '", expect_status
= 1)
218 compile('setup', hello_selections
, '.', 'foo',
219 expect
= "usage", expect_status
= 1)
220 os
.chdir(self
.hello_dir
)
221 compile('setup', expect
= "Selections are fixed", expect_status
= 1)
223 def testReportBug(self
):
224 broken_src
= os
.path
.join(self
.hello_dir
, "broken.xml")
225 os
.mkdir(self
.hello_dir
)
226 shutil
.copy(local_hello_path
, broken_src
)
227 os
.chdir(self
.hello_dir
)
228 compile('setup', broken_src
, '.')
229 compile('build', expect
= 'Build failed with exit code', expect_status
= 1)
230 compile('report-bug', expect
= "http://sourceforge.net")
232 env
= support
.BuildEnv()
233 os
.unlink(os
.path
.join(env
.metadir
, "build-environment.xml"))
234 compile('report-bug', expect
= "file+not+found")
236 suite
= unittest
.makeSuite(TestCompile
)
237 if __name__
== '__main__':