On Thu, 2007-02-08 at 09:20 +0000, Marnie McCormack wrote:
> Hi Carl & Kim,
> 
> Are there any applicable JIRAs I can look at for pointers ?
> 
> Thanks,
> Marnie
> 
> 
> On 2/6/07, Carl Trieloff <[EMAIL PROTECTED]> wrote:
> >
> >
> > Quite a few issues where found in this area on the 0-9 branch. I might
> > be good to sync up with Kim on the
> > issues resolved on the 0-9 branch that have not been merged back to
> > trunk yet.
> >
> > Carl.
> >
> >
> > Marnie McCormack (JIRA) wrote:
> > > Message loss after rollback
> > > ---------------------------
> > >
> > >                  Key: QPID-346
> > >                  URL: https://issues.apache.org/jira/browse/QPID-346
> > >              Project: Qpid
> > >           Issue Type: Bug
> > >           Components: Java Client
> > >     Affects Versions: M1
> > >             Reporter: Marnie McCormack
> > >
> > >
> > > Rolling back a transaction after a message consume alwasy results in the
> > loss of a message
> > >
> > >
I am not certain whether this is directly related to your problem, but
here are the details:

I have found that there is a problem with rollback() on the trunk
(mirrored in the 0-9 branch, but solved there), and the following patch
to TransactedTest reveals the problem. Part of the changes in the patch
move the creation of messages A,B,C into the two (original) tests that
use them, as the later addition of the
testResendsMsgsAfterSessionClose() method does not use these, and leaves
them around for later tests to stumble across.

If you patch the test, and run

mvn -Dtest=TransactedTest test

then you will see the following:

Running org.apache.qpid.test.unit.transacted.TransactedTest
Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 8.639 sec <<< 
FAILURE!
testEmpty2(org.apache.qpid.test.unit.transacted.TransactedTest)  Time elapsed: 
1.064 sec  <<< FAILURE!
junit.framework.AssertionFailedError
        at junit.framework.Assert.fail(Assert.java:47)
        at junit.framework.Assert.assertTrue(Assert.java:20)
        at junit.framework.Assert.assertTrue(Assert.java:27)
        at 
org.apache.qpid.test.unit.transacted.TransactedTest.testEmpty2(TransactedTest.java:181)

which indicates that the messages X,Y,Z are still around after the
rollback test completed. If the commit() method on line 158 (post-patch)
is uncommented, then the failure changes to:

Running org.apache.qpid.test.unit.transacted.TransactedTest
Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 8.689 sec <<< 
FAILURE!
testRollback(org.apache.qpid.test.unit.transacted.TransactedTest)  Time 
elapsed: 1.09 sec  <<< FAILURE!
junit.framework.AssertionFailedError
        at junit.framework.Assert.fail(Assert.java:47)
        at junit.framework.Assert.assertTrue(Assert.java:20)
        at junit.framework.Assert.assertTrue(Assert.java:27)
        at 
org.apache.qpid.test.unit.transacted.TransactedTest.testRollback(TransactedTest.java:167)

which shows that inspite the rollback, X,Y,Z were still downloaded.

Take a look at r501577 for how this was solved on the 0-9 branch.

Note that the changes to the definition of queue Q1 on line 61 made
earlier on the trunk may mask certain problems related to this... If
this line is changed back to

queue1 = new AMQQueue("Q1", false);

then if there are still messages left over from the test, they tend to
interfere with one of the later tests (RecoverTest, I think) when the
entire test suite is run together. For this reason I added the empty
checks after each test which consume any left-over messages in the
process of reporting the error. Ideally, tests should clean up after
themselves, and not leave stray messages around. Making the queue
temporary, as this change did, may have masked the underlying problem.

I plan to check this change to TransactedTest into Subversion at some
point, if you find that it is appropriate, you can do so for me...

I hope this helps,
Kim
Index: java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java
===================================================================
--- java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java	(revision 504866)
+++ java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java	(working copy)
@@ -74,23 +74,11 @@
         prepSession = prepCon.createSession(false, AMQSession.NO_ACKNOWLEDGE);
         prepProducer1 = prepSession.createProducer(queue1);
         prepCon.start();
