blob: ffa7f0b3ff501e69826e0d600e19dd5b815c0abf [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.types;
import java.util.*;
import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.tools.schemaframework.*;
import org.eclipse.persistence.testing.framework.*;
/**
* A Tester for BLOB data, treated as a byte array internally.
* NOTE: Direct attribute accessing for byte[] does not work (reflection problem)
*/
public class BLOBTester extends TypeTester {
public byte[] bytes;
protected int length;
public BLOBTester() {
this(0);
}
public BLOBTester(int numBytes) {
super("BLOB(" + numBytes + ")");
length = numBytes;
bytes = null;
}
private String buildName() {
return "BLOB(" + length + ")";
}
public static RelationalDescriptor descriptor() {
RelationalDescriptor descriptor = new RelationalDescriptor();
/* First define the class, table and descriptor properties. */
descriptor.setJavaClass(BLOBTester.class);
descriptor.setTableName("BLOBS");
descriptor.setPrimaryKeyFieldName("NAME");
/* Next define the attribute mappings. */
descriptor.addDirectMapping("testName", "getTestName", "setTestName", "NAME");
//MySQL gets confused when reserved words are used as a name such as BLOB. Changed to BLOB_
descriptor.addDirectMapping("bytes", "BLOB_");
return descriptor;
}
public static RelationalDescriptor descriptorWithAccessors() {
RelationalDescriptor descriptor = new RelationalDescriptor();
/* First define the class, table and descriptor properties. */
descriptor.setJavaClass(BLOBTester.class);
descriptor.setTableName("BLOBS");
descriptor.setPrimaryKeyFieldName("NAME");
/* Next define the attribute mappings. */
descriptor.addDirectMapping("testName", "getTestName", "setTestName", "NAME");
descriptor.addDirectMapping("bytes", "getBytes", "setBytes", "BLOB_");
return descriptor;
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] newBytes) {
length = newBytes.length;
bytes = newBytes;
}
@Override
public void setup(Session session) {
// Access does not support BLOBS or CLOBS
if (session.getPlatform().isAccess()) {
throw new TestWarningException("Access and DB2 do not support BLOBS or CLOBS.");
}
if (bytes == null) {
bytes = new byte[length];
new Random().nextBytes(bytes);
}
}
/**
*Return a platform independant definition of the database table.
*/
public static TableDefinition tableDefinition(Session session) {
TableDefinition definition = TypeTester.tableDefinition();
definition.setName("BLOBS");
definition.addField("BLOB_", Byte[].class, 33000);
return definition;
}
/**
* Catch null point that occurs frequently an make as warning (known bug).
*/
@Override
protected void test(WriteTypeObjectTest testCase) throws TestWarningException {
try {
super.test(testCase);
} catch (NullPointerException e) {
throw new TestWarningException("Blob value was returned as null, this means the drivers max size was exceeded." + org.eclipse.persistence.internal.helper.Helper.cr() + caughtException);
}
}
public static Vector testInstances() {
Vector tests = new Vector();
tests.addElement(new BLOBTester(1000));
tests.addElement(new BLOBTester(5000));
tests.addElement(new BLOBTester(10000));
tests.addElement(new BLOBTester(25000));
tests.addElement(new BLOBTester(32768));
tests.addElement(new BLOBTester(33000));
return tests;
}
public String toString() {
if (getTestName().equals(buildName())) {
return getTestName();
} else {
return getTestName() + " {" + length + "}";
}
}
@Override
protected void verify(WriteTypeObjectTest testCase) throws TestException {
try {
super.verify(testCase);
} catch (TestException e) {
// JConnect does not support non-native BLOBs
if ((caughtException != null) && (caughtException.toString().indexOf("JZ0S8: An escape sequence") != -1)) {
throw new TestProblemException("JConnect does not do BLOBs in non-native SQL:\n" + caughtException.getInternalException());
}
// In VA/Java setting array object reflectivey throws an exception
if ((e.getInternalException() != null) && (e.getInternalException().getClass() == IllegalAccessException.class)) {
try {
Class.forName("com.ibm.uvm.tools.DebugSupport");
throw new TestWarningException("IllegalAccessException attempting to reflectively set byte[]");
} catch (ClassNotFoundException ce) {
}
}
BLOBTester original = (BLOBTester)testCase.getOriginalObject();
BLOBTester database = (BLOBTester)testCase.getObjectFromDatabase();
if (database == null) {
throw new TestWarningException("Write of BLOB failed, nothing was written or read.\n" + caughtException);
}
if ((database.getBytes() != null) && (original.getBytes().length == database.getBytes().length)) {
int numGood = 0;
for (int index = 0; index < original.getBytes().length; index++) {
if (original.getBytes()[index] == database.getBytes()[index]) {
numGood++;
}
}
throw new TestWarningException("Two BLOBs did not match, " + numGood + " bytes matched");
}
throw new TestWarningException("Blobs just suck with this driver or max size exceeded, \n" + e);
}
}
}