Fix test suite pipeline and slack alerts (#10552)

* fix: change TestSuite to implement ServiceEntityInterface

* fix: updated slack alert URL for test suites

* added  as default service type
This commit is contained in:
Teddy 2023-03-15 07:52:32 +01:00 committed by GitHub
parent c9c798e89a
commit 8acd077c23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 146 additions and 12 deletions

View File

@ -31,7 +31,7 @@ public class TestSuiteRepository extends EntityRepository<TestSuite> {
@Override
public TestSuite setFields(TestSuite entity, EntityUtil.Fields fields) throws IOException {
entity.setPipeline(fields.contains("pipelines") ? getIngestionPipeline(entity) : null);
entity.setPipelines(fields.contains("pipelines") ? getIngestionPipelines(entity) : null);
return entity.withTests(fields.contains("tests") ? getTestCases(entity) : null);
}

View File

@ -180,18 +180,26 @@ public final class ChangeEventParser {
}
public static String getEntityUrl(PUBLISH_TO publishTo, ChangeEvent event) {
String fqn;
String entityType;
EntityInterface entity = (EntityInterface) event.getEntity();
URI urlInstance = entity.getHref();
String fqn = event.getEntityFullyQualifiedName();
if (entity instanceof TestCase) {
fqn = ((TestCase) entity).getTestSuite().getFullyQualifiedName();
entityType = "test-suites";
} else {
fqn = event.getEntityFullyQualifiedName();
entityType = event.getEntityType();
}
if (Objects.nonNull(urlInstance)) {
String scheme = urlInstance.getScheme();
String host = urlInstance.getHost();
if (publishTo == PUBLISH_TO.SLACK || publishTo == PUBLISH_TO.GCHAT) {
return String.format("<%s://%s/%s/%s|%s>", scheme, host, event.getEntityType(), fqn, fqn);
return String.format("<%s://%s/%s/%s|%s>", scheme, host, entityType, fqn, fqn);
} else if (publishTo == PUBLISH_TO.TEAMS) {
return String.format("[%s](%s://%s/%s/%s)", fqn, scheme, host, event.getEntityType(), fqn);
return String.format("[%s](%s://%s/%s/%s)", fqn, scheme, host, entityType, fqn);
} else if (publishTo == PUBLISH_TO.EMAIL) {
return String.format("%s://%s/%s/%s", scheme, host, event.getEntityType(), fqn);
return String.format("%s://%s/%s/%s", scheme, host, entityType, fqn);
}
}
return "";
@ -201,7 +209,13 @@ public final class ChangeEventParser {
SlackMessage slackMessage = new SlackMessage();
slackMessage.setUsername(event.getUserName());
if (event.getEntity() != null) {
String headerTxt = "%s posted on " + event.getEntityType() + " %s";
String eventType;
if ((EntityInterface) event.getEntity() instanceof TestCase) {
eventType = "testSuite";
} else {
eventType = event.getEntityType();
}
String headerTxt = "%s posted on " + eventType + " %s";
String headerText = String.format(headerTxt, event.getUserName(), getEntityUrl(PUBLISH_TO.SLACK, event));
slackMessage.setText(headerText);
}
@ -594,10 +608,10 @@ public final class ChangeEventParser {
if (result != null) {
String format =
String.format(
"Test Case %s is %s in %s/%s",
getBold(publishTo),
"Test Case status for %s against table/column %s is %s in test suite %s",
getBold(publishTo),
EntityLink.parse(testCaseEntity.getEntityLink()).getEntityFQN(),
getBold(publishTo),
testCaseEntity.getTestSuite().getName());
return String.format(format, testCaseName, result.getTestCaseStatus());
} else {

View File

@ -0,0 +1,93 @@
package org.openmetadata.service.alerts;
import java.net.URI;
import java.util.ArrayList;
import java.util.UUID;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openmetadata.schema.entity.data.Table;
import org.openmetadata.schema.tests.TestCase;
import org.openmetadata.schema.type.ChangeEvent;
import org.openmetadata.schema.type.Column;
import org.openmetadata.schema.type.ColumnDataType;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.schema.type.EventType;
import org.openmetadata.service.util.ChangeEventParser;
public class AlertsURLFormattingTest {
private static ChangeEvent testCaseChangeEvent;
private static ChangeEvent tableChangeEvent;
@BeforeAll
static void setUp() {
UUID testCaseId = UUID.randomUUID();
UUID tableId = UUID.randomUUID();
testCaseChangeEvent =
new ChangeEvent()
.withEventType(EventType.ENTITY_UPDATED)
.withEntityType("TestCase")
.withEntityId(UUID.randomUUID())
.withEntityFullyQualifiedName("UnitTest.TestCase")
.withUserName("UnitTestUser")
.withTimestamp(System.currentTimeMillis())
.withEntity(
new TestCase()
.withName("TestCaseForUnitTest")
.withId(testCaseId)
.withFullyQualifiedName("UnitTest.TestCase")
.withEntityLink("<#E::table::Table.For.UnitTest>")
.withEntityFQN("Table.For.UnitTest")
.withHref(URI.create(String.format("http://localhost:8080/api/v1/testCase/%s", testCaseId)))
.withTestSuite(
new EntityReference()
.withId(UUID.randomUUID())
.withName("TestSuiteForUnitTest")
.withFullyQualifiedName("UnitTest.TestSuite")));
ArrayList<Column> columns = new ArrayList<>();
for (int i = 0; i < 3; i++) {
columns.add(
new Column()
.withName("col" + i)
.withDataType(ColumnDataType.INT)
.withFullyQualifiedName("database.TableForUnitTest.col" + i));
}
columns.add(
new Column()
.withName("col1")
.withDataType(ColumnDataType.INT)
.withFullyQualifiedName("database.TableForUnitTest.col1"));
tableChangeEvent =
new ChangeEvent()
.withEventType(EventType.ENTITY_UPDATED)
.withEntityType("table")
.withEntityId(UUID.randomUUID())
.withEntityFullyQualifiedName("UnitTestService.database.TableForUnitTest")
.withUserName("UnitTestUser")
.withTimestamp(System.currentTimeMillis())
.withEntity(
new Table()
.withId(tableId)
.withName("database.TableForUnitTest")
.withFullyQualifiedName("UnitTestService.database.TableForUnitTest")
.withHref(URI.create(String.format("http://localhost:8080/api/v1/table/%s", tableId)))
.withColumns(columns)
.withDatabase(
new EntityReference()
.withId(UUID.randomUUID())
.withName("database")
.withFullyQualifiedName("UnitTestService.database")));
}
@Test
void testAlertsSlackURLFormatting() {
String testCaseUrl = ChangeEventParser.getEntityUrl(ChangeEventParser.PUBLISH_TO.SLACK, testCaseChangeEvent);
assert testCaseUrl.equals("<http://localhost/test-suites/UnitTest.TestSuite|UnitTest.TestSuite>");
String tableUrl = ChangeEventParser.getEntityUrl(ChangeEventParser.PUBLISH_TO.SLACK, tableChangeEvent);
assert tableUrl.equals(
"<http://localhost/table/UnitTestService.database.TableForUnitTest|UnitTestService.database.TableForUnitTest>");
}
}

View File

@ -5,8 +5,22 @@
"description": "TestSuite is a set of test cases to capture data quality tests against data entities.",
"type": "object",
"javaType": "org.openmetadata.schema.tests.TestSuite",
"javaInterfaces": ["org.openmetadata.schema.EntityInterface"],
"definitions": {},
"javaInterfaces": [
"org.openmetadata.schema.ServiceEntityInterface"
],
"definitions": {
"testSuiteConnection": {
"type": "object",
"javaInterfaces": [
"org.openmetadata.schema.ServiceConnectionEntityInterface"
],
"properties": {
"config": {
"type": "null"
}
}
}
},
"properties": {
"id": {
"description": "Unique identifier of this test suite instance.",
@ -35,11 +49,24 @@
},
"default": null
},
"pipeline": {
"connection": {
"$ref": "#/definitions/testSuiteConnection"
},
"testConnectionResult": {
"$ref": "../entity/services/connections/testConnectionResult.json"
},
"pipelines": {
"description": "References to pipelines deployed for this database service to extract metadata, usage, lineage etc..",
"$ref": "../type/entityReference.json",
"$ref": "../type/entityReference.json#/definitions/entityReferenceList",
"default": null
},
"serviceType": {
"description": "Type of database service such as MySQL, BigQuery, Snowflake, Redshift, Postgres...",
"javaInterfaces": ["org.openmetadata.schema.EnumInterface"],
"type": "string",
"enum": ["TestSuite"],
"default": "TestSuite"
},
"owner": {
"description": "Owner of this TestCase definition.",
"$ref": "../type/entityReference.json",