01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
03: * notice. All rights reserved.
04: */
05: package com.tc.object.gtx;
06:
07: import com.tc.net.groups.ClientID;
08: import com.tc.net.protocol.tcm.ChannelID;
09: import com.tc.object.tx.TestRemoteTransactionManager;
10: import com.tc.object.tx.TransactionID;
11:
12: import junit.framework.TestCase;
13:
14: public class ClientGlobalTransactionManagerTest extends TestCase {
15:
16: private ClientGlobalTransactionManagerImpl mgr;
17:
18: public void setUp() {
19: mgr = new ClientGlobalTransactionManagerImpl(
20: new TestRemoteTransactionManager());
21: }
22:
23: public void testBasics() throws Exception {
24: int max = 5;
25: for (int i = 100; i <= max; i++) {
26: GlobalTransactionID gtx1 = new GlobalTransactionID(i);
27: ClientID cid = new ClientID(new ChannelID(i));
28: TransactionID transactionID = new TransactionID(i);
29: // start the apply
30: assertTrue(mgr.startApply(cid, transactionID, gtx1));
31: // a further call to startApply should return false, since the apply is already in progress or complete.
32: assertFalse(mgr.startApply(cid, transactionID, gtx1));
33:
34: if (i > 2) {
35: GlobalTransactionID lowWatermark = new GlobalTransactionID(
36: i - 1);
37: ClientID chIDBelowWatermark = new ClientID(
38: new ChannelID(i - 2));
39: TransactionID txIDBelowWatermark = new TransactionID(
40: i - 2);
41: GlobalTransactionID belowLowWatermark = new GlobalTransactionID(
42: i - mgr.getAllowedLowWaterMarkDelta());
43: mgr.setLowWatermark(lowWatermark);
44:
45: try {
46: mgr.startApply(chIDBelowWatermark,
47: txIDBelowWatermark, belowLowWatermark);
48: fail("Should have thrown an UnknownTransactionError");
49: } catch (UnknownTransactionError e) {
50: // expected
51: }
52: }
53: }
54: }
55:
56: public void testCleanup() throws Exception {
57: ClientID cid = new ClientID(new ChannelID(1));
58: TransactionID txID = new TransactionID(1);
59: GlobalTransactionID gtxID1 = new GlobalTransactionID(1);
60: GlobalTransactionID gtxID2 = new GlobalTransactionID(2);
61: GlobalTransactionID gtxID3 = new GlobalTransactionID(3 + mgr
62: .getAllowedLowWaterMarkDelta());
63:
64: assertEquals(0, mgr.size());
65: assertTrue(mgr.startApply(cid, txID, gtxID1));
66: assertEquals(1, mgr.size());
67:
68: // calling startApply with a different GlobalTransactionID should have the same result as calling it with the
69: // same GlobalTransactionID.
70: assertFalse(mgr.startApply(cid, txID, gtxID1));
71: assertFalse(mgr.startApply(cid, txID, gtxID2));
72: assertEquals(1, mgr.size());
73:
74: // setting the low watermark to a gtxID equal to the lowest recorded for that pair should not remove that pair
75: mgr.setLowWatermark(gtxID1);
76: assertFalse(mgr.startApply(cid, txID, gtxID2));
77: assertEquals(1, mgr.size());
78:
79: // setting the low watermark to a gtxID above the highest recorded for that pair SHOULD remove that pair
80: // NOTE: The server should never re-send a transaction with the lower GlobalTransactionID: the only reason it will
81: // send a different global transaction id is if the server crashed before it was able to commit the earlier global
82: // transaction id => server transaction id mapping. In that case, the server will never send the lower gtx as the
83: // low watermark because the mapping doesn't exist in the server (because it didn't get committed)
84: mgr.setLowWatermark(gtxID3);
85: assertEquals(0, mgr.size());
86:
87: // NOTE: the following should never happen in practical use, but is useful to make sure that the cleanup is
88: // happening properly
89: // The mgr should have forgotten about the channel id and transaction id by setting the watermark above the highest
90: // global transaction id recorded for that transaction.
91: assertTrue(mgr.startApply(cid, txID, gtxID3));
92: }
93: }
|