blob: cbf59a5d389525149b6b79cbe8c3a6dc6ce8aaf9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite.internal.binary;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.UUID;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.binary.BinaryBasicNameMapper;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryReader;
import org.apache.ignite.binary.BinaryWriter;
import org.apache.ignite.binary.Binarylizable;
import org.apache.ignite.configuration.BinaryConfiguration;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
/**
* BinaryObjectExceptionSelfTest
*/
public class BinaryObjectExceptionSelfTest extends GridCommonAbstractTest {
/** */
private static final String TEST_KEY = "test_key";
/** Cache name. */
private final String cacheName = "cache";
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(gridName);
cfg.setMarshaller(new BinaryMarshaller());
cfg.setCacheConfiguration(
new CacheConfiguration(cacheName)
.setCopyOnRead(true)
);
BinaryConfiguration bcfg = new BinaryConfiguration()
.setNameMapper(new BinaryBasicNameMapper(false));
cfg.setBinaryConfiguration(bcfg);
return cfg;
}
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
startGrids(2);
awaitPartitionMapExchange();
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
stopAllGrids();
}
/**
* Test unexpected field type.
*
* @throws Exception If failed.
*/
@Test
public void testUnexpectedFieldType() throws Exception {
IgniteEx grid = grid(0);
IgniteCache<String, Value> cache = grid.cache(cacheName);
cache.put(TEST_KEY, new Value());
BinaryObjectImpl b = (BinaryObjectImpl)cache.withKeepBinary().get(TEST_KEY);
b.deserialize(); // deserialize working
byte[] a = b.array();
int unexpectedCnt = 0;
Field[] fields = Value.class.getDeclaredFields();
StringBuilder sb = new StringBuilder(4 << 10);
for (int i = b.dataStartOffset(), j = b.footerStartOffset(); i < j; ++i) {
byte old = a[i];
a[i] = -1;
try {
b.deserialize();
}
catch (Exception ex) {
Throwable root = ex;
sb.setLength(0);
sb.append(root.getMessage());
while (root.getCause() != null) {
root = root.getCause();
sb.append(". ").append(root.getMessage());
}
if (root instanceof BinaryObjectException && root.getMessage().startsWith("Unexpected field type")) {
log().info(sb.toString());
Field f = fields[unexpectedCnt];
Throwable t = ex;
assertTrue(t.getMessage(), t.getMessage().contains(
"object [typeName=org.apache.ignite.internal.binary.BinaryObjectExceptionSelfTest$Value"));
t = t.getCause();
assertTrue(t.getMessage(), t.getMessage().contains("field [name=" + f.getName()));
++unexpectedCnt;
}
else
log().info("Ignored exception: " + sb);
}
a[i] = old;
}
assertEquals("Fields count must match \"Unexpected field type\" exception count", fields.length, unexpectedCnt);
}
/**
* Test verbose logging of object marshalling.
*
* @throws Exception If failed.
*/
@Test
public void testFailedMarshallingLogging() throws Exception {
BinaryMarshaller marshaller = createStandaloneBinaryMarshaller();
try {
marshaller.marshal(new Value1());
}
catch (BinaryObjectException ex) {
assertTrue(ex.getMessage().contains(
"object [typeName=org.apache.ignite.internal.binary.BinaryObjectExceptionSelfTest$Value1"));
assertTrue(ex.getCause().getMessage().contains("field [name=objVal"));
}
}
/** */
private static class Value1 {
/** */
Value2 objVal = new Value2();
/** */
static class Value2 implements Binarylizable {
/** */
@Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
throw new RuntimeException("bad object");
}
/** */
@Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
throw new RuntimeException("bad object");
}
}
}
/** */
private enum EnumValues {
/** */
val1,
/** */
val2,
/** */
val3;
}
/** */
@SuppressWarnings("unused")
private static class Value {
/** */
public byte byteVal = 1;
/** */
public boolean booleanVal = true;
/** */
public short shortVal = 2;
/** */
public char charVal = 'Q';
/** */
public int intVal = 3;
/** */
public long longVal = 4;
/** */
public float floatVal = 5;
/** */
public double doubleVal = 6;
/** */
public BigDecimal bigDecimal = new BigDecimal(7);
/** */
public String string = "QWERTY";
/** */
public UUID uuid = UUID.randomUUID();
/** */
public Date date = new Date();
/** */
public Timestamp timestamp = new Timestamp(date.getTime() + 1000L);
/** */
public EnumValues enumVal = EnumValues.val2;
}
}