From 748fc0069ced2f6dccdaeb50899d105ccb2e00f8 Mon Sep 17 00:00:00 2001 From: Valery Yatsynovich Date: Fri, 11 Jun 2021 09:39:11 +0300 Subject: [PATCH] [plugin-db] Add ability to check one data set contains another data set --- .../bdd/steps/db/DataSetComparisonRule.java | 80 +++++ .../bdd/steps/db/DataSourceStatistics.java | 81 +++++ .../vividus/bdd/steps/db/DatabaseSteps.java | 258 ++++------------ .../bdd/steps/db/DuplicateKeysStrategy.java | 8 +- .../vividus/bdd/steps/db/QueryStatistic.java | 84 ++++++ .../resources/data-sources-statistics.ftl | 146 +++++++++ .../src/main/resources/queries-statistics.ftl | 153 ---------- .../bdd/steps/db/DatabaseStepsTests.java | 281 +++++++++++------- .../steps/db/DuplicateKeysStrategyTests.java | 18 +- .../story/integration/Databases.story | 11 + 10 files changed, 649 insertions(+), 471 deletions(-) create mode 100644 vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSetComparisonRule.java create mode 100644 vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSourceStatistics.java create mode 100644 vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/QueryStatistic.java create mode 100644 vividus-plugin-db/src/main/resources/data-sources-statistics.ftl delete mode 100644 vividus-plugin-db/src/main/resources/queries-statistics.ftl create mode 100644 vividus-tests/src/main/resources/story/integration/Databases.story diff --git a/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSetComparisonRule.java b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSetComparisonRule.java new file mode 100644 index 0000000000..f3e52fa325 --- /dev/null +++ b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSetComparisonRule.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.bdd.steps.db; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import com.google.common.collect.ListMultimap; + +import org.apache.commons.lang3.tuple.Pair; + +public enum DataSetComparisonRule +{ + IS_EQUAL_TO("Query results are equal") + { + @Override + Stream collectComparisonKeys(ListMultimap> leftData, + ListMultimap> rightData) + { + return Stream.concat(leftData.keySet().stream(), rightData.keySet().stream()).distinct(); + } + + @Override + public void fillStatistics(DataSourceStatistics statistics, + List, Map>> comparison) + { + statistics.getLeft().setNoPair(comparison.stream().map(Pair::getRight).filter(Map::isEmpty).count()); + statistics.getRight().setNoPair(comparison.stream().map(Pair::getLeft).filter(Map::isEmpty).count()); + } + }, + CONTAINS("The left data set contains all rows from the right data set") + { + @Override + Stream collectComparisonKeys(ListMultimap> leftData, + ListMultimap> rightData) + { + return rightData.keySet().stream(); + } + + @Override + public void fillStatistics(DataSourceStatistics statistics, + List, Map>> comparison) + { + statistics.getRight().setNoPair(comparison.stream().map(Pair::getLeft).filter(Map::isEmpty).count()); + } + }; + + private final String assertionDescription; + + DataSetComparisonRule(String assertionDescription) + { + this.assertionDescription = assertionDescription; + } + + public String getAssertionDescription() + { + return assertionDescription; + } + + abstract Stream collectComparisonKeys(ListMultimap> leftData, + ListMultimap> rightData); + + abstract void fillStatistics(DataSourceStatistics statistics, + List, Map>> comparison); +} diff --git a/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSourceStatistics.java b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSourceStatistics.java new file mode 100644 index 0000000000..87f7ed5791 --- /dev/null +++ b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DataSourceStatistics.java @@ -0,0 +1,81 @@ +/* + * Copyright 2019-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.bdd.steps.db; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DriverManagerDataSource; + +public final class DataSourceStatistics +{ + private long totalRows; + private long mismatched; + private final QueryStatistic left; + private final QueryStatistic right; + + DataSourceStatistics(JdbcTemplate leftJdbcTemplate) + { + left = createQueryStatistic(leftJdbcTemplate); + right = new QueryStatistic(null); + } + + DataSourceStatistics(JdbcTemplate leftJdbcTemplate, JdbcTemplate rightJdbcTemplate) + { + left = createQueryStatistic(leftJdbcTemplate); + right = createQueryStatistic(rightJdbcTemplate); + } + + private QueryStatistic createQueryStatistic(JdbcTemplate jdbcTemplate) + { + String url = ((DriverManagerDataSource) jdbcTemplate.getDataSource()).getUrl(); + return new QueryStatistic(url); + } + + public long getMismatched() + { + return mismatched; + } + + public long getMatched() + { + return totalRows - mismatched; + } + + public void setMismatched(long mismatched) + { + this.mismatched = mismatched; + } + + public long getTotalRows() + { + return totalRows; + } + + public void setTotalRows(long totalRows) + { + this.totalRows = totalRows; + } + + public QueryStatistic getLeft() + { + return left; + } + + public QueryStatistic getRight() + { + return right; + } +} diff --git a/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DatabaseSteps.java b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DatabaseSteps.java index bec37a6e2b..0ba5210991 100644 --- a/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DatabaseSteps.java +++ b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DatabaseSteps.java @@ -40,8 +40,6 @@ import com.google.common.hash.HashFunction; import org.apache.commons.lang3.Validate; -import org.apache.commons.lang3.time.DurationFormatUtils; -import org.apache.commons.lang3.time.StopWatch; import org.apache.commons.lang3.tuple.Pair; import org.jbehave.core.annotations.Then; import org.jbehave.core.annotations.When; @@ -225,27 +223,30 @@ public void executeSql(String sqlQuery, String dbKey) *
  • NOOP (by default)
  • *
  • DISTINCT
  • * - * @see Durations format - * @param leftSqlQuery baseline SQL query - * @param leftDbKey key identifying the database connection for the left data set - * @param rightSqlQuery checkpoint SQL query - * @param rightDbKey key identifying the database connection for the right data set - * @param keys comma-separated list of column's names to map resulting tables rows + * + * @param leftSqlQuery baseline SQL query + * @param leftDbKey key identifying the database connection for the left data set + * @param comparisonRule The data set comparison rule: "is equal to" or "contains" + * @param rightSqlQuery checkpoint SQL query + * @param rightDbKey key identifying the database connection for the right data set + * @param keys comma-separated list of column's names to map resulting tables rows * @throws InterruptedException in case of thread interruption - * @throws ExecutionException in case of any exception during DB query - * @throws TimeoutException in case when timeout to execute DB query expires + * @throws ExecutionException in case of any exception during DB query + * @throws TimeoutException in case when timeout to execute DB query expires + * @see Durations format */ - @Then("data from `$leftSqlQuery` executed against `$leftDbKey` is equal to data from `$rightSqlQuery` executed" + @Then("data from `$leftSqlQuery` executed against `$leftDbKey` $comparisonRule data from `$rightSqlQuery` executed" + " against `$rightDbKey` matching rows using keys:$keys") - public void compareData(String leftSqlQuery, String leftDbKey, String rightSqlQuery, String rightDbKey, - Set keys) throws InterruptedException, ExecutionException, TimeoutException + public void compareData(String leftSqlQuery, String leftDbKey, DataSetComparisonRule comparisonRule, + String rightSqlQuery, String rightDbKey, Set keys) + throws InterruptedException, ExecutionException, TimeoutException { JdbcTemplate leftJdbcTemplate = getJdbcTemplate(leftDbKey); JdbcTemplate rightJdbcTemplate = getJdbcTemplate(rightDbKey); - QueriesStatistic queriesStatistic = new QueriesStatistic(leftJdbcTemplate, rightJdbcTemplate); - QueryStatistic left = queriesStatistic.getLeft(); + DataSourceStatistics dataSourceStatistics = new DataSourceStatistics(leftJdbcTemplate, rightJdbcTemplate); + QueryStatistic left = dataSourceStatistics.getLeft(); left.setQuery(leftSqlQuery); - QueryStatistic right = queriesStatistic.getRight(); + QueryStatistic right = dataSourceStatistics.getRight(); right.setQuery(rightSqlQuery); CompletableFuture>> leftData = createCompletableRequest(leftJdbcTemplate, leftSqlQuery, keys, left); @@ -253,47 +254,51 @@ public void compareData(String leftSqlQuery, String leftDbKey, String rightSqlQu createCompletableRequest(rightJdbcTemplate, rightSqlQuery, keys, right); List> result = leftData.thenCombine(rightData, - (leftQueryResult, rightQueryResult) -> compareData(queriesStatistic, leftQueryResult, rightQueryResult)) + (leftResult, rightResult) -> compareData(comparisonRule, dataSourceStatistics, leftResult, rightResult)) .get(dbQueryTimeout.toMillis(), TimeUnit.MILLISECONDS); - verifyComparisonResult(queriesStatistic, result); + verifyComparisonResult(comparisonRule, dataSourceStatistics, result); } /** - * The step waits until the leftSqlQuery returns the data equal to the right examples table row + * The step waits until the leftSqlQuery returns the data which matches to the right examples table + * rows according the specified comparison rule * The order of columns is ignored * Actions performed in the step: *
      *
    • run the leftSqlQuery
    • *
    • compares the response with the examples table row
    • *
    • sleep for the duration
    • - *
    • repeat all of the above until there are no more retry attempts or the response is equal - * to the examples table row
    • + *
    • repeat all of the above until there are no more retry attempts or the result set matches + * to the right examples table rows according the specified comparison rule
    • *
    - * @param duration The time gap between two queries - * @param retryTimes How many times request will be retried; duration/retryTimes=timeout between requests - * @param leftSqlQuery SQL query to execute - * @param leftDbKey Key identifying the database connection - * @param rightTable Rows to compare data against + * + * @param duration The time gap between two queries + * @param retryTimes How many times request will be retried; duration/retryTimes=timeout between requests + * @param leftSqlQuery SQL query to execute + * @param leftDbKey Key identifying the database connection + * @param comparisonRule The data set comparison rule: "is equal to" or "contains" + * @param rightTable Rows to compare data against */ @When("I wait for '$duration' duration retrying $retryTimes times while data from `$leftSqlQuery`" - + " executed against `$leftDbKey` is equal to data from:$rightTable") + + " executed against `$leftDbKey` $comparisonRule data from:$rightTable") public void waitForDataAppearance(Duration duration, int retryTimes, String leftSqlQuery, String leftDbKey, - List> rightTable) + DataSetComparisonRule comparisonRule, List> rightTable) { JdbcTemplate leftJdbcTemplate = getJdbcTemplate(leftDbKey); - QueriesStatistic statistics = new QueriesStatistic(leftJdbcTemplate); + DataSourceStatistics statistic = new DataSourceStatistics(leftJdbcTemplate); + statistic.getLeft().setQuery(leftSqlQuery); ListMultimap> rightData = hashMap(Set.of(), rightTable); - statistics.getRight().setRowsQuantity(rightData.size()); + statistic.getRight().setRowsQuantity(rightData.size()); DurationBasedWaiter waiter = new DurationBasedWaiter(new WaitMode(duration, retryTimes)); List> comparisonResult = waiter.wait( () -> { List> left = leftJdbcTemplate.queryForList(leftSqlQuery); - statistics.getLeft().setRowsQuantity(left.size()); + statistic.getLeft().setRowsQuantity(left.size()); ListMultimap> leftData = hashMap(Set.of(), left.stream().map(this::convertValuesToString)); - return compareData(statistics, leftData, rightData); + return compareData(comparisonRule, statistic, leftData, rightData); }, result -> { boolean empty = result.isEmpty(); @@ -305,17 +310,18 @@ public void waitForDataAppearance(Duration duration, int retryTimes, String left return empty; } ); - verifyComparisonResult(statistics, filterPassedChecks(comparisonResult)); + verifyComparisonResult(comparisonRule, statistic, filterPassedChecks(comparisonResult)); } - private void verifyComparisonResult(QueriesStatistic statistics, List> result) + private void verifyComparisonResult(DataSetComparisonRule comparisonRule, DataSourceStatistics dataSourceStatistics, + List> result) { - attachmentPublisher.publishAttachment("queries-statistics.ftl", Map.of("statistics", statistics), - "Queries statistics"); - if (!softAssert.assertTrue("Query results are equal", result.isEmpty())) + attachmentPublisher.publishAttachment("data-sources-statistics.ftl", Map.of("statistics", dataSourceStatistics), + "Data sources statistics"); + if (!softAssert.assertTrue(comparisonRule.getAssertionDescription(), result.isEmpty())) { attachmentPublisher.publishAttachment("/templates/maps-comparison-table.ftl", Map.of("results", result), - "Queries comparison result"); + "Data sets comparison"); } } @@ -326,39 +332,43 @@ private void verifyComparisonResult(QueriesStatistic statistics, ListWhen I execute SQL query `${sqlQuery}` against `$dbKey` and save result to story variable `data` *
    Then `${data}` matching rows using `` from `$dbKey` is equal to data from: *
    tables/data.table - * @param leftData saved by step: - * When I execute SQL query `$sqlQuery` against `$dbKey` and save result to $scopes variable `$data`" - * @param keys comma-separated list of column's names to map resulting tables rows - * (could be empty - all columns will be used) - * @param leftDbKey key identifying the database connection used to get data - * @param rightTable rows to compare data against + * + * @param leftData saved by step: + * When I execute SQL query `$sqlQuery` against `$dbKey` and save result to $scopes + * variable `$data`" + * @param keys comma-separated list of column's names to map resulting tables rows + * (could be empty - all columns will be used) + * @param leftDbKey key identifying the database connection used to get data + * @param comparisonRule The data set comparison rule: "is equal to" or "contains" + * @param rightTable rows to compare data against */ - @Then("`$leftData` matching rows using `$keys` from `$leftDbKey` is equal to data from:$rightTable") + @Then("`$leftData` matching rows using `$keys` from `$leftDbKey` $comparisonRule data from:$rightTable") public void compareData(List> leftData, Set keys, String leftDbKey, - List> rightTable) + DataSetComparisonRule comparisonRule, List> rightTable) { JdbcTemplate leftJdbcTemplate = getJdbcTemplate(leftDbKey); - QueriesStatistic statistics = new QueriesStatistic(leftJdbcTemplate); + DataSourceStatistics statistics = new DataSourceStatistics(leftJdbcTemplate); statistics.getLeft().setRowsQuantity(leftData.size()); ListMultimap> left = hashMap(keys, leftData.stream().map(this::convertValuesToString)); ListMultimap> right = hashMap(keys, rightTable); statistics.getRight().setRowsQuantity(right.size()); - List> result = compareData(statistics, left, right); - verifyComparisonResult(statistics, filterPassedChecks(result)); + List> result = compareData(comparisonRule, statistics, left, right); + verifyComparisonResult(comparisonRule, statistics, filterPassedChecks(result)); } - private List> compareData(QueriesStatistic queriesStatistic, - ListMultimap> leftData, ListMultimap> rightData) + private List> compareData(DataSetComparisonRule comparisonRule, + DataSourceStatistics dataSourceStatistics, ListMultimap> leftData, + ListMultimap> rightData) { List, Map>> comparison = new ArrayList<>(); - Stream.concat(leftData.keySet().stream(), rightData.keySet().stream()).distinct().forEach(key -> + comparisonRule.collectComparisonKeys(leftData, rightData).forEach(key -> { List> left = leftData.get(key); List> right = rightData.get(key); int leftSize = left.size(); int rightSize = right.size(); - int size = duplicateKeysStrategy.getTargetSize(leftSize, rightSize); + int size = duplicateKeysStrategy.getTargetSize(comparisonRule, leftSize, rightSize); for (int i = 0; i < size; i++) { Map leftValue = i < leftSize ? left.get(i) : Map.of(); @@ -366,21 +376,14 @@ private List> compareData(QueriesStatistic queriesSt comparison.add(Pair.of(leftValue, rightValue)); } }); - queriesStatistic.getLeft().setNoPair(comparison.stream() - .map(Pair::getRight) - .filter(Map::isEmpty) - .count()); - queriesStatistic.getRight().setNoPair(comparison.stream() - .map(Pair::getLeft) - .filter(Map::isEmpty) - .count()); + comparisonRule.fillStatistics(dataSourceStatistics, comparison); List> comparisonResult = comparison.stream() .parallel() .map(p -> ComparisonUtils.compareMaps(p.getLeft(), p.getRight())) .collect(Collectors.toList()); List> mismatchedRows = filterPassedChecks(comparisonResult); - queriesStatistic.setMismatched(mismatchedRows.size()); - queriesStatistic.setTotalRows(comparisonResult.size()); + dataSourceStatistics.setMismatched(mismatchedRows.size()); + dataSourceStatistics.setTotalRows(comparisonResult.size()); return mismatchedRows.size() > diffLimit ? mismatchedRows.subList(0, diffLimit) : mismatchedRows; } @@ -465,133 +468,4 @@ public void setDiffLimit(int diffLimit) { this.diffLimit = diffLimit; } - - public static final class QueriesStatistic - { - private long totalRows; - private long mismatched; - private final QueryStatistic left; - private final QueryStatistic right; - - private QueriesStatistic(JdbcTemplate leftJdbcTemplate) - { - left = createQueryStatistic(leftJdbcTemplate); - right = new QueryStatistic(); - } - - private QueriesStatistic(JdbcTemplate leftJdbcTemplate, JdbcTemplate rightJdbcTemplate) - { - left = createQueryStatistic(leftJdbcTemplate); - right = createQueryStatistic(rightJdbcTemplate); - } - - private QueryStatistic createQueryStatistic(JdbcTemplate jdbcTemplate) - { - String url = ((DriverManagerDataSource) jdbcTemplate.getDataSource()).getUrl(); - return new QueryStatistic(url); - } - - public long getMismatched() - { - return mismatched; - } - - public long getMatched() - { - return totalRows - mismatched; - } - - public void setMismatched(long mismatched) - { - this.mismatched = mismatched; - } - - public long getTotalRows() - { - return totalRows; - } - - public void setTotalRows(long totalRows) - { - this.totalRows = totalRows; - } - - public QueryStatistic getLeft() - { - return left; - } - - public QueryStatistic getRight() - { - return right; - } - } - - public static final class QueryStatistic - { - private final StopWatch stopwatch = new StopWatch(); - private String url; - private long rowsQuantity; - private String query; - private long noPair; - - private QueryStatistic() - { - } - - private QueryStatistic(String url) - { - this.url = url; - } - - public void start() - { - stopwatch.start(); - } - - public void end() - { - stopwatch.stop(); - } - - public String getExecutionTime() - { - return DurationFormatUtils.formatDurationHMS(stopwatch.getTime()); - } - - public String getQuery() - { - return query; - } - - public void setQuery(String query) - { - this.query = query; - } - - public long getRowsQuantity() - { - return rowsQuantity; - } - - public void setRowsQuantity(long rowsQuantity) - { - this.rowsQuantity = rowsQuantity; - } - - public long getNoPair() - { - return noPair; - } - - public void setNoPair(long noPair) - { - this.noPair = noPair; - } - - public String getUrl() - { - return url; - } - } } diff --git a/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DuplicateKeysStrategy.java b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DuplicateKeysStrategy.java index 108f9e36b5..111ef693a3 100644 --- a/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DuplicateKeysStrategy.java +++ b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/DuplicateKeysStrategy.java @@ -21,7 +21,7 @@ public enum DuplicateKeysStrategy DISTINCT { @Override - public int getTargetSize(int leftSize, int rightSize) + public int getTargetSize(DataSetComparisonRule comparisonRule, int leftSize, int rightSize) { return 1; } @@ -29,11 +29,11 @@ public int getTargetSize(int leftSize, int rightSize) NOOP { @Override - public int getTargetSize(int leftSize, int rightSize) + public int getTargetSize(DataSetComparisonRule comparisonRule, int leftSize, int rightSize) { - return Math.max(leftSize, rightSize); + return comparisonRule == DataSetComparisonRule.CONTAINS ? rightSize : Math.max(leftSize, rightSize); } }; - public abstract int getTargetSize(int leftSize, int rightSize); + public abstract int getTargetSize(DataSetComparisonRule comparisonRule, int leftSize, int rightSize); } diff --git a/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/QueryStatistic.java b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/QueryStatistic.java new file mode 100644 index 0000000000..a736edd5fb --- /dev/null +++ b/vividus-plugin-db/src/main/java/org/vividus/bdd/steps/db/QueryStatistic.java @@ -0,0 +1,84 @@ +/* + * Copyright 2019-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.bdd.steps.db; + +import org.apache.commons.lang3.time.DurationFormatUtils; +import org.apache.commons.lang3.time.StopWatch; + +public final class QueryStatistic +{ + private final StopWatch stopwatch = new StopWatch(); + private final String url; + private long rowsQuantity; + private String query; + private Long noPair; + + QueryStatistic(String url) + { + this.url = url; + } + + public void start() + { + stopwatch.start(); + } + + public void end() + { + stopwatch.stop(); + } + + public String getExecutionTime() + { + return DurationFormatUtils.formatDurationHMS(stopwatch.getTime()); + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public long getRowsQuantity() + { + return rowsQuantity; + } + + public void setRowsQuantity(long rowsQuantity) + { + this.rowsQuantity = rowsQuantity; + } + + public Long getNoPair() + { + return noPair; + } + + public void setNoPair(Long noPair) + { + this.noPair = noPair; + } + + public String getUrl() + { + return url; + } +} diff --git a/vividus-plugin-db/src/main/resources/data-sources-statistics.ftl b/vividus-plugin-db/src/main/resources/data-sources-statistics.ftl new file mode 100644 index 0000000000..cc61dd50b6 --- /dev/null +++ b/vividus-plugin-db/src/main/resources/data-sources-statistics.ftl @@ -0,0 +1,146 @@ + + + + + Data Sources Statistics + + + + + + + + + <#assign left = statistics.left> + <#assign right = statistics.right> +
    + <#if left.query?has_content> +
    +
    +

    + +

    +
    +
    +
    ${left.query}
    +
    +
    + + + <#if right.query?has_content> +
    +
    +

    + +

    +
    +
    +
    ${right.query}
    +
    +
    + + +
    +
    + + + + + + + + + + <#assign emptyTime="00:00:00.000"> + <#if !(left.getExecutionTime() == emptyTime && right.getExecutionTime() == emptyTime)> + + + + + + + + + + + + + + + + + + + + + + +
    ParameterLeft data sourceRight data source
    Execution time hh:mm:ss:SSS${left.getExecutionTime()}${right.getExecutionTime()}
    Rows Quantity${left.rowsQuantity}${right.rowsQuantity}
    No pair found${(left.noPair)!'N/A'}${(right.noPair)!'N/A'}
    Connection${(left.url)!'N/A'}${(right.url)!'N/A'}
    +
    +
    +
    +
    +

    Total unique rows: ${statistics.totalRows}

    +
    +
    +

    Counts difference: ${(left.rowsQuantity - right.rowsQuantity)?abs}

    +
    +
    +

    + +

    +
    +
    +
    + + + + + + + + + + + diff --git a/vividus-plugin-db/src/main/resources/queries-statistics.ftl b/vividus-plugin-db/src/main/resources/queries-statistics.ftl deleted file mode 100644 index 9b8aac6045..0000000000 --- a/vividus-plugin-db/src/main/resources/queries-statistics.ftl +++ /dev/null @@ -1,153 +0,0 @@ - - - - - Queries statistics - - - - - - - - - <#assign left = statistics.left> - <#assign right = statistics.right> -
    - <#if left.query?has_content> -
    -
    -

    - -

    -
    -
    -
    ${left.query}
    -
    -
    - - - <#if right.query?has_content> -
    -
    -

    - -

    -
    -
    -
    ${right.query}
    -
    -
    - - -
    -
    -

    - -

    -
    -
    -
    - - - - - - - - - - <#assign emptyTime="00:00:00.000"> - <#if !(left.getExecutionTime() == emptyTime && right.getExecutionTime() == emptyTime)> - - - - - - - - - - - - - - - - - - - - - - -
    ParameterLeft data sourceRight data source
    Execution time hh:mm:ss:SSS${left.getExecutionTime()}${right.getExecutionTime()}
    Rows Quantity${left.rowsQuantity}${right.rowsQuantity}
    No pair found${left.noPair}${right.noPair}
    Connection${(left.url)!'N/A'}${(right.url)!'N/A'}
    -
    -
    -
    -
    -

    Total unique rows: ${statistics.totalRows}

    -
    -
    -

    Counts difference: ${(left.rowsQuantity - right.rowsQuantity)?abs}

    -
    -
    -

    - -

    -
    -
    -
    -
    - - - - - - - - - - - diff --git a/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DatabaseStepsTests.java b/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DatabaseStepsTests.java index d9e9fe7877..1cc4ec52f5 100644 --- a/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DatabaseStepsTests.java +++ b/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DatabaseStepsTests.java @@ -20,6 +20,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.params.provider.Arguments.arguments; import static org.mockito.ArgumentMatchers.any; @@ -63,6 +65,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.InjectMocks; import org.mockito.Mock; @@ -72,8 +75,6 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.vividus.bdd.context.IBddVariableContext; import org.vividus.bdd.steps.StringComparisonRule; -import org.vividus.bdd.steps.db.DatabaseSteps.QueriesStatistic; -import org.vividus.bdd.steps.db.DatabaseSteps.QueryStatistic; import org.vividus.bdd.variable.VariableScope; import org.vividus.reporter.event.IAttachmentPublisher; import org.vividus.softassert.ISoftAssert; @@ -100,15 +101,13 @@ class DatabaseStepsTests private static final String STATISTICS = "statistics"; - private static final String QUERIES_COMPARISON_RESULT = "Queries comparison result"; - - private static final String QUERIES_STATISTICS_FTL = "queries-statistics.ftl"; - - private static final String QUERIES_STATISTICS = "Queries statistics"; + private static final String DATA_SOURCES_STATISTICS_TITLE = "Data sources statistics"; + private static final String DATA_SOURCES_STATISTICS_FTL = "data-sources-statistics.ftl"; private static final String RESULTS = "results"; - private static final String TEMPLATE_PATH = "/templates/maps-comparison-table.ftl"; + private static final String DATA_SET_COMPARISON_FTL = "/templates/maps-comparison-table.ftl"; + private static final String DATA_SETS_COMPARISON_TITLE = "Data sets comparison"; private static final String QUERY_RESULTS_ARE_EQUAL = "Query results are equal"; @@ -122,6 +121,7 @@ class DatabaseStepsTests private static final String QUERY = "select col1 from table"; private static final String QUERY2 = "select col1 from table2"; + private static final Set KEYS = Set.of(COL1); private static final HashCode HASH1 = Hashing.murmur3_128().hashString(VAL1, StandardCharsets.UTF_8); @@ -142,14 +142,10 @@ class DatabaseStepsTests private final IAttachmentPublisher attachmentPublisher = mock(IAttachmentPublisher.class); - @Mock - private PropertyMappedCollection dataSources; - - @Mock - private HashFunction hashFunction; - - @InjectMocks - private final DatabaseSteps databaseSteps = new DatabaseSteps(bddVariableContext, attachmentPublisher, softAssert); + @Mock private PropertyMappedCollection dataSources; + @Mock private HashFunction hashFunction; + @InjectMocks private final DatabaseSteps databaseSteps = new DatabaseSteps(bddVariableContext, attachmentPublisher, + softAssert); @BeforeEach void beforeEach() @@ -168,18 +164,36 @@ void testExecuteSql() throws SQLException verify(bddVariableContext).putVariable(variableScope, variableName, singletonList); } - @Test - void shouldCompareQueriesResponsesAndDontPostDiffInCaseOfEqualData() throws InterruptedException, - ExecutionException, TimeoutException, SQLException + static Stream matchingResultSets() throws SQLException { - mockDataSource(QUERY, DB_KEY, mockResultSet(COL1, VAL1, COL2, VAL2, COL3, VAL3)); - mockDataSource(QUERY, DB_KEY2, mockResultSet(COL1, VAL1, COL2, VAL2, COL3, VAL3)); - when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, true)).thenReturn(true); + return Stream.of( + arguments( + DataSetComparisonRule.IS_EQUAL_TO, + mockResultSet(COL1, VAL1, COL2, VAL2, COL3, VAL3), + mockResultSet(COL1, VAL1, COL2, VAL2, COL3, VAL3) + ), + arguments( + DataSetComparisonRule.CONTAINS, + mockResultSet(COL1, VAL1, COL2, VAL2, COL3, VAL3), + mockResultSet(COL2, VAL2) + ) + ); + } + + @ParameterizedTest + @MethodSource("matchingResultSets") + void shouldCompareQueriesResponsesAndDontPostDiffInCaseOfEqualData(DataSetComparisonRule comparisonRule, + ResultSet leftResultSet, ResultSet rightResultSet) + throws InterruptedException, ExecutionException, TimeoutException, SQLException + { + mockDataSource(QUERY, DB_KEY, leftResultSet); + mockDataSource(QUERY, DB_KEY2, rightResultSet); + when(softAssert.assertTrue(comparisonRule.getAssertionDescription(), true)).thenReturn(true); configureTimeout(); databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.NOOP); - databaseSteps.compareData(QUERY, DB_KEY, QUERY, DB_KEY2, Set.of(COL1)); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), any(Map.class), - eq(QUERIES_STATISTICS)); + databaseSteps.compareData(QUERY, DB_KEY, comparisonRule, QUERY, DB_KEY2, KEYS); + verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL), any(Map.class), + eq(DATA_SOURCES_STATISTICS_TITLE)); verify(hashFunction, times(2)).hashString(any(), eq(StandardCharsets.UTF_8)); } @@ -198,9 +212,9 @@ void shouldCompareQueriesAndUseAllColumnValuesIfUserDoesntSpecifyKeys() throws I when(hashFunction.hashString(argThat(matcher), eq(StandardCharsets.UTF_8))).thenReturn(HASH1); configureTimeout(); databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.NOOP); - databaseSteps.compareData(QUERY, DB_KEY, QUERY, DB_KEY2, Set.of()); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), - any(Map.class), eq(QUERIES_STATISTICS)); + databaseSteps.compareData(QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, QUERY, DB_KEY2, Set.of()); + verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL), + any(Map.class), eq(DATA_SOURCES_STATISTICS_TITLE)); verify(hashFunction, times(2)).hashString(argThat(matcher), eq(StandardCharsets.UTF_8)); } @@ -286,10 +300,10 @@ void shouldCompareQueriesResponsesAndPostDiffTable() throws InterruptedException mockHashing(); configureTimeout(); databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.DISTINCT); - databaseSteps.compareData(QUERY, DB_KEY, QUERY2, DB_KEY2, Set.of(COL1)); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), + databaseSteps.compareData(QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, QUERY2, DB_KEY2, KEYS); + verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL), argThat(r -> { - QueriesStatistic statistics = ((Map) r).get(STATISTICS); + DataSourceStatistics statistics = ((Map) r).get(STATISTICS); QueryStatistic right = statistics.getRight(); QueryStatistic left = statistics.getLeft(); return 3 == statistics.getMismatched() @@ -305,10 +319,10 @@ void shouldCompareQueriesResponsesAndPostDiffTable() throws InterruptedException && 1 == right.getNoPair() && DB_URL.equals(left.getUrl()) && DB_URL.equals(right.getUrl()); - }), eq(QUERIES_STATISTICS)); - verify(attachmentPublisher).publishAttachment(eq(TEMPLATE_PATH), argThat(r -> + }), eq(DATA_SOURCES_STATISTICS_TITLE)); + verify(attachmentPublisher).publishAttachment(eq(DATA_SET_COMPARISON_FTL), argThat(r -> ((Map>>) r).get(RESULTS).size() == 3), - eq(QUERIES_COMPARISON_RESULT)); + eq(DATA_SETS_COMPARISON_TITLE)); } private void mockHashing() @@ -345,10 +359,10 @@ void shouldLimitDiffTable() throws InterruptedException, ExecutionException, Tim when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, false)).thenReturn(false); mockHashing(); configureTimeout(); - databaseSteps.compareData(QUERY, DB_KEY, QUERY, DB_KEY2, Set.of(COL1)); - verify(attachmentPublisher).publishAttachment(eq(TEMPLATE_PATH), argThat(r -> + databaseSteps.compareData(QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, QUERY, DB_KEY2, KEYS); + verify(attachmentPublisher).publishAttachment(eq(DATA_SET_COMPARISON_FTL), argThat(r -> ((Map>>) r).get(RESULTS).size() == 1), - eq(QUERIES_COMPARISON_RESULT)); + eq(DATA_SETS_COMPARISON_TITLE)); } @Test @@ -357,88 +371,125 @@ void shouldThrowTimeoutExceptionIfQueryTakesTooMuchTime() databaseSteps.setDbQueryTimeout(Duration.ofNanos(0)); mockDataSourceRetrieval(); assertThrows(TimeoutException.class, - () -> databaseSteps.compareData(QUERY, DB_KEY, QUERY, DB_KEY, Set.of(COL1))); + () -> databaseSteps.compareData(QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, QUERY, DB_KEY, KEYS)); verifyNoInteractions(attachmentPublisher, softAssert); } - static Stream equalDataProvider() + static Stream matchingDataSets() { return Stream.of( - arguments(List.of(Map.of(COL1, VAL1)), List.of(Map.of(COL1, VAL1))), - arguments(List.of(Map.of(COL1, VAL1, COL2, VAL2)), List.of(Map.of(COL2, VAL2, COL1, VAL1))) + arguments( + DataSetComparisonRule.IS_EQUAL_TO, + List.of(Map.of(COL1, VAL1)), + List.of(Map.of(COL1, VAL1)) + ), + arguments( + DataSetComparisonRule.CONTAINS, + List.of(Map.of(COL1, VAL1)), + List.of(Map.of(COL1, VAL1)) + ), + arguments( + DataSetComparisonRule.IS_EQUAL_TO, + List.of(Map.of(COL1, VAL1, COL2, VAL2)), + List.of(Map.of(COL2, VAL2, COL1, VAL1)) + ), + arguments( + DataSetComparisonRule.CONTAINS, + List.of(Map.of(COL1, VAL1), Map.of(COL1, VAL2)), + List.of(Map.of(COL1, VAL2)) + ) ); } @ParameterizedTest - @MethodSource("equalDataProvider") - void shouldCompareDataVsExamplesTableAndNotPostReportIfDataEqual(List> data, - List> table) + @MethodSource("matchingDataSets") + void shouldCompareDataVsExamplesTableAndNotPostReportIfDataEqual(DataSetComparisonRule comparisonRule, + List> leftDataSet, List> rightDataSet) { - when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, true)).thenReturn(true); + when(softAssert.assertTrue(comparisonRule.getAssertionDescription(), true)).thenReturn(true); databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.NOOP); + mockHashing(); mockDataSource(); - databaseSteps.compareData(data, Set.of(), DB_KEY, table); - verify(attachmentPublisher, never()).publishAttachment(eq(TEMPLATE_PATH), any(), any()); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), - argThat(r -> { - @SuppressWarnings("unchecked") - QueriesStatistic statistics = ((Map) r).get(STATISTICS); - QueryStatistic right = statistics.getRight(); - QueryStatistic left = statistics.getLeft(); - return 0 == statistics.getMismatched() - && 1 == statistics.getTotalRows() - && EMPTY_TIME.equals(left.getExecutionTime()) - && EMPTY_TIME.equals(right.getExecutionTime()) - && left.getQuery() == null - && right.getQuery() == null - && 1 == left.getRowsQuantity() - && 1 == right.getRowsQuantity() - && 1 == statistics.getMatched() - && 0 == right.getNoPair() - && 0 == left.getNoPair() - && right.getUrl() == null - && DB_URL.equals(left.getUrl()); - }), eq(QUERIES_STATISTICS)); + databaseSteps.compareData(leftDataSet, Set.of(), DB_KEY, comparisonRule, rightDataSet); + verify(attachmentPublisher, never()).publishAttachment(eq(DATA_SET_COMPARISON_FTL), any(), any()); + verifyQueryStatisticsPublishing(comparisonRule, leftDataSet, rightDataSet, 0, 1); + } + + static Stream notMatchingDataSets() + { + return Stream.of( + arguments( + DataSetComparisonRule.IS_EQUAL_TO, + List.of(Map.of(COL1, VAL1, COL2, VAL1)), + List.of(Map.of(COL1, VAL1, COL2, VAL2)) + ), + arguments( + DataSetComparisonRule.CONTAINS, + List.of(Map.of(COL1, VAL1, COL2, VAL1)), + List.of(Map.of(COL1, VAL1, COL2, VAL2)) + ), + arguments( + DataSetComparisonRule.CONTAINS, + List.of(Map.of(COL1, VAL1, COL2, VAL1), Map.of(COL1, VAL1, COL2, VAL3)), + List.of(Map.of(COL1, VAL1, COL2, VAL2)) + ) + ); } @SuppressWarnings("unchecked") - @Test - void shouldCompareDataVsExamplesTableAndPostReportFailedChecks() + @ParameterizedTest + @MethodSource("notMatchingDataSets") + void shouldCompareDataVsExamplesTableAndPostReportFailedChecks(DataSetComparisonRule comparisonRule, + List> leftDataSet, List> rightDataSet) { - when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, false)).thenReturn(false); + when(softAssert.assertTrue(comparisonRule.getAssertionDescription(), false)).thenReturn(false); databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.NOOP); + mockHashing(); mockDataSource(); - databaseSteps.compareData(List.of(Map.of(COL1, VAL1)), Set.of(), DB_KEY, TABLE); - verify(attachmentPublisher).publishAttachment(eq(TEMPLATE_PATH), argThat(r -> { - List> results = (List>) ((Map) r) - .get(RESULTS); - List firstRowResults = results.get(0); - EntryComparisonResult result = firstRowResults.get(0); - return 1 == results.size() - && 1 == firstRowResults.size() - && VAL2.equals(result.getRight()) - && VAL1.equals(result.getLeft()) - && !result.isPassed(); - }), - eq(QUERIES_COMPARISON_RESULT)); - verify(softAssert).assertTrue(QUERY_RESULTS_ARE_EQUAL, false); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), - argThat(r -> { - QueriesStatistic statistics = ((Map) r).get(STATISTICS); - QueryStatistic right = statistics.getRight(); - QueryStatistic left = statistics.getLeft(); - return 1 == statistics.getMismatched() - && 1 == statistics.getTotalRows() - && EMPTY_TIME.equals(right.getExecutionTime()) - && EMPTY_TIME.equals(left.getExecutionTime()) - && right.getQuery() == null - && left.getQuery() == null - && 1 == right.getRowsQuantity() - && 1 == left.getRowsQuantity() - && 0 == statistics.getMatched() - && 0 == left.getNoPair() - && 0 == right.getNoPair(); - }), eq(QUERIES_STATISTICS)); + databaseSteps.compareData(leftDataSet, KEYS, DB_KEY, comparisonRule, rightDataSet); + var resultsCaptor = ArgumentCaptor.forClass(Object.class); + verify(attachmentPublisher).publishAttachment(eq(DATA_SET_COMPARISON_FTL), resultsCaptor.capture(), + eq(DATA_SETS_COMPARISON_TITLE)); + + List> results = (List>) ((Map) resultsCaptor + .getValue()).get(RESULTS); + assertEquals(1, results.size()); + List firstRowResults = results.get(0); + assertEquals(2, firstRowResults.size()); + EntryComparisonResult result = firstRowResults.stream().filter(r -> COL2.equals(r.getKey())).findFirst().get(); + assertEquals(VAL1, result.getLeft()); + assertEquals(VAL2, result.getRight()); + assertFalse(result.isPassed()); + + verifyQueryStatisticsPublishing(comparisonRule, leftDataSet, rightDataSet, 1, 0); + } + + @SuppressWarnings("unchecked") + private void verifyQueryStatisticsPublishing(DataSetComparisonRule comparisonRule, + List> leftDataSet, List> rightDataSet, int expectedMismatched, + int expectedMatched) + { + var statisticsCaptor = ArgumentCaptor.forClass(Object.class); + verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL), statisticsCaptor.capture(), + eq(DATA_SOURCES_STATISTICS_TITLE)); + DataSourceStatistics statistics = ((Map) statisticsCaptor.getValue()).get( + STATISTICS); + assertEquals(expectedMismatched, statistics.getMismatched()); + assertEquals(1, statistics.getTotalRows()); + assertEquals(expectedMatched, statistics.getMatched()); + assertQueryStatistic(statistics.getLeft(), leftDataSet.size(), + comparisonRule == DataSetComparisonRule.CONTAINS ? null : 0L, DB_URL); + assertQueryStatistic(statistics.getRight(), rightDataSet.size(), 0L, null); + } + + private void assertQueryStatistic(QueryStatistic actual, int expectedRowsQuantity, Long expectedNoPair, + String expectedUrl) + { + assertEquals(EMPTY_TIME, actual.getExecutionTime()); + assertNull(actual.getQuery()); + assertEquals(expectedRowsQuantity, actual.getRowsQuantity()); + assertEquals(expectedNoPair, actual.getNoPair()); + assertEquals(expectedUrl, actual.getUrl()); } @Test @@ -447,9 +498,9 @@ void testWaitUntilQueryReturnedDataEqualToTable() throws SQLException databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.NOOP); mockDataSource(QUERY, DB_KEY, mockResultSet(COL1, VAL2)); when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, true)).thenReturn(true); - databaseSteps.waitForDataAppearance(TWO_SECONDS, 10, QUERY, DB_KEY, TABLE); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), - any(Map.class), eq(QUERIES_STATISTICS)); + databaseSteps.waitForDataAppearance(TWO_SECONDS, 10, QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, TABLE); + verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL), + any(Map.class), eq(DATA_SOURCES_STATISTICS_TITLE)); verify(softAssert).assertTrue(QUERY_RESULTS_ARE_EQUAL, true); } @@ -468,9 +519,9 @@ void testWaitTwiceUntilQueryReturnedDataEqualToTable() throws SQLException when(dataSource.getConnection()).thenReturn(con); when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, true)).thenReturn(true); - databaseSteps.waitForDataAppearance(TWO_SECONDS, 10, QUERY, DB_KEY, TABLE); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), - any(Map.class), eq(QUERIES_STATISTICS)); + databaseSteps.waitForDataAppearance(TWO_SECONDS, 10, QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, TABLE); + verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL), + any(Map.class), eq(DATA_SOURCES_STATISTICS_TITLE)); verify(softAssert).assertTrue(QUERY_RESULTS_ARE_EQUAL, true); } @@ -488,14 +539,14 @@ void testWaitUntilQueryReturnedDataEqualToTableFailed() throws SQLException DriverManagerDataSource dataSource = mockDataSourceRetrieval(); when(dataSource.getConnection()).thenReturn(con); - databaseSteps.waitForDataAppearance( - Duration.ofSeconds(2), 2, QUERY, DB_KEY, TABLE); + databaseSteps.waitForDataAppearance(Duration.ofSeconds(2), 2, QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, + TABLE); String logMessage = "SQL result data is not equal to expected data in {} records"; assertThat(LOGGER.getLoggingEvents(), equalTo(List.of(info(logMessage, 1), info(logMessage, 1)))); - verify(attachmentPublisher).publishAttachment(eq(QUERIES_STATISTICS_FTL), - any(Map.class), eq(QUERIES_STATISTICS)); + verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL), + any(Map.class), eq(DATA_SOURCES_STATISTICS_TITLE)); verify(softAssert).assertTrue(QUERY_RESULTS_ARE_EQUAL, false); - verify(attachmentPublisher).publishAttachment(eq(TEMPLATE_PATH), argThat(r -> { + verify(attachmentPublisher).publishAttachment(eq(DATA_SET_COMPARISON_FTL), argThat(r -> { @SuppressWarnings("unchecked") List> results = (List>) ((Map) r) .get(RESULTS); @@ -507,7 +558,7 @@ void testWaitUntilQueryReturnedDataEqualToTableFailed() throws SQLException && VAL3.equals(result.getLeft()) && !result.isPassed(); }), - eq(QUERIES_COMPARISON_RESULT)); + eq(DATA_SETS_COMPARISON_TITLE)); } @Test @@ -574,7 +625,7 @@ private DriverManagerDataSource mockDataSource(String query, String dbKey, Resul return dataSource; } - private ResultSet mockResultSet(String columnName, String value) throws SQLException + private static ResultSet mockResultSet(String columnName, String value) throws SQLException { ResultSetMetaData rsmd = mock(ResultSetMetaData.class); when(rsmd.getColumnCount()).thenReturn(1); @@ -586,7 +637,7 @@ private ResultSet mockResultSet(String columnName, String value) throws SQLExcep return rs; } - private ResultSet mockResultSet(String columnName1, String value1, String columnName2, String value2, + private static ResultSet mockResultSet(String columnName1, String value1, String columnName2, String value2, String columnName3, String value3) throws SQLException { ResultSetMetaData rsmd = mock(ResultSetMetaData.class); diff --git a/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DuplicateKeysStrategyTests.java b/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DuplicateKeysStrategyTests.java index 441eafd07c..5e254f6bb7 100644 --- a/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DuplicateKeysStrategyTests.java +++ b/vividus-plugin-db/src/test/java/org/vividus/bdd/steps/db/DuplicateKeysStrategyTests.java @@ -27,18 +27,22 @@ class DuplicateKeysStrategyTests @Test void shouldAlwaysReturnOneForDistinctStrategy() { - assertEquals(1, DuplicateKeysStrategy.DISTINCT.getTargetSize(0, 0)); + assertEquals(1, DuplicateKeysStrategy.DISTINCT.getTargetSize(null, 0, 0)); } @ParameterizedTest @CsvSource({ - "2, 3, 3", - "5, 4, 5", - "1, 0, 1", - "0, 1, 1" + "IS_EQUAL_TO, 2, 3, 3", + "CONTAINS, 2, 3, 3", + "IS_EQUAL_TO, 5, 4, 5", + "CONTAINS, 5, 4, 4", + "IS_EQUAL_TO, 1, 0, 1", + "CONTAINS, 1, 0, 0", + "IS_EQUAL_TO, 0, 1, 1" }) - void shouldReturnMaxValueForNoopStrategy(int leftSize, int rightSize, int expected) + void shouldReturnMaxValueForNoopStrategy(DataSetComparisonRule comparisonRule, int leftSize, int rightSize, + int expected) { - assertEquals(expected, DuplicateKeysStrategy.NOOP.getTargetSize(leftSize, rightSize)); + assertEquals(expected, DuplicateKeysStrategy.NOOP.getTargetSize(comparisonRule, leftSize, rightSize)); } } diff --git a/vividus-tests/src/main/resources/story/integration/Databases.story b/vividus-tests/src/main/resources/story/integration/Databases.story new file mode 100644 index 0000000000..5db0d70fab --- /dev/null +++ b/vividus-tests/src/main/resources/story/integration/Databases.story @@ -0,0 +1,11 @@ +Meta: + @epic vividus-plugin-db + +Scenario: Wait for data from the data source to contain rows from the table +Meta: + @issueId 1658 +When I wait for 'PT10s' duration retrying 3 times while data from ` +SELECT * FROM csv-with-semicolon-and-duplicates +` executed against `csv-data` contains data from: +|country|capital|data | +|Belarus|Minsk |{"sheet": [{"cols": 1, "name": "A", "rows": 2}], "name": "tests"}|