Index: /mergebot/trunk/utils/test.py
===================================================================
--- /mergebot/trunk/utils/test.py	(revision 66)
+++ /mergebot/trunk/utils/test.py	(revision 67)
@@ -11,4 +11,5 @@
 # - verify inter-ticket dependency checking
 # - verify failure cascades through inter-ticket dependencies
+# - change the version of a ticket, rebranch, and merge
 
 import os
@@ -92,9 +93,12 @@
         tc.notfind('No handler matched request to /mergebot')
 
-    def branch(self, ticket_id, component, timeout=1):
-        """timeout is in seconds."""
+    def queue_branch(self, ticket_id):
         self.go_to_mergebot()
         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
         tc.submit('Branch')
+
+    def branch(self, ticket_id, component, timeout=1):
+        """timeout is in seconds."""
+        self.queue_branch(ticket_id)
         self.wait_until_find('Nothing in the queue', timeout)
         tc.find('Rebranch')
@@ -108,9 +112,12 @@
             raise Exception('svn ls failed with exit code %s' % retval)
 
-    def _rebranch(self, ticket_id, component, search, timeout=15):
-        """timeout is in seconds."""
+    def queue_rebranch(self, ticket_id):
         self.go_to_mergebot()
         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
         tc.submit('Rebranch')
+
+    def _rebranch(self, ticket_id, component, search, timeout=15):
+        """timeout is in seconds."""
+        self.queue_rebranch(ticket_id)
         self.wait_until_find('Nothing in the queue', timeout)
         tc.find('Rebranch')
@@ -130,15 +137,18 @@
         self._rebranch(ticket_id, component, 'There were conflicts on rebranching', timeout)
 
-    def merge(self, ticket_id, component, timeout=5):
-        self._merge(ticket_id, component, 'Merged .* to .* for', timeout)
-
-    def merge_conflict(self, ticket_id, component, timeout=5):
-        self._merge(ticket_id, component, 'Found [0-9]+ conflicts? in attempt to merge ', timeout)
-
-    def _merge(self, ticket_id, component, search, timeout=5):
-        """timeout is in seconds."""
+    def queue_merge(self, ticket_id):
         self.go_to_mergebot()
         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
         tc.submit('Merge')
+
+    def merge(self, ticket_id, component, timeout=5):
+        self._merge(ticket_id, component, 'Merged .* to .* for', timeout)
+
+    def merge_conflict(self, ticket_id, component, timeout=5):
+        self._merge(ticket_id, component, 'Found [0-9]+ conflicts? in attempt to merge ', timeout)
+
+    def _merge(self, ticket_id, component, search, timeout=5):
+        """timeout is in seconds."""
+        self.queue_merge(ticket_id)
         self.wait_until_find('Nothing in the queue', timeout)
         tc.find('Branch')
@@ -151,9 +161,12 @@
             raise Exception('svn ls failed with exit code %s' % retval)
 
-    def checkmerge(self, ticket_id, component, timeout=5):
-        """timeout is in seconds."""
+    def queue_checkmerge(self, ticket_id):
         self.go_to_mergebot()
         tc.formvalue('ops-%s' % ticket_id, 'ticket', ticket_id) # Essentially a noop to select the right form
         tc.submit('CheckMerge')
+
+    def checkmerge(self, ticket_id, component, timeout=5):
+        """timeout is in seconds."""
+        self.queue_checkmerge(ticket_id)
         self.wait_until_find('Nothing in the queue', timeout)
         tc.find('Rebranch')
@@ -166,4 +179,8 @@
         if retval:
             raise Exception('svn ls failed with exit code %s' % retval)
+
+    def wait_for_empty_queue(self, timeout=10):
+        self.go_to_mergebot()
+        self.wait_until_find('Nothing in the queue', timeout)
 
 
@@ -232,5 +249,5 @@
         self.assertEqual(retval, 0, "svn checkout failed with error %s" % (retval))
 
-    def add_new_file(self, filename=None):
+    def add_new_file(self, filename=None, file_size=None):
         workdir = self.get_workdir()
         if filename is None:
@@ -238,5 +255,12 @@
         else:
             newfile = os.path.join(workdir, filename)
-        open(newfile, 'w').write(random_page())
+        if file_size is None:
+            data = random_page()
+        else:
+            data = ''
+            while len(data) < file_size:
+                data += random_page()
+            data = data[:file_size]
+        open(newfile, 'w').write(data)
         retval = call(['svn', 'add', newfile],
             cwd=workdir,
@@ -337,4 +361,5 @@
         self.cleanup()
 
+
 class MergeBotTestMergeWithChangeAndTrunkChange(FunctionalSvnTestCaseSetup):
     def runTest(self):
@@ -795,4 +820,37 @@
         self.commit('Make a second modification')
         self._tester.merge(ticket_id, 'stuff')
+        self.cleanup()
+
+
+class MergeBotTestMergeDependency(FunctionalSvnTestCaseSetup):
+    def runTest(self):
+        """Merge two branches to trunk; make sure the second one shows as waiting"""
+        # This test is fundamentally racy.  The size of the files has been
+        # chosen to slow down the test long enough to get a view of the
+        # mergebot page with one of them waiting for the other to complete.
+        ticket_one = self._tester.create_ticket(summary=self.__class__.__name__ + " one",
+            info={'component':'stuff', 'version':'trunk'})
+        ticket_two = self._tester.create_ticket(summary=self.__class__.__name__ + " two",
+            info={'component':'stuff', 'version':'trunk'})
+        basename = self.__class__.__name__
+
+        self._tester.branch(ticket_one, 'stuff')
+        self._tester.branch(ticket_two, 'stuff')
+
+        self.checkout(ticket_one)
+        self.add_new_file(basename + '-one', 30*1024**2)
+        self.commit('Add a new file')
+
+        self.switch(ticket_two)
+        self.add_new_file(basename + '-two', 30*1024**2)
+        self.commit('Add a new file')
+
+        self._tester.queue_merge(ticket_two)
+        self._tester.queue_merge(ticket_one)
+
+        #self._tester.go_to_mergebot()
+        tc.find('Waiting')
+        self._tester.wait_for_empty_queue()
+        
         self.cleanup()
 
@@ -824,4 +882,5 @@
     suite.addTest(MergeBotTestSingleUseCase())
     suite.addTest(MergeBotTestBranchReuse())
+    suite.addTest(MergeBotTestMergeDependency())
     return suite
 
