| [16] | 1 | #!/usr/bin/python | 
|---|
 | 2 | """Automated tests for MergeBot | 
|---|
| [41] | 3 |  | 
|---|
 | 4 | Run from a Trac source tree with mergebot installed system-wide.  (This needs | 
|---|
 | 5 | to be reworked to be less cumbersome.) | 
|---|
| [16] | 6 | """ | 
|---|
 | 7 |  | 
|---|
| [64] | 8 | # TODO: The testcases need to be extended to cover the following: | 
|---|
 | 9 | # - using a ticket #number as a version | 
|---|
 | 10 | # - using a release version number as a version | 
|---|
 | 11 | # - verify inter-ticket dependency checking | 
|---|
 | 12 | # - verify failure cascades through inter-ticket dependencies | 
|---|
 | 13 |  | 
|---|
| [16] | 14 | import os | 
|---|
 | 15 | import unittest | 
|---|
 | 16 | import time | 
|---|
 | 17 | import shutil | 
|---|
 | 18 |  | 
|---|
 | 19 | from subprocess import call, Popen #, PIPE, STDOUT | 
|---|
 | 20 | from twill.errors import TwillAssertionError | 
|---|
 | 21 |  | 
|---|
 | 22 |  | 
|---|
| [40] | 23 | from trac.tests.functional import FunctionalTestSuite, FunctionalTester, FunctionalTwillTestCaseSetup, tc, b, logfile | 
|---|
 | 24 | from trac.tests.functional.svntestenv import SvnFunctionalTestEnvironment | 
|---|
| [54] | 25 | from trac.tests.contentgen import random_page, random_sentence #, random_word | 
|---|
| [16] | 26 |  | 
|---|
 | 27 |  | 
|---|
| [17] | 28 | #class MergeBotTestEnvironment(FunctionalTestEnvironment): | 
|---|
 | 29 | #    """Slight change to FunctionalTestEnvironment to keep the PYTHONPATH from | 
|---|
 | 30 | #    our environment. | 
|---|
 | 31 | #    """ | 
|---|
 | 32 | #    def start(self): | 
|---|
 | 33 | #        """Starts the webserver""" | 
|---|
 | 34 | #        server = Popen(["python", "./trac/web/standalone.py", | 
|---|
 | 35 | #                        "--port=%s" % self.port, "-s", | 
|---|
 | 36 | #                        "--basic-auth=trac,%s," % self.htpasswd, | 
|---|
 | 37 | #                        self.tracdir], | 
|---|
 | 38 | #                       #env={'PYTHONPATH':'.'}, | 
|---|
 | 39 | #                       stdout=logfile, stderr=logfile, | 
|---|
 | 40 | #                      ) | 
|---|
 | 41 | #        self.pid = server.pid | 
|---|
 | 42 | #        time.sleep(1) # Give the server time to come up | 
|---|
 | 43 | # | 
|---|
 | 44 | #    def _tracadmin(self, *args): | 
|---|
 | 45 | #        """Internal utility method for calling trac-admin""" | 
|---|
 | 46 | #        if call(["python", "./trac/admin/console.py", self.tracdir] + | 
|---|
 | 47 | #                list(args), | 
|---|
 | 48 | #                #env={'PYTHONPATH':'.'}, | 
|---|
 | 49 | #                stdout=logfile, stderr=logfile): | 
|---|
 | 50 | #            raise Exception('Failed running trac-admin with %r' % (args, )) | 
|---|
 | 51 | # | 
|---|
 | 52 | # | 
|---|
 | 53 | #FunctionalTestEnvironment = MergeBotTestEnvironment | 
|---|
| [16] | 54 |  | 
|---|
 | 55 |  | 
|---|
 | 56 | class MergeBotFunctionalTester(FunctionalTester): | 
|---|
 | 57 |     """Adds some MergeBot functionality to the functional tester.""" | 
|---|
 | 58 |     # FIXME: the tc.find( <various actions> ) checks are bogus: any ticket can | 
|---|
 | 59 |     # satisfy them, not just the one we're working on. | 
|---|
| [44] | 60 |     def __init__(self, trac_url, repo_url): | 
|---|
 | 61 |         FunctionalTester.__init__(self, trac_url) | 
|---|
 | 62 |         self.repo_url = repo_url | 
|---|
| [16] | 63 |         self.mergeboturl = self.url + '/mergebot' | 
|---|
 | 64 |  | 
|---|
 | 65 |     def wait_until_find(self, search, timeout=5): | 
|---|
 | 66 |         start = time.time() | 
|---|
 | 67 |         while time.time() - start < timeout: | 
|---|
 | 68 |             try: | 
|---|
| [45] | 69 |                 #tc.reload() # This appears to re-POST | 
|---|
 | 70 |                 tc.go(b.get_url()) | 
|---|
| [16] | 71 |                 tc.find(search) | 
|---|
 | 72 |                 return | 
|---|
 | 73 |             except TwillAssertionError: | 
|---|
 | 74 |                 pass | 
|---|
 | 75 |         raise TwillAssertionError("Unable to find %r within %s seconds" % (search, timeout)) | 
|---|
 | 76 |  | 
|---|
 | 77 |     def wait_until_notfind(self, search, timeout=5): | 
|---|
 | 78 |         start = time.time() | 
|---|
 | 79 |         while time.time() - start < timeout: | 
|---|
 | 80 |             try: | 
|---|
| [45] | 81 |                 #tc.reload() # This appears to re-POST | 
|---|
 | 82 |                 tc.go(b.get_url()) | 
|---|
| [16] | 83 |                 tc.notfind(search) | 
|---|
 | 84 |                 return | 
|---|
 | 85 |             except TwillAssertionError: | 
|---|
 | 86 |                 pass | 
|---|
 | 87 |         raise TwillAssertionError("Unable to notfind %r within %s seconds" % (search, timeout)) | 
|---|
 | 88 |  | 
|---|
 | 89 |     def go_to_mergebot(self): | 
|---|
 | 90 |         tc.go(self.mergeboturl) | 
|---|
 | 91 |         tc.url(self.mergeboturl) | 
|---|
 | 92 |         tc.notfind('No handler matched request to /mergebot') | 
|---|
 | 93 |  | 
|---|
 | 94 |     def branch(self, ticket_id, component, timeout=1): | 
|---|
 | 95 |         """timeout is in seconds.""" | 
|---|
 | 96 |         self.go_to_mergebot() | 
