View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.transaction.memory;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import junit.framework.Test;
23  import junit.framework.TestSuite;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  import org.apache.commons.transaction.util.CommonsLoggingLogger;
29  import org.apache.commons.transaction.util.LoggerFacade;
30  import org.apache.commons.transaction.util.RendezvousBarrier;
31  
32  /**
33   * Tests for map wrapper. 
34   *
35   * @version $Id: OptimisticMapWrapperTest.java 493628 2007-01-07 01:42:48Z joerg $
36   */
37  public class OptimisticMapWrapperTest extends MapWrapperTest {
38  
39      private static final Log log = LogFactory.getLog(OptimisticMapWrapperTest.class.getName());
40      private static final LoggerFacade sLogger = new CommonsLoggingLogger(log);
41  
42      public static Test suite() {
43          TestSuite suite = new TestSuite(OptimisticMapWrapperTest.class);
44          return suite;
45      }
46  
47      public static void main(java.lang.String[] args) {
48          junit.textui.TestRunner.run(suite());
49      }
50  
51      public OptimisticMapWrapperTest(String testName) {
52          super(testName);
53      }
54  
55  	protected TransactionalMapWrapper getNewWrapper(Map map) {
56  		return new OptimisticMapWrapper(map);
57  	}
58  
59  	// XXX no need for this code, just to make clear those tests are run as well 
60      public void testBasic() throws Throwable {
61  		super.testBasic();
62      }
63  
64  	public void testComplex() throws Throwable {
65  		super.testComplex();
66  	}
67  
68  	public void testSets() throws Throwable {
69  		super.testSets();
70  	}
71  
72      public void testMulti() throws Throwable {
73          log.info("Checking concurrent transaction features");
74  
75          final Map map1 = new HashMap();
76  
77          final OptimisticMapWrapper txMap1 = (OptimisticMapWrapper) getNewWrapper(map1);
78  
79          final RendezvousBarrier beforeCommitBarrier =
80              new RendezvousBarrier("Before Commit", 2, BARRIER_TIMEOUT, sLogger);
81  
82          final RendezvousBarrier afterCommitBarrier = new RendezvousBarrier("After Commit", 2, BARRIER_TIMEOUT, sLogger);
83  
84          Thread thread1 = new Thread(new Runnable() {
85              public void run() {
86                  txMap1.startTransaction();
87                  try {
88                      beforeCommitBarrier.meet();
89                      txMap1.put("key1", "value2");
90                      txMap1.commitTransaction();
91                      afterCommitBarrier.call();
92                  } catch (InterruptedException e) {
93                      sLogger.logWarning("Thread interrupted", e);
94                      afterCommitBarrier.reset();
95                      beforeCommitBarrier.reset();
96                  }
97              }
98          }, "Thread1");
99  
100         txMap1.put("key1", "value1");
101 
102         txMap1.startTransaction();
103         thread1.start();
104 
105         report("value1", (String) txMap1.get("key1"));
106         beforeCommitBarrier.call();
107         afterCommitBarrier.meet();
108         // we have serializable as isolation level, that's why I will still see the old value
109         report("value1", (String) txMap1.get("key1"));
110 
111         // now when I override it it should of course be my value
112         txMap1.put("key1", "value3");
113         report("value3", (String) txMap1.get("key1"));
114 
115         // after rollback it must be the value written by the other thread
116         txMap1.rollbackTransaction();
117         report("value2", (String) txMap1.get("key1"));
118     }
119 
120 	public void testConflict() throws Throwable {
121 		log.info("Checking concurrent transaction features");
122 
123 		final Map map1 = new HashMap();
124 
125 		final OptimisticMapWrapper txMap1 = (OptimisticMapWrapper) getNewWrapper(map1);
126 
127 		final RendezvousBarrier beforeCommitBarrier =
128 			new RendezvousBarrier("Before Commit", 2, BARRIER_TIMEOUT, sLogger);
129 
130 		final RendezvousBarrier afterCommitBarrier = new RendezvousBarrier("After Commit", 2, BARRIER_TIMEOUT, sLogger);
131 
132 		Thread thread1 = new Thread(new Runnable() {
133 			public void run() {
134 				txMap1.startTransaction();
135 				try {
136 					beforeCommitBarrier.meet();
137 					txMap1.put("key1", "value2");
138 					txMap1.commitTransaction();
139 					afterCommitBarrier.call();
140 				} catch (InterruptedException e) {
141 					sLogger.logWarning("Thread interrupted", e);
142 					afterCommitBarrier.reset();
143 					beforeCommitBarrier.reset();
144 				}
145 			}
146 		}, "Thread1");
147 
148 		txMap1.put("key1", "value1");
149 
150 		txMap1.startTransaction();
151 		thread1.start();
152 
153 		report("value1", (String) txMap1.get("key1"));
154 		beforeCommitBarrier.call();
155 		afterCommitBarrier.meet();
156 		// we have serializable as isolation level, that's why I will still see the old value
157 		report("value1", (String) txMap1.get("key1"));
158 
159 		// now when I override it it should of course be my value
160 		txMap1.put("key1", "value3");
161 		report("value3", (String) txMap1.get("key1"));
162 		
163 		boolean conflict = false;
164 		
165 		try {
166 			txMap1.commitTransaction();
167 		} catch (ConflictException ce) {
168 			conflict = true;
169 		}
170 		assertTrue(conflict);
171 		// after failed commit it must be the value written by the other thread
172 		report("value2", (String) map1.get("key1"));
173 
174 		// force commit anyhow...
175 		txMap1.commitTransaction(true);
176 		// after successful commit it must be the value written by this thread
177 		report("value3", (String) txMap1.get("key1"));
178 		report("value3", (String) map1.get("key1"));
179 	}
180 
181     public void testTxControl() throws Throwable {
182 		super.testTxControl();
183     }
184 
185 }