Skip to content

Commit

Permalink
Merge pull request #258 from AdaptiveScale/release-2.5.5
Browse files Browse the repository at this point in the history
Release 2.5.5
  • Loading branch information
nbesimi authored Oct 30, 2024
2 parents 1845b36 + 88226d0 commit 7d1c657
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 12 deletions.
88 changes: 88 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,14 @@ This command runs tests for columns using assertions. Then they are translated i

rosetta [-c, --config CONFIG_FILE] test [-h, --help] [-s, --source CONNECTION_NAME]

rosetta [-c, --config CONFIG_FILE] test [-h, --help] [-s, --source CONNECTION_NAME] [-t, --target CONNECTION_NAME]

Parameter | Description
--- | ---
-h, --help | Show the help message and exit.
-c, --config CONFIG_FILE | YAML config file. If none is supplied it will use main.conf in the current directory if it exists.
-s, --source CONNECTION_NAME | The source connection is used to specify which models and connections to use.
-t, --target CONNECTION_NAME (Optional) | The target connection is used to specify the target connection to use for testing the data. The source tests needs to match the values from the tarrget connection.

**Note:** Value for BigQuery Array columns should be comma separated value ('a,b,c,d,e').

Expand Down Expand Up @@ -560,6 +563,91 @@ tables:
expected: 1
```

When running the tests against a target connection, you don't have to specify the expected value.

```yaml
---
safeMode: false
databaseType: "mysql"
operationLevel: database
tables:
- name: "actor"
type: "TABLE"
columns:
- name: "actor_id"
typeName: "SMALLINT UNSIGNED"
ordinalPosition: 0
primaryKeySequenceId: 1
columnDisplaySize: 5
scale: 0
precision: 5
nullable: false
primaryKey: true
autoincrement: false
tests:
assertion:
- operator: '='
value: 16
- name: "first_name"
typeName: "VARCHAR"
ordinalPosition: 0
primaryKeySequenceId: 0
columnDisplaySize: 45
scale: 0
precision: 45
nullable: false
primaryKey: false
autoincrement: false
tests:
assertion:
- operator: '!='
value: 'Michael'
```

If you need to overwrite the test column query (e.x. for Geospatial data), you can use `columnDef`.
```yaml
---
safeMode: false
databaseType: "mysql"
operationLevel: database
tables:
- name: "actor"
type: "TABLE"
columns:
- name: "actor_id"
typeName: "SMALLINT UNSIGNED"
ordinalPosition: 0
primaryKeySequenceId: 1
columnDisplaySize: 5
scale: 0
precision: 5
nullable: false
primaryKey: true
autoincrement: false
tests:
assertion:
- operator: '='
value: 16
expected: 1
- name: "wkt"
typeName: "GEOMETRY"
ordinalPosition: 0
primaryKeySequenceId: 0
columnDisplaySize: 1000000000
scale: 0
precision: 1000000000
columnProperties: []
nullable: true
primaryKey: false
autoincrement: false
tests:
assertion:
- operator: '>'
value: 434747
expected: 4
columnDef: 'ST_AREA(wkt, 1)'
```

Output example:
```bash
Running tests for mysql. Found: 2
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {

allprojects {
group = 'com.adaptivescale'
version = '2.5.4'
version = '2.5.5'
sourceCompatibility = 11
targetCompatibility = 11
}
Expand Down
17 changes: 14 additions & 3 deletions cli/src/main/java/com/adaptivescale/rosetta/cli/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
@Slf4j
@CommandLine.Command(name = "cli",
mixinStandardHelpOptions = true,
version = "2.5.4",
version = "2.5.5",
description = "Declarative Database Management - DDL Transpiler"
)
class Cli implements Callable<Void> {
Expand Down Expand Up @@ -247,10 +247,15 @@ private void apply(@CommandLine.Option(names = {"-s", "--source"}, required = tr
}

@CommandLine.Command(name = "test", description = "Run tests written on columns", mixinStandardHelpOptions = true)
private void test(@CommandLine.Option(names = {"-s", "--source"}) String sourceName) throws Exception {
private void test(
@CommandLine.Option(names = {"-s", "--source"}) String sourceName,
@CommandLine.Option(names = {"-t", "--target"}) String targetName
) throws Exception {
requireConfig(config);

Optional<Connection> source = config.getConnection(sourceName);
Optional<Connection> target = config.getConnection(targetName);

if (source.isEmpty()) {
throw new RuntimeException("Can not find source with name: " + sourceName + " configured in config.");
}
Expand All @@ -267,7 +272,13 @@ private void test(@CommandLine.Option(names = {"-s", "--source"}) String sourceN
for (Database database : collect) {
AssertionSqlGenerator assertionSqlGenerator = AssertionSqlGeneratorFactory.generatorFor(source.get());
DefaultSqlExecution defaultSqlExecution = new DefaultSqlExecution(source.get(), new DriverManagerDriverProvider());
new DefaultAssertTestEngine(assertionSqlGenerator, defaultSqlExecution).run(source.get(), database);

if (target.isEmpty()) {
new DefaultAssertTestEngine(assertionSqlGenerator, defaultSqlExecution, null).run(source.get(), database);
} else {
DefaultSqlExecution targetSqlExecution = new DefaultSqlExecution(target.get(), new DriverManagerDriverProvider());
new DefaultAssertTestEngine(assertionSqlGenerator, defaultSqlExecution, targetSqlExecution).run(source.get(), target.get(), database);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class AssertTest implements Test {
private String operator;
private Object value;
private String expected;
private String columnDef;

public String getOperator() {
return operator;
Expand All @@ -32,6 +33,14 @@ public void setExpected(String expected) {
this.expected = expected;
}

public String getColumnDef() {
return columnDef;
}

public void setColumnDef(String columnDef) {
this.columnDef = columnDef;
}

@Override
public String toString() {
return "AssertTest{" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@

public interface AssertTestEngine {
void run(Connection connection, Database database);
void run(Connection sourceConnection, Connection targetConnection, Database sourceDatabase);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,21 @@ public class DefaultAssertTestEngine implements AssertTestEngine {

private final AssertionSqlGenerator sqlGenerator;
private final SqlExecution sqlExecution;
private final SqlExecution targetSqlExecution;
private final Output output;
private final List<AssertionResult> results = new ArrayList<>();

public DefaultAssertTestEngine(AssertionSqlGenerator sqlGenerator, SqlExecution sqlExecution) {
this.sqlGenerator = sqlGenerator;
this.sqlExecution = sqlExecution;
this.targetSqlExecution = null;
output = new ConsoleOutput();
}

public DefaultAssertTestEngine(AssertionSqlGenerator sqlGenerator, SqlExecution sqlExecution, SqlExecution targetSqlExecution) {
this.sqlGenerator = sqlGenerator;
this.sqlExecution = sqlExecution;
this.targetSqlExecution = targetSqlExecution;
output = new ConsoleOutput();
}

Expand Down Expand Up @@ -69,6 +78,53 @@ public void run(Connection connection, Database database) {
output.endTestForDatabase();
}

@Override
public void run(Connection sourceConnection, Connection targetConnection, Database sourceDatabase) {
List<AssertTest> collect = sourceDatabase
.getTables()
.stream()
.flatMap(table1 -> table1.getColumns().stream())
.filter(column -> column.getTests() != null && column.getTests().getAssertion() != null && column.getTests().getAssertion().size() > 0)
.flatMap(column -> column.getTests().getAssertion().stream()).collect(Collectors.toList());

output.startTestForDatabase(sourceConnection.getName(), collect.size());

for (Table table : sourceDatabase.getTables()) {
Collection<Column> columns = table.getColumns();
for (Column column : columns) {
Tests tests = column.getTests();
if (tests == null) {
continue;
}
Collection<AssertTest> assertions = tests.getAssertion();
if (assertions == null || assertions.isEmpty()) {
continue;
}
for (AssertTest assertion : assertions) {
AssertionResult assertionResult = new AssertionResult();
assertionResult.setAssertTest(assertion);
long startTime = output.printStartTest(assertion, column);
assertionResult.setStartTime(startTime);

String sql = sqlGenerator.generateSql(sourceConnection, table, column, assertion);
assertionResult.setSqlExecuted(sql);
String result = sqlExecution.execute(sql);

String targetSql = sqlGenerator.generateSql(targetConnection, table, column, assertion);
String expected = targetSqlExecution.execute(targetSql);
assertion.setExpected(expected);

boolean pass = Objects.equals(expected, result);
assertionResult.setPass(pass);
results.add(assertionResult);
output.printEndTest(assertion, column, startTime, pass, result);
}
}
}

output.endTestForDatabase();
}

public List<AssertionResult> getResults() {
return results;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public abstract class BaseAssertionSqlGenerator implements AssertionSqlGenerator
@Override
public String generateSql(Connection connection, Table table, Column column, AssertTest assertion) {
String whereClauseCondition = prepareWhereCondition(column, assertion);
return prepareSql(connection, table, column, whereClauseCondition);
return prepareSql(connection, table, column, assertion, whereClauseCondition);
}

String prepareWhereCondition(Column column, AssertTest assertion) {
Expand All @@ -34,7 +34,7 @@ String prepareWhereCondition(Column column, AssertTest assertion) {
return String.format("%s %s", assertion.getOperator(), handleOperator(assertion, column));
}

abstract String prepareSql(Connection connection, Table table, Column column, String whereClauseCondition);
abstract String prepareSql(Connection connection, Table table, Column column, AssertTest assertion, String whereClauseCondition);

private String handleOperator(AssertTest assertion, Column column) {
if (OperatorEnum.IN.getName().equalsIgnoreCase(assertion.getOperator())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.adaptivescale.rosetta.test.assertion.generator;

import com.adaptivescale.rosetta.common.models.AssertTest;
import com.adaptivescale.rosetta.common.models.Column;
import com.adaptivescale.rosetta.common.models.Table;
import com.adaptivescale.rosetta.common.models.input.Connection;

import java.util.Optional;

public class BigQueryAssertionSqlGenerator extends BaseAssertionSqlGenerator {

@Override
String prepareSql(Connection connection, Table table, Column column, String whereClauseCondition) {
String prepareSql(Connection connection, Table table, Column column, AssertTest assertion, String whereClauseCondition) {
String columnName = isArray(column) ? String.format("ARRAY_TO_STRING(%s,',')", column.getName()) : column.getName();
return String.format("Select Count(*) from %s.%s.%s where %s %s",
connection.getDatabaseName(),
connection.getSchemaName(),
table.getName(),
columnName,
Optional.ofNullable(assertion.getColumnDef())
.orElse(columnName),
whereClauseCondition);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package com.adaptivescale.rosetta.test.assertion.generator;

import com.adaptivescale.rosetta.common.models.AssertTest;
import com.adaptivescale.rosetta.common.models.Column;
import com.adaptivescale.rosetta.common.models.Table;
import com.adaptivescale.rosetta.common.models.input.Connection;

import javax.swing.text.html.Option;
import java.util.Optional;

public class DefaultAssertionSqlGenerator extends BaseAssertionSqlGenerator {

@Override
String prepareSql(Connection connection, Table table, Column column, String whereClauseCondition) {
String prepareSql(Connection connection, Table table, Column column, AssertTest assertion, String whereClauseCondition) {
return String.format("Select Count(*) from %s where %s %s",
table.getName(),
column.getName(), whereClauseCondition);
Optional.ofNullable(assertion.getColumnDef())
.orElse(column.getName()),
whereClauseCondition
);
}

String castValue(Object value, Column column) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package com.adaptivescale.rosetta.test.assertion.generator;

import com.adaptivescale.rosetta.common.models.AssertTest;
import com.adaptivescale.rosetta.common.models.Column;
import com.adaptivescale.rosetta.common.models.Table;
import com.adaptivescale.rosetta.common.models.input.Connection;

import java.util.Optional;

public class SnowflakeAssertionSqlGenerator extends BaseAssertionSqlGenerator {

@Override
String prepareSql(Connection connection, Table table, Column column, String whereClauseCondition) {
String prepareSql(Connection connection, Table table, Column column, AssertTest assertion, String whereClauseCondition) {
return String.format("Select Count(*) from \"%s\".\"%s\".\"%s\" where \"%s\" %s",
connection.getDatabaseName(),
connection.getSchemaName(),
table.getName(),
column.getName(), whereClauseCondition);
Optional.ofNullable(assertion.getColumnDef())
.orElse(column.getName()),
whereClauseCondition
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.adaptivescale.rosetta.common.models.Column;

public class SpannerAssertionSqlGenerator extends DefaultAssertionSqlGenerator {

private boolean isArray(Column column) {
return "ARRAY".equals(column.getTypeName());
}
Expand Down

0 comments on commit 7d1c657

Please sign in to comment.