Search in sources :

Example 16 with CounterfactualDomainRange

use of org.kie.kogito.explainability.api.CounterfactualDomainRange in project kogito-apps by kiegroup.

the class TrustyServiceTest method givenStoredExecutionWhenCounterfactualRequestIsMadeThenExplainabilityEventHasCorrectPayload.

@Test
@SuppressWarnings("unchecked")
void givenStoredExecutionWhenCounterfactualRequestIsMadeThenExplainabilityEventHasCorrectPayload() {
    Storage<String, Decision> decisionStorage = mock(Storage.class);
    Storage<String, CounterfactualExplainabilityRequest> counterfactualStorage = mock(Storage.class);
    ArgumentCaptor<BaseExplainabilityRequest> explainabilityEventArgumentCaptor = ArgumentCaptor.forClass(BaseExplainabilityRequest.class);
    Decision decision = new Decision(TEST_EXECUTION_ID, TEST_SOURCE_URL, TEST_SERVICE_URL, 0L, true, null, "model", "modelNamespace", List.of(new DecisionInput("IN1", "yearsOfService", new UnitValue("integer", "integer", new IntNode(10)))), List.of(new DecisionOutcome("OUT1", "salary", "SUCCEEDED", new UnitValue("integer", "integer", new IntNode(1000)), Collections.emptyList(), Collections.emptyList())));
    when(decisionStorage.containsKey(eq(TEST_EXECUTION_ID))).thenReturn(true);
    when(trustyStorageServiceMock.getDecisionsStorage()).thenReturn(decisionStorage);
    when(trustyStorageServiceMock.getCounterfactualRequestStorage()).thenReturn(counterfactualStorage);
    when(decisionStorage.get(eq(TEST_EXECUTION_ID))).thenReturn(decision);
    trustyService.requestCounterfactuals(TEST_EXECUTION_ID, List.of(new NamedTypedValue("salary", new UnitValue("integer", "integer", new IntNode(2000)))), List.of(new CounterfactualSearchDomain("yearsOfService", new CounterfactualSearchDomainUnitValue("integer", "integer", false, new CounterfactualDomainRange(new IntNode(10), new IntNode(30))))));
    verify(explainabilityRequestProducerMock).sendEvent(explainabilityEventArgumentCaptor.capture());
    BaseExplainabilityRequest event = explainabilityEventArgumentCaptor.getValue();
    CounterfactualExplainabilityRequest request = (CounterfactualExplainabilityRequest) event;
    assertEquals(TEST_EXECUTION_ID, request.getExecutionId());
    assertEquals(TEST_SERVICE_URL, request.getServiceUrl());
    // Check original input value has been copied into CF request
    assertEquals(1, request.getOriginalInputs().size());
    assertTrue(request.getOriginalInputs().stream().anyMatch(i -> i.getName().equals("yearsOfService")));
    // It is safe to use the iterator unchecked as the collection only contains one item
    assertEquals(decision.getInputs().iterator().next().getValue().toUnit().getValue().asInt(), request.getOriginalInputs().iterator().next().getValue().toUnit().getValue().asInt());
    // Check CF goals have been copied into CF request
    assertEquals(1, request.getGoals().size());
    assertTrue(request.getGoals().stream().anyMatch(g -> g.getName().equals("salary")));
    // It is safe to use the iterator unchecked as the collection only contains one item
    assertEquals(2000, request.getGoals().iterator().next().getValue().toUnit().getValue().asInt());
    // Check CF search domains have been copied into CF request
    assertEquals(1, request.getSearchDomains().size());
    assertTrue(request.getSearchDomains().stream().anyMatch(sd -> sd.getName().equals("yearsOfService")));
    // It is safe to use the iterator unchecked as the collection only contains one item
    CounterfactualSearchDomainValue searchDomain = request.getSearchDomains().iterator().next().getValue();
    assertTrue(searchDomain instanceof CounterfactualSearchDomainUnitValue);
    CounterfactualSearchDomainUnitValue unit = (CounterfactualSearchDomainUnitValue) searchDomain;
    assertFalse(unit.isFixed());
    assertNotNull(unit.getDomain());
    assertTrue(unit.getDomain() instanceof CounterfactualDomainRange);
    CounterfactualDomainRange range = (CounterfactualDomainRange) unit.getDomain();
    assertEquals(10, range.getLowerBound().asInt());
    assertEquals(30, range.getUpperBound().asInt());
    // Check Max Running Time Seconds
    assertEquals(MAX_RUNNING_TIME_SECONDS, request.getMaxRunningTimeSeconds());
}
Also used : CounterfactualExplainabilityRequest(org.kie.kogito.explainability.api.CounterfactualExplainabilityRequest) DecisionInput(org.kie.kogito.trusty.storage.api.model.decision.DecisionInput) BeforeEach(org.junit.jupiter.api.BeforeEach) LIMEExplainabilityResult(org.kie.kogito.explainability.api.LIMEExplainabilityResult) BaseExplainabilityRequest(org.kie.kogito.explainability.api.BaseExplainabilityRequest) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) CounterfactualSearchDomainValue(org.kie.kogito.explainability.api.CounterfactualSearchDomainValue) CounterfactualDomainRange(org.kie.kogito.explainability.api.CounterfactualDomainRange) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) CounterfactualExplainerServiceHandler(org.kie.kogito.trusty.service.common.handlers.CounterfactualExplainerServiceHandler) Map(java.util.Map) CounterfactualExplainabilityResultsManagerSlidingWindow(org.kie.kogito.trusty.service.common.handlers.CounterfactualExplainabilityResultsManagerSlidingWindow) JsonNode(com.fasterxml.jackson.databind.JsonNode) Instance(javax.enterprise.inject.Instance) CounterfactualExplainabilityResultsManagerDuplicates(org.kie.kogito.trusty.service.common.handlers.CounterfactualExplainabilityResultsManagerDuplicates) CounterfactualExplainabilityRequest(org.kie.kogito.explainability.api.CounterfactualExplainabilityRequest) NamedTypedValue(org.kie.kogito.explainability.api.NamedTypedValue) ExplainabilityStatus(org.kie.kogito.explainability.api.ExplainabilityStatus) UUID(java.util.UUID) TextNode(com.fasterxml.jackson.databind.node.TextNode) UnitValue(org.kie.kogito.tracing.typedvalue.UnitValue) Test(org.junit.jupiter.api.Test) DMNModelMetadata(org.kie.kogito.trusty.storage.api.model.decision.DMNModelMetadata) List(java.util.List) ExplainabilityRequestProducer(org.kie.kogito.trusty.service.common.messaging.outgoing.ExplainabilityRequestProducer) OffsetDateTime(java.time.OffsetDateTime) Stream(java.util.stream.Stream) CollectionValue(org.kie.kogito.tracing.typedvalue.CollectionValue) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) CounterfactualExplainabilityResult(org.kie.kogito.explainability.api.CounterfactualExplainabilityResult) CounterfactualSearchDomain(org.kie.kogito.explainability.api.CounterfactualSearchDomain) StorageImplMock(org.kie.kogito.trusty.service.common.mocks.StorageImplMock) DecisionOutcome(org.kie.kogito.trusty.storage.api.model.decision.DecisionOutcome) Mockito.mock(org.mockito.Mockito.mock) IntStream(java.util.stream.IntStream) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Decision(org.kie.kogito.trusty.storage.api.model.decision.Decision) DecisionInput(org.kie.kogito.trusty.storage.api.model.decision.DecisionInput) IntNode(com.fasterxml.jackson.databind.node.IntNode) Query(org.kie.kogito.persistence.api.query.Query) StructureValue(org.kie.kogito.tracing.typedvalue.StructureValue) ArrayList(java.util.ArrayList) MatchedExecutionHeaders(org.kie.kogito.trusty.service.common.models.MatchedExecutionHeaders) CounterfactualSearchDomainStructureValue(org.kie.kogito.explainability.api.CounterfactualSearchDomainStructureValue) ArgumentCaptor(org.mockito.ArgumentCaptor) ExplainerServiceHandler(org.kie.kogito.trusty.service.common.handlers.ExplainerServiceHandler) ExplainerServiceHandlerRegistry(org.kie.kogito.trusty.service.common.handlers.ExplainerServiceHandlerRegistry) Storage(org.kie.kogito.persistence.api.Storage) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) LIMEExplainerServiceHandler(org.kie.kogito.trusty.service.common.handlers.LIMEExplainerServiceHandler) TrustyStorageService(org.kie.kogito.trusty.storage.common.TrustyStorageService) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) Mockito.never(org.mockito.Mockito.never) CounterfactualDomain(org.kie.kogito.explainability.api.CounterfactualDomain) CounterfactualSearchDomainUnitValue(org.kie.kogito.explainability.api.CounterfactualSearchDomainUnitValue) Assertions(org.junit.jupiter.api.Assertions) Collections(java.util.Collections) DMNModelWithMetadata(org.kie.kogito.trusty.storage.api.model.decision.DMNModelWithMetadata) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CounterfactualDomainRange(org.kie.kogito.explainability.api.CounterfactualDomainRange) DecisionOutcome(org.kie.kogito.trusty.storage.api.model.decision.DecisionOutcome) UnitValue(org.kie.kogito.tracing.typedvalue.UnitValue) CounterfactualSearchDomainUnitValue(org.kie.kogito.explainability.api.CounterfactualSearchDomainUnitValue) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Decision(org.kie.kogito.trusty.storage.api.model.decision.Decision) IntNode(com.fasterxml.jackson.databind.node.IntNode) NamedTypedValue(org.kie.kogito.explainability.api.NamedTypedValue) BaseExplainabilityRequest(org.kie.kogito.explainability.api.BaseExplainabilityRequest) CounterfactualSearchDomainUnitValue(org.kie.kogito.explainability.api.CounterfactualSearchDomainUnitValue) CounterfactualSearchDomainValue(org.kie.kogito.explainability.api.CounterfactualSearchDomainValue) CounterfactualSearchDomain(org.kie.kogito.explainability.api.CounterfactualSearchDomain) Test(org.junit.jupiter.api.Test)

