Skip to content

Commit

Permalink
fix: Fix hang if the provided trigger function needed to call back to…
Browse files Browse the repository at this point in the history
… ContractCase's core
  • Loading branch information
TimothyJones committed Oct 17, 2024
1 parent 1913332 commit 6fefba5
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,24 +152,25 @@ public void onNext(final ContractResponse coreResponse) {
);
}

rpcConnector.sendResponse(
ResultResponse.newBuilder().setResult(
mapResult(
ConnectorResult.fromConnectorResult(
configHandle.getTriggerFunction(handle)
.trigger(ConnectorIncomingMapper.map(
triggerFunctionRequest.getSetup(),
(name, args) -> rpcConnector.executeCallAndWait(
rpcConnector.makeInvokeFunction(
name,
args
), "Invoking function '" + name + "' in core")
)
))
)
).build(),
requestId, LogLevel.NONE
);
executor.submit(() ->
rpcConnector.sendResponse(
ResultResponse.newBuilder().setResult(
mapResult(
ConnectorResult.fromConnectorResult(
configHandle.getTriggerFunction(handle)
.trigger(ConnectorIncomingMapper.map(
triggerFunctionRequest.getSetup(),
(name, args) -> rpcConnector.executeCallAndWait(
rpcConnector.makeInvokeFunction(
name,
args
), "Invoking function '" + name + "' in core")
)
))
)
).build(),
requestId, LogLevel.NONE
));
}
case RESULT_RESPONSE -> {
rpcConnector.completeWait(requestId, coreResponse.getResultResponse().getResult());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
package io.contract_testing.contractcase.test.function;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.assertj.core.api.Assertions.assertThat;

import io.contract_testing.contractcase.ContractCaseConfig;
import io.contract_testing.contractcase.ContractDefiner;
import io.contract_testing.contractcase.ExampleDefinition;
import io.contract_testing.contractcase.IndividualSuccessTestConfig;
import io.contract_testing.contractcase.InvokableFunctions;
import io.contract_testing.contractcase.IndividualSuccessTestConfig.IndividualSuccessTestConfigBuilder;
import io.contract_testing.contractcase.LogLevel;
import io.contract_testing.contractcase.PublishType;
import io.contract_testing.contractcase.definitions.matchers.AnyInteger;
import io.contract_testing.contractcase.definitions.matchers.AnyNull;
import io.contract_testing.contractcase.definitions.mocks.functions.FunctionExecutionExample;
import io.contract_testing.contractcase.definitions.mocks.functions.WillReceiveFunctionCall;
import io.contract_testing.contractcase.definitions.mocks.functions.WillCallFunction;
import java.util.List;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;

public class FunctionCallerExampleTest {

static final ObjectMapper mapper = new ObjectMapper();
private static final ContractDefiner contract = new ContractDefiner(ContractCaseConfig.ContractCaseConfigBuilder.aContractCaseConfig()
.consumerName("Java Function Caller Example")
.providerName("Java Function Execution Example")
Expand All @@ -34,56 +30,51 @@ static void after() {
contract.endRecord();
}

public class NoArgFunction {
public void apply() {
}
}

@Test
public void testNoArgFunction() {
contract.registerFunction("NoArgFunction", () -> {
return null;
});
contract.runExample(new ExampleDefinition<>(
List.of(),
new WillReceiveFunctionCall(FunctionExecutionExample.builder()
.arguments(List.of())
.returnValue(new AnyNull())
.functionName("NoArgFunction")
.build())
));
contract.runExample(
new ExampleDefinition<>(
List.of(),
new WillCallFunction(FunctionExecutionExample.builder()
.arguments(List.of())
.returnValue(new AnyNull())
.functionName("NoArgFunction")
.build())
),
IndividualSuccessTestConfigBuilder.<String>builder()
.withTrigger((setupInfo) ->
setupInfo.getFunction(setupInfo.getMockSetup("functionHandle"))
.apply(List.of()))
.withTestResponse((result, setupInfo) -> {
assertThat(result).isEqualTo("null");
})
);
}

@Test
public void testOneArgFunction() {

Function<Integer, String> functionUnderTest = (Integer num) -> num + " pages";

contract.registerFunction("PageNumbers", convertJsonArgs(functionUnderTest));
contract.runExample(new ExampleDefinition<>(
contract.runExample(
new ExampleDefinition<>(
List.of(),
new WillReceiveFunctionCall(FunctionExecutionExample.builder()
new WillCallFunction(FunctionExecutionExample.builder()
.arguments(List.of(new AnyInteger(2)))
.returnValue("2 pages")
.functionName("PageNumbers")
.build())
),
IndividualSuccessTestConfig.IndividualSuccessTestConfigBuilder.builder()
.build()
IndividualSuccessTestConfigBuilder.<String>builder()
.withTrigger((setupInfo) ->
setupInfo.getFunction(setupInfo.getMockSetup("functionHandle"))
.apply(List.of("2")))
.withTestResponse((result, setupInfo) -> {
assertThat(result).isEqualTo("\"2 pages\"");
})
);
}

@NotNull
private static InvokableFunctions.InvokableFunction1 convertJsonArgs(Function<Integer, String> functionUnderTest) {
return (String a) -> {
try {
var arg1 = mapper.readValue(a, Integer.class);
return mapper.writeValueAsString(mapper.writeValueAsString(functionUnderTest.apply(arg1)));
} catch (JsonProcessingException e) {
throw new RuntimeException("Unable to parse argument");
}
};
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package io.contract_testing.contractcase.test.function;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.contract_testing.contractcase.ContractCaseConfig;
import io.contract_testing.contractcase.ContractDefiner;
import io.contract_testing.contractcase.ExampleDefinition;
import io.contract_testing.contractcase.IndividualSuccessTestConfig;
import io.contract_testing.contractcase.InvokableFunctions;
import io.contract_testing.contractcase.PublishType;
import io.contract_testing.contractcase.definitions.matchers.AnyInteger;
import io.contract_testing.contractcase.definitions.matchers.AnyNull;
import io.contract_testing.contractcase.definitions.mocks.functions.FunctionExecutionExample;
import io.contract_testing.contractcase.definitions.mocks.functions.WillReceiveFunctionCall;
import java.util.List;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;

public class FunctionImplementerExampleTest {

static final ObjectMapper mapper = new ObjectMapper();
private static final ContractDefiner contract = new ContractDefiner(ContractCaseConfig.ContractCaseConfigBuilder.aContractCaseConfig()
.consumerName("Java Function Implementer Example")
.providerName("Java Function Execution Example")
.publish(PublishType.NEVER)
.contractDir("temp-contracts")
.build());

@AfterAll
static void after() {
contract.endRecord();
}


@Test
public void testNoArgFunction() {
contract.registerFunction("NoArgFunction", () -> {
return null;
});
contract.runExample(new ExampleDefinition<>(
List.of(),
new WillReceiveFunctionCall(FunctionExecutionExample.builder()
.arguments(List.of())
.returnValue(new AnyNull())
.functionName("NoArgFunction")
.build())
));
}

@Test
public void testOneArgFunction() {

Function<Integer, String> functionUnderTest = (Integer num) -> num + " pages";

contract.registerFunction("PageNumbers", convertJsonArgs(functionUnderTest));
contract.runExample(new ExampleDefinition<>(
List.of(),
new WillReceiveFunctionCall(FunctionExecutionExample.builder()
.arguments(List.of(new AnyInteger(2)))
.returnValue("2 pages")
.functionName("PageNumbers")
.build())
),
IndividualSuccessTestConfig.IndividualSuccessTestConfigBuilder.builder()
.build()
);
}

@NotNull
private static InvokableFunctions.InvokableFunction1 convertJsonArgs(Function<Integer, String> functionUnderTest) {
return (String a) -> {
try {
var arg1 = mapper.readValue(a, Integer.class);
return mapper.writeValueAsString(mapper.writeValueAsString(functionUnderTest.apply(arg1)));
} catch (JsonProcessingException e) {
throw new RuntimeException("Unable to parse argument");
}
};
}


}

0 comments on commit 6fefba5

Please sign in to comment.