|---|
 | 97 |         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form | 
|---|
 | 98 |         tc.submit('Branch') | 
|---|
| [44] | 99 |         self.wait_until_find('Nothing in the queue', timeout) | 
|---|
| [16] | 100 |         tc.find('Rebranch') | 
|---|
 | 101 |         tc.find('Merge') | 
|---|
 | 102 |         tc.find('CheckMerge') | 
|---|
 | 103 |         self.go_to_ticket(ticket_id) | 
|---|
 | 104 |         tc.find('Created branch from .* for .*') | 
|---|
 | 105 |         retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id], | 
|---|
 | 106 |                     stdout=logfile, stderr=logfile) | 
|---|
 | 107 |         if retval: | 
|---|
 | 108 |             raise Exception('svn ls failed with exit code %s' % retval) | 
|---|
 | 109 |  | 
|---|
| [57] | 110 |     def _rebranch(self, ticket_id, component, search, timeout=15): | 
|---|
| [16] | 111 |         """timeout is in seconds.""" | 
|---|
 | 112 |         self.go_to_mergebot() | 
|---|
 | 113 |         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form | 
|---|
 | 114 |         tc.submit('Rebranch') | 
|---|
| [44] | 115 |         self.wait_until_find('Nothing in the queue', timeout) | 
|---|
| [16] | 116 |         tc.find('Rebranch') | 
|---|
 | 117 |         tc.find('Merge') | 
|---|
 | 118 |         tc.find('CheckMerge') | 
|---|
 | 119 |         self.go_to_ticket(ticket_id) | 
|---|
| [57] | 120 |         tc.find(search) | 
|---|
| [16] | 121 |         retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id], | 
|---|
 | 122 |                     stdout=logfile, stderr=logfile) | 
|---|
 | 123 |         if retval: | 
|---|
 | 124 |             raise Exception('svn ls failed with exit code %s' % retval) | 
|---|
 | 125 |  | 
|---|
| [57] | 126 |     def rebranch(self, ticket_id, component, timeout=15): | 
|---|
 | 127 |         self._rebranch(ticket_id, component, 'Rebranched from .* for .*', timeout) | 
|---|
 | 128 |  | 
|---|
 | 129 |     def rebranch_conflict(self, ticket_id, component, timeout=15): | 
|---|
 | 130 |         self._rebranch(ticket_id, component, 'There were conflicts on rebranching', timeout) | 
|---|
 | 131 |  | 
|---|
| [16] | 132 |     def merge(self, ticket_id, component, timeout=5): | 
|---|
| [59] | 133 |         self._merge(ticket_id, component, 'Merged .* to .* for', timeout) | 
|---|
 | 134 |  | 
|---|
 | 135 |     def merge_conflict(self, ticket_id, component, timeout=5): | 
|---|
 | 136 |         self._merge(ticket_id, component, 'Found [0-9]+ conflicts? in attempt to merge ', timeout) | 
|---|
 | 137 |  | 
|---|
 | 138 |     def _merge(self, ticket_id, component, search, timeout=5): | 
|---|
| [16] | 139 |         """timeout is in seconds.""" | 
|---|
 | 140 |         self.go_to_mergebot() | 
|---|
 | 141 |         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form | 
|---|
 | 142 |         tc.submit('Merge') | 
|---|
| [44] | 143 |         self.wait_until_find('Nothing in the queue', timeout) | 
|---|
| [16] | 144 |         tc.find('Branch') | 
|---|
 | 145 |         self.go_to_ticket(ticket_id) | 
|---|
| [59] | 146 |         tc.find(search) | 
|---|
| [16] | 147 |         # TODO: We may want to change this to remove the "dead" branch | 
|---|
 | 148 |         retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id], | 
|---|
 | 149 |                     stdout=logfile, stderr=logfile) | 
|---|
 | 150 |         if retval: | 
|---|
 | 151 |             raise Exception('svn ls failed with exit code %s' % retval) | 
|---|
 | 152 |  | 
|---|
 | 153 |     def checkmerge(self, ticket_id, component, timeout=5): | 
|---|
 | 154 |         """timeout is in seconds.""" | 
|---|
 | 155 |         self.go_to_mergebot() | 
|---|
 | 156 |         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form | 
|---|
 | 157 |         tc.submit('CheckMerge') | 
|---|
| [44] | 158 |         self.wait_until_find('Nothing in the queue', timeout) | 
|---|
| [16] | 159 |         tc.find('Rebranch') | 
|---|
 | 160 |         tc.find('Merge') | 
|---|
 | 161 |         tc.find('CheckMerge') | 
|---|
 | 162 |         self.go_to_ticket(ticket_id) | 
|---|
 | 163 |         tc.find('while checking merge of') | 
|---|
 | 164 |         retval = call(['svn', 'ls', self.repo_url + '/' + component + '/branches/ticket-%s' % ticket_id], | 
|---|
 | 165 |                     stdout=logfile, stderr=logfile) | 
|---|
 | 166 |         if retval: | 
|---|
 | 167 |             raise Exception('svn ls failed with exit code %s' % retval) | 
|---|
 | 168 |  | 
|---|
 | 169 |  | 
|---|
 | 170 | class MergeBotTestSuite(FunctionalTestSuite): | 
|---|
 | 171 |     def setUp(self): | 
|---|
 | 172 |         port = 8889 | 
|---|
 | 173 |         baseurl = "http://localhost:%s" % port | 
|---|
| [40] | 174 |         self._testenv = SvnFunctionalTestEnvironment("testenv%s" % port, port, baseurl) | 
|---|
| [16] | 175 |  | 
|---|
 | 176 |         # Configure mergebot | 
|---|
 | 177 |         env = self._testenv.get_trac_environment() | 
|---|
 | 178 |         env.config.set('components', 'mergebot.web_ui.mergebotmodule', 'enabled') | 
|---|
| [40] | 179 |         env.config.save() | 
|---|
| [44] | 180 |         os.mkdir(os.path.join("testenv%s" % port, 'trac', 'mergebot')) | 
|---|
| [40] | 181 |         self._testenv._tracadmin('upgrade') # sets up the bulk of the mergebot config | 
|---|
 | 182 |         env.config.parse_if_needed() | 
|---|
| [16] | 183 |         env.config.set('mergebot', 'repository_url', self._testenv.repo_url()) | 
|---|
 | 184 |         env.config.set('logging', 'log_type', 'file') | 
