~brz/brz-debian/byoci

« back to all changes in this revision

Viewing changes to tests/test_builder.py

  • Committer: James Westby
  • Date: 2007-05-03 18:42:47 UTC
  • mfrom: (95.1.14 bzr-builddeb.0.15.tests)
  • Revision ID: jw+debian@jameswestby.net-20070503184247-3si8cp52q0soyy0f
* Lock the working trees to fix compatibility with 0.15+ dirstate trees.
  (Closes: #421900)
* Add the start of a test suite to help avoid bugs like that.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#    __init__.py -- Testsuite for builddeb builder.py
 
2
#    Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
 
3
#    
 
4
#    This file is part of bzr-builddeb.
 
5
#
 
6
#    bzr-builddeb is free software; you can redistribute it and/or modify
 
7
#    it under the terms of the GNU General Public License as published by
 
8
#    the Free Software Foundation; either version 2 of the License, or
 
9
#    (at your option) any later version.
 
10
#
 
11
#    bzr-builddeb is distributed in the hope that it will be useful,
 
12
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
#    GNU General Public License for more details.
 
15
#
 
16
#    You should have received a copy of the GNU General Public License
 
17
#    along with bzr-builddeb; if not, write to the Free Software
 
18
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
#
 
20
 
 
21
import commands
 
22
import os
 
23
from os.path import join
 
24
import shutil
 
25
import tarfile
 
26
 
 
27
from debian_bundle.changelog import (Changelog, Version)
 
28
 
 
29
from bzrlib.errors import NotBranchError
 
30
from bzrlib.tests import (TestCaseInTempDir,
 
31
                          TestCaseWithTransport,
 
32
                          )
 
33
from bzrlib.workingtree import WorkingTree
 
34
 
 
35
from builder import (remove_dir,
 
36
                     remove_bzrbuilddeb_dir,
 
37
                     remove_debian_dir,
 
38
                     DebBuild,
 
39
                     DebNativeBuild,
 
40
                     DebSplitBuild,
 
41
                     DebMergeBuild,
 
42
                     DebMergeExportUpstreamBuild,
 
43
                     )
 
44
import errors
 
45
from properties import BuildProperties
 
46
 
 
47
class TestUtil(TestCaseInTempDir):
 
48
  """Test the utility functions from builder.py."""
 
49
 
 
50
  def test_remove_dir(self):
 
51
    """Test that remove_dir correctly removes teh named directory/."""
 
52
    os.mkdir('dir1')
 
53
    os.mkdir('dir2')
 
54
    self.assert_(os.path.isdir('dir1'))
 
55
    self.assert_(os.path.isdir('dir2'))
 
56
    remove_dir('.', 'dir1')
 
57
    self.failIf(os.path.exists('dir1'))
 
58
    self.assert_(os.path.isdir('dir2'))
 
59
 
 
60
  def test_remove_dir_in_dir(self):
 
61
    """Test that remove_dir correctly removes a subdir."""
 
62
    os.mkdir('dir1')
 
63
    os.mkdir('dir2')
 
64
    self.assert_(os.path.isdir('dir1'))
 
65
    self.assert_(os.path.isdir('dir2'))
 
66
    os.mkdir(join('dir1', 'subdir1'))
 
67
    os.mkdir(join('dir1', 'subdir2'))
 
68
    os.mkdir(join('dir2', 'subdir1'))
 
69
 
 
70
    self.assert_(os.path.isdir(join('dir1', 'subdir1')))
 
71
    self.assert_(os.path.isdir(join('dir1', 'subdir2')))
 
72
    self.assert_(os.path.isdir(join('dir2', 'subdir1')))
 
73
    remove_dir('dir1', 'subdir1')
 
74
    self.failIf(os.path.exists(join('dir1', 'subdir1')))
 
75
    self.assert_(os.path.isdir(join('dir1', 'subdir2')))
 
76
    self.assert_(os.path.isdir(join('dir2', 'subdir1')))
 
77
 
 
78
  def test_remove_dir_works_on_non_empty_dirs(self):
 
79
    """Test that t can remove a non empty dir"""
 
80
    os.mkdir('dir1')
 
81
    os.mkdir(join('dir1', 'subdir1'))
 
82
    self.assert_(os.path.isdir(join('dir1', 'subdir1')))
 
83
    remove_dir('.', 'dir1')
 
84
    self.failIf(os.path.exists('dir1'))
 
85
 
 
86
  def test_remove_dir_copes_with_no_dir(self):
 
87
    """Test that it doesn't fail if the path doesn't exist."""
 
88
    self.failIf(os.path.exists('dir1'))
 
89
    remove_dir('.', 'dir1')
 
90
 
 
91
  def test_remove_dir_no_remove_file(self):
 
92
    """Test that it doesn't remove files"""
 
93
    file = open('file', 'w')
 
94
    file.write('test\n')
 
95
    file.close()
 
96
    self.assert_(os.path.exists('file'))
 
97
    remove_dir('.', 'file')
 
98
    self.assert_(os.path.exists('file'))
 
99
 
 
100
  def test_remove_dir_no_remove_symlink(self):
 
101
    """Test that it neither removes the symlink or the target."""
 
102
    os.mkdir('dir1')
 
103
    os.symlink('dir1', 'link1')
 
104
    self.assert_(os.path.exists('dir1'))
 
105
    self.assert_(os.path.exists('link1'))
 
106
    remove_dir(',', 'link1')
 
107
    self.assert_(os.path.exists('dir1'))
 
108
    self.assert_(os.path.exists('link1'))
 
109
 
 
110
  def test_remove_bzr_builddeb_dir(self):
 
111
    """Tests that a dir named .bzr-buiddeb is removed"""
 
112
    os.mkdir('.bzr-builddeb')
 
113
    self.assert_(os.path.exists('.bzr-builddeb'))
 
114
    remove_bzrbuilddeb_dir('.')
 
115
    self.failIf(os.path.exists('.bzr-builddeb'))
 
116
 
 
117
  def test_remove_debian_dir(self):
 
118
    """Tests that a dir named debian/ is removed"""
 
119
    os.mkdir('debian')
 
120
    self.assert_(os.path.exists('debian'))
 
121
    remove_debian_dir('.')
 
122
    self.failIf(os.path.exists('debian'))
 
123
 
 
124
class BuilderTestCase(TestCaseWithTransport):
 
125
  """A class that helps with the testing of builders."""
 
126
 
 
127
  package_name = 'test'
 
128
  package_version = Version('0.1-1')
 
129
  upstream_version = property(lambda self: \
 
130
                              self.package_version.upstream_version)
 
131
 
 
132
  def __init__(self, *args, **kwargs):
 
133
    self.basedir = 'base'
 
134
    self.build_dir = join(self.basedir, 'build')
 
135
    self.orig_dir = join(self.basedir, 'orig')
 
136
    self.result_dir = join(self.basedir, 'result')
 
137
    self.branch_dir = join(self.basedir, 'branch')
 
138
    self.source_dir = join(self.build_dir,
 
139
                           self.package_name + '-' + self.upstream_version)
 
140
    self.tarball_name = self.package_name + '_' + self.upstream_version + \
 
141
                        '.orig.tar.gz'
 
142
    super(BuilderTestCase, self).__init__(*args, **kwargs)
 
143
 
 
144
  def make_properties(self, changelog, larstiq):
 
145
    return BuildProperties(changelog, self.build_dir, self.orig_dir, larstiq)
 
146
 
 
147
  def change_to_branch_dir(self):
 
148
    os.chdir(self.branch_dir)
 
149
 
 
150
  def _make_branch(self):
 
151
    os.mkdir(self.basedir)
 
152
    tree = self.make_branch_and_tree(self.branch_dir)
 
153
    return tree
 
154
 
 
155
  def build_branch_tree(self, files, *args, **kwargs):
 
156
    #divert in to base
 
157
    newfiles = []
 
158
    for filename in files:
 
159
      newfiles.append(join(self.branch_dir, filename))
 
160
    self.build_tree(newfiles, *args, **kwargs)
 
161
 
 
162
  def make_orig_tarball(self):
 
163
    os.mkdir(self.orig_dir)
 
164
    tarball = join(self.orig_dir, self.tarball_name)
 
165
    f = open(tarball, 'wb')
 
166
    f.close()
 
167
 
 
168
  def make_changelog(self, version=None):
 
169
    if version is None:
 
170
      version = self.package_version
 
171
    c = Changelog()
 
172
    c.new_block()
 
173
    c.version = Version(version)
 
174
    c.package = self.package_name
 
175
    c.distributions = 'unstable'
 
176
    c.urgency = 'low'
 
177
    c.author = 'James Westby <jw+debian@jameswestby.net>'
 
178
    c.date = 'The,  3 Aug 2006 19:16:22 +0100'
 
179
    c.add_change('')
 
180
    c.add_change('  *  test build')
 
181
    c.add_change('')
 
182
    return c
 
183
 
 
184
  def write_changelog(self, changelog, filename):
 
185
    f = open(filename, 'w')
 
186
    c.write_to_open_file(f)
 
187
    f.close()
 
188
 
 
189
  def get_arch(self):
 
190
    status, arch = commands.getstatusoutput(
 
191
        'dpkg-architecture -qDEB_BUILD_ARCH')
 
192
    if status > 0:
 
193
      self.fail("Couldn't discover arch")
 
194
    return arch
 
195
 
 
196
  def changes_filename(self):
 
197
    arch = self.get_arch()
 
198
    changesfilename = "%s_%s_%s.changes" % (self.package_name,
 
199
                                            self.package_version, arch)
 
200
    return changesfilename
 
201
 
 
202
  def make_changes_file(self):
 
203
    os.mkdir(self.build_dir)
 
204
    arch = self.get_arch()
 
205
    changesfilename = self.changes_filename()
 
206
    changesfile = open(join(self.build_dir, changesfilename), 'wb')
 
207
    changesfile.write("""Format: 1.7
 
208
Date: Wed, 31 Jan 2007 20:15:42 +0000
 
209
Source: """)
 
210
    changesfile.write(self.package_name)
 
211
    changesfile.write("\nBinary: %s" % self.package_name)
 
212
    changesfile.write("\nArchitecture: source %s" % arch)
 
213
    changesfile.write("\nVersion: %s" % self.package_version)
 
214
    changesfile.write("""
 
215
Distribution: experimental
 
216
Urgency: low
 
217
Maintainer: Noone <noone@nowhere.con>
 
218
Changed-By: Noone <noone@nowhere.com>
 
219
Description:
 
220
 test - A test package
 
221
Changes:""")
 
222
    changesfile.write("\n %s (%s) experimental; urgency=low" % (
 
223
                                self.package_name, self.package_version))
 
224
    changesfile.write("""
 
225
 .
 
226
   * A change.
 
227
Files:
 
228
 7fee96643187b7d498ca2ef32aea1b3c 441 devel optional """)
 
229
    changesfile.write("%s_%s.dsc\n" % (self.package_name, self.package_version))
 
230
    changesfile.write(" 3808bdf49220a86f097316207f8a7fce 24786 devel optional ")
 
231
    changesfile.write("%s_%s.tar.gz\n" % (self.package_name,
 
232
                                        self.package_version))
 
233
    changesfile.write(" 645fb698444a226c55e9af861604d643 29574 devel optional ")
 
234
    changesfile.write("%s_%s_%s.deb\n" % (self.package_name,
 
235
                                        self.package_version, arch))
 
236
    changesfile.close()
 
237
 
 
238
  def get_result_filenames(self):
 
239
    """Return a list of the filenames that a build might produce."""
 
240
    arch = self.get_arch()
 
241
    dsc = "%s_%s.dsc" % (self.package_name, self.package_version)
 
242
    tar = "%s_%s.tar.gz" % (self.package_name, self.package_version)
 
243
    deb = "%s_%s_%s.deb" % (self.package_name, self.package_version, arch)
 
244
    return [dsc, tar, deb]
 
245
 
 
246
  def make_result_files(self):
 
247
    """Make the files to go along with the .changes file."""
 
248
    for filename in self.get_result_filenames():
 
249
      f = open(join(self.build_dir, filename), 'wb')
 
250
      f.close()
 
251
 
 
252
  def get_builder(self, version=None, wt=None, larstiq=False):
 
253
    raise NotImplementedError("You must provide this method in the subclass")
 
254
 
 
255
  def check_tarball_contents(self, tarball, expected, basedir=None,
 
256
                             skip_basedir=False, mode=None):
 
257
    """Test that the tarball has certain contents.
 
258
 
 
259
    Test that the tarball has exactly expected contents. The basedir
 
260
    is checked for and prepended if it is not None. The mode is the mode
 
261
    used in tarfile.open defaults to r:gz. If skip_basedir is True and
 
262
    basedir is not None then the basedir wont be tested for itself.
 
263
    """
 
264
    if basedir is None:
 
265
      real_expected = expected[:]
 
266
    else:
 
267
      if skip_basedir:
 
268
        real_expected = []
 
269
      else:
 
270
        real_expected = [basedir]
 
271
      for item in expected:
 
272
        real_expected.append(join(basedir, item))
 
273
    extras = []
 
274
    tar = tarfile.open(tarball, 'r:gz')
 
275
    try:
 
276
      for tarinfo in tar:
 
277
        if tarinfo.name in real_expected:
 
278
          index = real_expected.index(tarinfo.name)
 
279
          del real_expected[index:index+1]
 
280
        else:
 
281
            extras.append(tarinfo.name)
 
282
 
 
283
      if len(real_expected) > 0:
 
284
        self.fail("Files not found in %s: %s" % (tarball,
 
285
                                                 ", ".join(real_expected)))
 
286
      if len(extras) > 0:
 
287
        self.fail("Files not expected to be found in %s: %s" % (tarball,
 
288
                                                 ", ".join(extras)))
 
289
    finally:
 
290
      tar.close()
 
291
 
 
292
class TestDefaultBuilder(BuilderTestCase):
 
293
  """Test the default builder (full source, non-native)"""
 
294
 
 
295
  def get_builder(self, version=None, wt=None, larstiq=False):
 
296
    """Returns a builder set up for this type."""
 
297
    if wt is None:
 
298
      wt = self._make_branch()
 
299
    changelog = self.make_changelog(version=version)
 
300
    properties = self.make_properties(changelog, larstiq)
 
301
    return DebBuild(properties, wt)
 
302
 
 
303
  def test_prepare_creates_build_dir(self):
 
304
    """Test that the build dir is created correctly."""
 
305
    builder = self.get_builder()
 
306
    self.failIfExists(self.build_dir)
 
307
    builder.prepare(False)
 
308
    self.failUnlessExists(self.build_dir)
 
309
 
 
310
  def test_prepare_allows_build_dir_to_exist(self):
 
311
    """Test that prepare doen't fall over if the build dir exists."""
 
312
    builder = self.get_builder()
 
313
    os.mkdir(self.build_dir)
 
314
    self.failUnlessExists(self.build_dir)
 
315
    builder.prepare(False)
 
316
    self.failUnlessExists(self.build_dir)
 
317
 
 
318
  def test_prepare_purges_the_source_dir(self):
 
319
    """Test that the source dir is purged if not keep_source_dir."""
 
320
    builder = self.get_builder()
 
321
    os.mkdir(self.build_dir)
 
322
    os.mkdir(self.source_dir)
 
323
    self.failUnlessExists(self.source_dir)
 
324
    builder.prepare(False)
 
325
    self.failIfExists(self.source_dir)
 
326
 
 
327
  def test_prepare_keeps_the_source_dir(self):
 
328
    """Test that the source dir is kept if keep_source_dir."""
 
329
    builder = self.get_builder()
 
330
    os.mkdir(self.build_dir)
 
331
    os.mkdir(self.source_dir)
 
332
    self.failUnlessExists(self.source_dir)
 
333
    builder.prepare(True)
 
334
    self.failUnlessExists(self.source_dir)
 
335
 
 
336
  def test_prepare_errors_on_keep_source_dir_and_it_doesnt_exist(self):
 
337
    """Test that there is an exception if keep_source_dir and there is none."""
 
338
    builder = self.get_builder()
 
339
    self.failIfExists(self.source_dir)
 
340
    self.assertRaises(errors.NoSourceDirError, builder.prepare, True)
 
341
    self.failIfExists(self.source_dir)
 
342
 
 
343
  def test__tarball_name_native(self):
 
344
    """Test the correct upstream tarball name for native package."""
 
345
    version = '0.1'
 
346
    builder = self.get_builder(version)
 
347
    self.assertEqual(builder._tarball_name(),
 
348
                     self.package_name+'_' + version + '.orig.tar.gz')
 
349
 
 
350
  def test__tarball_name_non_native(self):
 
351
    """Test the correct upstream tarball name for non-native package."""
 
352
    builder = self.get_builder()
 
353
    self.assertEqual(builder._tarball_name(),
 
354
                     self.package_name + '_' + self.upstream_version + \
 
355
                     '.orig.tar.gz')
 
356
 
 
357
  def test__find_tarball_present(self):
 
358
    """Test that _find_tarball returns the correct path if present."""
 
359
    builder = self.get_builder()
 
360
    tarball = join(self.orig_dir, builder._tarball_name())
 
361
    self.make_orig_tarball()
 
362
    self.failUnlessExists(tarball)
 
363
    self.assertEqual(builder._find_tarball(), tarball)
 
364
 
 
365
  def test__find_tarball_no_orig_dir(self):
 
366
    """Test that an exception is raised it the orig dir is not present."""
 
367
    builder = self.get_builder()
 
368
    self.failIfExists(self.orig_dir)
 
369
    self.assertRaises(errors.DebianError, builder._find_tarball)
 
370
 
 
371
  def test__find_tarball_not_exists(self):
 
372
    """Test that an exception is raised if the tarball is not found."""
 
373
    builder = self.get_builder()
 
374
    os.mkdir(self.orig_dir)
 
375
    tarball = join(self.orig_dir, builder._tarball_name())
 
376
    self.failIfExists(tarball)
 
377
    self.assertRaises(errors.DebianError, builder._find_tarball)
 
378
 
 
379
  def test_export_copies_tarball(self):
 
380
    """Test that the tarball is copied in to the build dir."""
 
381
    builder = self.get_builder()
 
382
    self.make_orig_tarball()
 
383
    builder.prepare()
 
384
    builder.export()
 
385
    self.failUnlessExists(join(self.build_dir, self.tarball_name))
 
386
 
 
387
  def test_export_use_existing_doesnt_copy_tarball(self):
 
388
    """Test that the tarball is not copied in to the build dir.
 
389
    
 
390
    If use_existing is given then the tarball should not be copied.
 
391
    
 
392
    This might not be the desired behaviour, but add a test for it
 
393
    either way.
 
394
    """
 
395
    builder = self.get_builder()
 
396
    self.make_orig_tarball()
 
397
    builder.prepare()
 
398
    builder.export(use_existing=True)
 
399
    self.failIfExists(join(self.build_dir, self.tarball_name))
 
400
 
 
401
  def test_export_creates_source_dir(self):
 
402
    """Test that the source dir is created on export."""
 
403
    builder = self.get_builder()
 
404
    self.make_orig_tarball()
 
405
    builder.prepare()
 
406
    builder.export()
 
407
    self.failUnlessExists(self.source_dir)
 
408
 
 
409
  def test_export_has_correct_contents_in_source_dir(self):
 
410
    """Test that the exported source dir has the correct contents."""
 
411
    wt = self._make_branch()
 
412
    self.build_branch_tree(['a', 'b'])
 
413
    wt.add(['a', 'b'])
 
414
    wt.commit('commit one')
 
415
    self.build_branch_tree(['c', 'd'])
 
416
    wt.add(['c'])
 
417
    wt.remove(['b'])
 
418
    builder = self.get_builder(wt=wt)
 
419
    self.make_orig_tarball()
 
420
    builder.prepare()
 
421
    builder.export()
 
422
    self.failUnlessExists(join(self.source_dir, 'a'))
 
423
    self.failIfExists(join(self.source_dir, 'b'))
 
424
    self.failUnlessExists(join(self.source_dir, 'c'))
 
425
    self.failIfExists(join(self.source_dir, 'd'))
 
426
 
 
427
  def test_export_removes_builddeb_dir(self):
 
428
    """Test that the builddeb dir is removed from the export."""
 
429
    wt = self._make_branch()
 
430
    files = ['a', '.bzr-builddeb/', '.bzr-builddeb/default.conf']
 
431
    self.build_branch_tree(files)
 
432
    wt.add(files)
 
433
    wt.commit('commit one')
 
434
    builder = self.get_builder(wt=wt)
 
435
    self.make_orig_tarball()
 
436
    builder.prepare()
 
437
    builder.export()
 
438
    self.failUnlessExists(join(self.source_dir, 'a'))
 
439
    self.failIfExists(join(self.source_dir, '.bzr-builddeb'))
 
440
 
 
441
  def test_build(self):
 
442
    """Test that the build command is run correctly."""
 
443
    builder = self.get_builder()
 
444
    self.make_orig_tarball()
 
445
    builder.prepare()
 
446
    builder.export()
 
447
    self.failIfExists(join(self.source_dir, 'built'))
 
448
    builder.build('touch built')
 
449
    self.failUnlessExists(join(self.source_dir, 'built'))
 
450
 
 
451
  def test_build_fails(self):
 
452
    """Test that a failing build raises an error."""
 
453
    builder = self.get_builder()
 
454
    self.make_orig_tarball()
 
455
    builder.prepare()
 
456
    builder.export()
 
457
    self.assertRaises(errors.BuildFailedError, builder.build, 'false')
 
458
 
 
459
  def test_clean(self):
 
460
    """Test that clean removes the source dir."""
 
461
    builder = self.get_builder()
 
462
    os.mkdir(self.build_dir)
 
463
    os.mkdir(self.source_dir)
 
464
    # make it non-empty for good measure
 
465
    f = open(join(self.source_dir, 'file'), 'wb')
 
466
    f.close()
 
467
    self.failUnlessExists(self.source_dir)
 
468
    builder.clean()
 
469
    self.failIfExists(self.source_dir)
 
470
 
 
471
  def test_move_result_creates_result_dir(self):
 
472
    """Test that move_result creates the result directory."""
 
473
    builder = self.get_builder()
 
474
    self.make_changes_file()
 
475
    self.make_result_files()
 
476
    self.failIfExists(self.result_dir)
 
477
    builder.move_result(self.result_dir)
 
478
    self.failUnlessExists(self.result_dir)
 
479
 
 
480
  def test_move_result_allows_existing_result_dir(self):
 
481
    """Test that move_result doesn't choke if the result directory exists."""
 
482
    builder = self.get_builder()
 
483
    self.make_changes_file()
 
484
    self.make_result_files()
 
485
    os.mkdir(self.result_dir)
 
486
    self.failUnlessExists(self.result_dir)
 
487
    builder.move_result(self.result_dir)
 
488
    self.failUnlessExists(self.result_dir)
 
489
 
 
490
  def test_move_result_moves_files(self):
 
491
    """Test that the move_result places the expected files in the result dir"""
 
492
    builder = self.get_builder()
 
493
    self.make_changes_file()
 
494
    self.make_result_files()
 
495
    builder.move_result(self.result_dir)
 
496
    self.failUnlessExists(join(self.result_dir, self.changes_filename()))
 
497
    for filename in self.get_result_filenames():
 
498
      self.failUnlessExists(join(self.result_dir, filename))
 
499
 
 
500
  def test_move_result_errors_on_missing_changes_file(self):
 
501
    """Test that the move_result errors if the changes file is missing."""
 
502
    builder = self.get_builder()
 
503
    self.assertRaises(errors.DebianError, builder.move_result, self.result_dir)
 
504
 
 
505
  def test_move_result_errors_on_missing_result_file(self):
 
506
    """Test that the move_result errors if one of the files is missing."""
 
507
    builder = self.get_builder()
 
508
    self.make_changes_file()
 
509
    self.assertRaises(errors.DebianError, builder.move_result, self.result_dir)
 
510
 
 
511
 
 
512
class TestNativeBuilder(BuilderTestCase):
 
513
  """Test the native builder."""
 
514
 
 
515
  package_version = Version('0.1')
 
516
 
 
517
  def get_builder(self, wt=None, version=None, larstiq=False):
 
518
    """Returns a native builder."""
 
519
    if wt is None:
 
520
      wt = self._make_branch()
 
521
    changelog = self.make_changelog(version=version)
 
522
    properties = self.make_properties(changelog, larstiq)
 
523
    return DebNativeBuild(properties, wt)
 
524
 
 
525
  def test_export_creates_source_dir(self):
 
526
    """Test that the source dir is created by export."""
 
527
    builder = self.get_builder()
 
528
    builder.prepare()
 
529
    builder.export()
 
530
    self.failUnlessExists(self.source_dir)
 
531
 
 
532
  def test_export_has_correct_contents_in_source_dir(self):
 
533
    """Test that the exported source dir has the correct contents."""
 
534
    wt = self._make_branch()
 
535
    self.build_branch_tree(['a', 'b'])
 
536
    wt.add(['a', 'b'])
 
537
    wt.commit('commit one')
 
538
    self.build_branch_tree(['c', 'd'])
 
539
    wt.add(['c'])
 
540
    wt.remove(['b'])
 
541
    builder = self.get_builder(wt=wt)
 
542
    builder.prepare()
 
543
    builder.export()
 
544
    self.failUnlessExists(join(self.source_dir, 'a'))
 
545
    self.failIfExists(join(self.source_dir, 'b'))
 
546
    self.failUnlessExists(join(self.source_dir, 'c'))
 
547
    self.failIfExists(join(self.source_dir, 'd'))
 
548
 
 
549
  def test_export_removes_builddeb_dir(self):
 
550
    """Test that the builddeb dir is removed from the export."""
 
551
    wt = self._make_branch()
 
552
    files = ['a', '.bzr-builddeb/', '.bzr-builddeb/default.conf']
 
553
    self.build_branch_tree(files)
 
554
    wt.add(files)
 
555
    wt.commit('commit one')
 
556
    builder = self.get_builder(wt=wt)
 
557
    builder.prepare()
 
558
    builder.export()
 
559
    self.failUnlessExists(join(self.source_dir, 'a'))
 
560
    self.failIfExists(join(self.source_dir, '.bzr-builddeb'))
 
561
 
 
562
class TestSplitBuilder(BuilderTestCase):
 
563
  """Test that the split builder does its thing correctly."""
 
564
 
 
565
  def get_builder(self, wt=None, version=None, larstiq=False):
 
566
    if wt is None:
 
567
      wt = self._make_branch()
 
568
    changelog = self.make_changelog(version=version)
 
569
    properties = self.make_properties(changelog, larstiq)
 
570
    return DebSplitBuild(properties, wt)
 
571
 
 
572
  def test_export_creates_source_dir(self):
 
573
    """Test that the source dir is created by export."""
 
574
    builder = self.get_builder()
 
575
    builder.prepare()
 
576
    builder.export()
 
577
    self.failUnlessExists(self.source_dir)
 
578
 
 
579
  def test_export_creates_tarball(self):
 
580
    """Test that a tarball is created in the build dir"""
 
581
    builder = self.get_builder()
 
582
    builder.prepare()
 
583
    builder.export()
 
584
    self.failUnlessExists(join(self.build_dir, self.tarball_name))
 
585
 
 
586
  def test_created_tarball_has_correct_contents(self):
 
587
    """Test that the tarball has the correct contents.
 
588
 
 
589
    The working tree state should be reflected, but the debian/ and
 
590
    .bzr-builddeb/ dirs should be removed.
 
591
    """
 
592
    wt = self._make_branch()
 
593
    files = ['a', 'b', 'dir/', 'debian/', 'debian/control', '.bzr-builddeb/',
 
594
             '.bzr-builddeb/default.conf']
 
595
    self.build_branch_tree(files)
 
596
    wt.add(files)
 
597
    wt.commit('commit one')
 
598
    self.build_branch_tree(['c', 'd'])
 
599
    wt.add(['c'])
 
600
    wt.remove(['b'])
 
601
    builder = self.get_builder(wt=wt)
 
602
    builder.prepare()
 
603
    builder.export()
 
604
    tarball = join(self.build_dir, self.tarball_name)
 
605
    expected = ['a', 'dir/', 'c']
 
606
    basename = self.package_name + '-' + self.upstream_version + '/'
 
607
    self.check_tarball_contents(tarball, expected, basedir=basename)
 
608
 
 
609
  def test_source_dir_has_full_contents(self):
 
610
    """Test that the source dir has the full contents after an export.
 
611
    
 
612
    The export of a split build should leave the full branch contents in
 
613
    the source dir (including debian/) except for the .bzr-builddeb/ dir.
 
614
    """
 
615
    wt = self._make_branch()
 
616
    files = ['a', 'b', 'dir/', 'debian/', 'debian/control', '.bzr-builddeb/',
 
617
             '.bzr-builddeb/default.conf']
 
618
    self.build_branch_tree(files)
 
619
    wt.add(files)
 
620
    wt.commit('commit one')
 
621
    self.build_branch_tree(['c', 'd'])
 
622
    wt.add(['c'])
 
623
    wt.remove(['b'])
 
624
    builder = self.get_builder(wt=wt)
 
625
    builder.prepare()
 
626
    builder.export()
 
627
    expected = ['a', 'c', 'dir/', 'debian/', 'debian/control']
 
628
    for filename in expected:
 
629
      self.failUnlessExists(join(self.source_dir, filename))
 
630
 
 
631
 
 
632
class TestMergeBuilder(BuilderTestCase):
 
633
  """Test the merge builder."""
 
634
 
 
635
  def get_builder(self, wt=None, version=None, larstiq=False):
 
636
    if wt is None:
 
637
      wt = self._make_branch()
 
638
    changelog = self.make_changelog(version=version)
 
639
    properties = self.make_properties(changelog, larstiq)
 
640
    return DebMergeBuild(properties, wt)
 
641
 
 
642
  upstream_files = ['a', 'b', 'dir/', 'dir/c']
 
643
  debian_files = ['control', 'changelog', 'patches/', 'patches/patch']
 
644
 
 
645
  def make_orig_tarball(self):
 
646
    """Make the orig tarball with some content for merge builders."""
 
647
    os.mkdir(self.orig_dir)
 
648
    tarball = join(self.orig_dir, self.tarball_name)
 
649
    basedir = self.package_name+'-'+self.upstream_version+'/'
 
650
    files = [basedir]
 
651
    files = files + [join(basedir, f) for f in self.upstream_files]
 
652
    self.build_tree(files)
 
653
    tar = tarfile.open(join(self.orig_dir, self.tarball_name), 'w:gz')
 
654
    try:
 
655
      tar.add(basedir)
 
656
    finally:
 
657
      tar.close()
 
658
    shutil.rmtree(basedir)
 
659
 
 
660
  def test__export_upstream_branch(self):
 
661
    """Simple sanity check on this private function."""
 
662
    builder = self.get_builder()
 
663
    self.assertEqual(builder._export_upstream_branch(), False)
 
664
 
 
665
  def test_export_creates_source_dir(self):
 
666
    """Test that the source dir is created on export."""
 
667
    builder = self.get_builder()
 
668
    self.make_orig_tarball()
 
669
    builder.prepare()
 
670
    builder.export()
 
671
    self.failUnlessExists(self.source_dir)
 
672
 
 
673
  def test_export_extracts_tarball(self):
 
674
    """Test that the upstream tarball is extracted in to the source dir."""
 
675
    builder = self.get_builder()
 
676
    self.make_orig_tarball()
 
677
    self.failUnlessExists(join(self.orig_dir, self.tarball_name))
 
678
    builder.prepare()
 
679
    builder.export()
 
680
    for f in self.upstream_files:
 
681
      self.failUnlessExists(join(self.source_dir, f))
 
682
 
 
683
  def test_export_copies_tarball(self):
 
684
    """Test that the tarball is copied in to the build dir."""
 
685
    builder = self.get_builder()
 
686
    self.make_orig_tarball()
 
687
    builder.prepare()
 
688
    builder.export()
 
689
    self.failUnlessExists(join(self.build_dir, self.tarball_name))
 
690
 
 
691
  def test_export_use_existing_doesnt_copy_tarball(self):
 
692
    """Test that if use_existing is true it doesn't copy the tarball."""
 
693
    builder = self.get_builder()
 
694
    self.make_orig_tarball()
 
695
    builder.prepare()
 
696
    builder.export(use_existing=True)
 
697
    self.failIfExists(join(self.build_dir, self.tarball_name))
 
698
 
 
699
  def test_export_use_existing_doesnt_extract_tarball(self):
 
700
    """Test that the tarball is not extracted if use_existing is True."""
 
701
    builder = self.get_builder()
 
702
    self.make_orig_tarball()
 
703
    builder.prepare()
 
704
    builder.export(use_existing=True)
 
705
    self.failIfExists(self.source_dir)
 
706
 
 
707
  def test_export_has_correct_contents_in_source_dir(self):
 
708
    """Test that the exported source dir has the correct contents."""
 
709
    wt = self._make_branch()
 
710
    basedir = 'debian/'
 
711
    files = [basedir]
 
712
    files = files + [join(basedir, f) for f in self.debian_files]
 
713
    self.build_branch_tree(files)
 
714
    wt.add(files)
 
715
    wt.commit('commit one')
 
716
    self.build_branch_tree(join(basedir, f) for f in ['rules', 'unknown'])
 
717
    wt.add(join(basedir, 'rules'))
 
718
    wt.remove(join(basedir, 'control'))
 
719
    builder = self.get_builder(wt=wt)
 
720
    self.make_orig_tarball()
 
721
    builder.prepare()
 
722
    builder.export()
 
723
    expected = ['changelog', 'patches', 'patches/patch', 'rules']
 
724
    for f in expected:
 
725
      self.failUnlessExists(join(self.source_dir, basedir, f))
 
726
    for f in ['control', 'unknown']:
 
727
      self.failIfExists(join(self.source_dir, basedir, f))
 
728
 
 
729
  def test_export_removes_builddeb_dir(self):
 
730
    """Test that the builddeb dir is removed from the export."""
 
731
    wt = self._make_branch()
 
732
    basedir = 'debian/'
 
733
    files = [basedir]
 
734
    files = files + [join(basedir, f) for f in ['.bzr-builddeb/',
 
735
                             '.bzr-builddeb/default.conf']]
 
736
    files = files + [join(basedir, f) for f in self.debian_files]
 
737
    self.build_branch_tree(files)
 
738
    wt.add(files)
 
739
    wt.commit('commit one')
 
740
    builder = self.get_builder(wt=wt)
 
741
    self.make_orig_tarball()
 
742
    builder.prepare()
 
743
    builder.export()
 
744
    for f in self.debian_files:
 
745
      self.failUnlessExists(join(self.source_dir, join(basedir, f)))
 
746
    self.failIfExists(join(self.source_dir, '.bzr-builddeb'))
 
747
 
 
748
  def test_larstiq(self):
 
749
    """Test that LarstiQ format is exported correctly"""
 
750
    wt = self._make_branch()
 
751
    self.build_branch_tree(self.debian_files)
 
752
    wt.add(self.debian_files)
 
753
    wt.commit('commit one')
 
754
    self.build_branch_tree(['rules', 'unknown'])
 
755
    wt.add('rules')
 
756
    wt.remove('control')
 
757
    builder = self.get_builder(wt=wt, larstiq=True)
 
758
    self.make_orig_tarball()
 
759
    builder.prepare()
 
760
    builder.export()
 
761
    expected = ['changelog', 'patches', 'patches/patch', 'rules']
 
762
    basedir = 'debian'
 
763
    for f in expected:
 
764
      self.failUnlessExists(join(self.source_dir, basedir, f))
 
765
    for f in self.upstream_files:
 
766
      self.failUnlessExists(join(self.source_dir, f))
 
767
    for f in ['control', 'unknown']:
 
768
      self.failIfExists(join(self.source_dir, f))
 
769
 
 
770
 
 
771
class TestMergeExportUpstreamBuilder(BuilderTestCase):
 
772
 
 
773
  upstream_branch = property(lambda self: join(self.basedir, 'upstream'))
 
774
  upstream_parent = property(lambda self: join(self.basedir, 'parent'))
 
775
 
 
776
  def get_builder(self, wt=None, version=None, larstiq=False,
 
777
                  export_revision=None, export_prepull=False,
 
778
                  stop_on_no_change=False):
 
779
    if wt is None:
 
780
      wt = self._make_branch()
 
781
    changelog = self.make_changelog(version=version)
 
782
    properties = self.make_properties(changelog, larstiq)
 
783
    return DebMergeExportUpstreamBuild(properties, wt, self.upstream_branch,
 
784
                                       export_revision, export_prepull,
 
785
                                       stop_on_no_change)
 
786
 
 
787
  def make_upstream_branch(self, parent=None):
 
788
    """Make the upstream branch that will be exported."""
 
789
    wt = self.make_branch_and_tree(self.upstream_branch)
 
790
    files = ['a', 'dir/', 'dir/b']
 
791
    newfiles = [join(self.upstream_branch, f) for f in files]
 
792
    self.build_tree(newfiles)
 
793
    wt.add(files)
 
794
    wt.commit('commit one', rev_id='rev1')
 
795
    self.build_tree([join(self.upstream_branch, 'c')])
 
796
    wt.add('c')
 
797
    wt.commit('commit two', rev_id='rev2')
 
798
    self.build_tree([join(self.upstream_branch, f) for f in
 
799
                                          ['added', 'unknown']])
 
800
    wt.add('added')
 
801
    if parent is not None:
 
802
      wt.branch.set_parent(parent)
 
803
    self._upstream_tree = wt
 
804
 
 
805
  def make_upstream_parent_no_changes(self):
 
806
    """Makes the upstream parent by just sprouting it off the upstream."""
 
807
    upstream = self._upstream_tree
 
808
    upstream.branch.bzrdir.sprout(os.path.abspath(self.upstream_parent))
 
809
 
 
810
  def make_upstream_parent_changes(self):
 
811
    """Makes the upstream parent and adds a commit."""
 
812
    self.make_upstream_parent_no_changes()
 
813
    parent_location = os.path.abspath(self.upstream_parent)
 
814
    parent = WorkingTree.open_containing(parent_location)[0]
 
815
    self.build_tree([join(self.upstream_parent, 'parent'),
 
816
                     join(self.upstream_parent, 'parent2')])
 
817
    parent.add(['parent'])
 
818
    parent.commit('parent commit 1', rev_id='parent1')
 
819
    parent.add(['parent2'])
 
820
    parent.commit('parent commit 2', rev_id='parent2')
 
821
 
 
822
  def test__find_tarball(self):
 
823
    """Test that the tarball is located in the build dir."""
 
824
    builder = self.get_builder()
 
825
    self.assertEqual(builder._find_tarball(), join(self.build_dir,
 
826
                     self.tarball_name))
 
827
 
 
828
  def test__export_upstream_branch_errors_on_no_branch(self):
 
829
    """Test that an error is raised if there is no branch to export."""
 
830
    wt = self._make_branch()
 
831
    changelog = self.make_changelog()
 
832
    properties = self.make_properties(changelog, False)
 
833
    builder = DebMergeExportUpstreamBuild(properties, wt, None, None, False,
 
834
                                          False)
 
835
    builder.prepare()
 
836
    self.assertRaises(errors.DebianError, builder._export_upstream_branch)
 
837
 
 
838
  def test__export_upstream_branch_errors_on_non_branch(self):
 
839
    """Test that the builder wont pull a branch that doesn't exists"""
 
840
    wt = self._make_branch()
 
841
    changelog = self.make_changelog()
 
842
    properties = self.make_properties(changelog, False)
 
843
    builder = DebMergeExportUpstreamBuild(properties, wt, 'invalid', None,
 
844
                                          False, False)
 
845
    builder.prepare()
 
846
    self.assertRaises(NotBranchError, builder._export_upstream_branch)
 
847
 
 
848
  def test__export_upstream_branch_errors_export_prepull_no_default(self):
 
849
    """Test that the export_prepull fails if the default location is not set."""
 
850
    builder = self.get_builder(export_prepull=True)
 
851
    self.make_upstream_branch()
 
852
    builder.prepare()
 
853
    self.assertRaises(errors.DebianError, builder._export_upstream_branch)
 
854
 
 
855
  def test__export_upstream_branch_errors_invalid_parent(self):
 
856
    """Test that the export_prepull fails if the parent doesn't exist."""
 
857
    builder = self.get_builder(export_prepull=True)
 
858
    self.make_upstream_branch(parent='invalid')
 
859
    builder.prepare()
 
860
    self.assertRaises(NotBranchError, builder._export_upstream_branch)
 
861
 
 
862
  def test__export_upstream_branch_stops_on_trivial(self):
 
863
    """Test that StopBuild is raised if there are no changes to pull."""
 
864
    builder = self.get_builder(export_prepull=True, stop_on_no_change=True)
 
865
    self.make_upstream_branch(parent=os.path.abspath(self.upstream_parent))
 
866
    self.make_upstream_parent_no_changes()
 
867
    builder.prepare()
 
868
    self.assertRaises(errors.StopBuild, builder._export_upstream_branch)
 
869
 
 
870
  def test__export_upstream_branch_doesnt_stop_on_trivial(self):
 
871
    """Test that the build normally doesn't stop if there is nothing to do."""
 
872
    builder = self.get_builder(export_prepull=True)
 
873
    self.make_upstream_branch(parent=os.path.abspath(self.upstream_parent))
 
874
    self.make_upstream_parent_no_changes()
 
875
    builder.prepare()
 
876
    builder._export_upstream_branch()
 
877
 
 
878
  def test__export_upstream_branch_doesnt_stop_on_changes(self):
 
879
    """Test the the build doesn't stop if there is something to do."""
 
880
    builder = self.get_builder(export_prepull=True, stop_on_no_change=True)
 
881
    self.make_upstream_branch(parent=os.path.abspath(self.upstream_parent))
 
882
    self.make_upstream_parent_changes()
 
883
    builder.prepare()
 
884
    builder._export_upstream_branch()
 
885
 
 
886
  def test__export_upstream_branch_has_correct_files(self):
 
887
    """Test that the upstream tarball has the correct files."""
 
888
    builder = self.get_builder()
 
889
    self.make_upstream_branch()
 
890
    builder.prepare()
 
891
    builder._export_upstream_branch()
 
892
    tarball = join(self.build_dir, self.tarball_name)
 
893
    self.failUnlessExists(tarball)
 
894
    expected = ['a', 'dir/', 'dir/b', 'c']
 
895
    basename = self.package_name + '-' + self.upstream_version + '/'
 
896
    self.check_tarball_contents(tarball, expected, basedir=basename,
 
897
                                skip_basedir=True)
 
898
 
 
899
  def test__export_upstream_pull_no_changes_has_correct_files(self):
 
900
    """Test that the upstream tarball has the correct files."""
 
901
    builder = self.get_builder(export_prepull=True)
 
902
    self.make_upstream_branch(parent=os.path.abspath(self.upstream_parent))
 
903
    self.make_upstream_parent_no_changes()
 
904
    builder.prepare()
 
905
    builder._export_upstream_branch()
 
906
    tarball = join(self.build_dir, self.tarball_name)
 
907
    self.failUnlessExists(tarball)
 
908
    expected = ['a', 'dir/', 'dir/b', 'c']
 
909
    basename = self.package_name + '-' + self.upstream_version + '/'
 
910
    self.check_tarball_contents(tarball, expected, basedir=basename,
 
911
                                skip_basedir=True)
 
912
 
 
913
  def test__export_upstream_pull_changes_has_correct_files(self):
 
914
    """Test that the upstream tarball has the correct files."""
 
915
    builder = self.get_builder(export_prepull=True)
 
916
    self.make_upstream_branch(parent=os.path.abspath(self.upstream_parent))
 
917
    self.make_upstream_parent_changes()
 
918
    builder.prepare()
 
919
    builder._export_upstream_branch()
 
920
    tarball = join(self.build_dir, self.tarball_name)
 
921
    self.failUnlessExists(tarball)
 
922
    expected = ['a', 'dir/', 'dir/b', 'c', 'parent', 'parent2']
 
923
    basename = self.package_name + '-' + self.upstream_version + '/'
 
924
    self.check_tarball_contents(tarball, expected, basedir=basename,
 
925
                                skip_basedir=True)
 
926
 
 
927
  def test__export_upstream_selects_correct_revision(self):
 
928
    """Test that if an upstream revision is selected it will be used."""
 
929
    builder = self.get_builder(export_prepull=True,
 
930
                               export_revision='revid:rev1')
 
931
    self.make_upstream_branch(parent=os.path.abspath(self.upstream_parent))
 
932
    self.make_upstream_parent_no_changes()
 
933
    builder.prepare()
 
934
    builder._export_upstream_branch()
 
935
    tarball = join(self.build_dir, self.tarball_name)
 
936
    self.failUnlessExists(tarball)
 
937
    expected = ['a', 'dir/', 'dir/b']
 
938
    basename = self.package_name + '-' + self.upstream_version + '/'
 
939
    self.check_tarball_contents(tarball, expected, basedir=basename,
 
940
                                skip_basedir=True)
 
941
 
 
942
  def test__export_upstream_can_select_parent_revision(self):
 
943
    """Test that if an upstream parent revision is selected it will be used."""
 
944
    builder = self.get_builder(export_prepull=True,
 
945
                               export_revision='revid:parent1')
 
946
    self.make_upstream_branch(parent=os.path.abspath(self.upstream_parent))
 
947
    self.make_upstream_parent_changes()
 
948
    builder.prepare()
 
949
    builder._export_upstream_branch()
 
950
    tarball = join(self.build_dir, self.tarball_name)
 
951
    self.failUnlessExists(tarball)
 
952
    expected = ['a', 'dir/', 'dir/b', 'c', 'parent']
 
953
    basename = self.package_name + '-' + self.upstream_version + '/'
 
954
    self.check_tarball_contents(tarball, expected, basedir=basename,
 
955
                                skip_basedir=True)
 
956
 
 
957
  def test__export_upstream_returns_true(self):
 
958
    """Sanity check that the function returns true."""
 
959
    builder = self.get_builder()
 
960
    self.make_upstream_branch()
 
961
    builder.prepare()
 
962
    self.assertEqual(builder._export_upstream_branch(), True)
 
963
 
 
964
  def test_export_has_correct_file(self):
 
965
    """A check that the top level export works as expected,"""
 
966
    builder = self.get_builder()
 
967
    self.make_upstream_branch()
 
968
    builder.prepare()
 
969
    builder.export()
 
970
    for f in ['a', 'dir', 'dir/b', 'c']:
 
971
      self.failUnlessExists(join(self.source_dir, f))
 
972