Fix durable return type void issue (#711)

* fix durable return type void issue

add unit tests

* fix stupid test name
This commit is contained in:
kaibocai 2023-04-14 12:35:13 -05:00 коммит произвёл GitHub
Родитель 9881b3a3e8
Коммит 2bc845aeb3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 84 добавлений и 3 удалений

Просмотреть файл

@ -52,7 +52,11 @@ public class ParameterResolver {
BindingData actualArg = argument.orElseThrow(WrongMethodTypeException::new);
invokeInfo.appendArgument(actualArg.getValue());
}
if (!method.getMethod().getReturnType().equals(void.class) && !method.getMethod().getReturnType().equals(Void.class)) {
// For function annotated with @HasImplicitOutput, we should allow it to send back data even function's return type is void
// Reference to https://github.com/microsoft/durabletask-java/issues/126
if (!method.getMethod().getReturnType().equals(void.class)
&& !method.getMethod().getReturnType().equals(Void.class)
|| method.hasImplicitOutput()) {
dataStore.getOrAddDataTarget(invokeInfo.getOutputsId(), BindingDataStore.RETURN_NAME, method.getMethod().getReturnType(), method.hasImplicitOutput());
}
return invokeInfo;
@ -63,8 +67,8 @@ public class ParameterResolver {
}
public static final class InvokeInfoBuilder extends JavaMethodInvokeInfo.Builder {
public InvokeInfoBuilder(MethodBindInfo method) { super.setMethod(method.getMethod()); }
private final UUID outputsId = UUID.randomUUID();
public InvokeInfoBuilder(MethodBindInfo method) { super.setMethod(method.getMethod()); }
public UUID getOutputsId() {
return outputsId;

Просмотреть файл

@ -12,7 +12,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)

Просмотреть файл

@ -0,0 +1,78 @@
package com.microsoft.azure.functions.worker.broker;
import com.microsoft.azure.functions.rpc.messages.RpcException;
import com.microsoft.azure.functions.spi.inject.FunctionInstanceInjector;
import com.microsoft.azure.functions.worker.WorkerLogManager;
import com.microsoft.azure.functions.worker.binding.BindingDataStore;
import com.microsoft.azure.functions.worker.binding.ExecutionContextDataSource;
import com.microsoft.azure.functions.worker.binding.ExecutionRetryContext;
import com.microsoft.azure.functions.worker.binding.ExecutionTraceContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class ParameterResolverTest {
private ExecutionContextDataSource executionContextDataSource;
@Mock
private MethodBindInfo methodBindInfo;
@BeforeEach
public void setup() {
String invocationId = "testInvocationId";
ExecutionTraceContext traceContext = new ExecutionTraceContext("traceParent", "traceState", new HashMap<>());
ExecutionRetryContext retryContext = new ExecutionRetryContext(1, 2, RpcException.newBuilder().build());
String functionName = "ParameterResolverTest";
BindingDataStore dataStore = new BindingDataStore();
dataStore.setBindingDefinitions(new HashMap<>());
try (MockedStatic<WorkerLogManager> workerLogManagerMockedStatic = Mockito.mockStatic(WorkerLogManager.class)) {
workerLogManagerMockedStatic.when(() -> WorkerLogManager.getInvocationLogger(invocationId))
.thenReturn(Logger.getAnonymousLogger());
executionContextDataSource = new ExecutionContextDataSource(invocationId,
traceContext, retryContext, functionName, dataStore, methodBindInfo,
this.getClass(), new ArrayList<>(), new FunctionInstanceInjector() {
@Override
public <T> T getInstance(Class<T> functionClass) throws Exception {
return null;
}
});
}
}
@Test
public void testResolveArgumentsHasImplicitOutputTrue() throws Exception {
Method testMethod = this.getClass().getDeclaredMethod("testMethod");
when(methodBindInfo.hasImplicitOutput()).thenReturn(true);
when(methodBindInfo.getMethod()).thenReturn(testMethod);
when(methodBindInfo.getParams()).thenReturn(new ArrayList<>());
ParameterResolver.resolveArguments(executionContextDataSource);
assertTrue(executionContextDataSource.getDataStore().getDataTargetTypedValue(BindingDataStore.RETURN_NAME).isPresent());
}
@Test
public void testResolveArgumentsHasImplicitOutputFalse() throws Exception {
Method testMethod = this.getClass().getDeclaredMethod("testMethod");
when(methodBindInfo.hasImplicitOutput()).thenReturn(false);
when(methodBindInfo.getMethod()).thenReturn(testMethod);
when(methodBindInfo.getParams()).thenReturn(new ArrayList<>());
ParameterResolver.resolveArguments(executionContextDataSource);
assertFalse(executionContextDataSource.getDataStore().getDataTargetTypedValue(BindingDataStore.RETURN_NAME).isPresent());
}
public void testMethod() {}
}