|---|
 | 185 |         env.config.save() | 
|---|
 | 186 |         env.config.parse_if_needed() | 
|---|
 | 187 |  | 
|---|
 | 188 |         self._testenv.start() | 
|---|
| [44] | 189 |         self._tester = MergeBotFunctionalTester(baseurl, self._testenv.repo_url()) | 
|---|
| [47] | 190 |         os.system('mergebotdaemon -f "%s" > %s/mergebotdaemon.log 2>&1 &' % (self._testenv.tracdir, self._testenv.tracdir)) | 
|---|
| [40] | 191 |         self.fixture = (self._testenv, self._tester) | 
|---|
| [16] | 192 |  | 
|---|
 | 193 |         # Setup some common component stuff for MergeBot's use: | 
|---|
 | 194 |         svnurl = self._testenv.repo_url() | 
|---|
 | 195 |         for component in ['stuff', 'flagship', 'submarine']: | 
|---|
 | 196 |             self._tester.create_component(component) | 
|---|
 | 197 |             if call(['svn', '-m', 'Create tree for "%s".' % component, 'mkdir', | 
|---|
 | 198 |                      svnurl + '/' + component, | 
|---|
 | 199 |                      svnurl + '/' + component + '/trunk', | 
|---|
 | 200 |                      svnurl + '/' + component + '/tags', | 
|---|
 | 201 |                      svnurl + '/' + component + '/branches'], | 
|---|
 | 202 |                     stdout=logfile, stderr=logfile): | 
|---|
 | 203 |                 raise Exception("svn mkdir failed") | 
|---|
 | 204 |  | 
|---|
 | 205 |         self._tester.create_version('trunk') | 
|---|
 | 206 |  | 
|---|
 | 207 |  | 
|---|
| [51] | 208 | class FunctionalSvnTestCaseSetup(FunctionalTwillTestCaseSetup): | 
|---|
 | 209 |     def get_workdir(self): | 
|---|
 | 210 |         return os.path.join(self._testenv.dirname, self.__class__.__name__) | 
|---|
 | 211 |  | 
|---|
 | 212 |     def checkout(self, ticket_id=None): | 
|---|
 | 213 |         """checkout a working copy of the branch for the given ticket, or trunk if none given""" | 
|---|
 | 214 |         if ticket_id is None: | 
|---|
 | 215 |             svnurl = self._testenv.repo_url() + '/stuff/trunk' | 
|---|
 | 216 |         else: | 
|---|
 | 217 |             svnurl = self._testenv.repo_url() + '/stuff/branches/ticket-%s' % ticket_id | 
|---|
 | 218 |         retval = call(['svn', 'checkout', svnurl, self.get_workdir()], | 
|---|
 | 219 |             stdout=logfile, stderr=logfile) | 
|---|
 | 220 |         self.assertEqual(retval, 0, "svn checkout failed with error %s" % (retval)) | 
|---|
 | 221 |  | 
|---|
| [64] | 222 |     def cleanup(self): | 
|---|
 | 223 |         shutil.rmtree(self.get_workdir()) | 
|---|
 | 224 |  | 
|---|
| [51] | 225 |     def switch(self, ticket_id=None): | 
|---|
 | 226 |         if ticket_id is None: | 
|---|
 | 227 |             svnurl = self._testenv.repo_url() + '/stuff/trunk' | 
|---|
 | 228 |         else: | 
|---|
 | 229 |             svnurl = self._testenv.repo_url() + '/stuff/branches/ticket-%s' % ticket_id | 
|---|
 | 230 |         retval = call(['svn', 'switch', svnurl, self.get_workdir()], | 
|---|
 | 231 |             stdout=logfile, stderr=logfile) | 
|---|
 | 232 |         self.assertEqual(retval, 0, "svn checkout failed with error %s" % (retval)) | 
|---|
 | 233 |  | 
|---|
 | 234 |     def add_new_file(self, filename=None): | 
|---|
 | 235 |         workdir = self.get_workdir() | 
|---|
 | 236 |         if filename is None: | 
|---|
 | 237 |             newfile = os.path.join(workdir, self.__class__.__name__) | 
|---|
 | 238 |         else: | 
|---|
 | 239 |             newfile = os.path.join(workdir, filename) | 
|---|
 | 240 |         open(newfile, 'w').write(random_page()) | 
|---|
 | 241 |         retval = call(['svn', 'add', newfile], | 
|---|
 | 242 |             cwd=workdir, | 
|---|
 | 243 |             stdout=logfile, stderr=logfile) | 
|---|
 | 244 |         self.assertEqual(retval, 0, "svn add failed with error %s" % (retval)) | 
|---|
 | 245 |  | 
|---|
 | 246 |     def commit(self, message, files=None): | 
|---|
 | 247 |         if files is None: | 
|---|
 | 248 |             files = ['.'] | 
|---|
| [54] | 249 |         commit_message = self.__class__.__name__ + ": " + message | 
|---|
 | 250 |         retval = call(['svn', 'commit', '-m', commit_message] + list(files), | 
|---|
| [51] | 251 |             cwd=self.get_workdir(), | 
|---|
 | 252 |             stdout=logfile, stderr=logfile) | 
|---|
 | 253 |         self.assertEqual(retval, 0, "svn commit failed with error %s" % (retval)) | 
|---|
 | 254 |  | 
|---|
| [57] | 255 |     def mv(self, oldname, newname): | 
|---|
 | 256 |         retval = call(['svn', 'mv', oldname, newname], | 
|---|
 | 257 |             cwd=self.get_workdir(), | 
|---|
 | 258 |             stdout=logfile, stderr=logfile) | 
|---|
 | 259 |         self.assertEqual(retval, 0, "svn mv failed with error %s" % (retval)) | 
|---|
| [51] | 260 |  | 
|---|
| [62] | 261 |     def propset(self, propname, propvalue, filename): | 
|---|
 | 262 |         retval = call(['svn', 'propset', propname, propvalue, filename], | 
|---|
 | 263 |             cwd=self.get_workdir(), | 
|---|
 | 264 |             stdout=logfile, stderr=logfile) | 
|---|
 | 265 |         self.assertEqual(retval, 0, "svn prposet failed with error %s" % (retval)) | 
|---|
 | 266 |          | 
|---|
| [63] | 267 |     def propdel(self, propname, filename): | 
|---|
 | 268 |         retval = call(['svn', 'propdel', propname, filename], | 
|---|
 | 269 |             cwd=self.get_workdir(), | 
|---|
 | 270 |             stdout=logfile, stderr=logfile) | 
