Accomodate relocation of 0install and 0launch scripts
[0compile.git] / tests / testcompile.py
blob390210653e55412a78d5c30abc1fefe52afe0c69
1 #!/usr/bin/env python
2 import sys, tempfile, os, shutil, tempfile, subprocess
3 from StringIO import StringIO
4 import unittest
5 from zeroinstall.injector import model, qdom
6 from zeroinstall.support import ro_rmtree, basedir
7 from zeroinstall.zerostore import Stores
9 stores = Stores()
11 my_dir = os.path.abspath(os.path.dirname(__file__))
12 sys.path.insert(0, os.path.dirname(my_dir))
13 import support
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)
29 if zeroinstall_dir:
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')
33 else:
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()
48 code = child.wait()
49 if code != kwargs.get('expect_status', 0):
50 raise Exception("Exit status %d:\n%s" % (code, got))
52 expected = kwargs.get('expect', '')
53 if expected:
54 if expected.lower() not in got.lower():
55 raise Exception("Expected '%s', got '%s'" % (expected, got))
56 elif 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']:
63 if x in os.environ:
64 del os.environ[x]
65 user_cache_dir = os.environ['XDG_CACHE_DIRS'] = basedir.xdg_cache_home
67 class TestCompile(unittest.TestCase):
68 def setUp(self):
69 os.chdir('/')
70 self.tmpdir = tempfile.mkdtemp(prefix = '0compile-test-')
71 self.hello_dir = os.path.join(self.tmpdir, 'hello')
73 os.environ['HOME'] = self.tmpdir
74 reload(basedir)
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')
80 stream.close()
82 stream = open(os.path.join(config_dir, 'global'), 'w')
83 stream.write('[global]\n'
84 'freshness = -1\n'
85 'help_with_testing = True\n'
86 'network_use = off-line\n')
87 stream.close()
89 def tearDown(self):
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)
95 os.chdir(self.tmpdir)
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!')
123 def testLocal(self):
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')
140 os.chdir(comp_dir)
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)
147 s.close()
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')
154 os.chdir(comp_dir)
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
162 compile('diff')
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')
172 stream.write(prog)
173 stream.close()
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!')
185 stream.close()
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
191 shutil.rmtree('src')
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')
213 def testSetup(self):
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__':
238 unittest.main()