blob: a4a353d6c97c7021d21a61ed5d1901a59bea0206 [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.thrift;
import java.nio.ByteBuffer;
import junit.framework.TestCase;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import thrift.test.Backwards;
import thrift.test.OneOfEach;
import thrift.test.PrimitiveThenStruct;
import thrift.test.StructWithAUnion;
import thrift.test.TestUnion;
public class TestTDeserializer extends TestCase {
private static final TProtocolFactory[] PROTOCOLS = new TProtocolFactory[] {
new TBinaryProtocol.Factory(),
new TCompactProtocol.Factory(),
new TJSONProtocol.Factory()
};
public void testPartialDeserialize() throws Exception {
//Root:StructWithAUnion
// 1:Union
// 1.3:OneOfEach
OneOfEach level3OneOfEach = Fixtures.oneOfEach;
TestUnion level2TestUnion = new TestUnion(TestUnion._Fields.STRUCT_FIELD, level3OneOfEach);
StructWithAUnion level1SWU = new StructWithAUnion(level2TestUnion);
Backwards bw = new Backwards(2, 1);
PrimitiveThenStruct pts = new PrimitiveThenStruct(12345, 67890, bw);
for (TProtocolFactory factory : PROTOCOLS) {
//Level 2 test
testPartialDeserialize(factory, level1SWU, new TestUnion(), level2TestUnion, StructWithAUnion._Fields.TEST_UNION);
//Level 3 on 3rd field test
testPartialDeserialize(factory, level1SWU, new OneOfEach(), level3OneOfEach, StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD);
//Test early termination when traversed path Field.id exceeds the one being searched for
testPartialDeserialize(factory, level1SWU, new OneOfEach(), new OneOfEach(), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.I32_FIELD);
//Test that readStructBegin isn't called on primitive
testPartialDeserialize(factory, pts, new Backwards(), bw, PrimitiveThenStruct._Fields.BW);
//Test primitive types
TDeserializer deserializer = new TDeserializer(factory);
Boolean expectedBool = level3OneOfEach.isIm_true();
Boolean resultBool = deserializer.partialDeserializeBool(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.IM_TRUE);
assertEquals(expectedBool, resultBool);
Byte expectedByte = level3OneOfEach.getA_bite();
Byte resultByte = deserializer.partialDeserializeByte(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.A_BITE);
assertEquals(expectedByte, resultByte);
Double expectedDouble = level3OneOfEach.getDouble_precision();
Double resultDouble = deserializer.partialDeserializeDouble(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.DOUBLE_PRECISION);
assertEquals(expectedDouble, resultDouble);
Short expectedI16 = level3OneOfEach.getInteger16();
Short resultI16 = deserializer.partialDeserializeI16(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER16);
assertEquals(expectedI16, resultI16);
Integer expectedI32 = level3OneOfEach.getInteger32();
Integer resultI32 = deserializer.partialDeserializeI32(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER32);
assertEquals(expectedI32, resultI32);
Long expectedI64 = level3OneOfEach.getInteger64();
Long resultI64= deserializer.partialDeserializeI64(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER64);
assertEquals(expectedI64, resultI64);
String expectedString = level3OneOfEach.getSome_characters();
String resultString = deserializer.partialDeserializeString(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.SOME_CHARACTERS);
assertEquals(expectedString, resultString);
byte[] expectedBinary = level3OneOfEach.getBase64();
ByteBuffer resultBinary = deserializer.partialDeserializeByteArray(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.BASE64);
assertEquals(expectedBinary.length, resultBinary.limit() - resultBinary.position() - resultBinary.arrayOffset());
assertEquals(ByteBuffer.wrap(expectedBinary), resultBinary);
// Test field id in Union
short id = deserializer.partialDeserializeSetFieldIdInUnion(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION);
assertEquals(level2TestUnion.getSetField().getThriftFieldId(), id);
}
}
public static void testPartialDeserialize(TProtocolFactory protocolFactory, TBase input, TBase output, TBase expected, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException {
byte[] record = serialize(input, protocolFactory);
TDeserializer deserializer = new TDeserializer(protocolFactory);
for (int i = 0; i < 2; i++) {
TBase outputCopy = output.deepCopy();
deserializer.partialDeserialize(outputCopy, record, fieldIdPathFirst, fieldIdPathRest);
assertEquals("on attempt " + i + ", with " + protocolFactory.toString()
+ ", expected " + expected + " but got " + outputCopy,
expected, outputCopy);
}
}
private static byte[] serialize(TBase input, TProtocolFactory protocolFactory) throws TException{
return new TSerializer(protocolFactory).serialize(input);
}
}