|---|
 | 271 |         self.assertEqual(retval, 0, "svn prposet failed with error %s" % (retval)) | 
|---|
| [57] | 272 |  | 
|---|
| [62] | 273 |  | 
|---|
| [17] | 274 | class MergeBotTestEnabled(FunctionalTwillTestCaseSetup): | 
|---|
| [16] | 275 |     def runTest(self): | 
|---|
 | 276 |         self._tester.logout() | 
|---|
 | 277 |         tc.go(self._tester.url) | 
|---|
 | 278 |         self._tester.login('admin') | 
|---|
 | 279 |         tc.follow('MergeBot') | 
|---|
 | 280 |         mergeboturl = self._tester.url + '/mergebot' | 
|---|
 | 281 |         tc.url(mergeboturl) | 
|---|
 | 282 |         tc.notfind('No handler matched request to /mergebot') | 
|---|
 | 283 |  | 
|---|
 | 284 |  | 
|---|
| [17] | 285 | class MergeBotTestNoVersion(FunctionalTwillTestCaseSetup): | 
|---|
| [16] | 286 |     """Verify that if a ticket does not have the version field set, it will not | 
|---|
 | 287 |     appear in the MergeBot list. | 
|---|
 | 288 |     """ | 
|---|
 | 289 |     def runTest(self): | 
|---|
 | 290 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 291 |             info={'component':'stuff', 'version':''}) | 
|---|
 | 292 |         tc.follow('MergeBot') | 
|---|
 | 293 |         tc.notfind(self.__class__.__name__) | 
|---|
 | 294 |  | 
|---|
 | 295 |  | 
|---|
| [17] | 296 | class MergeBotTestBranch(FunctionalTwillTestCaseSetup): | 
|---|
| [16] | 297 |     def runTest(self): | 
|---|
 | 298 |         """Verify that the 'branch' button works""" | 
|---|
 | 299 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 300 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 301 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 302 |  | 
|---|
 | 303 |  | 
|---|
| [17] | 304 | class MergeBotTestRebranch(FunctionalTwillTestCaseSetup): | 
|---|
| [16] | 305 |     def runTest(self): | 
|---|
 | 306 |         """Verify that the 'rebranch' button works""" | 
|---|
 | 307 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 308 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 309 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 310 |         self._tester.rebranch(ticket_id, 'stuff') | 
|---|
 | 311 |  | 
|---|
 | 312 |  | 
|---|
| [17] | 313 | class MergeBotTestMerge(FunctionalTwillTestCaseSetup): | 
|---|
| [16] | 314 |     def runTest(self): | 
|---|
 | 315 |         """Verify that the 'merge' button works""" | 
|---|
 | 316 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 317 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 318 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 319 |         self._tester.merge(ticket_id, 'stuff') | 
|---|
 | 320 |  | 
|---|
 | 321 |  | 
|---|
| [59] | 322 | class MergeBotTestMergeWithChange(FunctionalSvnTestCaseSetup): | 
|---|
 | 323 |     def runTest(self): | 
|---|
 | 324 |         """Verify that the 'merge' button works with changes on the branch""" | 
|---|
 | 325 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 326 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 327 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 328 |  | 
|---|
 | 329 |         # checkout a working copy & make a change | 
|---|
 | 330 |         self.checkout(ticket_id) | 
|---|
 | 331 |         # Create & add a new file | 
|---|
 | 332 |         self.add_new_file() | 
|---|
 | 333 |         self.commit('Add a new file') | 
|---|
 | 334 |  | 
|---|
 | 335 |         self._tester.merge(ticket_id, 'stuff') | 
|---|
 | 336 |  | 
|---|
| [64] | 337 |         self.cleanup() | 
|---|
| [59] | 338 |  | 
|---|
 | 339 | class MergeBotTestMergeWithChangeAndTrunkChange(FunctionalSvnTestCaseSetup): | 
|---|
 | 340 |     def runTest(self): | 
|---|
 | 341 |         """Verify that the 'merge' button works with changes on the branch and trunk""" | 
|---|
 | 342 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 343 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 344 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 345 |  | 
|---|
 | 346 |         # checkout a working copy & make a change | 
|---|
 | 347 |         self.checkout(ticket_id) | 
|---|
 | 348 |         # Create & add a new file | 
|---|
 | 349 |         basename = self.__class__.__name__ | 
|---|
 | 350 |         self.add_new_file(basename + '-ticket') | 
|---|
 | 351 |         self.commit('Add a new file on ticket') | 
|---|
 | 352 |         self.switch() | 
|---|
 | 353 |         self.add_new_file(basename + '-trunk') | 
|---|
 | 354 |         self.commit('Add a new file on trunk') | 
|---|
 | 355 |  | 
|---|
 | 356 |         self._tester.merge(ticket_id, 'stuff') | 
|---|
| [65] | 357 |         self.cleanup() | 
|---|
| [59] | 358 |  | 
|---|
 | 359 |  | 
|---|
 | 360 | class MergeBotTestMergeWithConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 361 |     def runTest(self): | 
|---|
 | 362 |         """Verify that the 'merge' button detects conflicts between the branch and trunk""" | 
|---|
 | 363 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 364 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 365 |         basename = self.__class__.__name__ | 
|---|
 | 366 |  | 
|---|
 | 367 |         # create a file in which to have conflicts | 
|---|
 | 368 |         self.checkout() | 
|---|
 | 369 |         self.add_new_file(basename) | 
|---|
 | 370 |         self.commit('Add a new file on trunk') | 
|---|
 | 371 |  | 
|---|
 | 372 |         # create the branch | 
|---|
 | 373 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 374 |  | 
|---|
 | 375 |         # modify the file on trunk | 
|---|
 | 376 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 377 |         self.commit('Modify the file on trunk') | 
|---|
 | 378 |  | 
|---|
 | 379 |         # modify the file on the branch | 
|---|
 | 380 |         self.switch(ticket_id) | 
|---|
 | 381 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 382 |         self.commit('Modify the file on branch') | 
|---|
 | 383 |  | 
|---|
 | 384 |         # merge, make sure it shows a conflict | 
|---|
 | 385 |         self._tester.merge_conflict(ticket_id, 'stuff') | 
|---|
 | 386 |  | 
