Skip to content

Commit

Permalink
Merge branch 'master' into test-ga
Browse files Browse the repository at this point in the history
  • Loading branch information
man-zhang committed Jul 31, 2023
2 parents 7b77924 + 06895fb commit 0f4c96f
Show file tree
Hide file tree
Showing 8 changed files with 919 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,18 +206,20 @@ public static InterfaceSchema build(String interfaceName, RPCType rpcType, Objec
InterfaceSchema schema = new InterfaceSchema(interfaceName, endpoints, getClientClass(client) , rpcType, skippedEndpoints, authEndpoints, endpointsForAuth);

for (Method m : interfaze.getDeclaredMethods()) {
if (filterRPCFunctionMethod(m, skipEndpointsByName, skipEndpointsByAnnotation, involveEndpointsByName, involveEndpointsByAnnotation)){
try{
EndpointSchema endpointSchema = build(schema, m, rpcType, authenticationDtoList, customizedRequestValueDtos, notNullAnnotations);
endpoints.add(endpointSchema);
}catch (RuntimeException exception){
if (filterRPCFunctionMethod(m)){
if (filterRPCFunctionMethodBasedOnSpecified(m, skipEndpointsByName, skipEndpointsByAnnotation, involveEndpointsByName, involveEndpointsByAnnotation)){
try{
EndpointSchema endpointSchema = build(schema, m, rpcType, authenticationDtoList, customizedRequestValueDtos, notNullAnnotations);
endpoints.add(endpointSchema);
}catch (RuntimeException exception){
/*
TODO might send such log to core in order to better identify problems which is not handled yet
*/
SimpleLogger.recordErrorMessage("EM Driver Error: fail to handle the endpoint schema "+m.getName()+" with the error msg:"+exception.getMessage());
SimpleLogger.recordErrorMessage("EM Driver Error: fail to handle the endpoint schema "+m.getName()+" with the error msg:"+exception.getMessage());
}
}else {
skippedEndpoints.add(m.getName());
}
} else {
skippedEndpoints.add(m.getName());
}

List<AuthenticationDto> auths = getAuthEndpointInInterface(authenticationDtoList, interfaceName, m);
Expand Down Expand Up @@ -337,19 +339,8 @@ private static List<AuthenticationDto> getAuthEndpointInInterface(List<Authentic
&& a.jsonAuthEndpoint.interfaceName.equals(interfaceName)).collect(Collectors.toList());
}

private static boolean filterRPCFunctionMethod(Method endpoint,
List<String> skipEndpointsByName, List<String> skipEndpointsByAnnotation,
List<String> involveEndpointsByName, List<String> involveEndpointsByAnnotation){
if (skipEndpointsByName != null && involveEndpointsByName != null)
throw new IllegalArgumentException("Driver Config Error: skipEndpointsByName and involveEndpointsByName should not be specified at same time.");
if (skipEndpointsByAnnotation != null && involveEndpointsByAnnotation != null)
throw new IllegalArgumentException("Driver Config Error: skipEndpointsByAnnotation and involveEndpointsByAnnotation should not be specified at same time.");
private static boolean filterRPCFunctionMethod(Method endpoint){

if (skipEndpointsByName != null || skipEndpointsByAnnotation != null)
return !anyMatchByNameAndAnnotation(endpoint, skipEndpointsByName, skipEndpointsByAnnotation);

if (involveEndpointsByName != null || involveEndpointsByAnnotation != null)
return anyMatchByNameAndAnnotation(endpoint, involveEndpointsByName, involveEndpointsByAnnotation);

/*
filter streaming API
Expand All @@ -370,6 +361,23 @@ private static boolean filterRPCFunctionMethod(Method endpoint,
return Modifier.isPublic(endpoint.getModifiers());
}

private static boolean filterRPCFunctionMethodBasedOnSpecified(Method endpoint,
List<String> skipEndpointsByName, List<String> skipEndpointsByAnnotation,
List<String> involveEndpointsByName, List<String> involveEndpointsByAnnotation){
if (skipEndpointsByName != null && involveEndpointsByName != null)
throw new IllegalArgumentException("Driver Config Error: skipEndpointsByName and involveEndpointsByName should not be specified at same time.");
if (skipEndpointsByAnnotation != null && involveEndpointsByAnnotation != null)
throw new IllegalArgumentException("Driver Config Error: skipEndpointsByAnnotation and involveEndpointsByAnnotation should not be specified at same time.");

if (skipEndpointsByName != null || skipEndpointsByAnnotation != null)
return !anyMatchByNameAndAnnotation(endpoint, skipEndpointsByName, skipEndpointsByAnnotation);

if (involveEndpointsByName != null || involveEndpointsByAnnotation != null)
return anyMatchByNameAndAnnotation(endpoint, involveEndpointsByName, involveEndpointsByAnnotation);

return true;
}

private static boolean isPotentialStreamingAPI(Method method){
Class<?> returnType = method.getReturnType();
if (returnType.equals(Iterator.class))
Expand Down Expand Up @@ -552,6 +560,9 @@ private static NamedTypedValue build(InterfaceSchema schema, Class<?> clazz, Typ
} else if (clazz == ByteBuffer.class){
// handle binary of thrift
namedValue = new ByteBufferParam(name, accessibleSchema, spec);
} else if (clazz.getName().equals(Protobuf3ByteStringType.PROTOBUF3_BYTE_STRING_TYPE_NAME)){
Protobuf3ByteStringType type = Protobuf3ByteStringType.getInstance(spec, clazz);
namedValue = new Protobuf3ByteStringParam(name, type, accessibleSchema);
} else if (List.class.isAssignableFrom(clazz) || Set.class.isAssignableFrom(clazz)){
if (genericType == null)
throw new RuntimeException("genericType should not be null for List and Set class");
Expand Down Expand Up @@ -932,12 +943,13 @@ private static boolean filterProtobuf3Field(Field field){
return (!field.getName().equals("bitField0_"));
}

/**
* TODO need to support com.google.protobuf.ByteString
*
*/

private static boolean filterProtobuf3Type(Class<?> clazz){
return !clazz.getName().equals("com.google.protobuf.ByteString");
/*
support all types for proto 3
might add if we found any type is not supported yet
*/
return true;
}

private static void handleNamedValueWithCustomizedDto(NamedTypedValue namedTypedValue, Map<Integer, CustomizedRequestValueDto> customizationDtos, Set<String> relatedCustomization){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,13 @@ public List<String> newInstanceWithJava(boolean isDeclaration, boolean doesInclu
if (f.accessibleSchema != null && f.accessibleSchema.setterMethodName != null){
String fName = ownVarName;
boolean fdeclar = false;
if (f instanceof ObjectParam || f instanceof MapParam || f instanceof CollectionParam || f instanceof DateParam || f instanceof BigDecimalParam || f instanceof BigIntegerParam){
if (needRenameField(f)){
fName = varName+"_"+f.getName();
fdeclar = true;
}
codes.addAll(f.newInstanceWithJava(fdeclar, true, fName, indent+1));

if (f instanceof ObjectParam || f instanceof MapParam || f instanceof CollectionParam || f instanceof DateParam || f instanceof BigDecimalParam || f instanceof BigIntegerParam){
if (needRenameField(f)){
CodeJavaGenerator.addCode(codes, CodeJavaGenerator.methodInvocation(ownVarName, f.accessibleSchema.setterMethodName, fName)+CodeJavaGenerator.appendLast(),indent+1);
}
}else {
Expand All @@ -279,6 +279,10 @@ public List<String> newInstanceWithJava(boolean isDeclaration, boolean doesInclu
return codes;
}

private boolean needRenameField(NamedTypedValue f){
return f instanceof ObjectParam || f instanceof MapParam || f instanceof CollectionParam || f instanceof DateParam || f instanceof BigDecimalParam || f instanceof BigIntegerParam || f instanceof Protobuf3ByteStringParam;
}

@Override
public List<String> newAssertionWithJava(int indent, String responseVarName, int maxAssertionForDataInCollection) {
List<String> codes = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package org.evomaster.client.java.controller.problem.rpc.schema.params;

import org.evomaster.client.java.controller.api.dto.problem.rpc.ParamDto;
import org.evomaster.client.java.controller.problem.rpc.CodeJavaGenerator;
import org.evomaster.client.java.controller.problem.rpc.schema.types.AccessibleSchema;
import org.evomaster.client.java.controller.problem.rpc.schema.types.Protobuf3ByteStringType;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* this is for handling bytes in gRPC with protobuf3 <a href="https://protobuf.dev/reference/java/api-docs/com/google/protobuf/ByteString">ByteString</a>
*
* handle it as string with utf8 now
* <a href="https://protobuf.dev/reference/java/api-docs/com/google/protobuf/ByteString.html#copyFromUtf8-java.lang.String-">copyFromUtf8</a>
* <a href="https://protobuf.dev/reference/java/api-docs/com/google/protobuf/ByteString.html#toStringUtf8--">toStringUtf8</a>
*/
public class Protobuf3ByteStringParam extends NamedTypedValue<Protobuf3ByteStringType,String>{


public final static String PROTOBUF3_BYTE_STRING_METHOD_COPY_FROM_METHOD = "copyFromUtf8";

public final static String PROTOBUF3_BYTE_STRING_METHOD_TO_STRING_UTF8 = "toStringUtf8";

public Protobuf3ByteStringParam(String name, Protobuf3ByteStringType type, AccessibleSchema accessibleSchema){
super(name, type, accessibleSchema);
}

@Override
public Object newInstance() throws ClassNotFoundException {
if (getValue() == null) return null;

try {
Method setMethod = getType().getClazz().getMethod(PROTOBUF3_BYTE_STRING_METHOD_COPY_FROM_METHOD, String.class);
Object instance = setMethod.invoke(null, getValue());
return instance;
} catch (NoSuchMethodException e) {
throw new RuntimeException("fail to find method copyFromUtf8 in the class com.google.protobuf.ByteString with error msg:", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("fail to invoke method copyFromUtf8 in the class com.google.protobuf.ByteString with error msg:", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("fail to access method copyFromUtf8 in the class com.google.protobuf.ByteString with error msg:", e);
}
}

@Override
public ParamDto getDto() {
ParamDto dto = super.getDto();
if (getValue() != null){
dto.stringValue = getValue();
}

return dto;
}


@Override
public Protobuf3ByteStringParam copyStructure() {
return new Protobuf3ByteStringParam(getName(), getType(), accessibleSchema);
}

@Override
public void setValueBasedOnDto(ParamDto dto) {
if (dto.stringValue != null)
setValue(dto.stringValue);
}

@Override
protected void setValueBasedOnValidInstance(Object instance) {
if (instance == null) setValue(null);
try {
Method getMethod = getType().getClazz().getMethod(PROTOBUF3_BYTE_STRING_METHOD_TO_STRING_UTF8);
Object strutf8 = getMethod.invoke(instance);
if (strutf8 instanceof String)
setValue((String) strutf8);
else{
throw new RuntimeException("fail to get string value of ByteString with toStringUtf8");
}
} catch (NoSuchMethodException e) {
throw new RuntimeException("fail to find method toStringUtf8 in the class com.google.protobuf.ByteString with error msg:", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("fail to invoke method toStringUtf8 in the class com.google.protobuf.ByteString with error msg:", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("fail to access method toStringUtf8 in the class com.google.protobuf.ByteString with error msg:", e);
}

}

@Override
public List<String> newInstanceWithJava(boolean isDeclaration, boolean doesIncludeName, String variableName, int indent) {
List<String> codes = new ArrayList<>();
String var = CodeJavaGenerator.oneLineInstance(isDeclaration, doesIncludeName, getType().getFullTypeName(), variableName, null);
CodeJavaGenerator.addCode(codes, var, indent);
if (getValue() == null) return codes;
CodeJavaGenerator.addCode(codes, "{", indent);
CodeJavaGenerator.addCode(codes,
CodeJavaGenerator.oneLineInstance(false, true, getType().getFullTypeName(), variableName, getType().getFullTypeName()+"."+PROTOBUF3_BYTE_STRING_METHOD_COPY_FROM_METHOD+"(\""+ getValue() + "\")"), indent + 1);
CodeJavaGenerator.addCode(codes, "}", indent);
return codes;
}

@Override
public List<String> newAssertionWithJava(int indent, String responseVarName, int maxAssertionForDataInCollection) {
StringBuilder sb = new StringBuilder();
sb.append(CodeJavaGenerator.getIndent(indent));
if (getValue() == null)
sb.append(CodeJavaGenerator.junitAssertNull(responseVarName));
else{
sb.append(CodeJavaGenerator.junitAssertEquals("\""+getValueAsJavaString()+"\"", responseVarName+"."+PROTOBUF3_BYTE_STRING_METHOD_TO_STRING_UTF8+"()"));
}

return Collections.singletonList(sb.toString());
}

@Override
public String getValueAsJavaString() {
return getValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.evomaster.client.java.controller.problem.rpc.schema.types;

import org.evomaster.client.java.controller.api.dto.problem.rpc.RPCSupportedDataType;
import org.evomaster.client.java.controller.api.dto.problem.rpc.TypeDto;


public class Protobuf3ByteStringType extends TypeSchema {
public final static String PROTOBUF3_BYTE_STRING_SIMPLE_TYPE_NAME = "ByteString";
public final static String PROTOBUF3_BYTE_STRING_TYPE_NAME = "com.google.protobuf.ByteString";

private static Protobuf3ByteStringType instance;
public static Protobuf3ByteStringType getInstance(JavaDtoSpec spec, Class<?> clazz){
if (instance == null)
instance = new Protobuf3ByteStringType(spec, clazz);
return instance;
}

public Protobuf3ByteStringType(JavaDtoSpec spec, Class<?> clazz) {
super(PROTOBUF3_BYTE_STRING_SIMPLE_TYPE_NAME, PROTOBUF3_BYTE_STRING_TYPE_NAME, clazz, spec);
}

@Override
public TypeDto getDto() {
TypeDto dto = super.getDto();
dto.type = RPCSupportedDataType.BYTEBUFFER;
return dto;
}

@Override
public Protobuf3ByteStringType copy() {
return new Protobuf3ByteStringType(spec, getClazz());
}
}
Loading

0 comments on commit 0f4c96f

Please sign in to comment.