ThriftMetadataTest.java
/*
* 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.partial;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.apache.thrift.TBase;
import org.apache.thrift.meta_data.EnumMetaData;
import org.apache.thrift.meta_data.FieldValueMetaData;
import org.apache.thrift.meta_data.ListMetaData;
import org.apache.thrift.meta_data.MapMetaData;
import org.apache.thrift.meta_data.SetMetaData;
import org.apache.thrift.meta_data.StructMetaData;
import org.apache.thrift.protocol.TType;
import org.junit.jupiter.api.Test;
public class ThriftMetadataTest {
private PartialThriftTestData testData = new PartialThriftTestData();
@Test
public void testArgChecks() {
// Should not throw.
List<ThriftField> testFields = ThriftField.fromNames(Arrays.asList("byteField"));
ThriftMetadata.ThriftStruct.fromFields(TestStruct.class, testFields);
// Verify it throws correctly.
assertThrows(
IllegalArgumentException.class,
() -> ThriftMetadata.ThriftStruct.fromFields(null, testFields),
"'clasz' must not be null");
assertThrows(
IllegalArgumentException.class,
() -> ThriftMetadata.ThriftStruct.fromFields(TestStruct.class, null),
"'fields' must not be null");
}
@Test
public void testThriftStructOf() {
ThriftMetadata.ThriftStruct testStruct = ThriftMetadata.ThriftStruct.of(TestStruct.class);
assertEquals(45, testStruct.fields.keySet().size());
validateFieldMetadata(testStruct, 1, "byteField", TType.BYTE);
validateFieldMetadata(testStruct, 2, "i16Field", TType.I16);
validateFieldMetadata(testStruct, 3, "i32Field", TType.I32);
validateFieldMetadata(testStruct, 4, "i64Field", TType.I64);
validateFieldMetadata(testStruct, 5, "doubleField", TType.DOUBLE);
validateFieldMetadata(testStruct, 6, "stringField", TType.STRING);
validateFieldMetadata(testStruct, 7, "enumField", TType.ENUM);
validateFieldMetadata(testStruct, 8, "binaryField", TType.STRING);
validateListFieldMetadata(testStruct, 10, "byteList", TType.BYTE);
validateSetFieldMetadata(testStruct, 35, "stringSet", TType.STRING);
validateMapFieldMetadata(testStruct, 61, "binaryMap", TType.I32, TType.STRING);
}
@Test
public void testUnion() {
ThriftMetadata.ThriftStruct structWithUnions =
ThriftMetadata.ThriftStruct.of(StructWithUnions.class);
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 1, "intValue");
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 2, "smallStruct");
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 3, "simpleUnion");
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 4, "unionList");
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 5, "unionSet");
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 6, "keyUnionMap");
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 7, "valUnionMap");
validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 8, "unionMap");
ThriftMetadata.ThriftStructBase smallStructMetadata =
(ThriftMetadata.ThriftStructBase) structWithUnions.fields.get(2);
assertFalse(smallStructMetadata.isUnion());
ThriftMetadata.ThriftStructBase simpleUnionMetadata =
(ThriftMetadata.ThriftStructBase) structWithUnions.fields.get(3);
assertTrue(simpleUnionMetadata.isUnion());
ThriftMetadata.ThriftList unionListMetadata =
(ThriftMetadata.ThriftList) structWithUnions.fields.get(4);
assertTrue(unionListMetadata.hasUnion());
ThriftMetadata.ThriftSet unionSetMetadata =
(ThriftMetadata.ThriftSet) structWithUnions.fields.get(5);
assertTrue(unionSetMetadata.hasUnion());
ThriftMetadata.ThriftMap keyUnionMapMetadata =
(ThriftMetadata.ThriftMap) structWithUnions.fields.get(6);
assertTrue(keyUnionMapMetadata.hasUnion());
ThriftMetadata.ThriftMap valUnionMapMetadata =
(ThriftMetadata.ThriftMap) structWithUnions.fields.get(7);
assertTrue(valUnionMapMetadata.hasUnion());
ThriftMetadata.ThriftMap unionMapMetadata =
(ThriftMetadata.ThriftMap) structWithUnions.fields.get(8);
assertTrue(unionMapMetadata.hasUnion());
}
private ThriftMetadata.ThriftObject validateBasicFieldMetadata(
ThriftMetadata.ThriftStruct testStruct, int id, String fieldName) {
return validateBasicFieldMetadata(testStruct, TestStruct.class, id, fieldName);
}
private ThriftMetadata.ThriftObject validateBasicFieldMetadata(
ThriftMetadata.ThriftStruct testStruct,
Class<? extends TBase> clazz,
int id,
String fieldName) {
assertNotNull(testStruct);
assertNull(testStruct.parent);
assertEquals(clazz, ((StructMetaData) testStruct.data.valueMetaData).structClass);
assertTrue(testStruct.fields.containsKey(id));
ThriftMetadata.ThriftObject fieldMetadata =
(ThriftMetadata.ThriftObject) testStruct.fields.get(id);
assertEquals(testStruct, fieldMetadata.parent);
assertEquals(id, fieldMetadata.fieldId.getThriftFieldId());
assertEquals(fieldName, fieldMetadata.fieldId.getFieldName());
assertEquals(fieldName, fieldMetadata.data.fieldName);
assertEquals("root ==> " + fieldName, fieldMetadata.toString());
return fieldMetadata;
}
private void validateBasicFieldValueMetadata(
ThriftMetadata.ThriftObject fieldMetadata, String fieldName, byte ttype) {
assertEquals(ttype, fieldMetadata.data.valueMetaData.type);
assertEquals(getMetaDataClassForTType(ttype), fieldMetadata.data.valueMetaData.getClass());
Class<? extends ThriftMetadata.ThriftObject> fieldMetadataClass = getClassForTType(ttype);
assertEquals(fieldMetadataClass, fieldMetadata.getClass());
if (fieldMetadataClass == ThriftMetadata.ThriftPrimitive.class) {
ThriftMetadata.ThriftPrimitive primitive = (ThriftMetadata.ThriftPrimitive) fieldMetadata;
if (fieldName.startsWith("binary") && (ttype == TType.STRING)) {
assertTrue(primitive.isBinary());
} else {
assertFalse(primitive.isBinary());
}
}
}
private void validateFieldMetadata(
ThriftMetadata.ThriftStruct testStruct, int id, String fieldName, byte ttype) {
ThriftMetadata.ThriftObject fieldMetadata =
validateBasicFieldMetadata(testStruct, id, fieldName);
validateBasicFieldValueMetadata(fieldMetadata, fieldName, ttype);
}
private void validateListFieldMetadata(
ThriftMetadata.ThriftStruct testStruct, int id, String fieldName, byte ttype) {
ThriftMetadata.ThriftObject fieldMetadata =
validateBasicFieldMetadata(testStruct, id, fieldName);
validateBasicFieldValueMetadata(fieldMetadata, fieldName, TType.LIST);
ThriftMetadata.ThriftList thriftList = (ThriftMetadata.ThriftList) fieldMetadata;
ThriftMetadata.ThriftObject elementMetadata = thriftList.elementData;
validateBasicFieldValueMetadata(elementMetadata, fieldName + "_element", ttype);
}
private void validateSetFieldMetadata(
ThriftMetadata.ThriftStruct testStruct, int id, String fieldName, byte ttype) {
ThriftMetadata.ThriftObject fieldMetadata =
validateBasicFieldMetadata(testStruct, id, fieldName);
validateBasicFieldValueMetadata(fieldMetadata, fieldName, TType.SET);
ThriftMetadata.ThriftSet thriftSet = (ThriftMetadata.ThriftSet) fieldMetadata;
ThriftMetadata.ThriftObject elementMetadata = thriftSet.elementData;
validateBasicFieldValueMetadata(elementMetadata, fieldName + "_element", ttype);
}
private void validateMapFieldMetadata(
ThriftMetadata.ThriftStruct testStruct,
int id,
String fieldName,
byte keyType,
byte valueType) {
ThriftMetadata.ThriftObject fieldMetadata =
validateBasicFieldMetadata(testStruct, id, fieldName);
validateBasicFieldValueMetadata(fieldMetadata, fieldName, TType.MAP);
ThriftMetadata.ThriftMap thriftMap = (ThriftMetadata.ThriftMap) fieldMetadata;
ThriftMetadata.ThriftObject keyMetadata = thriftMap.keyData;
ThriftMetadata.ThriftObject valueMetadata = thriftMap.valueData;
validateBasicFieldValueMetadata(keyMetadata, fieldName + "_key", keyType);
validateBasicFieldValueMetadata(valueMetadata, fieldName + "_value", valueType);
}
private Class<? extends FieldValueMetaData> getMetaDataClassForTType(byte ttype) {
switch (ttype) {
case TType.STRUCT:
return StructMetaData.class;
case TType.LIST:
return ListMetaData.class;
case TType.MAP:
return MapMetaData.class;
case TType.SET:
return SetMetaData.class;
case TType.ENUM:
return EnumMetaData.class;
case TType.BOOL:
case TType.BYTE:
case TType.I16:
case TType.I32:
case TType.I64:
case TType.DOUBLE:
case TType.STRING:
return FieldValueMetaData.class;
default:
throw ThriftMetadata.unsupportedFieldTypeException(ttype);
}
}
private Class<? extends ThriftMetadata.ThriftObject> getClassForTType(byte ttype) {
switch (ttype) {
case TType.STRUCT:
return ThriftMetadata.ThriftStruct.class;
case TType.LIST:
return ThriftMetadata.ThriftList.class;
case TType.MAP:
return ThriftMetadata.ThriftMap.class;
case TType.SET:
return ThriftMetadata.ThriftSet.class;
case TType.ENUM:
return ThriftMetadata.ThriftEnum.class;
case TType.BOOL:
case TType.BYTE:
case TType.I16:
case TType.I32:
case TType.I64:
case TType.DOUBLE:
case TType.STRING:
return ThriftMetadata.ThriftPrimitive.class;
default:
throw ThriftMetadata.unsupportedFieldTypeException(ttype);
}
}
}