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: */
021: package net.sf.hajdbc.sql;
022:
023: import java.io.ByteArrayInputStream;
024: import java.io.ByteArrayOutputStream;
025: import java.io.InputStream;
026: import java.io.OutputStream;
027: import java.sql.Blob;
028: import java.sql.SQLException;
029: import java.util.Map;
030: import java.util.Set;
031: import java.util.TreeMap;
032: import java.util.concurrent.ExecutorService;
033: import java.util.concurrent.Executors;
034: import java.util.concurrent.locks.Lock;
035:
036: import net.sf.hajdbc.Balancer;
037: import net.sf.hajdbc.Database;
038: import net.sf.hajdbc.DatabaseCluster;
039: import net.sf.hajdbc.LockManager;
040: import net.sf.hajdbc.MockDatabase;
041: import net.sf.hajdbc.util.reflect.ProxyFactory;
042:
043: import org.easymock.EasyMock;
044: import org.testng.annotations.AfterMethod;
045: import org.testng.annotations.BeforeClass;
046: import org.testng.annotations.DataProvider;
047: import org.testng.annotations.Test;
048:
049: /**
050: * @author Paul Ferraro
051: *
052: */
053: @SuppressWarnings({"unchecked","nls"})
054: public class TestBlob implements Blob {
055: private Balancer balancer = EasyMock
056: .createStrictMock(Balancer.class);
057: private DatabaseCluster cluster = EasyMock
058: .createStrictMock(DatabaseCluster.class);
059: private Lock readLock = EasyMock.createStrictMock(Lock.class);
060: private Lock writeLock1 = EasyMock.createStrictMock(Lock.class);
061: private Lock writeLock2 = EasyMock.createStrictMock(Lock.class);
062: private LockManager lockManager = EasyMock
063: .createStrictMock(LockManager.class);
064: private Blob blob1 = EasyMock.createStrictMock(java.sql.Blob.class);
065: private Blob blob2 = EasyMock.createStrictMock(java.sql.Blob.class);
066: private SQLProxy parent = EasyMock.createStrictMock(SQLProxy.class);
067: private SQLProxy root = EasyMock.createStrictMock(SQLProxy.class);
068:
069: private Database database1 = new MockDatabase("1");
070: private Database database2 = new MockDatabase("2");
071: private Set<Database> databaseSet;
072: private ExecutorService executor = Executors
073: .newSingleThreadExecutor();
074: private Blob blob;
075: private BlobInvocationHandler handler;
076:
077: @BeforeClass
078: void init() throws Exception {
079: Map<Database, Blob> map = new TreeMap<Database, Blob>();
080: map.put(this .database1, this .blob1);
081: map.put(this .database2, this .blob2);
082:
083: this .databaseSet = map.keySet();
084:
085: EasyMock.expect(this .parent.getDatabaseCluster()).andReturn(
086: this .cluster);
087:
088: this .parent.addChild(EasyMock.isA(BlobInvocationHandler.class));
089:
090: this .replay();
091:
092: this .handler = new BlobInvocationHandler(new Object(),
093: this .parent, EasyMock.createMock(Invoker.class), map);
094: this .blob = ProxyFactory.createProxy(Blob.class, this .handler);
095:
096: this .verify();
097: this .reset();
098: }
099:
100: private Object[] objects() {
101: return new Object[] { this .cluster, this .balancer, this .blob1,
102: this .blob2, this .readLock, this .writeLock1,
103: this .writeLock2, this .lockManager, this .parent,
104: this .root };
105: }
106:
107: void replay() {
108: EasyMock.replay(this .objects());
109: }
110:
111: void verify() {
112: EasyMock.verify(this .objects());
113: }
114:
115: @AfterMethod
116: void reset() {
117: EasyMock.reset(this .objects());
118: }
119:
120: /**
121: * @see java.sql.Blob#free()
122: */
123: @Test
124: public void free() throws SQLException {
125: EasyMock.expect(this .cluster.isActive()).andReturn(true);
126:
127: EasyMock.expect(this .cluster.getNonTransactionalExecutor())
128: .andReturn(this .executor);
129:
130: EasyMock.expect(this .cluster.getBalancer()).andReturn(
131: this .balancer);
132: EasyMock.expect(this .balancer.all())
133: .andReturn(this .databaseSet);
134:
135: EasyMock.expect(this .parent.getRoot()).andReturn(this .root);
136:
137: this .root.retain(this .databaseSet);
138:
139: this .parent.removeChild(this .handler);
140:
141: this .blob1.free();
142: this .blob2.free();
143:
144: this .replay();
145:
146: this .blob.free();
147:
148: this .verify();
149: }
150:
151: /**
152: * @see java.sql.Blob#getBinaryStream()
153: */
154: @Test
155: public InputStream getBinaryStream() throws SQLException {
156: InputStream input = new ByteArrayInputStream(new byte[0]);
157:
158: EasyMock.expect(this .cluster.isActive()).andReturn(true);
159:
160: EasyMock.expect(this .cluster.getBalancer()).andReturn(
161: this .balancer);
162: EasyMock.expect(this .balancer.next()).andReturn(this .database2);
163:
164: this .balancer.beforeInvocation(this .database2);
165:
166: EasyMock.expect(this .blob2.getBinaryStream()).andReturn(input);
167:
168: this .balancer.afterInvocation(this .database2);
169:
170: this .replay();
171:
172: InputStream result = this .blob.getBinaryStream();
173:
174: this .verify();
175:
176: assert result == input;
177:
178: return result;
179: }
180:
181: @DataProvider(name="long-long")
182: Object[][] longLongProvider() {
183: return new Object[][] { new Object[] { 1L, 1L } };
184: }
185:
186: /**
187: * @see java.sql.Blob#getBinaryStream(long, long)
188: */
189: @Test(dataProvider="long-long")
190: public InputStream getBinaryStream(long position, long length)
191: throws SQLException {
192: InputStream input = new ByteArrayInputStream(new byte[0]);
193:
194: EasyMock.expect(this .cluster.isActive()).andReturn(true);
195:
196: EasyMock.expect(this .cluster.getBalancer()).andReturn(
197: this .balancer);
198: EasyMock.expect(this .balancer.next()).andReturn(this .database2);
199:
200: this .balancer.beforeInvocation(this .database2);
201:
202: EasyMock.expect(this .blob2.getBinaryStream(position, length))
203: .andReturn(input);
204:
205: this .balancer.afterInvocation(this .database2);
206:
207: this .replay();
208:
209: InputStream result = this .blob
210: .getBinaryStream(position, length);
211:
212: this .verify();
213:
214: assert result == input;
215:
216: return result;
217: }
218:
219: @DataProvider(name="long-int")
220: Object[][] longIntProvider() {
221: return new Object[][] { new Object[] { 1L, 1 } };
222: }
223:
224: /**
225: * @see java.sql.Blob#getBytes(long, int)
226: */
227: @Test(dataProvider="long-int")
228: public byte[] getBytes(long position, int length)
229: throws SQLException {
230: byte[] bytes = new byte[0];
231:
232: EasyMock.expect(this .cluster.isActive()).andReturn(true);
233:
234: EasyMock.expect(this .cluster.getBalancer()).andReturn(
235: this .balancer);
236: EasyMock.expect(this .balancer.next()).andReturn(this .database2);
237:
238: this .balancer.beforeInvocation(this .database2);
239:
240: EasyMock.expect(this .blob2.getBytes(position, length))
241: .andReturn(bytes);
242:
243: this .balancer.afterInvocation(this .database2);
244:
245: this .replay();
246:
247: byte[] result = this .blob.getBytes(position, length);
248:
249: this .verify();
250:
251: assert result == bytes;
252:
253: return result;
254: }
255:
256: /**
257: * @see java.sql.Blob#length()
258: */
259: @Test
260: public long length() throws SQLException {
261: EasyMock.expect(this .cluster.isActive()).andReturn(true);
262:
263: EasyMock.expect(this .cluster.getBalancer()).andReturn(
264: this .balancer);
265: EasyMock.expect(this .balancer.next()).andReturn(this .database2);
266:
267: this .balancer.beforeInvocation(this .database2);
268:
269: EasyMock.expect(this .blob2.length()).andReturn(1L);
270:
271: this .balancer.afterInvocation(this .database2);
272:
273: this .replay();
274:
275: long result = this .blob.length();
276:
277: this .verify();
278:
279: assert result == 1L;
280:
281: return result;
282: }
283:
284: @DataProvider(name="bytes-long")
285: Object[][] bytesLongProvider() {
286: return new Object[][] { new Object[] { new byte[0], 1L } };
287: }
288:
289: /**
290: * @see java.sql.Blob#position(byte[], long)
291: */
292: @Test(dataProvider="bytes-long")
293: public long position(byte[] pattern, long start)
294: throws SQLException {
295: EasyMock.expect(this .cluster.isActive()).andReturn(true);
296:
297: EasyMock.expect(this .cluster.getBalancer()).andReturn(
298: this .balancer);
299: EasyMock.expect(this .balancer.next()).andReturn(this .database2);
300:
301: this .balancer.beforeInvocation(this .database2);
302:
303: EasyMock.expect(this .blob2.position(pattern, start)).andReturn(
304: 1L);
305:
306: this .balancer.afterInvocation(this .database2);
307:
308: this .replay();
309:
310: long result = this .blob.position(pattern, start);
311:
312: this .verify();
313:
314: assert result == 1L;
315:
316: return result;
317: }
318:
319: @DataProvider(name="blob-long")
320: Object[][] blobLongProvider() {
321: return new Object[][] { new Object[] {
322: EasyMock.createMock(Blob.class), 1L } };
323: }
324:
325: /**
326: * @see java.sql.Blob#position(java.sql.Blob, long)
327: */
328: @Test(dataProvider="blob-long")
329: public long position(Blob pattern, long start) throws SQLException {
330: EasyMock.expect(this .cluster.isActive()).andReturn(true);
331:
332: EasyMock.expect(this .cluster.getBalancer()).andReturn(
333: this .balancer);
334: EasyMock.expect(this .balancer.next()).andReturn(this .database2);
335:
336: this .balancer.beforeInvocation(this .database2);
337:
338: EasyMock.expect(this .blob2.position(pattern, start)).andReturn(
339: 1L);
340:
341: this .balancer.afterInvocation(this .database2);
342:
343: this .replay();
344:
345: long result = this .blob.position(pattern, start);
346:
347: this .verify();
348:
349: assert result == 1L;
350:
351: return result;
352: }
353:
354: @DataProvider(name="long")
355: Object[][] longProvider() {
356: return new Object[][] { new Object[] { 1L } };
357: }
358:
359: /**
360: * @see java.sql.Blob#setBinaryStream(long)
361: */
362: @Test(dataProvider="long")
363: public OutputStream setBinaryStream(long position)
364: throws SQLException {
365: OutputStream output1 = new ByteArrayOutputStream();
366: OutputStream output2 = new ByteArrayOutputStream();
367:
368: EasyMock.expect(this .cluster.isActive()).andReturn(true);
369:
370: EasyMock.expect(this .cluster.getNonTransactionalExecutor())
371: .andReturn(this .executor);
372:
373: EasyMock.expect(this .cluster.getBalancer()).andReturn(
374: this .balancer);
375: EasyMock.expect(this .balancer.all())
376: .andReturn(this .databaseSet);
377:
378: EasyMock.expect(this .parent.getRoot()).andReturn(this .root);
379:
380: this .root.retain(this .databaseSet);
381:
382: EasyMock.expect(this .blob1.setBinaryStream(position))
383: .andReturn(output1);
384: EasyMock.expect(this .blob2.setBinaryStream(position))
385: .andReturn(output2);
386:
387: this .replay();
388:
389: OutputStream result = this .blob.setBinaryStream(position);
390:
391: this .verify();
392:
393: assert result == output1;
394:
395: return result;
396: }
397:
398: @DataProvider(name="long-bytes")
399: Object[][] longBytesProvider() {
400: return new Object[][] { new Object[] { 1L, new byte[0] } };
401: }
402:
403: /**
404: * @see java.sql.Blob#setBytes(long, byte[])
405: */
406: @Test(dataProvider="long-bytes")
407: public int setBytes(long position, byte[] bytes)
408: throws SQLException {
409: EasyMock.expect(this .cluster.isActive()).andReturn(true);
410:
411: EasyMock.expect(this .cluster.getNonTransactionalExecutor())
412: .andReturn(this .executor);
413:
414: EasyMock.expect(this .cluster.getBalancer()).andReturn(
415: this .balancer);
416: EasyMock.expect(this .balancer.all())
417: .andReturn(this .databaseSet);
418:
419: EasyMock.expect(this .parent.getRoot()).andReturn(this .root);
420:
421: this .root.retain(this .databaseSet);
422:
423: EasyMock.expect(this .blob1.setBytes(position, bytes))
424: .andReturn(1);
425: EasyMock.expect(this .blob2.setBytes(position, bytes))
426: .andReturn(1);
427:
428: this .replay();
429:
430: int result = this .blob.setBytes(position, bytes);
431:
432: this .verify();
433:
434: assert result == 1;
435:
436: return result;
437: }
438:
439: @DataProvider(name="long-bytes-int-int")
440: Object[][] longBytesIntIntProvider() {
441: return new Object[][] { new Object[] { 1L, new byte[0], 1, 1 } };
442: }
443:
444: /**
445: * @see java.sql.Blob#setBytes(long, byte[], int, int)
446: */
447: @Test(dataProvider="long-bytes-int-int")
448: public int setBytes(long position, byte[] bytes, int offset,
449: int length) throws SQLException {
450: EasyMock.expect(this .cluster.isActive()).andReturn(true);
451:
452: EasyMock.expect(this .cluster.getNonTransactionalExecutor())
453: .andReturn(this .executor);
454:
455: EasyMock.expect(this .cluster.getBalancer()).andReturn(
456: this .balancer);
457: EasyMock.expect(this .balancer.all())
458: .andReturn(this .databaseSet);
459:
460: EasyMock.expect(this .parent.getRoot()).andReturn(this .root);
461:
462: this .root.retain(this .databaseSet);
463:
464: EasyMock.expect(
465: this .blob1.setBytes(position, bytes, offset, length))
466: .andReturn(1);
467: EasyMock.expect(
468: this .blob2.setBytes(position, bytes, offset, length))
469: .andReturn(1);
470:
471: this .replay();
472:
473: int result = this .blob
474: .setBytes(position, bytes, offset, length);
475:
476: this .verify();
477:
478: assert result == 1;
479:
480: return result;
481: }
482:
483: /**
484: * @see java.sql.Blob#truncate(long)
485: */
486: @Test(dataProvider="long")
487: public void truncate(long position) throws SQLException {
488: EasyMock.expect(this .cluster.isActive()).andReturn(true);
489:
490: EasyMock.expect(this.cluster.getNonTransactionalExecutor())
491: .andReturn(this.executor);
492:
493: EasyMock.expect(this.cluster.getBalancer()).andReturn(
494: this.balancer);
495: EasyMock.expect(this.balancer.all())
496: .andReturn(this.databaseSet);
497:
498: EasyMock.expect(this.parent.getRoot()).andReturn(this.root);
499:
500: this.root.retain(this.databaseSet);
501:
502: this.blob1.truncate(position);
503: this.blob2.truncate(position);
504:
505: this.replay();
506:
507: this.blob.truncate(position);
508:
509: this.verify();
510: }
511: }
|