|---|
| [64] | 387 |         self.cleanup() | 
|---|
| [59] | 388 |  | 
|---|
| [64] | 389 |  | 
|---|
| [62] | 390 | class MergeBotTestMergeWithPropertyConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 391 |     def runTest(self): | 
|---|
 | 392 |         """Verify that the 'merge' button detects property conflicts between the branch and trunk""" | 
|---|
 | 393 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 394 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 395 |         basename = self.__class__.__name__ | 
|---|
 | 396 |  | 
|---|
 | 397 |         self.checkout() | 
|---|
 | 398 |         self.propset('svn:ignore', basename, '.') | 
|---|
 | 399 |         self.commit('set property on trunk') | 
|---|
 | 400 |  | 
|---|
 | 401 |         # create the branch | 
|---|
 | 402 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 403 |  | 
|---|
 | 404 |         # modify the property on trunk | 
|---|
 | 405 |         self.propset('svn:ignore', basename + '\ntrunk', '.') | 
|---|
 | 406 |         self.commit('Modify the property on trunk') | 
|---|
 | 407 |  | 
|---|
 | 408 |         # modify the property on the branch | 
|---|
 | 409 |         self.switch(ticket_id) | 
|---|
 | 410 |         self.propset('svn:ignore', basename + '\nbranch', '.') | 
|---|
 | 411 |         self.commit('Modify the property on branch') | 
|---|
 | 412 |  | 
|---|
 | 413 |         # merge, make sure it shows a conflict | 
|---|
 | 414 |         self._tester.merge_conflict(ticket_id, 'stuff') | 
|---|
 | 415 |  | 
|---|
| [64] | 416 |         self.cleanup() | 
|---|
| [62] | 417 |  | 
|---|
| [64] | 418 |  | 
|---|
| [63] | 419 | class MergeBotTestMergeWithPropertyBranchDeleteConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 420 |     def runTest(self): | 
|---|
 | 421 |         """Verify that the 'merge' button detects property deleted on branch and modified on trunk""" | 
|---|
 | 422 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 423 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 424 |         basename = self.__class__.__name__ | 
|---|
 | 425 |  | 
|---|
 | 426 |         self.checkout() | 
|---|
 | 427 |         self.propset('svn:ignore', basename, '.') | 
|---|
 | 428 |         self.commit('set property on trunk') | 
|---|
 | 429 |  | 
|---|
 | 430 |         # create the branch | 
|---|
 | 431 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 432 |  | 
|---|
 | 433 |         # modify the property on trunk | 
|---|
 | 434 |         self.propset('svn:ignore', basename + '\ntrunk', '.') | 
|---|
 | 435 |         self.commit('Modify the property on trunk') | 
|---|
 | 436 |  | 
|---|
 | 437 |         # delete the property on the branch | 
|---|
 | 438 |         self.switch(ticket_id) | 
|---|
 | 439 |         self.propdel('svn:ignore', '.') | 
|---|
 | 440 |         self.commit('Delete the property on branch') | 
|---|
 | 441 |  | 
|---|
 | 442 |         # merge, make sure it shows a conflict | 
|---|
 | 443 |         self._tester.merge_conflict(ticket_id, 'stuff') | 
|---|
 | 444 |  | 
|---|
| [64] | 445 |         self.cleanup() | 
|---|
| [63] | 446 |  | 
|---|
| [64] | 447 |  | 
|---|
| [63] | 448 | class MergeBotTestMergeWithPropertyTrunkDeleteConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 449 |     def runTest(self): | 
|---|
 | 450 |         """Verify that the 'merge' button detects property deleted on trunk and modified on branch""" | 
|---|
 | 451 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 452 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 453 |         basename = self.__class__.__name__ | 
|---|
 | 454 |  | 
|---|
 | 455 |         self.checkout() | 
|---|
 | 456 |         self.propset('svn:ignore', basename, '.') | 
|---|
 | 457 |         self.commit('set property on trunk') | 
|---|
 | 458 |  | 
|---|
 | 459 |         # create the branch | 
|---|
 | 460 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 461 |  | 
|---|
 | 462 |         # delete the property on trunk | 
|---|
 | 463 |         self.propdel('svn:ignore', '.') | 
|---|
 | 464 |         self.commit('Delete the property on trunk') | 
|---|
 | 465 |  | 
|---|
 | 466 |         # delete the property on the branch | 
|---|
 | 467 |         self.switch(ticket_id) | 
|---|
 | 468 |         self.propset('svn:ignore', basename + '\nbranch', '.') | 
|---|
 | 469 |         self.commit('Modify the property on branch') | 
|---|
 | 470 |  | 
|---|
 | 471 |         # merge, make sure it shows a conflict | 
|---|
 | 472 |         self._tester.merge_conflict(ticket_id, 'stuff') | 
|---|
 | 473 |  | 
|---|
| [64] | 474 |         self.cleanup() | 
|---|
| [63] | 475 |  | 
|---|
| [64] | 476 |  | 
|---|
| [59] | 477 | class MergeBotTestMergeWithBranchRenameConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 478 |     def runTest(self): | 
|---|
 | 479 |         """Verify that the 'merge' button detects a conflict when a file renamed on the branch was modified on trunk""" | 
|---|
 | 480 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 481 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 482 |         basename = self.__class__.__name__ | 
|---|
 | 483 |  | 
|---|
 | 484 |         # create a file in which to have conflicts | 
|---|
 | 485 |         self.checkout() | 
|---|
 | 486 |         self.add_new_file(basename) | 
|---|
 | 487 |         self.commit('Add a new file on trunk') | 
|---|
 | 488 |  | 
|---|
 | 489 |         # create the branch | 
|---|
 | 490 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 491 |  | 
|---|
 | 492 |         # modify the file on trunk | 
|---|
 | 493 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 494 |         self.commit('Modify the file on trunk') | 
|---|
 | 495 |  | 
|---|
 | 496 |         # rename the file on the branch | 
|---|
 | 497 |         self.switch(ticket_id) | 
|---|
 | 498 |         self.mv(basename, basename + '-renamed') | 
|---|
 | 499 |         self.commit('Rename the file on the branch') | 
|---|
 | 500 |  | 
|---|
 | 501 |         self._tester.merge_conflict(ticket_id, 'stuff') | 
|---|
 | 502 |  | 