Example 17 with CounterfactualDomainRange

use of org.kie.kogito.explainability.api.CounterfactualDomainRange in project kogito-apps by kiegroup.

the class AbstractTrustyServiceIT method testCounterfactuals_StoreMultipleForMultipleExecutionsAndRetrieveSingleWithEmptyDefinition.

@Test
public void testCounterfactuals_StoreMultipleForMultipleExecutionsAndRetrieveSingleWithEmptyDefinition() {
    String executionId1 = "myCFExecution1";
    storeExecution(executionId1, 0L);
    String executionId2 = "myCFExecution2";
    storeExecution(executionId2, 0L);
    // The Goals structures must be comparable to the original decisions outcomes.
    // The Search Domain structures must be identical those of the original decision inputs.
    CounterfactualSearchDomain searchDomain = buildSearchDomainUnit("test", "number", new CounterfactualDomainRange(new IntNode(1), new IntNode(2)));
    CounterfactualExplainabilityRequest request1 = trustyService.requestCounterfactuals(executionId1, Collections.emptyList(), Collections.singletonList(searchDomain));
    assertNotNull(request1);
    assertEquals(request1.getExecutionId(), executionId1);
    assertNotNull(request1.getCounterfactualId());
    CounterfactualExplainabilityRequest request2 = trustyService.requestCounterfactuals(executionId2, Collections.emptyList(), Collections.singletonList(searchDomain));
    assertNotNull(request2);
    assertEquals(request2.getExecutionId(), executionId2);
    assertNotNull(request2.getCounterfactualId());
    CounterfactualExplainabilityRequest result1 = trustyService.getCounterfactualRequest(executionId1, request1.getCounterfactualId());
    assertNotNull(result1);
    assertEquals(request1.getExecutionId(), result1.getExecutionId());
    assertEquals(request1.getCounterfactualId(), result1.getCounterfactualId());
}
Also used : CounterfactualExplainabilityRequest(org.kie.kogito.explainability.api.CounterfactualExplainabilityRequest) IntNode(com.fasterxml.jackson.databind.node.IntNode) CounterfactualDomainRange(org.kie.kogito.explainability.api.CounterfactualDomainRange) CounterfactualSearchDomain(org.kie.kogito.explainability.api.CounterfactualSearchDomain) Test(org.junit.jupiter.api.Test)

