1 /* 2 Copyright 2010 Sun Microsystems, Inc. 3 All rights reserved. Use is subject to license terms. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 */ 25 26 package testsuite.clusterj; 27 28 import java.io.IOException; 29 import java.io.InputStream; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 import testsuite.clusterj.model.BlobTypes; 35 36 public class BlobTest extends AbstractClusterJModelTest { 37 38 /** The size of the blob column is 2 raised to the power i. */ 39 private static final int NUMBER_TO_INSERT = 16; 40 41 /** The blob instances for testing. */ 42 protected List<BlobTypes> blobs = new ArrayList<BlobTypes>(); 43 44 @Override localSetUp()45 public void localSetUp() { 46 createSessionFactory(); 47 session = sessionFactory.getSession(); 48 createBlobInstances(NUMBER_TO_INSERT); 49 tx = session.currentTransaction(); 50 tx.begin(); 51 session.deletePersistentAll(BlobTypes.class); 52 tx.commit(); 53 // the following tests the delete functionality 54 addTearDownClasses(BlobTypes.class); 55 } 56 test()57 public void test() { 58 insert(); 59 update(); 60 failOnError(); 61 } 62 insert()63 protected void insert() { 64 // insert instances 65 tx = session.currentTransaction(); 66 tx.begin(); 67 68 int count = 0; 69 70 for (int i = 0; i < NUMBER_TO_INSERT; ++i) { 71 // must be done with an active transaction 72 session.makePersistent(blobs.get(i)); 73 ++count; 74 } 75 tx.commit(); 76 } 77 update()78 protected void update() { 79 80 tx.begin(); 81 82 for (int i = 1; i < NUMBER_TO_INSERT; ++i) { 83 // must be done with an active transaction 84 BlobTypes e = session.find(BlobTypes.class, i); 85 // see if it is the right one 86 int actualId = e.getId(); 87 if (actualId != i) { 88 error("Expected BlobTypes.id " + i + " but got " + actualId); 89 } 90 byte[] bytes = e.getBlobbytes(); 91 // make sure all fields were fetched properly 92 checkBlobBytes("before update", bytes, i, false); 93 94 int position = getBlobSizeFor(i)/2; 95 // only update if the length is correct 96 if (bytes.length == (position * 2)) { 97 // modify the byte in the middle of the blob 98 bytes[position] = (byte)(position % 128); 99 checkBlobBytes("after update", bytes, i, true); 100 101 // mark the field as modified so it will be flushed 102 session.markModified(e, "blobbytes"); 103 104 // update the modified instance 105 session.updatePersistent(e); 106 } 107 } 108 tx.commit(); 109 tx.begin(); 110 111 for (int i = 1; i < NUMBER_TO_INSERT; ++i) { 112 // must be done with an active transaction 113 BlobTypes e = session.find(BlobTypes.class, i); 114 // see if it is the right one 115 int actualId = e.getId(); 116 if (actualId != i) { 117 error("Expected BlobTypes.id " + i + " but got " + actualId); 118 } 119 byte[] bytes = e.getBlobbytes(); 120 121 // check to see that the blob field has the right data 122 checkBlobBytes("after commit", e.getBlobbytes(), i, true); 123 } 124 tx.commit(); 125 } 126 createBlobInstances(int number)127 protected void createBlobInstances(int number) { 128 for (int i = 0; i < number; ++i) { 129 BlobTypes instance = session.newInstance(BlobTypes.class); 130 instance.setId(i); 131 int length = getBlobSizeFor(i); 132 instance.setBlobbytes(getBlobBytes(length)); 133 // blob streams are not yet supported 134 // instance.setBlobstream(getBlobStream(length)); 135 blobs.add(instance); 136 } 137 } 138 139 /** Create a new byte[] of the specified size containing a pattern 140 * of bytes in which each byte is the unsigned value of the index 141 * modulo 256. This pattern is easy to test. 142 * @param size the length of the returned byte[] 143 * @return the byte[] filled with the pattern 144 */ getBlobBytes(int size)145 protected byte[] getBlobBytes(int size) { 146 byte[] result = new byte[size]; 147 for (int i = 0; i < size; ++i) { 148 result[i] = (byte)((i % 256) - 128); 149 } 150 return result; 151 } 152 153 /** Check the byte[] to be sure it matches the pattern in both size 154 * and contents. 155 * @see getBlobBytes 156 * @param bytes the byte[] to check 157 * @param number the expected length of the byte[] 158 */ checkBlobBytes(String where, byte[] bytes, int number, boolean updated)159 protected void checkBlobBytes(String where, byte[] bytes, int number, boolean updated) { 160 // debugging statement; comment out once test passes 161 dumpBlob(where, bytes); 162 int expectedSize = getBlobSizeFor(number); 163 int actualSize = bytes.length; 164 if (expectedSize != actualSize) { 165 error("In " + where 166 + " wrong size of byte[]; " 167 + "expected: " + expectedSize 168 + " actual: " + actualSize); 169 } 170 for (int i = 0; i < actualSize; ++i) { 171 byte expected; 172 int position = expectedSize/2; 173 if (updated && (i == position)) { 174 expected = (byte)(position % 128); 175 } else { 176 expected = (byte)((i % 256) - 128); 177 } 178 byte actual = bytes[i]; 179 if (expected != actual) { 180 error("In " + where + " for size: " + actualSize 181 + " mismatch in byte[] at position " + i 182 + " expected: " + expected 183 + " actual: " + actual); 184 } 185 } 186 187 } 188 getBlobStream(final int i)189 protected InputStream getBlobStream(final int i) { 190 return new InputStream() { 191 int size = i; 192 int counter = 0; 193 @Override 194 public int read() throws IOException { 195 if (counter >= i) { 196 return -1; 197 } else { 198 return counter++ %256; 199 } 200 } 201 }; 202 } 203 dumpBlob(String where, byte[] blob)204 protected void dumpBlob(String where, byte[] blob) { 205 // System.out.println("In " + where + " dumpBlob of size: " + blob.length); 206 // for (byte b: blob) { 207 // System.out.print("[" + b + "]"); 208 // } 209 // System.out.println(); 210 } 211 getBlobSizeFor(int i)212 protected int getBlobSizeFor(int i) { 213 int length = (int) Math.pow(2, i); 214 return length; 215 } 216 217 } 218