|---|
| [64] | 503 |         self.cleanup() | 
|---|
| [59] | 504 |  | 
|---|
| [64] | 505 |  | 
|---|
| [59] | 506 | class MergeBotTestMergeWithTrunkRenameConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 507 |     def runTest(self): | 
|---|
 | 508 |         """Verify that the 'merge' button detects conflicts when a file renamed on trunk was modified on the branch""" | 
|---|
 | 509 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 510 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 511 |         basename = self.__class__.__name__ | 
|---|
 | 512 |  | 
|---|
 | 513 |         # create a file in which to have conflicts | 
|---|
 | 514 |         self.checkout() | 
|---|
 | 515 |         self.add_new_file(basename) | 
|---|
 | 516 |         self.commit('Add a new file on trunk') | 
|---|
 | 517 |  | 
|---|
 | 518 |         # create the branch | 
|---|
 | 519 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 520 |  | 
|---|
 | 521 |         # rename the file on trunk | 
|---|
 | 522 |         self.mv(basename, basename + '-renamed') | 
|---|
 | 523 |         self.commit('Rename the file on trunk') | 
|---|
 | 524 |  | 
|---|
 | 525 |         # rename the file on the branch | 
|---|
 | 526 |         self.switch(ticket_id) | 
|---|
 | 527 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 528 |         self.commit('Modify the file on the branch') | 
|---|
 | 529 |  | 
|---|
 | 530 |         # make sure it finds the conflict | 
|---|
 | 531 |         self._tester.merge_conflict(ticket_id, 'stuff') | 
|---|
 | 532 |  | 
|---|
| [64] | 533 |         self.cleanup() | 
|---|
| [59] | 534 |  | 
|---|
| [64] | 535 |  | 
|---|
| [17] | 536 | class MergeBotTestCheckMerge(FunctionalTwillTestCaseSetup): | 
|---|
| [16] | 537 |     def runTest(self): | 
|---|
 | 538 |         """Verify that the 'checkmerge' button works""" | 
|---|
 | 539 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 540 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 541 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 542 |         self._tester.checkmerge(ticket_id, 'stuff') | 
|---|
 | 543 |  | 
|---|
 | 544 |  | 
|---|
| [51] | 545 | class MergeBotTestRebranchWithChange(FunctionalSvnTestCaseSetup): | 
|---|
| [46] | 546 |     def runTest(self): | 
|---|
 | 547 |         """Verify that the 'rebranch' button works with changes on the branch""" | 
|---|
 | 548 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 549 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 550 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 551 |  | 
|---|
 | 552 |         # checkout a working copy & make a change | 
|---|
| [51] | 553 |         self.checkout(ticket_id) | 
|---|
| [46] | 554 |         # Create & add a new file | 
|---|
| [51] | 555 |         self.add_new_file() | 
|---|
 | 556 |         self.commit('Add a new file') | 
|---|
| [46] | 557 |  | 
|---|
 | 558 |         self._tester.rebranch(ticket_id, 'stuff') | 
|---|
| [64] | 559 |         self.cleanup() | 
|---|
| [46] | 560 |  | 
|---|
 | 561 |  | 
|---|
| [51] | 562 | class MergeBotTestRebranchWithChangeAndTrunkChange(FunctionalSvnTestCaseSetup): | 
|---|
 | 563 |     def runTest(self): | 
|---|
| [52] | 564 |         """Verify that the 'rebranch' button works with changes on the branch and trunk""" | 
|---|
| [51] | 565 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 566 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 567 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 568 |  | 
|---|
 | 569 |         # checkout a working copy & make a change | 
|---|
 | 570 |         self.checkout(ticket_id) | 
|---|
 | 571 |         # Create & add a new file | 
|---|
 | 572 |         basename = self.__class__.__name__ | 
|---|
 | 573 |         self.add_new_file(basename + '-ticket') | 
|---|
 | 574 |         self.commit('Add a new file on ticket') | 
|---|
 | 575 |         self.switch() | 
|---|
 | 576 |         self.add_new_file(basename + '-trunk') | 
|---|
 | 577 |         self.commit('Add a new file on trunk') | 
|---|
 | 578 |  | 
|---|
 | 579 |         self._tester.rebranch(ticket_id, 'stuff') | 
|---|
| [64] | 580 |         self.cleanup() | 
|---|
| [51] | 581 |  | 
|---|
 | 582 |  | 
|---|
| [54] | 583 | class MergeBotTestRebranchWithConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 584 |     def runTest(self): | 
|---|
| [59] | 585 |         """Verify that the 'rebranch' button detects conflicts between the branch and trunk""" | 
|---|
| [54] | 586 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 587 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 588 |         basename = self.__class__.__name__ | 
|---|
 | 589 |  | 
|---|
 | 590 |         # create a file in which to have conflicts | 
|---|
 | 591 |         self.checkout() | 
|---|
 | 592 |         self.add_new_file(basename) | 
|---|
 | 593 |         self.commit('Add a new file on trunk') | 
|---|
 | 594 |  | 
|---|
 | 595 |         # create the branch | 
|---|
 | 596 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 597 |  | 
|---|
 | 598 |         # modify the file on trunk | 
|---|
 | 599 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 600 |         self.commit('Modify the file on trunk') | 
|---|
 | 601 |  | 
|---|
 | 602 |         # modify the file on the branch | 
|---|
 | 603 |         self.switch(ticket_id) | 
|---|
 | 604 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 605 |         self.commit('Modify the file on branch') | 
|---|
 | 606 |  | 
|---|
| [57] | 607 |         # rebranch, make sure it shows a conflict | 
|---|
 | 608 |         self._tester.rebranch_conflict(ticket_id, 'stuff') | 
|---|
| [54] | 609 |  | 
|---|
| [64] | 610 |         self.cleanup() | 
|---|
| [54] | 611 |  | 
|---|
| [64] | 612 |  | 
|---|
| [62] | 613 | class MergeBotTestRebranchWithPropertyConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 614 |     def runTest(self): | 
|---|
 | 615 |         """Verify that the 'rebranch' button detects property conflicts between the branch and trunk""" | 
|---|
 | 616 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 617 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 618 |         basename = self.__class__.__name__ | 
|---|
 | 619 |  | 
|---|
 | 620 |         self.checkout() | 
|---|
 | 621 |         self.propset('svn:ignore', basename, '.') | 
|---|
 | 622 |         self.commit('set property on trunk') | 
|---|
 | 623 |  | 
|---|
 | 624 |         # create the branch | 
|---|
 | 625 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 626 |  | 
|---|
 | 627 |         # modify the property on trunk | 