Example 18 with CounterfactualDomainRange

use of org.kie.kogito.explainability.api.CounterfactualDomainRange in project kogito-apps by kiegroup.

the class AbstractTrustyServiceIT method testCounterfactuals_StoreSingleAndRetrieveSingleWithGoals.

@Test
public void testCounterfactuals_StoreSingleAndRetrieveSingleWithGoals() {
    String executionId = "myCFExecution1";
    storeExecutionWithOutcomes(executionId, 0L);
    // The Goals structures must be comparable to the original decisions outcomes.
    // The Search Domain structures must be identical those of the original decision inputs.
    CounterfactualSearchDomain searchDomain = buildSearchDomainUnit("test", "number", new CounterfactualDomainRange(new IntNode(1), new IntNode(2)));
    NamedTypedValue goal1 = buildGoalUnit("outcome1", "number", new IntNode(25));
    NamedTypedValue goal2 = buildGoalUnit("outcome2", "string", new TextNode("cheese"));
    CounterfactualExplainabilityRequest request = trustyService.requestCounterfactuals(executionId, List.of(goal1, goal2), Collections.singletonList(searchDomain));
    assertNotNull(request);
    assertEquals(request.getExecutionId(), executionId);
    assertNotNull(request.getCounterfactualId());
    assertEquals(2, request.getGoals().size());
    List<NamedTypedValue> requestGoals = new ArrayList<>(request.getGoals());
    assertCounterfactualGoal(goal1, requestGoals.get(0));
    assertCounterfactualGoal(goal2, requestGoals.get(1));
    CounterfactualExplainabilityRequest result = trustyService.getCounterfactualRequest(executionId, request.getCounterfactualId());
    assertNotNull(result);
    assertEquals(request.getExecutionId(), result.getExecutionId());
    assertEquals(request.getCounterfactualId(), result.getCounterfactualId());
    assertEquals(2, result.getGoals().size());
    List<NamedTypedValue> resultGoals = new ArrayList<>(request.getGoals());
    assertCounterfactualGoal(goal1, resultGoals.get(0));
    assertCounterfactualGoal(goal2, resultGoals.get(1));
}
Also used : CounterfactualExplainabilityRequest(org.kie.kogito.explainability.api.CounterfactualExplainabilityRequest) IntNode(com.fasterxml.jackson.databind.node.IntNode) NamedTypedValue(org.kie.kogito.explainability.api.NamedTypedValue) CounterfactualDomainRange(org.kie.kogito.explainability.api.CounterfactualDomainRange) ArrayList(java.util.ArrayList) TextNode(com.fasterxml.jackson.databind.node.TextNode) CounterfactualSearchDomain(org.kie.kogito.explainability.api.CounterfactualSearchDomain) Test(org.junit.jupiter.api.Test)