-
-
-        //add some messages
-        prepProducer1.send(prepSession.createTextMessage("A"));
-        prepProducer1.send(prepSession.createTextMessage("B"));
-        prepProducer1.send(prepSession.createTextMessage("C"));
-
-        testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "test");
-        testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE);
-        testConsumer2 = testSession.createConsumer(queue2);
-
     }
 
     protected void tearDown() throws Exception
     {
         con.close();
-        testCon.close();
         prepCon.close();
         TransportConnection.killAllVMBrokers();
         super.tearDown();
@@ -98,6 +86,11 @@
 
     public void testCommit() throws Exception
     {
+        //add some messages
+        prepProducer1.send(prepSession.createTextMessage("A"));
+        prepProducer1.send(prepSession.createTextMessage("B"));
+        prepProducer1.send(prepSession.createTextMessage("C"));
+
         //send and receive some messages
         producer2.send(session.createTextMessage("X"));
         producer2.send(session.createTextMessage("Y"));
@@ -108,19 +101,44 @@
 
         //commit
         session.commit();
+
+        //ensure sent messages can be received and received messages are gone
+        testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "test");
+        testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE);
+        testConsumer1 = testSession.createConsumer(queue1);
+        testConsumer2 = testSession.createConsumer(queue2);
         testCon.start();
-        //ensure sent messages can be received and received messages are gone
+
         expect("X", testConsumer2.receive(1000));
         expect("Y", testConsumer2.receive(1000));
         expect("Z", testConsumer2.receive(1000));
 
+        assertTrue(null == testConsumer1.receive(1000));
+        assertTrue(null == testConsumer2.receive(1000));
+        testCon.close();
+    }
+    
+    // This checks that queues Q1 & Q2 are in fact empty and do not have any stray
+    // messages left over from the last test (which can affect later tests)...
+    public void testEmpty1() throws Exception
+    {
+        testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "test");
+        testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE);
         testConsumer1 = testSession.createConsumer(queue1);
+        testConsumer2 = testSession.createConsumer(queue2);
+        testCon.start();
         assertTrue(null == testConsumer1.receive(1000));
         assertTrue(null == testConsumer2.receive(1000));
+        testCon.close();
     }
 
     public void testRollback() throws Exception
     {
+        //add some messages
+        prepProducer1.send(prepSession.createTextMessage("A"));
+        prepProducer1.send(prepSession.createTextMessage("B"));
+        prepProducer1.send(prepSession.createTextMessage("C"));
+
         producer2.send(session.createTextMessage("X"));
         producer2.send(session.createTextMessage("Y"));
         producer2.send(session.createTextMessage("Z"));
@@ -135,10 +153,33 @@
         expect("A", consumer1.receive(1000));
         expect("B", consumer1.receive(1000));
         expect("C", consumer1.receive(1000));
+
+        //commit
+        //session.commit();
+
+        testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "test");
+        testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE);
+        testConsumer1 = testSession.createConsumer(queue1);
+        testConsumer2 = testSession.createConsumer(queue2);
         testCon.start();
+        
+        assertTrue(null == testConsumer1.receive(1000));
+        assertTrue(null == testConsumer2.receive(1000));
+        testCon.close();
+    }
+    
+    // This checks that queues Q1 & Q2 are in fact empty and do not have any stray
+    // messages left over from the last test (which can affect later tests)...
+    public void testEmpty2() throws Exception
+    {
+        testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "test");
+        testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE);
         testConsumer1 = testSession.createConsumer(queue1);
+        testConsumer2 = testSession.createConsumer(queue2);
+        testCon.start();
         assertTrue(null == testConsumer1.receive(1000));
         assertTrue(null == testConsumer2.receive(1000));
+        testCon.close();
     }
 
     public void testResendsMsgsAfterSessionClose() throws Exception

Reply via email to