001: /**
002: * HA-JDBC: High-Availability JDBC
003: * Copyright (c) 2004-2007 Paul Ferraro
004: *
005: * This library is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU Lesser General Public License as published by the
007: * Free Software Foundation; either version 2.1 of the License, or (at your
008: * option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
013: * for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software Foundation,
017: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Contact: ferraro@users.sourceforge.net
020: */package net.sf.hajdbc.sql;
021:
022: import java.io.PrintWriter;
023: import java.io.StringWriter;
024: import java.lang.reflect.Proxy;
025: import java.sql.Connection;
026: import java.sql.SQLException;
027: import java.util.Map;
028: import java.util.Set;
029: import java.util.TreeMap;
030: import java.util.concurrent.ExecutorService;
031: import java.util.concurrent.Executors;
032: import java.util.concurrent.locks.Lock;
033:
034: import net.sf.hajdbc.Balancer;
035: import net.sf.hajdbc.Database;
036: import net.sf.hajdbc.DatabaseCluster;
037: import net.sf.hajdbc.LockManager;
038: import net.sf.hajdbc.util.reflect.ProxyFactory;
039:
040: import org.easymock.EasyMock;
041: import org.testng.annotations.AfterMethod;
042: import org.testng.annotations.BeforeClass;
043: import org.testng.annotations.DataProvider;
044: import org.testng.annotations.Test;
045:
046: @SuppressWarnings({"unchecked","nls"})
047: public class TestDataSource implements javax.sql.DataSource {
048: private DatabaseCluster cluster = EasyMock
049: .createStrictMock(DatabaseCluster.class);
050: private Balancer balancer = EasyMock
051: .createStrictMock(Balancer.class);
052: private javax.sql.DataSource dataSource1 = EasyMock
053: .createStrictMock(javax.sql.DataSource.class);
054: private javax.sql.DataSource dataSource2 = EasyMock
055: .createStrictMock(javax.sql.DataSource.class);
056: private LockManager lockManager = EasyMock
057: .createStrictMock(LockManager.class);
058: private Lock lock = EasyMock.createStrictMock(Lock.class);
059:
060: private Database database1 = new MockDataSourceDatabase("1",
061: this .dataSource1);
062: private Database database2 = new MockDataSourceDatabase("2",
063: this .dataSource2);
064: private Set<Database> databaseSet;
065: private ExecutorService executor = Executors
066: .newSingleThreadExecutor();
067:
068: private javax.sql.DataSource dataSource;
069:
070: @BeforeClass
071: void init() {
072: Map<Database, javax.sql.DataSource> map = new TreeMap<Database, javax.sql.DataSource>();
073: map.put(this .database1, this .dataSource1);
074: map.put(this .database2, this .dataSource2);
075:
076: this .databaseSet = map.keySet();
077:
078: EasyMock.expect(this .cluster.getBalancer()).andReturn(
079: this .balancer);
080: EasyMock.expect(this .balancer.all())
081: .andReturn(this .databaseSet);
082:
083: this .replay();
084:
085: this .dataSource = ProxyFactory.createProxy(
086: javax.sql.DataSource.class,
087: new DataSourceInvocationHandler(this .cluster));
088:
089: this .verify();
090: this .reset();
091: }
092:
093: private Object[] objects() {
094: return new Object[] { this .cluster, this .balancer,
095: this .dataSource1, this .dataSource2, this .lockManager,
096: this .lock };
097: }
098:
099: void replay() {
100: EasyMock.replay(this .objects());
101: }
102:
103: void verify() {
104: EasyMock.verify(this .objects());
105: }
106:
107: @AfterMethod
108: void reset() {
109: EasyMock.reset(this .objects());
110: }
111:
112: /**
113: * @see javax.sql.DataSource#getConnection()
114: */
115: @Test
116: public Connection getConnection() throws SQLException {
117: Connection connection1 = EasyMock
118: .createStrictMock(Connection.class);
119: Connection connection2 = EasyMock
120: .createStrictMock(Connection.class);
121:
122: EasyMock.expect(this .cluster.isActive()).andReturn(true);
123:
124: EasyMock.expect(this .cluster.getLockManager()).andReturn(
125: this .lockManager);
126: EasyMock.expect(this .lockManager.readLock(LockManager.GLOBAL))
127: .andReturn(this .lock);
128:
129: EasyMock.expect(this .cluster.getNonTransactionalExecutor())
130: .andReturn(this .executor);
131:
132: EasyMock.expect(this .cluster.getBalancer()).andReturn(
133: this .balancer);
134: EasyMock.expect(this .balancer.all())
135: .andReturn(this .databaseSet);
136:
137: EasyMock.expect(this .dataSource1.getConnection()).andReturn(
138: connection1);
139: EasyMock.expect(this .dataSource2.getConnection()).andReturn(
140: connection2);
141:
142: this .replay();
143:
144: Connection result = this .dataSource.getConnection();
145:
146: this .verify();
147:
148: assert Proxy.isProxyClass(result.getClass());
149:
150: SQLProxy proxy = SQLProxy.class.cast(Proxy
151: .getInvocationHandler(result));
152:
153: assert proxy.getObject(this .database1) == connection1;
154: assert proxy.getObject(this .database2) == connection2;
155:
156: return result;
157: }
158:
159: @DataProvider(name="string-string")
160: Object[][] connectProvider() {
161: return new Object[][] { new Object[] { "", "" } };
162: }
163:
164: /**
165: * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
166: */
167: @Test(dataProvider="string-string")
168: public Connection getConnection(String user, String password)
169: throws SQLException {
170: Connection connection1 = EasyMock
171: .createStrictMock(Connection.class);
172: Connection connection2 = EasyMock
173: .createStrictMock(Connection.class);
174:
175: EasyMock.expect(this .cluster.isActive()).andReturn(true);
176:
177: EasyMock.expect(this .cluster.getLockManager()).andReturn(
178: this .lockManager);
179: EasyMock.expect(this .lockManager.readLock(LockManager.GLOBAL))
180: .andReturn(this .lock);
181:
182: EasyMock.expect(this .cluster.getNonTransactionalExecutor())
183: .andReturn(this .executor);
184:
185: EasyMock.expect(this .cluster.getBalancer()).andReturn(
186: this .balancer);
187: EasyMock.expect(this .balancer.all())
188: .andReturn(this .databaseSet);
189:
190: EasyMock.expect(this .dataSource1.getConnection(user, password))
191: .andReturn(connection1);
192: EasyMock.expect(this .dataSource2.getConnection(user, password))
193: .andReturn(connection2);
194:
195: this .replay();
196:
197: Connection result = this .dataSource.getConnection(user,
198: password);
199:
200: this .verify();
201:
202: assert Proxy.isProxyClass(result.getClass());
203:
204: SQLProxy proxy = SQLProxy.class.cast(Proxy
205: .getInvocationHandler(result));
206:
207: assert proxy.getObject(this .database1) == connection1;
208: assert proxy.getObject(this .database2) == connection2;
209:
210: return result;
211: }
212:
213: /**
214: * @see javax.sql.CommonDataSource#getLogWriter()
215: */
216: @Test
217: public PrintWriter getLogWriter() throws SQLException {
218: PrintWriter writer = new PrintWriter(System.out);
219:
220: EasyMock.expect(this .cluster.isActive()).andReturn(true);
221:
222: EasyMock.expect(this .dataSource1.getLogWriter()).andReturn(
223: writer);
224:
225: this .replay();
226:
227: PrintWriter result = this .dataSource.getLogWriter();
228:
229: this .verify();
230:
231: assert result == writer;
232:
233: return result;
234: }
235:
236: /**
237: * @see javax.sql.CommonDataSource#getLoginTimeout()
238: */
239: @Test
240: public int getLoginTimeout() throws SQLException {
241: int timeout = 1;
242:
243: EasyMock.expect(this .cluster.isActive()).andReturn(true);
244:
245: EasyMock.expect(this .dataSource1.getLoginTimeout()).andReturn(
246: timeout);
247:
248: this .replay();
249:
250: int result = this .dataSource.getLoginTimeout();
251:
252: this .verify();
253:
254: assert result == timeout;
255:
256: return result;
257: }
258:
259: @DataProvider(name="writer")
260: Object[][] writerProvider() {
261: return new Object[][] { new Object[] { new PrintWriter(
262: new StringWriter()) } };
263: }
264:
265: /**
266: * @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter)
267: */
268: @Test(dataProvider="writer")
269: public void setLogWriter(PrintWriter writer) throws SQLException {
270: EasyMock.expect(this .cluster.isActive()).andReturn(true);
271:
272: this .dataSource1.setLogWriter(writer);
273: this .dataSource2.setLogWriter(writer);
274:
275: this .replay();
276:
277: this .dataSource.setLogWriter(writer);
278:
279: this .verify();
280: }
281:
282: @DataProvider(name="int")
283: Object[][] timeoutProvider() {
284: return new Object[][] { new Object[] { 0 } };
285: }
286:
287: /**
288: * @see javax.sql.CommonDataSource#setLoginTimeout(int)
289: */
290: @Test(dataProvider="int")
291: public void setLoginTimeout(int timeout) throws SQLException {
292: EasyMock.expect(this .cluster.isActive()).andReturn(true);
293:
294: this .dataSource1.setLoginTimeout(timeout);
295: this .dataSource2.setLoginTimeout(timeout);
296:
297: this .replay();
298:
299: this .dataSource.setLoginTimeout(timeout);
300:
301: this .verify();
302: }
303:
304: @DataProvider(name="class")
305: Object[][] classProvider() {
306: return new Object[][] { new Object[] { Object.class } };
307: }
308:
309: /**
310: * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
311: */
312: @Test(dataProvider="class")
313: public boolean isWrapperFor(Class<?> targetClass)
314: throws SQLException {
315: EasyMock.expect(this .cluster.isActive()).andReturn(true);
316:
317: EasyMock.expect(this .dataSource1.isWrapperFor(targetClass))
318: .andReturn(true);
319:
320: this .replay();
321:
322: boolean result = this .dataSource.isWrapperFor(targetClass);
323:
324: this .verify();
325:
326: assert result;
327:
328: return result;
329: }
330:
331: /**
332: * @see java.sql.Wrapper#unwrap(java.lang.Class)
333: */
334: @Test(dataProvider="class")
335: public <T> T unwrap(Class<T> targetClass) throws SQLException {
336: try {
337: T object = targetClass.newInstance();
338:
339: EasyMock.expect(this .cluster.isActive()).andReturn(true);
340:
341: EasyMock.expect(this .dataSource1.unwrap(targetClass))
342: .andReturn(object);
343:
344: this .replay();
345:
346: T result = this .dataSource.unwrap(targetClass);
347:
348: this .verify();
349:
350: assert result == object;
351:
352: return result;
353: } catch (InstantiationException e) {
354: assert false : e;
355: } catch (IllegalAccessException e) {
356: assert false : e;
357: }
358:
359: return null;
360: }
361: }
|