|---|
 | 628 |         self.propset('svn:ignore', basename + '\ntrunk', '.') | 
|---|
 | 629 |         self.commit('Modify the property on trunk') | 
|---|
 | 630 |  | 
|---|
 | 631 |         # modify the property on the branch | 
|---|
 | 632 |         self.switch(ticket_id) | 
|---|
 | 633 |         self.propset('svn:ignore', basename + '\nbranch', '.') | 
|---|
 | 634 |         self.commit('Modify the property on branch') | 
|---|
 | 635 |  | 
|---|
 | 636 |         # rebranch, make sure it shows a conflict | 
|---|
 | 637 |         self._tester.rebranch_conflict(ticket_id, 'stuff') | 
|---|
 | 638 |  | 
|---|
| [64] | 639 |         self.cleanup() | 
|---|
| [62] | 640 |  | 
|---|
| [64] | 641 |  | 
|---|
| [63] | 642 | class MergeBotTestRebranchWithPropertyBranchDeleteConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 643 |     def runTest(self): | 
|---|
 | 644 |         """Verify that the 'rebranch' button detects property deleted on branch and modified on trunk""" | 
|---|
 | 645 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 646 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 647 |         basename = self.__class__.__name__ | 
|---|
 | 648 |  | 
|---|
 | 649 |         self.checkout() | 
|---|
 | 650 |         self.propset('svn:ignore', basename, '.') | 
|---|
 | 651 |         self.commit('set property on trunk') | 
|---|
 | 652 |  | 
|---|
 | 653 |         # create the branch | 
|---|
 | 654 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 655 |  | 
|---|
 | 656 |         # modify the property on trunk | 
|---|
 | 657 |         self.propset('svn:ignore', basename + '\ntrunk', '.') | 
|---|
 | 658 |         self.commit('Modify the property on trunk') | 
|---|
 | 659 |  | 
|---|
 | 660 |         # delete the property on the branch | 
|---|
 | 661 |         self.switch(ticket_id) | 
|---|
 | 662 |         self.propdel('svn:ignore', '.') | 
|---|
 | 663 |         self.commit('Delete the property on branch') | 
|---|
 | 664 |  | 
|---|
 | 665 |         # rebranch, make sure it shows a conflict | 
|---|
 | 666 |         self._tester.rebranch_conflict(ticket_id, 'stuff') | 
|---|
 | 667 |  | 
|---|
| [64] | 668 |         self.cleanup() | 
|---|
| [63] | 669 |  | 
|---|
| [64] | 670 |  | 
|---|
| [63] | 671 | class MergeBotTestRebranchWithPropertyTrunkDeleteConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 672 |     def runTest(self): | 
|---|
 | 673 |         """Verify that the 'rebranch' button detects property deleted on trunk and modified on branch""" | 
|---|
 | 674 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 675 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 676 |         basename = self.__class__.__name__ | 
|---|
 | 677 |  | 
|---|
 | 678 |         self.checkout() | 
|---|
 | 679 |         self.propset('svn:ignore', basename, '.') | 
|---|
 | 680 |         self.commit('set property on trunk') | 
|---|
 | 681 |  | 
|---|
 | 682 |         # create the branch | 
|---|
 | 683 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 684 |  | 
|---|
 | 685 |         # delete the property on trunk | 
|---|
 | 686 |         self.propdel('svn:ignore', '.') | 
|---|
 | 687 |         self.commit('Delete the property on trunk') | 
|---|
 | 688 |  | 
|---|
 | 689 |         # delete the property on the branch | 
|---|
 | 690 |         self.switch(ticket_id) | 
|---|
 | 691 |         self.propset('svn:ignore', basename + '\nbranch', '.') | 
|---|
 | 692 |         self.commit('Modify the property on branch') | 
|---|
 | 693 |  | 
|---|
 | 694 |         # rebranch, make sure it shows a conflict | 
|---|
 | 695 |         self._tester.rebranch_conflict(ticket_id, 'stuff') | 
|---|
 | 696 |  | 
|---|
| [64] | 697 |         self.cleanup() | 
|---|
| [63] | 698 |  | 
|---|
| [64] | 699 |  | 
|---|
| [57] | 700 | class MergeBotTestRebranchWithBranchRenameConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 701 |     def runTest(self): | 
|---|
| [59] | 702 |         """Verify that the 'rebranch' button detects a conflict when a file renamed on the branch was modified on trunk""" | 
|---|
| [57] | 703 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 704 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 705 |         basename = self.__class__.__name__ | 
|---|
 | 706 |  | 
|---|
 | 707 |         # create a file in which to have conflicts | 
|---|
 | 708 |         self.checkout() | 
|---|
 | 709 |         self.add_new_file(basename) | 
|---|
 | 710 |         self.commit('Add a new file on trunk') | 
|---|
 | 711 |  | 
|---|
 | 712 |         # create the branch | 
|---|
 | 713 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 714 |  | 
|---|
 | 715 |         # modify the file on trunk | 
|---|
 | 716 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 717 |         self.commit('Modify the file on trunk') | 
|---|
 | 718 |  | 
|---|
 | 719 |         # rename the file on the branch | 
|---|
 | 720 |         self.switch(ticket_id) | 
|---|
 | 721 |         self.mv(basename, basename + '-renamed') | 
|---|
| [58] | 722 |         self.commit('Rename the file on the branch') | 
|---|
| [57] | 723 |  | 
|---|
 | 724 |         self._tester.rebranch_conflict(ticket_id, 'stuff') | 
|---|
 | 725 |  | 
|---|
| [64] | 726 |         self.cleanup() | 
|---|
| [57] | 727 |  | 
|---|
| [64] | 728 |  | 
|---|
| [58] | 729 | class MergeBotTestRebranchWithTrunkRenameConflict(FunctionalSvnTestCaseSetup): | 
|---|
 | 730 |     def runTest(self): | 
|---|
| [59] | 731 |         """Verify that the 'rebranch' button detects conflicts when a file renamed on trunk was modified on the branch""" | 
|---|
| [58] | 732 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 733 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 734 |         basename = self.__class__.__name__ | 
|---|
 | 735 |  | 
|---|
 | 736 |         # create a file in which to have conflicts | 
|---|
 | 737 |         self.checkout() | 
|---|
 | 738 |         self.add_new_file(basename) | 
|---|
 | 739 |         self.commit('Add a new file on trunk') | 
