source: mergebot/trunk/utils/test.py @ 59

Last change on this file since 59 was 59, checked in by retracile, 15 years ago

Mergebot: add testcases for merge operations

File size: 24.2 KB
Line 
1#!/usr/bin/python
2"""Automated tests for MergeBot
3
4Run from a Trac source tree with mergebot installed system-wide.  (This needs
5to be reworked to be less cumbersome.)
6"""
7
8import os
9import unittest
10import time
11import shutil
12
13from subprocess import call, Popen #, PIPE, STDOUT
14from twill.errors import TwillAssertionError
15
16
17from trac.tests.functional import FunctionalTestSuite, FunctionalTester, FunctionalTwillTestCaseSetup, tc, b, logfile
18from trac.tests.functional.svntestenv import SvnFunctionalTestEnvironment
19from trac.tests.contentgen import random_page, random_sentence #, random_word
20
21
22#class MergeBotTestEnvironment(FunctionalTestEnvironment):
23#    """Slight change to FunctionalTestEnvironment to keep the PYTHONPATH from
24#    our environment.
25#    """
26#    def start(self):
27#        """Starts the webserver"""
28#        server = Popen(["python", "./trac/web/standalone.py",
29#                        "--port=%s" % self.port, "-s",
30#                        "--basic-auth=trac,%s," % self.htpasswd,
31#                        self.tracdir],
32#                       #env={'PYTHONPATH':'.'},
33#                       stdout=logfile, stderr=logfile,
34#                      )
35#        self.pid = server.pid
36#        time.sleep(1) # Give the server time to come up
37#
38#    def _tracadmin(self, *args):
39#        """Internal utility method for calling trac-admin"""
40#        if call(["python", "./trac/admin/console.py", self.tracdir] +
41#                list(args),
42#                #env={'PYTHONPATH':'.'},
43#                stdout=logfile, stderr=logfile):
44#            raise Exception('Failed running trac-admin with %r' % (args, ))
45#
46#
47#FunctionalTestEnvironment = MergeBotTestEnvironment
48
49
50class MergeBotFunctionalTester(FunctionalTester):
51    """Adds some MergeBot functionality to the functional tester."""
52    # FIXME: the tc.find( <various actions> ) checks are bogus: any ticket can
53    # satisfy them, not just the one we're working on.
54    def __init__(self, trac_url, repo_url):
55        FunctionalTester.__init__(self, trac_url)
56        self.repo_url = repo_url
57        self.mergeboturl = self.url + '/mergebot'
58
59    def wait_until_find(self, search, timeout=5):
60        start = time.time()
61        while time.time() - start < timeout:
62            try:
63                #tc.reload() # This appears to re-POST
64                tc.go(b.get_url())
65                tc.find(search)
66                return
67            except TwillAssertionError:
68                pass
69        raise TwillAssertionError("Unable to find %r within %s seconds" % (search, timeout))
70
71    def wait_until_notfind(self, search, timeout=5):
72        start = time.time()
73        while time.time() - start < timeout:
74            try:
75                #tc.reload() # This appears to re-POST
76                tc.go(b.get_url())
77                tc.notfind(search)
78                return
79            except TwillAssertionError:
80                pass
81        raise TwillAssertionError("Unable to notfind %r within %s seconds" % (search, timeout))
82
83    def go_to_mergebot(self):
84        tc.go(self.mergeboturl)
85        tc.url(self.mergeboturl)
86        tc.notfind('No handler matched request to /mergebot')
87
88    def branch(self, ticket_id, component, timeout=1):
89        """timeout is in seconds."""
90        self.go_to_mergebot()
91        tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
92        tc.submit('Branch')
93        self.wait_until_find('Nothing in the queue', timeout)
94        tc.find('Rebranch')
95        tc.find('Merge')
96        tc.find('CheckMerge')
97        self.go_to_ticket(ticket_id)
98        tc.find('Created branch from .* for .*')
99        retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id],
100                    stdout=logfile, stderr=logfile)
101        if retval:
102            raise Exception('svn ls failed with exit code %s' % retval)
103
104    def _rebranch(self, ticket_id, component, search, timeout=15):
105        """timeout is in seconds."""
106        self.go_to_mergebot()
107        tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
108        tc.submit('Rebranch')
109        self.wait_until_find('Nothing in the queue', timeout)
110        tc.find('Rebranch')
111        tc.find('Merge')
112        tc.find('CheckMerge')
113        self.go_to_ticket(ticket_id)
114        tc.find(search)
115        retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id],
116                    stdout=logfile, stderr=logfile)
117        if retval:
118            raise Exception('svn ls failed with exit code %s' % retval)
119
120    def rebranch(self, ticket_id, component, timeout=15):
121        self._rebranch(ticket_id, component, 'Rebranched from .* for .*', timeout)
122
123    def rebranch_conflict(self, ticket_id, component, timeout=15):
124        self._rebranch(ticket_id, component, 'There were conflicts on rebranching', timeout)
125
126    def merge(self, ticket_id, component, timeout=5):
127        self._merge(ticket_id, component, 'Merged .* to .* for', timeout)
128
129    def merge_conflict(self, ticket_id, component, timeout=5):
130        self._merge(ticket_id, component, 'Found [0-9]+ conflicts? in attempt to merge ', timeout)
131
132    def _merge(self, ticket_id, component, search, timeout=5):
133        """timeout is in seconds."""
134        self.go_to_mergebot()
135        tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
136        tc.submit('Merge')
137        self.wait_until_find('Nothing in the queue', timeout)
138        tc.find('Branch')
139        self.go_to_ticket(ticket_id)
140        tc.find(search)
141        # TODO: We may want to change this to remove the "dead" branch
142        retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id],
143                    stdout=logfile, stderr=logfile)
144        if retval:
145            raise Exception('svn ls failed with exit code %s' % retval)
146
147    def checkmerge(self, ticket_id, component, timeout=5):
148        """timeout is in seconds."""
149        self.go_to_mergebot()
150        tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
151        tc.submit('CheckMerge')
152        self.wait_until_find('Nothing in the queue', timeout)
153        tc.find('Rebranch')
154        tc.find('Merge')
155        tc.find('CheckMerge')
156        self.go_to_ticket(ticket_id)
157        tc.find('while checking merge of')
158        # TODO: We may want to change this to remove the "dead" branch
159        retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id],
160                    stdout=logfile, stderr=logfile)
161        if retval:
162            raise Exception('svn ls failed with exit code %s' % retval)
163
164
165class MergeBotTestSuite(FunctionalTestSuite):
166    def setUp(self):
167        port = 8889
168        baseurl = "http://localhost:%s" % port
169        self._testenv = SvnFunctionalTestEnvironment("testenv%s" % port, port, baseurl)
170
171        # Configure mergebot
172        env = self._testenv.get_trac_environment()
173        env.config.set('components', 'mergebot.web_ui.mergebotmodule', 'enabled')
174        env.config.save()
175        os.mkdir(os.path.join("testenv%s" % port, 'trac', 'mergebot'))
176        self._testenv._tracadmin('upgrade') # sets up the bulk of the mergebot config
177        env.config.parse_if_needed()
178        env.config.set('mergebot', 'repository_url', self._testenv.repo_url())
179        env.config.set('logging', 'log_type', 'file')
180        env.config.save()
181        env.config.parse_if_needed()
182
183        self._testenv.start()
184        self._tester = MergeBotFunctionalTester(baseurl, self._testenv.repo_url())
185        os.system('mergebotdaemon -f "%s" > %s/mergebotdaemon.log 2>&1 &' % (self._testenv.tracdir, self._testenv.tracdir))
186        self.fixture = (self._testenv, self._tester)
187
188        # Setup some common component stuff for MergeBot's use:
189        svnurl = self._testenv.repo_url()
190        for component in ['stuff', 'flagship', 'submarine']:
191            self._tester.create_component(component)
192            if call(['svn', '-m', 'Create tree for "%s".' % component, 'mkdir',
193                     svnurl + '/' + component,
194                     svnurl + '/' + component + '/trunk',
195                     svnurl + '/' + component + '/tags',
196                     svnurl + '/' + component + '/branches'],
197                    stdout=logfile, stderr=logfile):
198                raise Exception("svn mkdir failed")
199
200        self._tester.create_version('trunk')
201
202
203class FunctionalSvnTestCaseSetup(FunctionalTwillTestCaseSetup):
204    def get_workdir(self):
205        return os.path.join(self._testenv.dirname, self.__class__.__name__)
206
207    def checkout(self, ticket_id=None):
208        """checkout a working copy of the branch for the given ticket, or trunk if none given"""
209        if ticket_id is None:
210            svnurl = self._testenv.repo_url() + '/stuff/trunk'
211        else:
212            svnurl = self._testenv.repo_url() + '/stuff/branches/ticket-%s' % ticket_id
213        retval = call(['svn', 'checkout', svnurl, self.get_workdir()],
214            stdout=logfile, stderr=logfile)
215        self.assertEqual(retval, 0, "svn checkout failed with error %s" % (retval))
216
217    def switch(self, ticket_id=None):
218        if ticket_id is None:
219            svnurl = self._testenv.repo_url() + '/stuff/trunk'
220        else:
221            svnurl = self._testenv.repo_url() + '/stuff/branches/ticket-%s' % ticket_id
222        retval = call(['svn', 'switch', svnurl, self.get_workdir()],
223            stdout=logfile, stderr=logfile)
224        self.assertEqual(retval, 0, "svn checkout failed with error %s" % (retval))
225
226    def add_new_file(self, filename=None):
227        workdir = self.get_workdir()
228        if filename is None:
229            newfile = os.path.join(workdir, self.__class__.__name__)
230        else:
231            newfile = os.path.join(workdir, filename)
232        open(newfile, 'w').write(random_page())
233        retval = call(['svn', 'add', newfile],
234            cwd=workdir,
235            stdout=logfile, stderr=logfile)
236        self.assertEqual(retval, 0, "svn add failed with error %s" % (retval))
237
238    def commit(self, message, files=None):
239        if files is None:
240            files = ['.']
241        commit_message = self.__class__.__name__ + ": " + message
242        retval = call(['svn', 'commit', '-m', commit_message] + list(files),
243            cwd=self.get_workdir(),
244            stdout=logfile, stderr=logfile)
245        self.assertEqual(retval, 0, "svn commit failed with error %s" % (retval))
246
247    def mv(self, oldname, newname):
248        retval = call(['svn', 'mv', oldname, newname],
249            cwd=self.get_workdir(),
250            stdout=logfile, stderr=logfile)
251        self.assertEqual(retval, 0, "svn mv failed with error %s" % (retval))
252
253
254class MergeBotTestEnabled(FunctionalTwillTestCaseSetup):
255    def runTest(self):
256        self._tester.logout()
257        tc.go(self._tester.url)
258        self._tester.login('admin')
259        tc.follow('MergeBot')
260        mergeboturl = self._tester.url + '/mergebot'
261        tc.url(mergeboturl)
262        tc.notfind('No handler matched request to /mergebot')
263
264
265class MergeBotTestNoVersion(FunctionalTwillTestCaseSetup):
266    """Verify that if a ticket does not have the version field set, it will not
267    appear in the MergeBot list.
268    """
269    def runTest(self):
270        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
271            info={'component':'stuff', 'version':''})
272        tc.follow('MergeBot')
273        tc.notfind(self.__class__.__name__)
274
275
276class MergeBotTestBranch(FunctionalTwillTestCaseSetup):
277    def runTest(self):
278        """Verify that the 'branch' button works"""
279        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
280            info={'component':'stuff', 'version':'trunk'})
281        self._tester.branch(ticket_id, 'stuff')
282
283
284class MergeBotTestRebranch(FunctionalTwillTestCaseSetup):
285    def runTest(self):
286        """Verify that the 'rebranch' button works"""
287        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
288            info={'component':'stuff', 'version':'trunk'})
289        self._tester.branch(ticket_id, 'stuff')
290        self._tester.rebranch(ticket_id, 'stuff')
291
292
293class MergeBotTestMerge(FunctionalTwillTestCaseSetup):
294    def runTest(self):
295        """Verify that the 'merge' button works"""
296        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
297            info={'component':'stuff', 'version':'trunk'})
298        self._tester.branch(ticket_id, 'stuff')
299        self._tester.merge(ticket_id, 'stuff')
300
301
302class MergeBotTestMergeWithChange(FunctionalSvnTestCaseSetup):
303    def runTest(self):
304        """Verify that the 'merge' button works with changes on the branch"""
305        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
306            info={'component':'stuff', 'version':'trunk'})
307        self._tester.branch(ticket_id, 'stuff')
308
309        # checkout a working copy & make a change
310        self.checkout(ticket_id)
311        # Create & add a new file
312        self.add_new_file()
313        self.commit('Add a new file')
314
315        self._tester.merge(ticket_id, 'stuff')
316
317
318class MergeBotTestMergeWithChangeAndTrunkChange(FunctionalSvnTestCaseSetup):
319    def runTest(self):
320        """Verify that the 'merge' button works with changes on the branch and trunk"""
321        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
322            info={'component':'stuff', 'version':'trunk'})
323        self._tester.branch(ticket_id, 'stuff')
324
325        # checkout a working copy & make a change
326        self.checkout(ticket_id)
327        # Create & add a new file
328        basename = self.__class__.__name__
329        self.add_new_file(basename + '-ticket')
330        self.commit('Add a new file on ticket')
331        self.switch()
332        self.add_new_file(basename + '-trunk')
333        self.commit('Add a new file on trunk')
334
335        self._tester.merge(ticket_id, 'stuff')
336
337
338class MergeBotTestMergeWithConflict(FunctionalSvnTestCaseSetup):
339    def runTest(self):
340        """Verify that the 'merge' button detects conflicts between the branch and trunk"""
341        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
342            info={'component':'stuff', 'version':'trunk'})
343        basename = self.__class__.__name__
344
345        # create a file in which to have conflicts
346        self.checkout()
347        self.add_new_file(basename)
348        self.commit('Add a new file on trunk')
349
350        # create the branch
351        self._tester.branch(ticket_id, 'stuff')
352
353        # modify the file on trunk
354        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
355        self.commit('Modify the file on trunk')
356
357        # modify the file on the branch
358        self.switch(ticket_id)
359        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
360        self.commit('Modify the file on branch')
361
362        # merge, make sure it shows a conflict
363        self._tester.merge_conflict(ticket_id, 'stuff')
364
365
366class MergeBotTestMergeWithBranchRenameConflict(FunctionalSvnTestCaseSetup):
367    def runTest(self):
368        """Verify that the 'merge' button detects a conflict when a file renamed on the branch was modified on trunk"""
369        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
370            info={'component':'stuff', 'version':'trunk'})
371        basename = self.__class__.__name__
372
373        # create a file in which to have conflicts
374        self.checkout()
375        self.add_new_file(basename)
376        self.commit('Add a new file on trunk')
377
378        # create the branch
379        self._tester.branch(ticket_id, 'stuff')
380
381        # modify the file on trunk
382        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
383        self.commit('Modify the file on trunk')
384
385        # rename the file on the branch
386        self.switch(ticket_id)
387        self.mv(basename, basename + '-renamed')
388        self.commit('Rename the file on the branch')
389
390        self._tester.merge_conflict(ticket_id, 'stuff')
391
392
393class MergeBotTestMergeWithTrunkRenameConflict(FunctionalSvnTestCaseSetup):
394    def runTest(self):
395        """Verify that the 'merge' button detects conflicts when a file renamed on trunk was modified on the branch"""
396        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
397            info={'component':'stuff', 'version':'trunk'})
398        basename = self.__class__.__name__
399
400        # create a file in which to have conflicts
401        self.checkout()
402        self.add_new_file(basename)
403        self.commit('Add a new file on trunk')
404
405        # create the branch
406        self._tester.branch(ticket_id, 'stuff')
407
408        # rename the file on trunk
409        self.mv(basename, basename + '-renamed')
410        self.commit('Rename the file on trunk')
411
412        # rename the file on the branch
413        self.switch(ticket_id)
414        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
415        self.commit('Modify the file on the branch')
416
417        # make sure it finds the conflict
418        self._tester.merge_conflict(ticket_id, 'stuff')
419
420
421class MergeBotTestCheckMerge(FunctionalTwillTestCaseSetup):
422    def runTest(self):
423        """Verify that the 'checkmerge' button works"""
424        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
425            info={'component':'stuff', 'version':'trunk'})
426        self._tester.branch(ticket_id, 'stuff')
427        self._tester.checkmerge(ticket_id, 'stuff')
428
429
430class MergeBotTestRebranchWithChange(FunctionalSvnTestCaseSetup):
431    def runTest(self):
432        """Verify that the 'rebranch' button works with changes on the branch"""
433        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
434            info={'component':'stuff', 'version':'trunk'})
435        self._tester.branch(ticket_id, 'stuff')
436
437        # checkout a working copy & make a change
438        self.checkout(ticket_id)
439        # Create & add a new file
440        self.add_new_file()
441        self.commit('Add a new file')
442
443        self._tester.rebranch(ticket_id, 'stuff')
444
445
446class MergeBotTestRebranchWithChangeAndTrunkChange(FunctionalSvnTestCaseSetup):
447    def runTest(self):
448        """Verify that the 'rebranch' button works with changes on the branch and trunk"""
449        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
450            info={'component':'stuff', 'version':'trunk'})
451        self._tester.branch(ticket_id, 'stuff')
452
453        # checkout a working copy & make a change
454        self.checkout(ticket_id)
455        # Create & add a new file
456        basename = self.__class__.__name__
457        self.add_new_file(basename + '-ticket')
458        self.commit('Add a new file on ticket')
459        self.switch()
460        self.add_new_file(basename + '-trunk')
461        self.commit('Add a new file on trunk')
462
463        self._tester.rebranch(ticket_id, 'stuff')
464
465
466class MergeBotTestRebranchWithConflict(FunctionalSvnTestCaseSetup):
467    def runTest(self):
468        """Verify that the 'rebranch' button detects conflicts between the branch and trunk"""
469        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
470            info={'component':'stuff', 'version':'trunk'})
471        basename = self.__class__.__name__
472
473        # create a file in which to have conflicts
474        self.checkout()
475        self.add_new_file(basename)
476        self.commit('Add a new file on trunk')
477
478        # create the branch
479        self._tester.branch(ticket_id, 'stuff')
480
481        # modify the file on trunk
482        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
483        self.commit('Modify the file on trunk')
484
485        # modify the file on the branch
486        self.switch(ticket_id)
487        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
488        self.commit('Modify the file on branch')
489
490        # rebranch, make sure it shows a conflict
491        self._tester.rebranch_conflict(ticket_id, 'stuff')
492
493
494class MergeBotTestRebranchWithBranchRenameConflict(FunctionalSvnTestCaseSetup):
495    def runTest(self):
496        """Verify that the 'rebranch' button detects a conflict when a file renamed on the branch was modified on trunk"""
497        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
498            info={'component':'stuff', 'version':'trunk'})
499        basename = self.__class__.__name__
500
501        # create a file in which to have conflicts
502        self.checkout()
503        self.add_new_file(basename)
504        self.commit('Add a new file on trunk')
505
506        # create the branch
507        self._tester.branch(ticket_id, 'stuff')
508
509        # modify the file on trunk
510        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
511        self.commit('Modify the file on trunk')
512
513        # rename the file on the branch
514        self.switch(ticket_id)
515        self.mv(basename, basename + '-renamed')
516        self.commit('Rename the file on the branch')
517
518        self._tester.rebranch_conflict(ticket_id, 'stuff')
519
520
521class MergeBotTestRebranchWithTrunkRenameConflict(FunctionalSvnTestCaseSetup):
522    def runTest(self):
523        """Verify that the 'rebranch' button detects conflicts when a file renamed on trunk was modified on the branch"""
524        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
525            info={'component':'stuff', 'version':'trunk'})
526        basename = self.__class__.__name__
527
528        # create a file in which to have conflicts
529        self.checkout()
530        self.add_new_file(basename)
531        self.commit('Add a new file on trunk')
532
533        # create the branch
534        self._tester.branch(ticket_id, 'stuff')
535
536        # rename the file on trunk
537        self.mv(basename, basename + '-renamed')
538        self.commit('Rename the file on trunk')
539
540        # rename the file on the branch
541        self.switch(ticket_id)
542        open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence())
543        self.commit('Modify the file on the branch')
544
545        # make sure it finds the conflict
546        self._tester.rebranch_conflict(ticket_id, 'stuff')
547
548
549class MergeBotTestSingleUseCase(FunctionalTwillTestCaseSetup):
550    def runTest(self):
551        """Create a branch, make a change, checkmerge, and merge it."""
552        ticket_id = self._tester.create_ticket(summary=self.__class__.__name__,
553            info={'component':'stuff', 'version':'trunk'})
554        self._tester.branch(ticket_id, 'stuff')
555        # checkout a working copy & make a change
556        svnurl = self._testenv.repo_url()
557        workdir = os.path.join(self._testenv.dirname, self.__class__.__name__)
558        retval = call(['svn', 'checkout', svnurl + '/stuff/branches/ticket-%s' % ticket_id, workdir],
559            stdout=logfile, stderr=logfile)
560        self.assertEqual(retval, 0, "svn checkout failed with error %s" % (retval))
561        # Create & add a new file
562        newfile = os.path.join(workdir, self.__class__.__name__)
563        open(newfile, 'w').write(random_page())
564        retval = call(['svn', 'add', self.__class__.__name__],
565            cwd=workdir,
566            stdout=logfile, stderr=logfile)
567        self.assertEqual(retval, 0, "svn add failed with error %s" % (retval))
568        retval = call(['svn', 'commit', '-m', 'Add a new file', self.__class__.__name__],
569            cwd=workdir,
570            stdout=logfile, stderr=logfile)
571        self.assertEqual(retval, 0, "svn commit failed with error %s" % (retval))
572
573        self._tester.checkmerge(ticket_id, 'stuff')
574        self._tester.merge(ticket_id, 'stuff')
575
576        shutil.rmtree(workdir) # cleanup working copy
577
578
579def suite():
580    suite = MergeBotTestSuite()
581    suite.addTest(MergeBotTestEnabled())
582    suite.addTest(MergeBotTestNoVersion())
583    suite.addTest(MergeBotTestBranch())
584    suite.addTest(MergeBotTestRebranch())
585    suite.addTest(MergeBotTestCheckMerge())
586    suite.addTest(MergeBotTestMerge())
587    suite.addTest(MergeBotTestRebranchWithChange())
588    suite.addTest(MergeBotTestRebranchWithChangeAndTrunkChange())
589    suite.addTest(MergeBotTestRebranchWithConflict())
590    suite.addTest(MergeBotTestRebranchWithBranchRenameConflict())
591    suite.addTest(MergeBotTestRebranchWithTrunkRenameConflict())
592    suite.addTest(MergeBotTestMergeWithChange())
593    suite.addTest(MergeBotTestMergeWithChangeAndTrunkChange())
594    suite.addTest(MergeBotTestMergeWithConflict())
595    suite.addTest(MergeBotTestMergeWithBranchRenameConflict())
596    suite.addTest(MergeBotTestMergeWithTrunkRenameConflict())
597    suite.addTest(MergeBotTestSingleUseCase())
598    return suite
599
600if __name__ == '__main__':
601    unittest.main(defaultTest='suite')
Note: See TracBrowser for help on using the repository browser.