fix: summary for logical test suite (#13005)

* fix: summary for logical test suite + DI aggregation on OS

* fix: added logic to attached test case result summary to logical test suite

* fix: test case timestamp in ingestion to milliseconds

* fix: updated entityExtensionTimeSeries DAO to dataQualityDataTimeSeries DAO

* fix: revert aggregation changes
This commit is contained in:
Teddy 2023-09-01 18:01:59 +02:00 committed by GitHub
parent ab3042e8ee
commit 0ef085cfc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 110 additions and 29 deletions

View File

@ -93,7 +93,7 @@ class PandasTestSuiteInterface(TestSuiteInterface, PandasInterfaceMixin):
test_handler = TestHandler(
self.dfs,
test_case=test_case,
execution_date=datetime.now(tz=timezone.utc).timestamp(),
execution_date=int(datetime.now(tz=timezone.utc).timestamp() * 1000),
)
return Validator(validator_obj=test_handler).validate()

View File

@ -165,7 +165,7 @@ class SQATestSuiteInterface(SQAInterfaceMixin, TestSuiteInterface):
test_handler = TestHandler(
self.runner,
test_case=test_case,
execution_date=datetime.now(tz=timezone.utc).timestamp(),
execution_date=int(datetime.now(tz=timezone.utc).timestamp() * 1000),
)
return Validator(validator_obj=test_handler).validate()

View File

@ -241,27 +241,51 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
String.format("Failed to find testCase result for %s at %s", testCase.getName(), timestamp));
}
private void setTestSuiteSummary(TestCase testCase, Long timestamp, TestCaseStatus testCaseStatus) {
ResultSummary resultSummary =
new ResultSummary()
.withTestCaseName(testCase.getFullyQualifiedName())
.withStatus(testCaseStatus)
.withTimestamp(timestamp);
EntityReference ref = testCase.getTestSuite();
TestSuite testSuite = Entity.getEntity(ref.getType(), ref.getId(), "", Include.ALL, false);
List<ResultSummary> resultSummaries = listOrEmpty(testSuite.getTestCaseResultSummary());
if (resultSummaries.isEmpty()) {
resultSummaries.add(resultSummary);
} else {
// We'll remove the existing summary for this test case and add the new one
resultSummaries.removeIf(summary -> summary.getTestCaseName().equals(resultSummary.getTestCaseName()));
resultSummaries.add(resultSummary);
}
private ResultSummary getResultSummary(TestCase testCase, Long timestamp, TestCaseStatus testCaseStatus) {
return new ResultSummary()
.withTestCaseName(testCase.getFullyQualifiedName())
.withStatus(testCaseStatus)
.withTimestamp(timestamp);
}
testSuite.setTestCaseResultSummary(resultSummaries);
daoCollection
.testSuiteDAO()
.update(testSuite.getId(), testSuite.getFullyQualifiedName(), JsonUtils.pojoToJson(testSuite));
private void setTestSuiteSummary(TestCase testCase, Long timestamp, TestCaseStatus testCaseStatus) {
ResultSummary resultSummary = getResultSummary(testCase, timestamp, testCaseStatus);
// list all executable and logical test suite linked to the test case
// We'll only fetch the logical ones as we'll get the executable one from the
// test case object itself
List<TestSuite> testSuites = new ArrayList<>();
List<CollectionDAO.EntityRelationshipRecord> entityRelationshipRecords =
daoCollection
.relationshipDAO()
.findFrom(testCase.getId().toString(), TEST_CASE, Relationship.CONTAINS.ordinal(), TEST_SUITE);
for (CollectionDAO.EntityRelationshipRecord entityRelationshipRecord : entityRelationshipRecords) {
TestSuite testSuite = Entity.getEntity(TEST_SUITE, entityRelationshipRecord.getId(), "", Include.ALL, false);
if (Boolean.FALSE.equals(testSuite.getExecutable())) {
testSuites.add(testSuite);
}
}
EntityReference ref = testCase.getTestSuite();
testSuites.add(Entity.getEntity(ref.getType(), ref.getId(), "", Include.ALL, false));
// update the summary for each test suite
for (TestSuite testSuite : testSuites) {
List<ResultSummary> resultSummaries = listOrEmpty(testSuite.getTestCaseResultSummary());
if (resultSummaries.isEmpty()) {
resultSummaries.add(resultSummary);
} else {
// We'll remove the existing summary for this test case and add the new one
resultSummaries.removeIf(summary -> summary.getTestCaseName().equals(resultSummary.getTestCaseName()));
resultSummaries.add(resultSummary);
}
// set test case result summary for the test suite
// and update it in the database
testSuite.setTestCaseResultSummary(resultSummaries);
daoCollection
.testSuiteDAO()
.update(testSuite.getId(), testSuite.getFullyQualifiedName(), JsonUtils.pojoToJson(testSuite));
}
}
private ChangeDescription addTestCaseChangeDescription(Double version, Object newValue) {
@ -330,8 +354,21 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
public RestUtil.PutResponse<TestSuite> addTestCasesToLogicalTestSuite(TestSuite testSuite, List<UUID> testCaseIds) {
bulkAddToRelationship(testSuite.getId(), testCaseIds, TEST_SUITE, TEST_CASE, Relationship.CONTAINS);
List<EntityReference> testCasesEntityReferences = new ArrayList<>();
List<ResultSummary> resultSummaries = listOrEmpty(testSuite.getTestCaseResultSummary());
for (UUID testCaseId : testCaseIds) {
TestCase testCase = Entity.getEntity(Entity.TEST_CASE, testCaseId, "", Include.ALL);
// Get the latest result to set the testSuite summary field
String result =
daoCollection
.dataQualityDataTimeSeriesDao()
.getLatestExtension(testCase.getFullyQualifiedName(), TESTCASE_RESULT_EXTENSION);
if (result != null) {
TestCaseResult testCaseResult = JsonUtils.readValue(result, TestCaseResult.class);
ResultSummary resultSummary =
getResultSummary(testCase, testCaseResult.getTimestamp(), testCaseResult.getTestCaseStatus());
resultSummaries.removeIf(summary -> summary.getTestCaseName().equals(resultSummary.getTestCaseName()));
resultSummaries.add(resultSummary);
}
testCasesEntityReferences.add(
new EntityReference()
.withId(testCase.getId())
@ -342,6 +379,13 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
.withHref(testCase.getHref())
.withDeleted(testCase.getDeleted()));
}
// set test case result summary for logical test suite
// and update it in the database
testSuite.setTestCaseResultSummary(resultSummaries);
daoCollection
.testSuiteDAO()
.update(testSuite.getId(), testSuite.getFullyQualifiedName(), JsonUtils.pojoToJson(testSuite));
testSuite.setTests(testCasesEntityReferences);
return new RestUtil.PutResponse<>(Response.Status.OK, testSuite, LOGICAL_TEST_CASES_ADDED);
}
@ -349,6 +393,14 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
public RestUtil.DeleteResponse<TestCase> deleteTestCaseFromLogicalTestSuite(UUID testSuiteId, UUID testCaseId) {
TestCase testCase = Entity.getEntity(Entity.TEST_CASE, testCaseId, null, null);
deleteRelationship(testSuiteId, TEST_SUITE, testCaseId, TEST_CASE, Relationship.CONTAINS);
// remove test case from logical test suite summary and update test suite
TestSuite testSuite = Entity.getEntity(TEST_SUITE, testSuiteId, "*", Include.ALL, false);
List<ResultSummary> resultSummaries = testSuite.getTestCaseResultSummary();
resultSummaries.removeIf(summary -> summary.getTestCaseName().equals(testCase.getFullyQualifiedName()));
testSuite.setTestCaseResultSummary(resultSummaries);
daoCollection
.testSuiteDAO()
.update(testSuite.getId(), testSuite.getFullyQualifiedName(), JsonUtils.pojoToJson(testSuite));
EntityReference entityReference = Entity.getEntityReferenceById(TEST_SUITE, testSuiteId, Include.ALL);
testCase.setTestSuite(entityReference);
return new RestUtil.DeleteResponse<>(testCase, RestUtil.ENTITY_DELETED);

View File

@ -58,6 +58,7 @@ public class TestSuiteRepository extends EntityRepository<TestSuite> {
}
private TestSummary buildTestSummary(HashMap<String, Integer> testCaseSummary, int total) {
return new TestSummary()
.withAborted(testCaseSummary.getOrDefault(TestCaseStatus.Aborted.toString(), 0))
.withFailed(testCaseSummary.getOrDefault(TestCaseStatus.Failed.toString(), 0))
@ -115,13 +116,10 @@ public class TestSuiteRepository extends EntityRepository<TestSuite> {
List<TestSuite> testSuites = listAll(EntityUtil.Fields.EMPTY_FIELDS, filter);
testSummary = getTestCasesExecutionSummary(testSuites);
} else {
TestSuite testSuite = find(testSuiteId, Include.ALL);
if (!Boolean.TRUE.equals(testSuite.getExecutable())) {
throw new IllegalArgumentException("Test Suite is not executable. Please provide an executable test suite.");
}
// don't want to get it from the cache as test results summary may be stale
TestSuite testSuite = Entity.getEntity(TEST_SUITE, testSuiteId, "", Include.ALL, false);
testSummary = getTestCasesExecutionSummary(testSuite);
}
return testSummary;
}

View File

@ -621,7 +621,9 @@ public class TestCaseResource extends EntityResource<TestCase, TestCaseRepositor
@Context SecurityContext securityContext,
@Valid CreateLogicalTestCases createLogicalTestCases) {
TestSuite testSuite = Entity.getEntity(Entity.TEST_SUITE, createLogicalTestCases.getTestSuiteId(), null, null);
// don't get entity from cache as test result summary may be stale
TestSuite testSuite =
Entity.getEntity(Entity.TEST_SUITE, createLogicalTestCases.getTestSuiteId(), null, null, false);
OperationContext operationContext = new OperationContext(Entity.TEST_SUITE, MetadataOperation.EDIT_TESTS);
ResourceContextInterface resourceContext = TestCaseResourceContext.builder().entity(testSuite).build();
authorizer.authorize(securityContext, operationContext, resourceContext);

View File

@ -253,7 +253,7 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
ADMIN_AUTH_HEADERS);
verifyTestCaseResults(testCaseResults, List.of(testCaseResult), 1);
// Add new date for TableCaseResult
// Add new data for TableCaseResult
TestCaseResult newTestCaseResult =
new TestCaseResult()
.withResult("tested")
@ -342,6 +342,35 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
() -> getTestSummary(ADMIN_AUTH_HEADERS, randomUUID),
NOT_FOUND,
"testSuite instance for " + randomUUID + " not found");
// Test that we can get the test summary for a logical test suite and that
// adding a logical test suite does not change the total number of tests
TestSuiteResourceTest testSuiteResourceTest = new TestSuiteResourceTest();
CreateTestSuite createLogicalTestSuite = testSuiteResourceTest.createRequest(test);
TestSuite logicalTestSuite = testSuiteResourceTest.createEntity(createLogicalTestSuite, ADMIN_AUTH_HEADERS);
List<UUID> testCaseIds = new ArrayList<>();
testCaseIds.add(testCase1.getId());
testSuiteResourceTest.addTestCasesToLogicalTestSuite(logicalTestSuite, testCaseIds);
testSummary = getTestSummary(ADMIN_AUTH_HEADERS, logicalTestSuite.getId().toString());
assertEquals(1, testSummary.getTotal());
assertEquals(1, testSummary.getFailed());
// add a new test case to the logical test suite to validate if the
// summary is updated correctly
testCaseIds.removeAll(testCaseIds);
testCaseIds.add(testCase.getId());
testSuiteResourceTest.addTestCasesToLogicalTestSuite(logicalTestSuite, testCaseIds);
testSummary = getTestSummary(ADMIN_AUTH_HEADERS, logicalTestSuite.getId().toString());
assertEquals(2, testSummary.getTotal());
// remove test case from logical test suite and validate
// the summary is updated as expected
deleteLogicalTestCase(logicalTestSuite, testCase.getId());
testSummary = getTestSummary(ADMIN_AUTH_HEADERS, logicalTestSuite.getId().toString());
assertEquals(1, testSummary.getTotal());
}
@Test