|---|
 | 740 |  | 
|---|
 | 741 |         # create the branch | 
|---|
 | 742 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 743 |  | 
|---|
 | 744 |         # rename the file on trunk | 
|---|
 | 745 |         self.mv(basename, basename + '-renamed') | 
|---|
 | 746 |         self.commit('Rename the file on trunk') | 
|---|
 | 747 |  | 
|---|
 | 748 |         # rename the file on the branch | 
|---|
 | 749 |         self.switch(ticket_id) | 
|---|
 | 750 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 751 |         self.commit('Modify the file on the branch') | 
|---|
 | 752 |  | 
|---|
 | 753 |         # make sure it finds the conflict | 
|---|
 | 754 |         self._tester.rebranch_conflict(ticket_id, 'stuff') | 
|---|
 | 755 |  | 
|---|
| [64] | 756 |         self.cleanup() | 
|---|
| [58] | 757 |  | 
|---|
| [64] | 758 |  | 
|---|
 | 759 | class MergeBotTestSingleUseCase(FunctionalSvnTestCaseSetup): | 
|---|
| [16] | 760 |     def runTest(self): | 
|---|
 | 761 |         """Create a branch, make a change, checkmerge, and merge it.""" | 
|---|
 | 762 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 763 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 764 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 765 |         # checkout a working copy & make a change | 
|---|
| [64] | 766 |         self.checkout(ticket_id) | 
|---|
| [16] | 767 |         # Create & add a new file | 
|---|
| [64] | 768 |         self.add_new_file() | 
|---|
 | 769 |         self.commit('Add a new file') | 
|---|
| [16] | 770 |         self._tester.checkmerge(ticket_id, 'stuff') | 
|---|
 | 771 |         self._tester.merge(ticket_id, 'stuff') | 
|---|
| [64] | 772 |         self.cleanup() | 
|---|
| [16] | 773 |  | 
|---|
 | 774 |  | 
|---|
| [64] | 775 | class MergeBotTestBranchReuse(FunctionalSvnTestCaseSetup): | 
|---|
 | 776 |     def runTest(self): | 
|---|
 | 777 |         """Merge a branch, branch it again, and merge it a second time.""" | 
|---|
 | 778 |         ticket_id = self._tester.create_ticket(summary=self.__class__.__name__, | 
|---|
 | 779 |             info={'component':'stuff', 'version':'trunk'}) | 
|---|
 | 780 |         basename = self.__class__.__name__ | 
|---|
| [16] | 781 |  | 
|---|
| [64] | 782 |         self.checkout() | 
|---|
 | 783 |         self.add_new_file(basename) | 
|---|
 | 784 |         self.commit('Add a new file') | 
|---|
 | 785 |  | 
|---|
 | 786 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 787 |         self.switch(ticket_id) | 
|---|
 | 788 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 789 |         self.commit('Make a modification') | 
|---|
 | 790 |         self._tester.merge(ticket_id, 'stuff') | 
|---|
 | 791 |  | 
|---|
 | 792 |         self._tester.branch(ticket_id, 'stuff') | 
|---|
 | 793 |         self.switch(ticket_id) | 
|---|
 | 794 |         open(os.path.join(self.get_workdir(), basename), 'a').write(random_sentence()) | 
|---|
 | 795 |         self.commit('Make a second modification') | 
|---|
 | 796 |         self._tester.merge(ticket_id, 'stuff') | 
|---|
 | 797 |         self.cleanup() | 
|---|
 | 798 |  | 
|---|
 | 799 |  | 
|---|
| [16] | 800 | def suite(): | 
|---|
 | 801 |     suite = MergeBotTestSuite() | 
|---|
 | 802 |     suite.addTest(MergeBotTestEnabled()) | 
|---|
 | 803 |     suite.addTest(MergeBotTestNoVersion()) | 
|---|
 | 804 |     suite.addTest(MergeBotTestBranch()) | 
|---|
| [45] | 805 |     suite.addTest(MergeBotTestRebranch()) | 
|---|
| [16] | 806 |     suite.addTest(MergeBotTestCheckMerge()) | 
|---|
| [45] | 807 |     suite.addTest(MergeBotTestMerge()) | 
|---|
| [46] | 808 |     suite.addTest(MergeBotTestRebranchWithChange()) | 
|---|
| [51] | 809 |     suite.addTest(MergeBotTestRebranchWithChangeAndTrunkChange()) | 
|---|
| [54] | 810 |     suite.addTest(MergeBotTestRebranchWithConflict()) | 
|---|
| [62] | 811 |     suite.addTest(MergeBotTestRebranchWithPropertyConflict()) | 
|---|
| [57] | 812 |     suite.addTest(MergeBotTestRebranchWithBranchRenameConflict()) | 
|---|
| [58] | 813 |     suite.addTest(MergeBotTestRebranchWithTrunkRenameConflict()) | 
|---|
| [63] | 814 |     suite.addTest(MergeBotTestRebranchWithPropertyBranchDeleteConflict()) | 
|---|
 | 815 |     suite.addTest(MergeBotTestRebranchWithPropertyTrunkDeleteConflict()) | 
|---|
| [59] | 816 |     suite.addTest(MergeBotTestMergeWithChange()) | 
|---|
 | 817 |     suite.addTest(MergeBotTestMergeWithChangeAndTrunkChange()) | 
|---|
 | 818 |     suite.addTest(MergeBotTestMergeWithConflict()) | 
|---|
| [62] | 819 |     suite.addTest(MergeBotTestMergeWithPropertyConflict()) | 
|---|
| [59] | 820 |     suite.addTest(MergeBotTestMergeWithBranchRenameConflict()) | 
|---|
 | 821 |     suite.addTest(MergeBotTestMergeWithTrunkRenameConflict()) | 
|---|
| [63] | 822 |     suite.addTest(MergeBotTestMergeWithPropertyBranchDeleteConflict()) | 
|---|
 | 823 |     suite.addTest(MergeBotTestMergeWithPropertyTrunkDeleteConflict()) | 
|---|
| [16] | 824 |     suite.addTest(MergeBotTestSingleUseCase()) | 
|---|
| [64] | 825 |     suite.addTest(MergeBotTestBranchReuse()) | 
|---|
| [16] | 826 |     return suite | 
|---|
 | 827 |  | 
|---|
 | 828 | if __name__ == '__main__': | 
|---|
 | 829 |     unittest.main(defaultTest='suite') | 
|---|