Example 19 with CounterfactualDomainRange

use of org.kie.kogito.explainability.api.CounterfactualDomainRange in project kogito-apps by kiegroup.

the class AbstractTrustyServiceIT method testCounterfactuals_WithDisparateGoalsStructure.

@Test
public void testCounterfactuals_WithDisparateGoalsStructure() {
    String executionId = "myCFExecution1";
    storeExecutionWithOutcomes(executionId, 0L);
    // The Goals structures must be comparable to the original decisions outcomes.
    // The Search Domain structures must be identical those of the original decision inputs.
    // For this test we're providing the correct structure for searchDomains but a sub-structure for goals.
    CounterfactualSearchDomain searchDomain = buildSearchDomainUnit("test", "number", new CounterfactualDomainRange(new IntNode(1), new IntNode(2)));
    CounterfactualExplainabilityRequest request = trustyService.requestCounterfactuals(executionId, Collections.emptyList(), Collections.singletonList(searchDomain));
    assertNotNull(request);
    assertEquals(request.getExecutionId(), executionId);
    assertNotNull(request.getCounterfactualId());
    assertTrue(request.getGoals().isEmpty());
    CounterfactualExplainabilityRequest result = trustyService.getCounterfactualRequest(executionId, request.getCounterfactualId());
    assertNotNull(result);
    assertEquals(request.getExecutionId(), result.getExecutionId());
    assertEquals(request.getCounterfactualId(), result.getCounterfactualId());
    assertTrue(result.getGoals().isEmpty());
}
Also used : CounterfactualExplainabilityRequest(org.kie.kogito.explainability.api.CounterfactualExplainabilityRequest) IntNode(com.fasterxml.jackson.databind.node.IntNode) CounterfactualDomainRange(org.kie.kogito.explainability.api.CounterfactualDomainRange) CounterfactualSearchDomain(org.kie.kogito.explainability.api.CounterfactualSearchDomain) Test(org.junit.jupiter.api.Test)

Example 20 with CounterfactualDomainRange

use of org.kie.kogito.explainability.api.CounterfactualDomainRange in project kogito-apps by kiegroup.

the class AbstractTrustyServiceIT method testCounterfactuals_StoreMultipleAndRetrieveSingleWithEmptyDefinition.

@Test
public void testCounterfactuals_StoreMultipleAndRetrieveSingleWithEmptyDefinition() {
    String executionId = "myCFExecution3";
    storeExecution(executionId, 0L);
    // The Goals structures must be comparable to the original decisions outcomes.
    // The Search Domain structures must be identical those of the original decision inputs.
    CounterfactualSearchDomain searchDomain = buildSearchDomainUnit("test", "number", new CounterfactualDomainRange(new IntNode(1), new IntNode(2)));
    CounterfactualExplainabilityRequest request1 = trustyService.requestCounterfactuals(executionId, Collections.emptyList(), Collections.singletonList(searchDomain));
    CounterfactualExplainabilityRequest request2 = trustyService.requestCounterfactuals(executionId, Collections.emptyList(), Collections.singletonList(searchDomain));
    CounterfactualExplainabilityRequest result1 = trustyService.getCounterfactualRequest(executionId, request1.getCounterfactualId());
    assertNotNull(result1);
    assertEquals(request1.getCounterfactualId(), result1.getCounterfactualId());
    CounterfactualExplainabilityRequest result2 = trustyService.getCounterfactualRequest(executionId, request2.getCounterfactualId());
    assertNotNull(result2);
    assertEquals(request2.getCounterfactualId(), result2.getCounterfactualId());
}
Also used : CounterfactualExplainabilityRequest(org.kie.kogito.explainability.api.CounterfactualExplainabilityRequest) IntNode(com.fasterxml.jackson.databind.node.IntNode) CounterfactualDomainRange(org.kie.kogito.explainability.api.CounterfactualDomainRange) CounterfactualSearchDomain(org.kie.kogito.explainability.api.CounterfactualSearchDomain) Test(org.junit.jupiter.api.Test)

Aggregations

CounterfactualDomainRange (org.kie.kogito.explainability.api.CounterfactualDomainRange)21 Test (org.junit.jupiter.api.Test)18 CounterfactualSearchDomain (org.kie.kogito.explainability.api.CounterfactualSearchDomain)17 IntNode (com.fasterxml.jackson.databind.node.IntNode)13 CounterfactualExplainabilityRequest (org.kie.kogito.explainability.api.CounterfactualExplainabilityRequest)13 CounterfactualSearchDomainUnitValue (org.kie.kogito.explainability.api.CounterfactualSearchDomainUnitValue)10 NamedTypedValue (org.kie.kogito.explainability.api.NamedTypedValue)8 ArrayList (java.util.ArrayList)6 UnitValue (org.kie.kogito.tracing.typedvalue.UnitValue)5 List (java.util.List)4 CounterfactualDomainCategorical (org.kie.kogito.explainability.api.CounterfactualDomainCategorical)4 JsonNode (com.fasterxml.jackson.databind.JsonNode)3 TextNode (com.fasterxml.jackson.databind.node.TextNode)3 EmptyFeatureDomain (org.kie.kogito.explainability.model.domain.EmptyFeatureDomain)3 NumericalFeatureDomain (org.kie.kogito.explainability.model.domain.NumericalFeatureDomain)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 QuarkusTest (io.quarkus.test.junit.QuarkusTest)2 RequestLoggingFilter (io.restassured.filter.log.RequestLoggingFilter)2 ResponseLoggingFilter (io.restassured.filter.log.ResponseLoggingFilter)2 OffsetDateTime (java.time.OffsetDateTime)2