├── .github └── workflows │ ├── codeql.yml │ └── github-actions.yml ├── .gitignore ├── LICENSE ├── LICENSE-3RD-PARTY ├── README.md ├── azure-pipelines.yml ├── copyArtifact.ps1 ├── deploy ├── Config │ ├── DEV01 │ └── DEV02 └── build.xml ├── docker ├── docker-compose.yml ├── my-mysql │ └── Dockerfile ├── my-postgres │ └── Dockerfile └── my_sqlserver │ └── Dockerfile ├── downloadBackupAndJDBCDrivers.ps1 ├── images ├── DBTestCompare.png ├── Githubactions.png ├── comparingDB.png └── comparingDataDB.png ├── jdbc_drivers ├── mariadb-java-client-2.6.0.jar ├── mysql-connector-java-8.0.23.jar └── postgresql-42.7.4.jar ├── pom.xml ├── restoreBackup.ps1 ├── setDBTestCompareVersion.ps1 ├── src └── main │ ├── java │ └── uk │ │ └── co │ │ └── objectivity │ │ └── test │ │ └── db │ │ ├── DBTestCompare.java │ │ ├── RunTests.java │ │ ├── TestDataProvider.java │ │ ├── aggregators │ │ ├── Aggregator.java │ │ ├── AggregatorType.java │ │ ├── DateAggregator.java │ │ ├── OverrideAgregator.java │ │ ├── SumIntegersAggregator.java │ │ └── condition │ │ │ ├── AggregatorCondition.java │ │ │ ├── AggregatorConditionType.java │ │ │ ├── Equals.java │ │ │ └── NotEquals.java │ │ ├── beans │ │ ├── CheckPresenceAlgorithm.java │ │ ├── CompareMode.java │ │ ├── ConditionType.java │ │ ├── FileRow.java │ │ ├── TestParams.java │ │ ├── TestResults.java │ │ └── xml │ │ │ ├── Aggregator.java │ │ │ ├── AggregatorCondition.java │ │ │ ├── Aggregators.java │ │ │ ├── BeforeSqls.java │ │ │ ├── CmpSqlResultsConfig.java │ │ │ ├── CmpSqlResultsTest.java │ │ │ ├── Compare.java │ │ │ ├── Condition.java │ │ │ ├── Datasource.java │ │ │ ├── Datasources.java │ │ │ ├── File.java │ │ │ ├── Filter.java │ │ │ ├── Logger.java │ │ │ ├── Sql.java │ │ │ ├── Transformer.java │ │ │ └── Transformers.java │ │ ├── comparators │ │ ├── Comparator.java │ │ ├── FetchComparator.java │ │ ├── FileComparator.java │ │ ├── KeyComparator.java │ │ ├── MinusComparator.java │ │ ├── NmbOfResultsComparator.java │ │ ├── printer │ │ │ ├── CompareResult.java │ │ │ ├── ExcelPrinter.java │ │ │ ├── Headers.java │ │ │ └── utils │ │ │ │ ├── Excel.java │ │ │ │ └── ExcelStyle.java │ │ └── results │ │ │ ├── DBResults.java │ │ │ └── DBRow.java │ │ ├── transformers │ │ ├── RemoveLeadingZerosTransformer.java │ │ ├── SwapTransformer.java │ │ ├── Transformer.java │ │ └── TransformerType.java │ │ └── utils │ │ ├── DataSource.java │ │ ├── Printer.java │ │ ├── SavedTimes.java │ │ └── TCMessages.java │ └── resources │ └── log4j.properties └── test-definitions ├── cmpSqlResults-config.xml ├── compare_with_file ├── SQLExceptioncompare_with_file_SQL_Server.xml ├── compare_with_file_SQL_Server.xml ├── fileSource.csv ├── sql1.sql └── sql2Exception.sql ├── compare_with_file_stucture ├── compare_with_db_structure_SQLServer.xml ├── compare_with_db_structure_SQLServerFileWithHeader.xml ├── db_structure_current.csv └── db_structure_currentFileWithHeader.csv ├── cube └── test.xml ├── delta └── floating_point │ ├── ActualTable.sql │ ├── ExpectedTable.sql │ └── SalesOrderDetail_SQL_SERVER.xml ├── fetch_compare_test ├── Exception_inline_sql_SQL_SERVER_PostgreSQL_FAIL.xml ├── from_file_sql_MySQL_PostgreSQL_FAIL.xml ├── inline_sql_SQL_SERVER_PostgreSQL.xml ├── sql1.sql └── sql2.sql ├── key_comparator ├── ContactType │ ├── ContactType.csv │ ├── ContactTypeActualTable.sql │ └── KeyContactType_FAIL.xml └── Product │ ├── Product.xml │ ├── create.sql │ ├── drop.sql │ ├── insert.sql │ ├── product.csv │ └── product.sql ├── minus_file_output ├── union_compare_failure_count_test.xml └── union_compare_failure_test.xml ├── minus_many_xml_files ├── ExceptionPersonAddress_SQL_SERVER_first_FAIL.xml ├── PersonAddress_PostgreSQL.xml ├── PersonAddress_SQL_SERVER_diffTableSize_0_FAIL.xml ├── PersonAddress_SQL_SERVER_first_FAIL.xml └── PersonAddress_SQL_SERVER_second.xml ├── minus_on_union ├── SQL_SERVER_union_noIndicator_FAIL.xml ├── SQL_SERVER_union_noIndicator_SUCCESS.xml ├── SQL_SERVER_union_withIndicator_FAIL.xml └── SQL_SERVER_union_withIndicator_SUCCESS.xml ├── multilevel_tests ├── Two │ ├── Three │ │ └── not_from_files.xml │ └── lvl_two_not_from_files.xml └── union_compare_failure_test.xml ├── nmb_of_results ├── Exception_assert_equal_FAIL.xml └── assert_equal.xml └── sql-from-file ├── from_files.xml ├── misconfigured_FAIL.xml ├── mixed.xml ├── not_from_files.xml ├── sql1.sql └── sql2.sql /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL Advanced" 13 | 14 | on: 15 | push: 16 | branches: [ "master" ] 17 | pull_request: 18 | branches: [ "master" ] 19 | schedule: 20 | - cron: '37 17 * * 5' 21 | 22 | jobs: 23 | analyze: 24 | name: Analyze (${{ matrix.language }}) 25 | # Runner size impacts CodeQL analysis time. To learn more, please see: 26 | # - https://gh.io/recommended-hardware-resources-for-running-codeql 27 | # - https://gh.io/supported-runners-and-hardware-resources 28 | # - https://gh.io/using-larger-runners (GitHub.com only) 29 | # Consider using larger runners or machines with greater resources for possible analysis time improvements. 30 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} 31 | permissions: 32 | # required for all workflows 33 | security-events: write 34 | 35 | # required to fetch internal or private CodeQL packs 36 | packages: read 37 | 38 | # only required for workflows in private repositories 39 | actions: read 40 | contents: read 41 | 42 | strategy: 43 | fail-fast: false 44 | matrix: 45 | include: 46 | - language: java-kotlin 47 | build-mode: none # This mode only analyzes Java. Set this to 'autobuild' or 'manual' to analyze Kotlin too. 48 | # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' 49 | # Use `c-cpp` to analyze code written in C, C++ or both 50 | # Use 'java-kotlin' to analyze code written in Java, Kotlin or both 51 | # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both 52 | # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, 53 | # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. 54 | # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how 55 | # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages 56 | steps: 57 | - name: Checkout repository 58 | uses: actions/checkout@v4 59 | 60 | # Initializes the CodeQL tools for scanning. 61 | - name: Initialize CodeQL 62 | uses: github/codeql-action/init@v3 63 | with: 64 | languages: ${{ matrix.language }} 65 | build-mode: ${{ matrix.build-mode }} 66 | # If you wish to specify custom queries, you can do so here or in a config file. 67 | # By default, queries listed here will override any specified in a config file. 68 | # Prefix the list here with "+" to use these queries and those in the config file. 69 | 70 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 71 | # queries: security-extended,security-and-quality 72 | 73 | # If the analyze step fails for one of the languages you are analyzing with 74 | # "We were unable to automatically build your code", modify the matrix above 75 | # to set the build mode to "manual" for that language. Then modify this step 76 | # to build your code. 77 | # ℹ️ Command-line programs to run using the OS shell. 78 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 79 | - if: matrix.build-mode == 'manual' 80 | shell: bash 81 | run: | 82 | echo 'If you are using a "manual" build mode for one or more of the' \ 83 | 'languages you are analyzing, replace this with the commands to build' \ 84 | 'your code, for example:' 85 | echo ' make bootstrap' 86 | echo ' make release' 87 | exit 1 88 | 89 | - name: Perform CodeQL Analysis 90 | uses: github/codeql-action/analyze@v3 91 | with: 92 | category: "/language:${{matrix.language}}" 93 | -------------------------------------------------------------------------------- /.github/workflows/github-actions.yml: -------------------------------------------------------------------------------- 1 | # Maven 2 | # Build your Java project and run tests with Apache Maven. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/java 5 | 6 | on: 7 | workflow_dispatch: 8 | push: 9 | branches: 10 | - '*' 11 | paths-ignore: 12 | - README.md 13 | - gh-pages 14 | tags: 15 | - '*' 16 | schedule: 17 | - cron: '0 19 * * 0' 18 | jobs: 19 | build: 20 | runs-on: ubuntu-latest 21 | env: 22 | dBTestCompareVersion: 1.9.6 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Install Docker Compose and build docker image 26 | run: | 27 | sudo apt-get update 28 | sudo apt-get install -y docker-compose 29 | - uses: cedx/setup-ant@v2 30 | - shell: pwsh 31 | run: | 32 | $tags = git tag --sort=-creatordate 33 | $tag = $tags[0] 34 | Write-Host "##vso[task.setvariable variable=dBTestCompareVersion]$tag" 35 | if: startsWith(github.ref, 'refs/tags/') 36 | - shell: pwsh 37 | run: | 38 | ./setDBTestCompareVersion.ps1 39 | - shell: pwsh 40 | run: | 41 | ./downloadBackupAndJDBCDrivers.ps1 42 | - run: docker-compose -f "./docker/docker-compose.yml" up -d 43 | - shell: pwsh 44 | run: | 45 | ./restoreBackup.ps1 46 | - name: Run ant build 47 | run: ant -noinput -buildfile ./deploy/build.xml -Dconfig=DEV02 compile tokens.copy.files testdbq.run 48 | - name: Publish Test Report 49 | uses: mikepenz/action-junit-report@v4 50 | if: success() || failure() 51 | with: 52 | report_paths: '**/TEST-*.xml' 53 | - shell: pwsh 54 | run: | 55 | ./copyArtifact.ps1 56 | - uses: actions/upload-artifact@v4 57 | with: 58 | name: DBTestCompare${{ env.dBTestCompareVersion }}.TestResults.${{github.run_number}} 59 | path: ./target/test-output 60 | - uses: actions/upload-artifact@v4 61 | with: 62 | name: DBTestCompare${{ env.dBTestCompareVersion }}.TestDefinitionsResults.${{github.run_number}} 63 | path: ./target/test-definitions 64 | - uses: actions/upload-artifact@v4 65 | with: 66 | name: DBTestCompare${{ env.dBTestCompareVersion }} 67 | path: ./release 68 | - shell: pwsh 69 | run: compress-archive -path "./release" ./release/DBTestCompare${{ env.dBTestCompareVersion }}.zip 70 | - shell: pwsh 71 | run: Copy './release/DBTestCompare${{ env.dBTestCompareVersion }}.zip' '${{ github.workspace }}' 72 | - shell: bash 73 | run: | 74 | upload_url=$(curl -sL https://api.github.com/repos/Accenture/DBTestCompare/releases/latest | jq -r '.upload_url') 75 | echo UPLOAD_URL=$upload_url >> $GITHUB_ENV 76 | - name: 'Upload linux artifact to Release' 77 | run: gh release upload ${{ env.dBTestCompareVersion }} ./release/DBTestCompare${{ env.dBTestCompareVersion }}.zip 78 | env: 79 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 80 | if: startsWith(github.ref, 'refs/tags/') 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /target/ 3 | /test-output/ 4 | /test-definitions2/ 5 | /AdventureWorks2008R2FullDatabaseBackup.zip 6 | /sqljdbc_8.2.0.0_enu.zip 7 | /sql-scripts.zip 8 | /docker/**/*.sql 9 | /docker/AdventureWorks2008R2FullDatabaseBackup.bak 10 | /jdbc_drivers/mssql-jdbc-8.2.0.jre11.jar 11 | /jdbc_drivers/mssql-jdbc-8.2.0.jre13.jar 12 | /jdbc_drivers/mssql-jdbc-8.2.0.jre8.jar 13 | /zip 14 | /release 15 | /*.iml 16 | /*.jar 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Objectivity Bespoke Software Specialists 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /LICENSE-3RD-PARTY: -------------------------------------------------------------------------------- 1 | Third-Party Software Used by DB.Quality: 2 | |Software|Version|Licensed| 3 | |SIROCCO :: Text Table Formatter|1.0|The Apache Software License, Version 2.0| 4 | |Apache Log4j|1.2.17|Apache 2.0| 5 | |com.sun.xml.bind :: JAXB Runtime|2.1.8|CDDL 1.1,GPL 1.1| 6 | |com.mchange :: c3p0 - a JDBC Connection pooling / Statement caching library|0.9.5.2|GNU Lesser General Public License, Version 2.1,Eclipse Public License, Version 1.0| -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Maven 2 | # Build your Java project and run tests with Apache Maven. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/java 5 | 6 | trigger: 7 | branches: 8 | include: 9 | - '*' 10 | exclude: 11 | - gh-pages 12 | paths: 13 | exclude: 14 | - README.md 15 | tags: 16 | include: 17 | - '*' 18 | 19 | schedules: 20 | - cron: "0 19 * * 0" 21 | displayName: Weekly build 22 | branches: 23 | include: 24 | - master 25 | always: true 26 | 27 | pool: 28 | vmImage: 'ubuntu-latest' 29 | 30 | variables: 31 | - name: dBTestCompareVersion 32 | value: 1.9.3 33 | 34 | steps: 35 | - task: PowerShell@2 36 | condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/') 37 | inputs: 38 | targetType: 'inline' 39 | script: | 40 | $tags = git tag --sort=-creatordate 41 | $tag = $tags[0] 42 | Write-Host "##vso[task.setvariable variable=dBTestCompareVersion]$tag" 43 | 44 | - task: PowerShell@2 45 | inputs: 46 | filePath: './setDBTestCompareVersion.ps1' 47 | 48 | - task: PowerShell@2 49 | inputs: 50 | filePath: './downloadBackupAndJDBCDrivers.ps1' 51 | 52 | - task: DockerCompose@0 53 | inputs: 54 | containerregistrytype: 'Container Registry' 55 | dockerComposeFile: '**/docker-compose.yml' 56 | action: 'Run a Docker Compose command' 57 | dockerComposeCommand: 'up -d' 58 | 59 | - task: PowerShell@2 60 | inputs: 61 | filePath: './restoreBackup.ps1' 62 | errorActionPreference: 'silentlyContinue' 63 | 64 | - task: Ant@1 65 | inputs: 66 | buildFile: './deploy/build.xml' 67 | options: '-Dconfig=DEV02' 68 | targets: 'compile tokens.copy.files testdbq.run' 69 | publishJUnitResults: true 70 | testResultsFiles: '**/TEST-*.xml' 71 | javaHomeOption: 'JDKVersion' 72 | 73 | - task: PowerShell@2 74 | inputs: 75 | filePath: './copyArtifact.ps1' 76 | 77 | - task: PublishPipelineArtifact@1 78 | inputs: 79 | targetPath: './target/test-output' 80 | artifact: 'DBTestCompare$(dBTestCompareVersion).TestResults.$(Build.BuildNumber)' 81 | publishLocation: 'pipeline' 82 | 83 | - task: PublishPipelineArtifact@1 84 | inputs: 85 | targetPath: './target/test-definitions' 86 | artifact: 'DBTestCompare$(dBTestCompareVersion).TestDefinitionsResults.$(Build.BuildNumber)' 87 | publishLocation: 'pipeline' 88 | 89 | - task: PublishPipelineArtifact@1 90 | inputs: 91 | targetPath: './release' 92 | artifact: 'DBTestCompare$(dBTestCompareVersion)' 93 | publishLocation: 'pipeline' 94 | 95 | - task: PowerShell@2 96 | inputs: 97 | targetType: 'inline' 98 | script: 'compress-archive -path "./release/**" ./release/DBTestCompare$(dBTestCompareVersion).zip' 99 | 100 | - task: CopyFiles@2 101 | inputs: 102 | sourceFolder: './release' 103 | contents: 'DBTestCompare$(dBTestCompareVersion).zip' 104 | targetFolder: $(Build.ArtifactStagingDirectory) 105 | 106 | - task: GitHubRelease@1 107 | condition: and(succeeded(),startsWith(variables['Build.SourceBranch'], 'refs/tags/')) 108 | inputs: 109 | gitHubConnection: 'github.com_dbtestcompare' 110 | repositoryName: '$(Build.Repository.Name)' 111 | action: 'edit' 112 | target: '$(Build.SourceVersion)' 113 | tag: '$(dBTestCompareVersion)' 114 | title: 'Version $(dBTestCompareVersion)' 115 | assets: '$(Build.ArtifactStagingDirectory)/DBTestCompare$(dBTestCompareVersion).zip' 116 | addChangeLog: false 117 | -------------------------------------------------------------------------------- /copyArtifact.ps1: -------------------------------------------------------------------------------- 1 | $release="./release" 2 | New-Item -Path $release -ItemType Directory -Force 3 | Write-Output "Artifact application file name $release" 4 | Remove-Item -path "./target/jdbc_drivers" -Recurse -Include mssql*.jar 5 | Get-ChildItem -path "./target/" -Recurse -Include DBTestCompare-*SNAPSHOT-jar-with-dependencies.jar ` 6 | | Copy-Item -Destination $release 7 | Copy-Item -path "./test-definitions/" -destination $release -Force -Recurse -Container 8 | Copy-Item -path "./deploy/" -destination $release -Force -Recurse -Container 9 | Copy-Item -path "./target/jdbc_drivers/" -destination $release -Force -Recurse -Container 10 | Copy-Item "README.md" -destination $release -Force 11 | Copy-Item "LICENSE" -destination $release -Force 12 | Copy-Item "LICENSE-3RD-PARTY" -destination $release -Force -------------------------------------------------------------------------------- /deploy/Config/DEV01: -------------------------------------------------------------------------------- 1 | TERADATADBSERVER=TERADATADBSERVERVALUE 2 | TERADATADBNAME=TERADATADBNAMEVALUE 3 | 4 | SQL_SERVER=SQL_SERVERVALUE 5 | SQL_SERVERINSTANCE=SQL_SERVERINSTANCEVALUE 6 | SQL_SERVERDBNAME=SQL_SERVERDBNAMEVALUE 7 | 8 | MYSQLDBSERVER=MYSQLDBSERVERVALUE 9 | MYSQLDBNAME=MYSQLDBNAMEVALUE 10 | MYSQLDBPORT=3306 11 | 12 | POSTGRESSSQLDBSERVER=POSTGRESSSQLDBSERVERVALUE 13 | POSTGRESSSQLDBNAME=POSTGRESSSQLDBNAMEVALUE 14 | 15 | USERNAME=USERNAMEVALUE 16 | PASSWORD=PASSWORDVALUE 17 | SQL_SERVER_USERNAME=USERNAMEVALUE 18 | SQL_SERVER_PASSWORD=PASSWORDVALUE -------------------------------------------------------------------------------- /deploy/Config/DEV02: -------------------------------------------------------------------------------- 1 | TERADATADBSERVER=TERADATADBSERVERVALUE 2 | TERADATADBNAME=TERADATADBNAMEVALUE 3 | 4 | SQL_SERVER=localhost 5 | SQL_SERVERINSTANCE=SQLEXPRESS 6 | SQL_SERVERDBNAME=AdventureWorks2008R2 7 | 8 | MYSQLDBSERVER=localhost 9 | MYSQLDBNAME=dbquality 10 | MYSQLDBPORT=13306 11 | 12 | POSTGRESSSQLDBSERVER=localhost 13 | POSTGRESSSQLDBNAME=dbquality 14 | 15 | USERNAME=dbquality 16 | PASSWORD=dbquality 17 | SQL_SERVER_USERNAME=sa 18 | SQL_SERVER_PASSWORD=yourStrong22Password -------------------------------------------------------------------------------- /deploy/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Compile solution and replace tokens 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Coping target files and replacing tokens 40 | ${line.separator} 41 | 42 | 43 | 44 | 45 | ${line.separator}Coping files to target folder 46 | ${line.separator} 47 | ${line.separator}Coping test examples 48 | ${line.separator} 49 | 50 | 51 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | ${line.separator}Compile DBTestCompare project 73 | ${line.separator} 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | ${line.separator}Compile DBTestCompare project 82 | ${line.separator} 83 | 84 | 85 | 86 | 87 | 88 | ${line.separator}Execute tests 89 | ${line.separator} 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | sqlserver_db_container: 4 | image: mcr.microsoft.com/mssql/server:2019-latest 5 | build: ./my_sqlserver 6 | container_name: sqlserver-container 7 | environment: 8 | SA_PASSWORD: yourStrong22Password 9 | ACCEPT_EULA: Y 10 | volumes: 11 | - sqlserver_db_data_container:/var/opt/mssql 12 | ports: 13 | - 1433:1433 14 | 15 | mysql_db_container: 16 | image: mysql:latest 17 | environment: 18 | MYSQL_ROOT_PASSWORD: my-secret-pw 19 | MYSQL_DATABASE: dbquality 20 | MYSQL_USER: dbquality 21 | MYSQL_PASSWORD: dbquality 22 | ports: 23 | - 13306:3306 24 | volumes: 25 | - ./my-mysql/sql-scripts:/docker-entrypoint-initdb.d/ 26 | - mysql_db_data_container:/var/lib/mysql 27 | 28 | postgres: 29 | image: postgres:latest 30 | environment: 31 | POSTGRES_USER: dbquality 32 | POSTGRES_PASSWORD: dbquality 33 | POSTGRES_DB: dbquality 34 | volumes: 35 | - ./my-postgres/sql-scripts:/docker-entrypoint-initdb.d/ 36 | - postgresql_db_data_container:/var/lib/postgresql/data/ 37 | ports: 38 | - 5432:5432 39 | 40 | volumes: 41 | mysql_db_data_container: 42 | postgresql_db_data_container: 43 | sqlserver_db_data_container: -------------------------------------------------------------------------------- /docker/my-mysql/Dockerfile: -------------------------------------------------------------------------------- 1 | # Derived from official mysql image (our base image) 2 | FROM mysql 3 | 4 | # Add a database 5 | ENV MYSQL_DATABASE dbquality 6 | 7 | 8 | # Add the content of the sql-scripts/ directory to your image 9 | # All scripts in docker-entrypoint-initdb.d/ are automatically 10 | # executed during container startup 11 | COPY ./sql-scripts/ /docker-entrypoint-initdb.d/ -------------------------------------------------------------------------------- /docker/my-postgres/Dockerfile: -------------------------------------------------------------------------------- 1 | # Derived from official postgres image (our base image) 2 | FROM library/postgres 3 | 4 | # Add a database 5 | ENV POSTGRES_USER dbquality 6 | ENV POSTGRES_PASSWORD dbquality 7 | ENV POSTGRES_DB dbquality 8 | 9 | 10 | # Add the content of the sql-scripts/ directory to your image 11 | # All scripts in docker-entrypoint-initdb.d/ are automatically 12 | # executed during container startup 13 | COPY ./sql-scripts/ /docker-entrypoint-initdb.d/ -------------------------------------------------------------------------------- /docker/my_sqlserver/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/mssql/server:2019-latest 2 | 3 | USER root 4 | 5 | RUN apt-get update \ 6 | && apt-get install -y gnupg gnupg2 gnupg1 \ 7 | && apt-get install -y curl apt-transport-https \ 8 | && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \ 9 | && curl https://packages.microsoft.com/config/ubuntu/18.04/prod.list > /etc/apt/sources.list.d/mssql-release.list \ 10 | && apt-get update \ 11 | && ACCEPT_EULA=Y apt-get install -y msodbcsql17 mssql-tools \ 12 | && echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc \ 13 | && . ~/.bashrc 14 | 15 | HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=10 \ 16 | CMD /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "yourStrong22Password" -Q"SELECT 1" || exit 1 17 | -------------------------------------------------------------------------------- /downloadBackupAndJDBCDrivers.ps1: -------------------------------------------------------------------------------- 1 | Write-Output "Downloading AdventureWorks2008R2FullDatabaseBackup" 2 | New-Item -Path './zip' -ItemType Directory -Force 3 | (New-Object System.Net.WebClient).DownloadFile("https://github.com/raczeja/DBTestCompare_backups/raw/master/AdventureWorks2008R2FullDatabaseBackup.zip", "./zip/AdventureWorks2008R2FullDatabaseBackup.zip") 4 | Invoke-WebRequest -Uri "https://github.com/raczeja/DBTestCompare_backups/raw/master/AdventureWorks2008R2FullDatabaseBackup.zip" -OutFile "./zip/AdventureWorks2008R2FullDatabaseBackup.zip" 5 | Write-Output "Unzipping AdventureWorks2008R2FullDatabaseBackup" 6 | Expand-Archive -LiteralPath './zip/AdventureWorks2008R2FullDatabaseBackup.zip' -DestinationPath ./docker -Force 7 | 8 | Write-Output "Downloading sqljdbc drivers" 9 | Invoke-WebRequest -Uri "https://download.microsoft.com/download/4/0/8/40815588-bef6-4715-bde9-baace8726c2a/sqljdbc_8.2.0.0_enu.zip" -OutFile "./zip/sqljdbc_8.2.0.0_enu.zip" 10 | Write-Output "Unzipping sqljdbc drivers" 11 | Expand-Archive -LiteralPath './zip/sqljdbc_8.2.0.0_enu.zip' -DestinationPath "./zip/sqljdbc" -Force 12 | Copy-Item -Path "./zip/sqljdbc/sqljdbc_8.2/enu/*" -Destination "./jdbc_drivers" -Include "mssql-jdbc-*.jar" 13 | 14 | Write-Output "Downloading mysql sctipts" 15 | Invoke-WebRequest -Uri "https://github.com/raczeja/DBTestCompare_backups/raw/master/my-mysql/sql-scripts/sql-scripts.zip" -OutFile "./zip/sql-scripts-mysql.zip" 16 | Write-Output "Unzipping mysql sctipts" 17 | Expand-Archive -LiteralPath './zip/sql-scripts-mysql.zip' -DestinationPath "./docker/my-mysql/sql-scripts" -Force 18 | 19 | Write-Output "Downloading postgres sctipts" 20 | Invoke-WebRequest -Uri "https://github.com/raczeja/DBTestCompare_backups/raw/master/my-postgres/sql-scripts/sql-scripts.zip" -OutFile "./zip/sql-scripts-postgres.zip" 21 | Write-Output "Unzipping postgres sctipts" 22 | Expand-Archive -LiteralPath './zip/sql-scripts-postgres.zip' -DestinationPath "./docker/my-postgres/sql-scripts" -Force -------------------------------------------------------------------------------- /images/DBTestCompare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Accenture/DBTestCompare/fc3cb1cb08b3c6447a74dee28c5b2a7891984054/images/DBTestCompare.png -------------------------------------------------------------------------------- /images/Githubactions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Accenture/DBTestCompare/fc3cb1cb08b3c6447a74dee28c5b2a7891984054/images/Githubactions.png -------------------------------------------------------------------------------- /images/comparingDB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Accenture/DBTestCompare/fc3cb1cb08b3c6447a74dee28c5b2a7891984054/images/comparingDB.png -------------------------------------------------------------------------------- /images/comparingDataDB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Accenture/DBTestCompare/fc3cb1cb08b3c6447a74dee28c5b2a7891984054/images/comparingDataDB.png -------------------------------------------------------------------------------- /jdbc_drivers/mariadb-java-client-2.6.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Accenture/DBTestCompare/fc3cb1cb08b3c6447a74dee28c5b2a7891984054/jdbc_drivers/mariadb-java-client-2.6.0.jar -------------------------------------------------------------------------------- /jdbc_drivers/mysql-connector-java-8.0.23.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Accenture/DBTestCompare/fc3cb1cb08b3c6447a74dee28c5b2a7891984054/jdbc_drivers/mysql-connector-java-8.0.23.jar -------------------------------------------------------------------------------- /jdbc_drivers/postgresql-42.7.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Accenture/DBTestCompare/fc3cb1cb08b3c6447a74dee28c5b2a7891984054/jdbc_drivers/postgresql-42.7.4.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | uk.co.objectivity.test.db 8 | DBTestCompare 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | 7.5.1 13 | 2.2.7 14 | 2.24.2 15 | 2.24.2 16 | 0.10.1 17 | 4.1.1 18 | 3.9 19 | 1.0 20 | 21 | 22 | 23 | 24 | 25 | org.apache.maven.plugins 26 | maven-compiler-plugin 27 | 28 | 1.8 29 | 1.8 30 | 31 | 32 | 33 | maven-assembly-plugin 34 | 35 | 36 | 37 | uk.co.objectivity.test.db.RunTests 38 | 39 | 40 | 41 | jdbc_drivers/mssql-jdbc-8.2.0.jre8.jar jdbc_drivers/mssql-jdbc-8.2.0.jre11.jar jdbc_drivers/mssql-jdbc-8.2.0.jre13.jar jdbc_drivers/tdgssconfig-4.jar 42 | jdbc_drivers/terajdbc-4.jar jdbc_drivers/mysql-connector-java-8.0.23.jar 43 | jdbc_drivers/postgresql-42.7.4.jar jdbc_drivers/mariadb-java-client-2.6.0.jar jdbc_drivers/snowflake-jdbc-3.9.2.jar 44 | 45 | 46 | 47 | jar-with-dependencies 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | org.testng 63 | testng 64 | ${testng.version} 65 | 66 | 67 | 68 | 69 | com.sun.xml.bind 70 | jaxb-impl 71 | ${jaxb-impl.version} 72 | 73 | 74 | javax.activation 75 | activation 76 | 1.1.1 77 | 78 | 79 | 80 | org.ow2.sirocco 81 | sirocco-text-table-formatter 82 | ${sirocco.version} 83 | 84 | 85 | 86 | 87 | com.mchange 88 | c3p0 89 | ${c3p0.version} 90 | 91 | 92 | org.apache.logging.log4j 93 | log4j-api 94 | ${log4j.version} 95 | 96 | 97 | org.apache.logging.log4j 98 | log4j-core 99 | ${log4jcore.version} 100 | 101 | 102 | 103 | 104 | org.apache.poi 105 | poi 106 | ${poi.version} 107 | 108 | 109 | 110 | org.apache.commons 111 | commons-lang3 112 | ${commons.version} 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /restoreBackup.ps1: -------------------------------------------------------------------------------- 1 | docker ps -a 2 | Write-Output "mkdir /var/opt/mssql/backup" 3 | docker exec -i "sqlserver-container" mkdir "/var/opt/mssql/backup" 4 | Write-Output "copy ./docker/AdventureWorks2008R2FullDatabaseBackup.bak to /var/opt/mssql/backup" 5 | docker cp "./docker/AdventureWorks2008R2FullDatabaseBackup.bak" sqlserver-container:/var/opt/mssql/backup 6 | Write-Output "restore backup" 7 | $count = 0 8 | do 9 | { 10 | $JSON=docker inspect --format='{{json .State.Health}}' sqlserver-container | Out-String | ConvertFrom-Json 11 | Write-Host HEALTHCHECK: $JSON.Status.ToString() sqlserver-container 12 | Start-Sleep -s 10 13 | $count++ 14 | docker ps -a 15 | if ($count -gt 10) { 16 | Write-Host "Loop terminated after 10 iterations." 17 | break 18 | } 19 | } 20 | Until ($JSON.Status.ToString() -eq 'healthy') 21 | docker exec -i sqlserver-container /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "yourStrong22Password" ` 22 | -Q "RESTORE DATABASE AdventureWorks2008R2 FROM DISK = '/var/opt/mssql/backup/AdventureWorks2008R2FullDatabaseBackup.bak' ` 23 | WITH MOVE 'AdventureWorks2008R2_Data' TO '/var/opt/mssql/data/AdventureWorks2008R2.mdf', ` 24 | MOVE 'AdventureWorks2008R2_Log' TO '/var/opt/mssql/data/AdventureWorks2008R2_1.LDF'" 25 | -------------------------------------------------------------------------------- /setDBTestCompareVersion.ps1: -------------------------------------------------------------------------------- 1 | Write-Output "Setting DBTestCompare version " $env:DBTESTCOMPAREVERSION 2 | $version="$env:DBTESTCOMPAREVERSION-SNAPSHOT" 3 | ((Get-Content -path ./pom.xml -Raw) -replace '\d\.\d.\d-SNAPSHOT<\/version>',$version) | Set-Content -Path ./pom.xml -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/RunTests.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db; 24 | 25 | import java.io.File; 26 | 27 | import javax.xml.bind.JAXBContext; 28 | import javax.xml.bind.JAXBException; 29 | import javax.xml.bind.Unmarshaller; 30 | 31 | import org.apache.log4j.Logger; 32 | import org.testng.TestNG; 33 | import org.testng.xml.XmlSuite; 34 | 35 | import uk.co.objectivity.test.db.beans.xml.CmpSqlResultsConfig; 36 | import uk.co.objectivity.test.db.beans.xml.Filter; 37 | import uk.co.objectivity.test.db.utils.DataSource; 38 | import uk.co.objectivity.test.db.utils.Printer; 39 | 40 | public class RunTests { 41 | 42 | private static final Logger log = Logger.getLogger(RunTests.class); 43 | 44 | private static final String PROP_TESTS_DIR = "testsDir"; 45 | private static final String PROP_TC_LOGS_ENABLED = "teamcityLogsEnabled"; 46 | private static final String PROP_FILTER_INCLUDE = "filterInclude"; 47 | private static final String PROP_FILTER_EXCLUDE = "filterExclude"; 48 | 49 | private static String TEST_DIR = "test-definitions"; 50 | private static final String CONFIG_FILE_NAME = "/cmpSqlResults-config.xml"; 51 | private static String MAIN_CONFIG_FILE_PATH = TEST_DIR + CONFIG_FILE_NAME; 52 | 53 | public static void main(String[] args) { 54 | displayHelpMessage(); 55 | String testDir = System.getProperty(PROP_TESTS_DIR); 56 | if (testDir != null) { 57 | TEST_DIR = testDir; 58 | MAIN_CONFIG_FILE_PATH = testDir + CONFIG_FILE_NAME; 59 | } 60 | 61 | CmpSqlResultsConfig cmpSqlResultsConfig = readConfigAndInit(); 62 | if (cmpSqlResultsConfig == null) return; 63 | 64 | // we do not need to validate cmpSqlResultsConfig.getThreads() - thanks to JAXB and TestNG 65 | runTestNG(cmpSqlResultsConfig.getThreads(), cmpSqlResultsConfig.getFilter()); 66 | 67 | if (!DBTestCompare.ALL_TESTS_SUCCEEDED) { 68 | System.exit(cmpSqlResultsConfig.getTestFailureExitCode()); 69 | } 70 | } 71 | 72 | static CmpSqlResultsConfig readConfigAndInit() { 73 | log.debug("Working Directory = " + System.getProperty("user.dir")); 74 | log.debug("Scanning tests directory: \"" + TEST_DIR + "\" ..."); 75 | File testsDirFile = new File(TEST_DIR); 76 | if (!testsDirFile.exists()) { 77 | log.error("Tests directory does not exists! Please create directory: " + testsDirFile.getAbsolutePath()); 78 | return null; 79 | } 80 | CmpSqlResultsConfig cmpSqlResultsConfig = readConfiguration(); 81 | if (cmpSqlResultsConfig == null) { 82 | log.error("Errors while reading configuration file: " + MAIN_CONFIG_FILE_PATH); 83 | return null; 84 | } 85 | log.debug("Number of Threads set in configuration: " + cmpSqlResultsConfig.getThreads()); 86 | log.debug("Initializing all components ..."); 87 | DataSource.init(cmpSqlResultsConfig.getDatasources()); // it also adds shutdown hook (closing connections) 88 | TestDataProvider.init(testsDirFile, cmpSqlResultsConfig); 89 | Printer.init(cmpSqlResultsConfig); 90 | return cmpSqlResultsConfig; 91 | } 92 | 93 | private static void runTestNG(int threadCount, Filter filter) { 94 | TestNG testng = new TestNG(); 95 | testng.setTestClasses(new Class[]{DBTestCompare.class}); 96 | String suiteName = "Compare SQL results suite"; 97 | if (filter != null && ((filter.getIncludes() != null && !filter.getIncludes().isEmpty()) || (filter.getExcludes() 98 | != null && !filter.getExcludes().isEmpty()))) { 99 | suiteName = "FILTERED compare SQL results suite"; 100 | } 101 | testng.setDefaultSuiteName(suiteName); 102 | testng.setPreserveOrder(true); 103 | testng.setParallel(XmlSuite.ParallelMode.INSTANCES); 104 | testng.setThreadCount(threadCount); 105 | // testng.setDataProviderThreadCount(cmpSqlResultsConfig.getThreads()); 106 | testng.run(); 107 | } 108 | 109 | private static CmpSqlResultsConfig readConfiguration() { 110 | try { 111 | log.debug("Reading configuration: " + MAIN_CONFIG_FILE_PATH); 112 | File file = new File(MAIN_CONFIG_FILE_PATH); 113 | JAXBContext jaxbContext = JAXBContext.newInstance(CmpSqlResultsConfig.class); 114 | Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 115 | CmpSqlResultsConfig cmpSqlResultsConfig = (CmpSqlResultsConfig) jaxbUnmarshaller.unmarshal(file); 116 | // user can override some properties from command line 117 | String tcLog = System.getProperty(PROP_TC_LOGS_ENABLED); 118 | if (tcLog != null) { 119 | cmpSqlResultsConfig.getLogger().setTeamcityLogsEnabled("true".equals(tcLog)); 120 | } 121 | String filterInc = System.getProperty(PROP_FILTER_INCLUDE); 122 | if (filterInc != null) { 123 | cmpSqlResultsConfig.getFilter().setIncludesString(filterInc); 124 | } 125 | String filterExc = System.getProperty(PROP_FILTER_EXCLUDE); 126 | if (filterExc != null) { 127 | cmpSqlResultsConfig.getFilter().setExcludesString(filterExc); 128 | } 129 | cmpSqlResultsConfig.getFilter().trim(); 130 | return cmpSqlResultsConfig; 131 | } catch (JAXBException e) { 132 | log.error(e); 133 | return null; 134 | } 135 | } 136 | 137 | private static void displayHelpMessage() { 138 | log.info("You can override some of the application configuration properties\r\nRun app with:\r\n" + 139 | " -D" + PROP_TESTS_DIR + "=path - set tests directory (default: " + TEST_DIR + ")\r\n" + 140 | " -D" + PROP_TC_LOGS_ENABLED + "=true - log test output in TeamCity format\r\n" + 141 | " -D" + PROP_FILTER_INCLUDE + "=a.b,g.z.f - comma separated directories or test files which " + 142 | "you want to include\r\n" + 143 | " -D" + PROP_FILTER_EXCLUDE + "=a.b.test - comma separated directories or test files " + 144 | "which you want to exclude"); 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/Aggregator.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators; 2 | 3 | import java.util.List; 4 | 5 | public interface Aggregator { 6 | 7 | boolean isValid(String aggregatedValue, String columnValue); 8 | 9 | String getAggregated(String aggregatedValue, String columnValue); 10 | 11 | void setParams(List params); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/AggregatorType.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.aggregators; 24 | 25 | public enum AggregatorType { 26 | SUM_INTEGERS, DATE, OVERRIDE; 27 | 28 | public Aggregator getAggregator() { 29 | switch (this) { 30 | case SUM_INTEGERS: 31 | return new SumIntegersAggregator(); 32 | case DATE: 33 | return new DateAggregator(); 34 | case OVERRIDE: 35 | return new OverrideAgregator(); 36 | } 37 | return null; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/DateAggregator.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | import java.util.List; 7 | 8 | import org.apache.log4j.Logger; 9 | 10 | public class DateAggregator implements Aggregator { 11 | 12 | private final static Logger log = Logger.getLogger(DateAggregator.class); 13 | 14 | private SimpleDateFormat dateFormat; 15 | private int greaterThan; 16 | 17 | @Override public boolean isValid(String aggregatedValue, String columnValue) { 18 | try { 19 | dateFormat.parse(columnValue); 20 | dateFormat.parse(aggregatedValue); 21 | return true; 22 | } catch (ParseException e) { 23 | log.warn(e); 24 | return false; 25 | } 26 | } 27 | 28 | @Override public String getAggregated(String aggregatedValue, String columnValue) { 29 | Date newDate, oldDate; 30 | try { 31 | newDate = dateFormat.parse(columnValue); 32 | oldDate = dateFormat.parse(aggregatedValue); 33 | } catch (ParseException e) { 34 | log.error(e); 35 | return null; 36 | } 37 | return (greaterThan * newDate.compareTo(oldDate)) > 0 ? columnValue : aggregatedValue; 38 | } 39 | 40 | @Override public void setParams(List params) { 41 | // TODO kontrola liczebnosci i poprawnosci params 42 | dateFormat = new SimpleDateFormat(params.get(0)); 43 | greaterThan = "gt".equals(params.get(1)) ? 1 : -1; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/OverrideAgregator.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators; 2 | 3 | import java.util.List; 4 | 5 | public class OverrideAgregator implements Aggregator { 6 | 7 | @Override public boolean isValid(String aggregatedValue, String columnValue) { 8 | return true; 9 | } 10 | 11 | @Override public String getAggregated(String aggregatedValue, String columnValue) { 12 | return columnValue; 13 | } 14 | 15 | @Override public void setParams(List params) { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/SumIntegersAggregator.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators; 2 | 3 | import java.util.List; 4 | 5 | public class SumIntegersAggregator implements Aggregator { 6 | 7 | private static final String INT_REGEX = "-?\\d+"; 8 | 9 | @Override public boolean isValid(String aggregatedValue, String columnValue) { 10 | return columnValue != null && aggregatedValue != null && columnValue.matches(INT_REGEX) && aggregatedValue.matches(INT_REGEX); 11 | } 12 | 13 | @Override public String getAggregated(String aggregatedValue, String columnValue) { 14 | Integer aggInt = Integer.parseInt(aggregatedValue); 15 | Integer colInt = Integer.parseInt(columnValue); 16 | return String.valueOf(aggInt + colInt); 17 | } 18 | 19 | @Override public void setParams(List params) { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/condition/AggregatorCondition.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators.condition; 2 | 3 | import java.util.List; 4 | 5 | public interface AggregatorCondition { 6 | 7 | public boolean shouldAggregate(List row); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/condition/AggregatorConditionType.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators.condition; 2 | 3 | public enum AggregatorConditionType { 4 | EQUALS, NOT_EQUALS; 5 | 6 | public AggregatorCondition getAggregatorCondition(String conditionValue, int column) { 7 | switch (this) { 8 | case EQUALS: 9 | return new Equals(conditionValue, column); 10 | case NOT_EQUALS: 11 | return new NotEquals(conditionValue, column); 12 | default: 13 | throw new RuntimeException("Unknown Aggregator condition!"); 14 | } 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/condition/Equals.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators.condition; 2 | 3 | import java.util.List; 4 | 5 | public class Equals implements AggregatorCondition { 6 | private String conditionValue; 7 | private int column; 8 | 9 | private Equals() { 10 | } 11 | 12 | public Equals(String conditionValue, int column) { 13 | this(); 14 | this.conditionValue = conditionValue; 15 | this.column = column; 16 | } 17 | 18 | public boolean shouldAggregate(List row) { 19 | return this.conditionValue.equals(row.get(this.column - 1)); 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/aggregators/condition/NotEquals.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.aggregators.condition; 2 | 3 | import java.util.List; 4 | 5 | public class NotEquals implements AggregatorCondition { 6 | private String conditionValue; 7 | private int column; 8 | 9 | private NotEquals() { 10 | } 11 | 12 | public NotEquals(String conditionValue, int column) { 13 | this(); 14 | this.conditionValue = conditionValue; 15 | this.column = column; 16 | } 17 | 18 | public boolean shouldAggregate(List row) { 19 | return !this.conditionValue.equals(row.get(this.column - 1)); 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/CheckPresenceAlgorithm.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.beans; 2 | 3 | public enum CheckPresenceAlgorithm { 4 | ON_EXISTING_COLUMN, ON_NEW_COLUMN; 5 | } -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/CompareMode.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans; 24 | 25 | import uk.co.objectivity.test.db.comparators.KeyComparator; 26 | import uk.co.objectivity.test.db.comparators.Comparator; 27 | import uk.co.objectivity.test.db.comparators.FetchComparator; 28 | import uk.co.objectivity.test.db.comparators.FileComparator; 29 | import uk.co.objectivity.test.db.comparators.MinusComparator; 30 | import uk.co.objectivity.test.db.comparators.NmbOfResultsComparator; 31 | 32 | public enum CompareMode { 33 | MINUS, FETCH, NMB_OF_RESULTS, FILE, KEY; 34 | 35 | public Comparator getComparator() { 36 | switch (this) { 37 | case MINUS: 38 | return new MinusComparator(); 39 | case FETCH: 40 | return new FetchComparator(); 41 | case NMB_OF_RESULTS: 42 | return new NmbOfResultsComparator(); 43 | case FILE: 44 | return new FileComparator(); 45 | case KEY: 46 | return new KeyComparator(); 47 | } 48 | return null; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/ConditionType.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans; 24 | 25 | 26 | import org.testng.Assert; 27 | 28 | public enum ConditionType { 29 | EQ, NE, LT, LE, GE, GT; 30 | 31 | public void assertByType(Integer actual, Integer expected) throws AssertionError { 32 | Assert.assertNotNull(actual, "Number of query results is null -"); 33 | Assert.assertNotNull(expected, "Check assert value in test configuration -"); 34 | switch (this) { 35 | case EQ: 36 | Assert.assertEquals(actual, expected, "Incorrect number of results -"); 37 | break; 38 | case NE: 39 | Assert.assertNotEquals(actual, expected, "Number of results should not be equal " + expected); 40 | break; 41 | case LT: 42 | Assert.assertTrue(actual.compareTo(expected) < 0, 43 | "Number of results (" + actual + ") should be less than " + expected + " -"); 44 | break; 45 | case LE: 46 | Assert.assertTrue(actual.compareTo(expected) <= 0, 47 | "Number of results (" + actual + ") should be less or equal " + expected + " -"); 48 | break; 49 | case GE: 50 | Assert.assertTrue(actual.compareTo(expected) >= 0, 51 | "Number of results (" + actual + ") should be greater or equal " + expected + " -"); 52 | break; 53 | case GT: 54 | Assert.assertTrue(actual.compareTo(expected) > 0, 55 | "Number of results (" + actual + ") should be greater than " + expected + " -"); 56 | break; 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/FileRow.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.beans; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | import org.apache.log4j.Logger; 9 | 10 | import uk.co.objectivity.test.db.aggregators.Aggregator; 11 | import uk.co.objectivity.test.db.aggregators.AggregatorType; 12 | import uk.co.objectivity.test.db.aggregators.condition.AggregatorCondition; 13 | import uk.co.objectivity.test.db.beans.xml.Aggregators; 14 | import uk.co.objectivity.test.db.beans.xml.Transformer; 15 | 16 | public class FileRow { 17 | private final static Logger log = Logger.getLogger(FileRow.class); 18 | 19 | private List transformers; 20 | private List aggregators; 21 | private List aggregatorConditions; 22 | private List keyColumns; 23 | 24 | private List aggregatedRow; 25 | private List> excludedRows; 26 | private List> allRows; 27 | private boolean aggregated; 28 | private boolean arbitratorOn; 29 | 30 | public FileRow(List row, List keyColumns, List transformers, Aggregators aggregators, 31 | boolean arbitratorOn) { 32 | this.keyColumns = keyColumns; 33 | this.aggregators = new ArrayList<>(); 34 | this.excludedRows = new ArrayList<>(); 35 | this.transformers = transformers; 36 | this.aggregated = false; 37 | this.arbitratorOn = arbitratorOn; 38 | 39 | setColumnAggregators(row.size(), 40 | (aggregators == null || aggregators.getAggregators() == null) ? Collections.emptyList() 41 | : aggregators.getAggregators()); 42 | this.aggregatorConditions = (aggregators == null || aggregators.getConditions() == null) 43 | ? Collections.emptyList() 44 | : aggregators.getConditions(); 45 | this.allRows = new ArrayList<>(); 46 | add(row); 47 | } 48 | 49 | public void add(List row) { 50 | transform(row); 51 | allRows.add(row); 52 | if (arbitratorOn || !this.shouldAggregate(row)) { 53 | this.excludedRows.add(row); 54 | } else if (aggregatedRow == null || aggregatedRow.isEmpty()) { 55 | this.aggregated = true; 56 | aggregatedRow = new ArrayList<>(row); 57 | } else { 58 | aggregate(row); 59 | } 60 | } 61 | 62 | private boolean shouldAggregate(List row) { 63 | return this.aggregatorConditions.stream().allMatch(ac -> ac.shouldAggregate(row)); 64 | } 65 | 66 | private void aggregate(List row) { 67 | this.aggregated = true; 68 | 69 | for (int i = 0; i < row.size(); i++) { 70 | if (keyColumns.contains(i + 1)) 71 | continue; 72 | Aggregator agg = aggregators.get(i); 73 | if (agg.isValid(aggregatedRow.get(i), row.get(i))) 74 | aggregatedRow.set(i, agg.getAggregated(aggregatedRow.get(i), row.get(i))); 75 | else { 76 | log.error("Column " + (i + 1) + " can not be aggregated! Invalid values (to be merged): '" 77 | + aggregatedRow.get(i) + "' and '" + row.get(i) 78 | + "'. Previous/first row will be used to compare with CSV row"); 79 | } 80 | } 81 | } 82 | 83 | private void transform(List row) { 84 | transformers.stream().filter(t -> t.getTransformer() != null).forEach(t -> { 85 | String transStr = t.getTransformer().transform(row.get(t.getColumn() - 1)); 86 | row.set(t.getColumn() - 1, transStr); 87 | }); 88 | } 89 | 90 | public List getAggregatedRow() { 91 | return aggregatedRow; 92 | } 93 | 94 | private ArrayList> copyList(List> listToCopy) { 95 | ArrayList> newList = new ArrayList<>(); 96 | for (List inArr : listToCopy) { 97 | ArrayList newStrList = new ArrayList<>(); 98 | for (String inStr : inArr) { 99 | newStrList.add(inStr); 100 | } 101 | newList.add(newStrList); 102 | } 103 | return newList; 104 | } 105 | 106 | public ArrayList> getRows() { 107 | ArrayList> rowList = copyList(this.excludedRows); 108 | if (this.aggregated) { 109 | rowList.add((ArrayList) getAggregatedRow()); 110 | } 111 | return rowList; 112 | } 113 | 114 | public List getAggregatedRowKeyVals() { 115 | List keyVals = new ArrayList<>(); 116 | if (aggregatedRow != null) { 117 | for (int i = 0; i < aggregatedRow.size(); i++) { 118 | if (keyColumns.contains(i + 1)) 119 | keyVals.add(aggregatedRow.get(i)); 120 | } 121 | } else if (excludedRows != null && excludedRows.size() > 0) { 122 | List excludedRow = excludedRows.get(0); 123 | 124 | for (int i = 0; i < excludedRow.size(); i++) { 125 | if (keyColumns.contains(i + 1)) 126 | keyVals.add(excludedRow.get(i)); 127 | } 128 | } 129 | return keyVals; 130 | } 131 | 132 | public List> getAllRows() { 133 | return allRows; 134 | } 135 | 136 | public List> getExcludedRows() { 137 | return excludedRows; 138 | } 139 | 140 | public boolean isAggregated() { 141 | return this.aggregated && (this.allRows.size() - this.excludedRows.size()) > 1; 142 | } 143 | 144 | public void setColumnAggregators(int columnsNo, 145 | List xmlAggregators) { 146 | for (int i = 1; i <= columnsNo; i++) { 147 | boolean aggregatorDefined = false; 148 | for (uk.co.objectivity.test.db.beans.xml.Aggregator aggregator : xmlAggregators) { 149 | if (aggregator.getColumn() == i) { 150 | uk.co.objectivity.test.db.aggregators.Aggregator agg = aggregator.getAggregatorType() 151 | .getAggregator(); 152 | if (aggregator.getParams() != null && !aggregator.getParams().trim().isEmpty()) 153 | agg.setParams(Arrays.asList(aggregator.getParams().split(";"))); 154 | aggregators.add(agg); 155 | aggregatorDefined = true; 156 | } 157 | } 158 | if (!aggregatorDefined) 159 | aggregators.add(AggregatorType.OVERRIDE.getAggregator()); 160 | } 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/TestParams.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans; 24 | 25 | import java.io.File; 26 | 27 | import uk.co.objectivity.test.db.beans.xml.CmpSqlResultsConfig; 28 | import uk.co.objectivity.test.db.beans.xml.CmpSqlResultsTest; 29 | 30 | public class TestParams { 31 | 32 | private String testName; 33 | 34 | private File testConfigFile; 35 | 36 | private String skipTestMessage; 37 | 38 | private CmpSqlResultsTest cmpSqlResultsTest; 39 | 40 | private CmpSqlResultsConfig cmpSqlResultsConfig; 41 | 42 | public TestParams(String testName) { 43 | this.testName = testName; 44 | } 45 | 46 | public String getTestName() { 47 | return testName; 48 | } 49 | 50 | public void setTestName(String testName) { 51 | this.testName = testName; 52 | } 53 | 54 | public CmpSqlResultsTest getCmpSqlResultsTest() { 55 | return cmpSqlResultsTest; 56 | } 57 | 58 | public void setCmpSqlResultsTest(CmpSqlResultsTest cmpSqlResultsTest) { 59 | this.cmpSqlResultsTest = cmpSqlResultsTest; 60 | } 61 | 62 | public CmpSqlResultsConfig getCmpSqlResultsConfig() { 63 | return cmpSqlResultsConfig; 64 | } 65 | 66 | public void setCmpSqlResultsConfig(CmpSqlResultsConfig cmpSqlResultsConfig) { 67 | this.cmpSqlResultsConfig = cmpSqlResultsConfig; 68 | } 69 | 70 | public String getSkipTestMessage() { 71 | return skipTestMessage; 72 | } 73 | 74 | public void setSkipTestMessage(String skipTestMessage) { 75 | this.skipTestMessage = skipTestMessage; 76 | } 77 | 78 | public void addSkipTestMessage(String skipTestMessage) { 79 | if (skipTestMessage != null && !skipTestMessage.isEmpty()) { 80 | if (this.skipTestMessage == null) { 81 | this.skipTestMessage = ""; 82 | } else { 83 | this.skipTestMessage += "\r\n"; 84 | } 85 | this.skipTestMessage += skipTestMessage; 86 | } 87 | } 88 | 89 | public boolean isMarkedToSkip() { 90 | return skipTestMessage != null; 91 | } 92 | 93 | public File getTestConfigFile() { 94 | return testConfigFile; 95 | } 96 | 97 | public void setTestConfigFile(File testConfigFile) { 98 | this.testConfigFile = testConfigFile; 99 | } 100 | 101 | @Override 102 | public String toString() { 103 | return testName; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/TestResults.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans; 24 | 25 | import java.util.List; 26 | 27 | public class TestResults { 28 | 29 | private Integer nmbOfRows; 30 | 31 | private Integer nmbOfComparedRows; 32 | 33 | private List columns; 34 | 35 | private List> rows; 36 | 37 | private String output = ""; 38 | 39 | private String executedQuery; 40 | 41 | public TestResults(String executedQuery, int nmbOfRows) { 42 | this.executedQuery = executedQuery; 43 | this.nmbOfRows = nmbOfRows; 44 | } 45 | 46 | public void appendOutput(String message){ 47 | output += message + "\r\n"; 48 | } 49 | 50 | public String getOutput() { 51 | return output; 52 | } 53 | 54 | public Integer getNmbOfComparedRows() { 55 | return nmbOfComparedRows; 56 | } 57 | 58 | public void setNmbOfComparedRows(Integer nmbOfComparedRows) { 59 | this.nmbOfComparedRows = nmbOfComparedRows; 60 | } 61 | 62 | public Integer getNmbOfRows() { 63 | return nmbOfRows; 64 | } 65 | 66 | public void setNmbOfRows(Integer nmbOfRows) { 67 | this.nmbOfRows = nmbOfRows; 68 | } 69 | 70 | public List getColumns() { 71 | return columns; 72 | } 73 | 74 | public void setColumns(List columns) { 75 | this.columns = columns; 76 | } 77 | 78 | public List> getRows() { 79 | return rows; 80 | } 81 | 82 | public void setRows(List> rows) { 83 | this.rows = rows; 84 | } 85 | 86 | public String getExecutedQuery() { 87 | return executedQuery; 88 | } 89 | 90 | public void setExecutedQuery(String executedQuery) { 91 | this.executedQuery = executedQuery; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Aggregator.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlAttribute; 28 | import javax.xml.bind.annotation.XmlValue; 29 | 30 | import uk.co.objectivity.test.db.aggregators.AggregatorType; 31 | 32 | @XmlAccessorType(XmlAccessType.FIELD) 33 | public class Aggregator { 34 | 35 | @XmlAttribute 36 | private Integer column; 37 | 38 | @XmlAttribute 39 | private String params; //comma separated list of aggregator params 40 | 41 | @XmlValue 42 | private AggregatorType aggregatorType; 43 | 44 | public Integer getColumn() { 45 | return column; 46 | } 47 | 48 | public void setColumn(Integer column) { 49 | this.column = column; 50 | } 51 | 52 | public String getParams() { 53 | return params; 54 | } 55 | 56 | public void setParams(String params) { 57 | this.params = params; 58 | } 59 | 60 | public AggregatorType getAggregatorType() { 61 | return aggregatorType; 62 | } 63 | 64 | public void setAggregatorType(AggregatorType aggregatorType) { 65 | this.aggregatorType = aggregatorType; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/AggregatorCondition.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.beans.xml; 2 | 3 | import javax.xml.bind.annotation.XmlAccessType; 4 | import javax.xml.bind.annotation.XmlAccessorType; 5 | import javax.xml.bind.annotation.XmlAttribute; 6 | import javax.xml.bind.annotation.XmlValue; 7 | 8 | import uk.co.objectivity.test.db.aggregators.condition.AggregatorConditionType; 9 | 10 | @XmlAccessorType(XmlAccessType.FIELD) 11 | public class AggregatorCondition { 12 | @XmlAttribute 13 | private String column; 14 | 15 | @XmlAttribute 16 | private String conditionValue; 17 | 18 | @XmlValue 19 | private AggregatorConditionType type; 20 | 21 | public uk.co.objectivity.test.db.aggregators.condition.AggregatorCondition getAggregatorCondition() { 22 | return type.getAggregatorCondition(this.conditionValue, Integer.parseInt(column)); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Aggregators.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import java.util.List; 26 | import java.util.stream.Collectors; 27 | 28 | import javax.xml.bind.annotation.XmlAccessType; 29 | import javax.xml.bind.annotation.XmlAccessorType; 30 | import javax.xml.bind.annotation.XmlElement; 31 | import javax.xml.bind.annotation.XmlRootElement; 32 | 33 | @XmlRootElement(name = "aggregators") 34 | @XmlAccessorType(XmlAccessType.FIELD) 35 | public class Aggregators { 36 | 37 | @XmlElement(name = "aggregator") 38 | private List aggregators; 39 | 40 | @XmlElement(name = "condition") 41 | private List conditions; 42 | 43 | public List getAggregators() { 44 | return aggregators; 45 | } 46 | 47 | public List getConditions() { 48 | if (conditions == null || conditions.isEmpty()) 49 | return null; 50 | return conditions.stream().map(cond -> cond.getAggregatorCondition()).collect(Collectors.toList()); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/BeforeSqls.java: -------------------------------------------------------------------------------- 1 | // 2 | //Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import java.util.List; 26 | 27 | import javax.xml.bind.annotation.XmlAccessType; 28 | import javax.xml.bind.annotation.XmlAccessorType; 29 | import javax.xml.bind.annotation.XmlElement; 30 | 31 | @XmlAccessorType(XmlAccessType.FIELD) 32 | public class BeforeSqls { 33 | 34 | @XmlElement(name = "sql") 35 | private List sqls; 36 | 37 | public List getSqls() { 38 | return sqls; 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/CmpSqlResultsConfig.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlRootElement; 28 | 29 | @XmlRootElement(name = "cmpSqlResultsConfig") 30 | @XmlAccessorType(XmlAccessType.FIELD) 31 | public class CmpSqlResultsConfig { 32 | 33 | private Datasources datasources; 34 | 35 | private int threads; 36 | 37 | private Logger logger; 38 | 39 | private Filter filter = new Filter(); 40 | 41 | private int testFailureExitCode = 0; 42 | 43 | public Datasources getDatasources() { 44 | return datasources; 45 | } 46 | 47 | public void setDatasources(Datasources datasources) { 48 | this.datasources = datasources; 49 | } 50 | 51 | public int getThreads() { 52 | return threads; 53 | } 54 | 55 | public void setThreads(int threads) { 56 | this.threads = threads; 57 | } 58 | 59 | public Logger getLogger() { 60 | return logger; 61 | } 62 | 63 | public void setLogger(Logger logger) { 64 | this.logger = logger; 65 | } 66 | 67 | public Filter getFilter() { 68 | return filter; 69 | } 70 | 71 | public void setFilter(Filter filter) { 72 | this.filter = filter; 73 | } 74 | 75 | public Datasource getDatasourceByName(String name) { 76 | return datasources.getDatasourceByName(name); 77 | } 78 | 79 | public int getTestFailureExitCode() { 80 | return testFailureExitCode; 81 | } 82 | 83 | public void setTestFailureExitCode(int testFailureExitCode) { 84 | this.testFailureExitCode = testFailureExitCode; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/CmpSqlResultsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlElement; 28 | import javax.xml.bind.annotation.XmlRootElement; 29 | 30 | @XmlRootElement(name = "cmpSqlResultsTest") 31 | @XmlAccessorType(XmlAccessType.FIELD) 32 | public class CmpSqlResultsTest { 33 | 34 | @XmlElement 35 | private Compare compare; 36 | 37 | public Compare getCompare() { 38 | return compare; 39 | } 40 | 41 | public void setCompare(Compare compare) { 42 | this.compare = compare; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Compare.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import java.math.BigDecimal; 26 | import java.util.List; 27 | 28 | import javax.xml.bind.annotation.XmlAccessType; 29 | import javax.xml.bind.annotation.XmlAccessorType; 30 | import javax.xml.bind.annotation.XmlAttribute; 31 | import javax.xml.bind.annotation.XmlElement; 32 | 33 | import uk.co.objectivity.test.db.beans.CompareMode; 34 | 35 | @XmlAccessorType(XmlAccessType.FIELD) 36 | public class Compare { 37 | 38 | @XmlAttribute 39 | private String defaultDatasourceName; 40 | 41 | @XmlAttribute(name = "mode") 42 | private CompareMode compareMode; 43 | 44 | @XmlAttribute 45 | private int diffTableSize = 5; 46 | 47 | @XmlAttribute 48 | private int fetchSize = 100; 49 | 50 | @XmlAttribute 51 | private int chunk = 0; 52 | 53 | @XmlAttribute 54 | private BigDecimal delta = BigDecimal.ZERO; 55 | 56 | @XmlAttribute 57 | private boolean fileOutputOn = false; 58 | 59 | @XmlAttribute 60 | private String keyColumns = null; 61 | 62 | @XmlAttribute 63 | private boolean minusQueryIndicatorOn = false; 64 | 65 | @XmlElement(name = "sql") 66 | private List sqls; 67 | 68 | @XmlElement(name = "beforeSqls") 69 | private List beforeSqls; 70 | 71 | @XmlElement(name = "assert") 72 | private List assertions; 73 | 74 | @XmlElement(name = "file") 75 | private File file; 76 | 77 | public String getDefaultDatasourceName() { 78 | return defaultDatasourceName; 79 | } 80 | 81 | public void setDefaultDatasourceName(String defaultDatasourceName) { 82 | this.defaultDatasourceName = defaultDatasourceName; 83 | } 84 | 85 | public CompareMode getCompareMode() { 86 | return compareMode; 87 | } 88 | 89 | public void setCompareMode(CompareMode compareMode) { 90 | this.compareMode = compareMode; 91 | } 92 | 93 | public List getSqls() { 94 | return sqls; 95 | } 96 | 97 | public void setSqls(List sqls) { 98 | this.sqls = sqls; 99 | } 100 | 101 | public List getBeforeSqls() { 102 | return beforeSqls; 103 | } 104 | 105 | public int getDiffTableSize() { 106 | return diffTableSize; 107 | } 108 | 109 | public void setDiffTableSize(int diffTableSize) { 110 | this.diffTableSize = diffTableSize; 111 | } 112 | 113 | public int getFetchSize() { 114 | return fetchSize; 115 | } 116 | 117 | public void setFetchSize(int fetchSize) { 118 | this.fetchSize = fetchSize; 119 | } 120 | 121 | public int getChunk() { 122 | return chunk; 123 | } 124 | 125 | public void setChunk(int chunk) { 126 | this.chunk = chunk; 127 | } 128 | 129 | public boolean isFileOutputOn() { 130 | return fileOutputOn; 131 | } 132 | 133 | public boolean isMinusQueryIndicatorOn() { 134 | return minusQueryIndicatorOn; 135 | } 136 | 137 | public void setFileOutputOn(boolean fileOutputOn) { 138 | this.fileOutputOn = fileOutputOn; 139 | } 140 | 141 | public String getKeyColumns() { 142 | return keyColumns; 143 | } 144 | 145 | public void setKeyColumns(String keyColumns) { 146 | this.keyColumns = keyColumns; 147 | } 148 | 149 | public void setMinusQueryIndicatorOn(boolean minusQueryIndicatorOn) { 150 | this.minusQueryIndicatorOn = minusQueryIndicatorOn; 151 | } 152 | 153 | public List getAssertions() { 154 | return assertions; 155 | } 156 | 157 | public void setAssertions(List assertions) { 158 | this.assertions = assertions; 159 | } 160 | 161 | public BigDecimal getDelta() { 162 | return delta; 163 | } 164 | 165 | public void setDelta(BigDecimal delta) { 166 | this.delta = delta; 167 | } 168 | 169 | public File getFile() { 170 | return file; 171 | } 172 | 173 | public void setFile(File file) { 174 | this.file = file; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Condition.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlAttribute; 28 | import javax.xml.bind.annotation.XmlValue; 29 | 30 | import uk.co.objectivity.test.db.beans.ConditionType; 31 | 32 | @XmlAccessorType(XmlAccessType.FIELD) 33 | public class Condition { 34 | 35 | @XmlAttribute(name = "type") 36 | private ConditionType conditionType; 37 | 38 | @XmlValue 39 | private Integer value; 40 | 41 | public ConditionType getConditionType() { 42 | return conditionType; 43 | } 44 | 45 | public void setConditionType(ConditionType conditionType) { 46 | this.conditionType = conditionType; 47 | } 48 | 49 | public Integer getValue() { 50 | return value; 51 | } 52 | 53 | public void setValue(Integer value) { 54 | this.value = value; 55 | } 56 | } -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Datasource.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlAttribute; 28 | 29 | @XmlAccessorType(XmlAccessType.FIELD) 30 | public class Datasource { 31 | 32 | @XmlAttribute 33 | private Integer maxPollSize; 34 | 35 | private String name; 36 | 37 | private String driver; 38 | 39 | private String url; 40 | 41 | private String user; 42 | 43 | private String password; 44 | 45 | public String getName() { 46 | return name; 47 | } 48 | 49 | public void setName(String name) { 50 | this.name = name; 51 | } 52 | 53 | public String getDriver() { 54 | return driver; 55 | } 56 | 57 | public void setDriver(String driver) { 58 | this.driver = driver; 59 | } 60 | 61 | public String getUrl() { 62 | return url; 63 | } 64 | 65 | public void setUrl(String url) { 66 | this.url = url; 67 | } 68 | 69 | public String getUser() { 70 | return user; 71 | } 72 | 73 | public void setUser(String user) { 74 | this.user = user; 75 | } 76 | 77 | public String getPassword() { 78 | return password; 79 | } 80 | 81 | public void setPassword(String password) { 82 | this.password = password; 83 | } 84 | 85 | public Integer getMaxPollSize() { 86 | return maxPollSize; 87 | } 88 | 89 | public void setMaxPollSize(Integer maxPollSize) { 90 | this.maxPollSize = maxPollSize; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Datasources.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import java.util.List; 26 | 27 | import javax.xml.bind.annotation.XmlAccessType; 28 | import javax.xml.bind.annotation.XmlAccessorType; 29 | import javax.xml.bind.annotation.XmlElement; 30 | import javax.xml.bind.annotation.XmlRootElement; 31 | 32 | @XmlRootElement(name = "datasources") 33 | @XmlAccessorType(XmlAccessType.FIELD) 34 | public class Datasources { 35 | 36 | @XmlElement(name = "datasource") 37 | private List datasources; 38 | 39 | public List getDatasources() { 40 | return datasources; 41 | } 42 | 43 | public Datasource getDatasourceByName(String name) { 44 | for (Datasource datasource : datasources) { 45 | if (datasource.getName() != null && datasource.getName().equals(name)) { 46 | return datasource; 47 | } 48 | } 49 | return null; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/File.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlAttribute; 28 | import javax.xml.bind.annotation.XmlElement; 29 | 30 | import uk.co.objectivity.test.db.beans.CheckPresenceAlgorithm; 31 | 32 | @XmlAccessorType(XmlAccessType.FIELD) 33 | public class File { 34 | 35 | @XmlAttribute 36 | private String filename; 37 | 38 | @XmlAttribute 39 | private String separator = ","; 40 | 41 | @XmlAttribute 42 | private int startAtRow = 1; 43 | 44 | @XmlAttribute 45 | private Integer testSetColumn; 46 | 47 | @XmlAttribute 48 | private String checkPresenceColumn; 49 | 50 | @XmlAttribute 51 | private CheckPresenceAlgorithm presenceAlgorithm; 52 | 53 | @XmlAttribute 54 | private String presenceColumnHeader; 55 | 56 | @XmlAttribute 57 | private String absentIndicator; 58 | 59 | @XmlAttribute 60 | private String ignoredColumns; 61 | 62 | @XmlElement(name = "transformers") 63 | private Transformers transformers; 64 | 65 | @XmlElement(name = "aggregators") 66 | private Aggregators aggregators; 67 | 68 | public String getFilename() { 69 | return filename; 70 | } 71 | 72 | public void setFilename(String filename) { 73 | this.filename = filename; 74 | } 75 | 76 | public String getSeparator() { 77 | return separator; 78 | } 79 | 80 | public void setSeparator(String separator) { 81 | this.separator = separator; 82 | } 83 | 84 | public int getStartAtRow() { 85 | return startAtRow; 86 | } 87 | 88 | public String getIgnoredColumns() { 89 | return ignoredColumns; 90 | } 91 | 92 | public Transformers getTransformers() { 93 | return transformers; 94 | } 95 | 96 | public Aggregators getAggregators() { 97 | return aggregators; 98 | } 99 | 100 | public Integer getTestSetColumn() { 101 | return testSetColumn; 102 | } 103 | 104 | public String getCheckPresenceHeader() { 105 | return presenceColumnHeader; 106 | } 107 | 108 | public String getAbsentIndicator() { 109 | if (absentIndicator != null) 110 | return absentIndicator.toUpperCase(); 111 | return "C"; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Filter.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import java.beans.Transient; 26 | import java.util.ArrayList; 27 | import java.util.Arrays; 28 | import java.util.List; 29 | import java.util.stream.Collectors; 30 | 31 | import javax.xml.bind.annotation.XmlAccessType; 32 | import javax.xml.bind.annotation.XmlAccessorType; 33 | import javax.xml.bind.annotation.XmlElement; 34 | 35 | @XmlAccessorType(XmlAccessType.FIELD) 36 | public class Filter { 37 | 38 | @XmlElement(name = "include") 39 | private List includes = new ArrayList<>(); 40 | 41 | @XmlElement(name = "exclude") 42 | private List excludes = new ArrayList<>(); 43 | 44 | public List getIncludes() { 45 | return includes; 46 | } 47 | 48 | public void setIncludes(List includes) { 49 | this.includes = includes; 50 | } 51 | 52 | public void setIncludesString(String includesString) { 53 | includes = new ArrayList<>(Arrays.asList(includesString.split(","))); 54 | } 55 | 56 | public List getExcludes() { 57 | return excludes; 58 | } 59 | 60 | public void setExcludes(List excludes) { 61 | this.excludes = excludes; 62 | } 63 | 64 | public void setExcludesString(String includesString) { 65 | excludes = new ArrayList<>(Arrays.asList(includesString.split(","))); 66 | } 67 | 68 | @Transient 69 | public void trim() { 70 | includes = includes.stream().map(String::trim).filter(str -> !str.isEmpty()).collect(Collectors.toList()); 71 | excludes = excludes.stream().map(String::trim).filter(str -> !str.isEmpty()).collect(Collectors.toList()); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Logger.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlAttribute; 28 | 29 | @XmlAccessorType(XmlAccessType.FIELD) 30 | public class Logger { 31 | 32 | @XmlAttribute 33 | protected boolean teamcityLogsEnabled; 34 | 35 | @XmlAttribute 36 | protected String logLevel; 37 | 38 | public boolean isTeamcityLogsEnabled() { 39 | return teamcityLogsEnabled; 40 | } 41 | 42 | public void setTeamcityLogsEnabled(boolean teamcityLogsEnabled) { 43 | this.teamcityLogsEnabled = teamcityLogsEnabled; 44 | } 45 | 46 | public String getLogLevel() { 47 | return logLevel; 48 | } 49 | 50 | public void setLogLevel(String logLevel) { 51 | this.logLevel = logLevel; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Sql.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import java.util.ArrayList; 26 | import java.util.Arrays; 27 | import java.util.List; 28 | import java.util.stream.Collectors; 29 | 30 | import javax.xml.bind.annotation.XmlAccessType; 31 | import javax.xml.bind.annotation.XmlAccessorType; 32 | import javax.xml.bind.annotation.XmlAttribute; 33 | import javax.xml.bind.annotation.XmlValue; 34 | 35 | import org.testng.TestException; 36 | 37 | @XmlAccessorType(XmlAccessType.FIELD) 38 | public class Sql { 39 | 40 | @XmlValue 41 | private String sql; 42 | 43 | @XmlAttribute 44 | private String filename; 45 | 46 | @XmlAttribute 47 | private String datasourceName; 48 | 49 | @XmlAttribute 50 | private String minusQueryIndicatorOccurence = "1"; 51 | 52 | @XmlAttribute 53 | private int startAtRow = 1; 54 | 55 | @XmlAttribute 56 | private String minusQueryIndicatorText; 57 | 58 | @XmlAttribute 59 | private String keyTableName; 60 | 61 | @XmlAttribute 62 | private String keyTableColumns; 63 | 64 | @XmlAttribute 65 | private boolean emptyStringToNull = false; 66 | 67 | @XmlAttribute 68 | private String duplicatesArbitratorColumns; 69 | 70 | @XmlAttribute 71 | private String dateFormat; 72 | 73 | public String getSql() { 74 | return sql; 75 | } 76 | 77 | public int getStartAtRow() { 78 | return startAtRow; 79 | } 80 | 81 | public void setSql(String sql) { 82 | this.sql = sql; 83 | } 84 | 85 | public String getDatasourceName() { 86 | return datasourceName; 87 | } 88 | 89 | public void setDatasourceName(String datasourceName) { 90 | this.datasourceName = datasourceName; 91 | } 92 | 93 | public String getFilename() { 94 | return filename; 95 | } 96 | 97 | public void setFilename(String filename) { 98 | this.filename = filename; 99 | } 100 | 101 | public String getMinusQueryIndicatorOccurence() { 102 | return minusQueryIndicatorOccurence; 103 | } 104 | 105 | public String getMinusQueryIndicatorText() { 106 | return minusQueryIndicatorText; 107 | } 108 | 109 | public void setMinusQueryIndicatorText(String minusQueryIndicatorText) { 110 | this.minusQueryIndicatorText = minusQueryIndicatorText; 111 | } 112 | 113 | public String getKeyTableName() { 114 | return keyTableName; 115 | } 116 | 117 | public void setKeyTableName(String keyTableName) { 118 | this.keyTableName = keyTableName; 119 | } 120 | 121 | public String getKeyTableColumns() { 122 | return keyTableColumns; 123 | } 124 | 125 | public void setKeyTableColumns(String keyTableColumns) { 126 | this.keyTableColumns = keyTableColumns; 127 | } 128 | 129 | public boolean isEmptyStringToNull() { 130 | return emptyStringToNull; 131 | } 132 | 133 | public void setEmptyStringToNull(boolean emptyStringToNull) { 134 | this.emptyStringToNull = emptyStringToNull; 135 | } 136 | 137 | public String getDateFormat() { 138 | return this.dateFormat != null ? this.dateFormat : "yyyy-MM-dd"; 139 | } 140 | 141 | public List getDuplicatesArbitratorColumns() { 142 | if (duplicatesArbitratorColumns == null) 143 | return new ArrayList(); 144 | try { 145 | return Arrays.stream(duplicatesArbitratorColumns.split(",")).map(s -> s.trim()).map(Integer::valueOf) 146 | .collect(Collectors.toList()); 147 | } catch (NumberFormatException nfe) { 148 | throw new TestException("Incorrect value in the 'duplicatesArbitratorColumns' property"); 149 | } 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Transformer.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import javax.xml.bind.annotation.XmlAccessType; 26 | import javax.xml.bind.annotation.XmlAccessorType; 27 | import javax.xml.bind.annotation.XmlAttribute; 28 | import javax.xml.bind.annotation.XmlValue; 29 | 30 | import java.util.ArrayList; 31 | import java.util.Arrays; 32 | import java.util.List; 33 | 34 | import uk.co.objectivity.test.db.transformers.TransformerType; 35 | 36 | @XmlAccessorType(XmlAccessType.FIELD) 37 | public class Transformer { 38 | 39 | @XmlAttribute 40 | private Integer column; 41 | 42 | @XmlAttribute 43 | private String params; // comma separated list of aggregator params 44 | 45 | @XmlValue 46 | private TransformerType transformerType; 47 | 48 | private List convertParams() { 49 | return this.params != null ? Arrays.asList(this.params.split(";")) : new ArrayList(); 50 | } 51 | 52 | public Integer getColumn() { 53 | return column; 54 | } 55 | 56 | public void setColumn(Integer column) { 57 | this.column = column; 58 | } 59 | 60 | public String getParams() { 61 | return params; 62 | } 63 | 64 | public void setParams(String params) { 65 | this.params = params; 66 | } 67 | 68 | public uk.co.objectivity.test.db.transformers.Transformer getTransformer() { 69 | uk.co.objectivity.test.db.transformers.Transformer transformer = transformerType.getTransformer(); 70 | if (transformer == null) 71 | return null; 72 | return transformer.setParams(this.convertParams()); 73 | } 74 | 75 | public void setTransformerType(TransformerType transformerType) { 76 | this.transformerType = transformerType; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/beans/xml/Transformers.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.beans.xml; 24 | 25 | import java.util.List; 26 | 27 | import javax.xml.bind.annotation.XmlAccessType; 28 | import javax.xml.bind.annotation.XmlAccessorType; 29 | import javax.xml.bind.annotation.XmlElement; 30 | import javax.xml.bind.annotation.XmlRootElement; 31 | 32 | @XmlRootElement(name = "transformers") 33 | @XmlAccessorType(XmlAccessType.FIELD) 34 | public class Transformers { 35 | 36 | @XmlElement(name = "transformer") 37 | private List transformers; 38 | 39 | public List getTransformers() { 40 | return transformers; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/Comparator.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.comparators; 24 | 25 | import java.io.File; 26 | import java.io.PrintWriter; 27 | import java.util.Iterator; 28 | import java.util.List; 29 | 30 | import uk.co.objectivity.test.db.beans.TestParams; 31 | import uk.co.objectivity.test.db.beans.TestResults; 32 | 33 | 34 | public abstract class Comparator { 35 | 36 | /** 37 | * Compares results of two SQL queries 38 | * 39 | * @param testParams 40 | * @return 41 | * @throws Exception 42 | */ 43 | public abstract TestResults compare(TestParams testParams) throws Exception; 44 | 45 | protected File getNewFileBasedOnTestConfigFile(File testFile, String postfix) { 46 | String fileAbsPath = testFile.getParentFile().getAbsolutePath() + File.separator + "results" + File.separator; 47 | File resultDir = new File(fileAbsPath); 48 | if(!resultDir.exists()){ 49 | resultDir.mkdir(); 50 | } 51 | fileAbsPath += testFile.getName().replaceFirst("[.][^.]+$", "") + postfix; 52 | return new File(fileAbsPath); 53 | } 54 | 55 | protected void writeRowAsCSV(PrintWriter pw, List row) { 56 | this.writeRowAsCSV(pw, row, false); 57 | } 58 | 59 | protected void writeRowAsCSV(PrintWriter pw, List row, boolean skipFirst) { 60 | if (pw == null) return; 61 | Iterator rowIt = row.iterator(); 62 | if (skipFirst && rowIt.hasNext()) rowIt.next(); 63 | while (rowIt.hasNext()) { 64 | String col = rowIt.next(); 65 | if(col!=null) 66 | pw.write("\"" + col.replaceAll("\"", "\"\"") + "\""); 67 | if (rowIt.hasNext()) pw.write(","); 68 | else pw.write("\r\n"); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/NmbOfResultsComparator.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.comparators; 24 | 25 | import java.sql.Connection; 26 | import java.sql.PreparedStatement; 27 | import java.sql.ResultSet; 28 | import java.sql.SQLException; 29 | 30 | import org.apache.log4j.Logger; 31 | import org.testng.TestException; 32 | 33 | import uk.co.objectivity.test.db.beans.TestParams; 34 | import uk.co.objectivity.test.db.beans.TestResults; 35 | import uk.co.objectivity.test.db.beans.xml.CmpSqlResultsConfig; 36 | import uk.co.objectivity.test.db.beans.xml.CmpSqlResultsTest; 37 | import uk.co.objectivity.test.db.beans.xml.Datasource; 38 | import uk.co.objectivity.test.db.beans.xml.Sql; 39 | import uk.co.objectivity.test.db.utils.DataSource; 40 | import uk.co.objectivity.test.db.utils.SavedTimes; 41 | 42 | import static uk.co.objectivity.test.db.TestDataProvider.savedTimesList; 43 | 44 | public class NmbOfResultsComparator extends Comparator { 45 | 46 | private final static Logger log = Logger.getLogger(MinusComparator.class); 47 | 48 | @Override 49 | public TestResults compare(TestParams testParams) throws Exception { 50 | CmpSqlResultsConfig cmpSqlResultsConfig = testParams.getCmpSqlResultsConfig(); 51 | CmpSqlResultsTest cmpSqlResultsTest = testParams.getCmpSqlResultsTest(); 52 | 53 | // (get(0) - IndexOutOfBoundsException) checked in TestDataProvider, but still - schema would be nice! 54 | Sql sql1 = cmpSqlResultsTest.getCompare().getSqls().get(0); 55 | Datasource datasource = cmpSqlResultsConfig.getDatasourceByName(sql1.getDatasourceName()); 56 | if (datasource == null) { 57 | throw new TestException( 58 | "Datasource '" + sql1.getDatasourceName() + "' not found! Please check configuration"); 59 | } 60 | String query = getCountQuery(sql1.getSql()); 61 | 62 | Connection connection = null; 63 | try { 64 | connection = DataSource.getConnection(datasource.getName()); 65 | return getTestResults(connection, query, sql1.getDatasourceName(), testParams); 66 | } catch (Exception e) { 67 | throw new Exception(e+"\nAssert Query : " + query); 68 | } finally { 69 | DataSource.closeConnection(connection); 70 | } 71 | } 72 | 73 | public TestResults getTestResults(Connection conn, String query, String datasourceName, TestParams testParams) throws Exception { 74 | PreparedStatement stmt = null; 75 | SavedTimes savedTimes = new SavedTimes(testParams.getTestName()); 76 | try { 77 | stmt = conn.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, 78 | ResultSet.CONCUR_READ_ONLY); 79 | savedTimes.startMeasure("NmbOfResults "+ datasourceName); 80 | ResultSet rs = stmt.executeQuery(); 81 | savedTimes.stopMeasure(); 82 | savedTimesList.add(savedTimes); 83 | 84 | rs.next(); 85 | String executedQuery = "[" + datasourceName + "]:\r\n" + query+ 86 | "\nTime execution of query:\n"+ 87 | savedTimes.getFormattedDuration(); 88 | return new TestResults(executedQuery, rs.getInt(1)); 89 | } finally { 90 | if (stmt != null) 91 | try { 92 | stmt.close(); 93 | } catch (SQLException e) { 94 | log.error(e); 95 | } 96 | } 97 | } 98 | 99 | private String getCountQuery(String selectSql) { 100 | StringBuffer sqlStrBuff = new StringBuffer("select COUNT(*) from ( ").append(selectSql).append( 101 | " ) countTable"); 102 | return sqlStrBuff.toString(); 103 | } 104 | 105 | } 106 | 107 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/printer/CompareResult.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.comparators.printer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.stream.Collectors; 7 | 8 | public class CompareResult { 9 | public enum Test { 10 | PASSED, FAILED, CHECK_ALL_COLUMNS 11 | }; 12 | 13 | private static int TESTSET_COLUMN_INDEX = 1; 14 | 15 | private String key; 16 | private List rowFile; 17 | private List rowDB; 18 | private Test test; 19 | 20 | public CompareResult(String key, List rowFile, List rowDB, Test test) { 21 | this.key = key; 22 | this.rowFile = rowFile.stream().collect(Collectors.toList()); 23 | this.rowDB = rowDB.stream().collect(Collectors.toList()); 24 | this.test = test; 25 | } 26 | 27 | public Test getTest() { 28 | return this.test; 29 | } 30 | 31 | public String getKey() { 32 | return key; 33 | } 34 | 35 | public List getRowFile() { 36 | return rowFile; 37 | } 38 | 39 | public List getRowDB() { 40 | return rowDB; 41 | } 42 | 43 | public List> getRows() { 44 | List> allRows = new ArrayList<>(); 45 | allRows.add(rowFile); 46 | allRows.add(rowDB); 47 | return allRows; 48 | } 49 | 50 | public void setTestSets(Map testSets) { 51 | String testSet = testSets.containsKey(key) ? testSets.get(key) : "N/A"; 52 | rowFile.add(TESTSET_COLUMN_INDEX, testSet); 53 | rowDB.add(TESTSET_COLUMN_INDEX, testSet); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/printer/Headers.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.comparators.printer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.Stream; 7 | 8 | public class Headers { 9 | 10 | private List headers, extHeaders; 11 | 12 | public Headers() { 13 | this(null); 14 | } 15 | 16 | public Headers(List headers) { 17 | if (headers == null) 18 | headers = new ArrayList<>(); 19 | this.headers = headers; 20 | extHeaders = new ArrayList<>(); 21 | } 22 | 23 | public void addHeader(String header) { 24 | headers.add(header); 25 | } 26 | 27 | public void addExtendedHeader(String header) { 28 | extHeaders.add(header); 29 | } 30 | 31 | public List getHeaders() { 32 | return headers; 33 | } 34 | 35 | public List getExtendedHeaders() { 36 | return Stream.of(extHeaders, headers) 37 | .flatMap(x -> x.stream()) 38 | .collect(Collectors.toList()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/printer/utils/Excel.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.comparators.printer.utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | import java.util.Iterator; 10 | import java.util.List; 11 | import java.util.regex.Pattern; 12 | 13 | import org.apache.log4j.Logger; 14 | import org.apache.poi.hssf.usermodel.HSSFCell; 15 | import org.apache.poi.hssf.usermodel.HSSFCellStyle; 16 | import org.apache.poi.hssf.usermodel.HSSFRow; 17 | import org.apache.poi.hssf.usermodel.HSSFSheet; 18 | import org.apache.poi.hssf.usermodel.HSSFWorkbook; 19 | import org.apache.poi.ss.usermodel.Cell; 20 | import org.apache.poi.ss.usermodel.Row; 21 | import org.apache.poi.ss.usermodel.Sheet; 22 | import org.apache.poi.ss.usermodel.Workbook; 23 | 24 | public class Excel { 25 | 26 | private final static Logger log = Logger.getLogger(Excel.class); 27 | 28 | public static void printFile(HSSFWorkbook workbook, String sheetName, File csvFile, String separator) { 29 | Pattern linePattern = Pattern.compile("\\Q" + separator + "\\E(?=(?:(?:[^\"]*\"){2})*[^\"]*$)"); 30 | try { 31 | HSSFSheet sheet = workbook.createSheet(sheetName); 32 | ArrayList> rows = getFileAsList(csvFile, linePattern); 33 | 34 | for (int k = 0; k < rows.size(); k++) { 35 | ArrayList columns = rows.get(k); 36 | HSSFRow row = sheet.createRow((short) k); 37 | for (int p = 0; p < columns.size(); p++) { 38 | HSSFCell cell = row.createCell((short) p); 39 | cell.setCellValue(columns.get(p)); 40 | } 41 | } 42 | 43 | } catch (Exception ex) { 44 | log.info(ex); 45 | } 46 | } 47 | 48 | public static ArrayList> getFileAsList(File csvFile, Pattern linePattern) throws IOException { 49 | ArrayList> rows = new ArrayList<>(); 50 | String line; 51 | ArrayList columnList; 52 | FileInputStream fis = new FileInputStream(csvFile); 53 | BufferedReader br = new BufferedReader(new InputStreamReader(fis)); 54 | while ((line = br.readLine()) != null) { 55 | columnList = new ArrayList<>(); 56 | String[] columns = linePattern.split(line, -1); 57 | for (int j = 0; j < columns.length; j++) { 58 | if (columns[j] != null && !columns[j].isEmpty()) { 59 | columns[j] = columns[j].replaceAll("^\"|\"$", "").replaceAll("\"\"", "\""); 60 | } else { 61 | columns[j] = null; 62 | } 63 | columnList.add(columns[j]); 64 | } 65 | rows.add(columnList); 66 | } 67 | fis.close(); 68 | br.close(); 69 | return rows; 70 | } 71 | 72 | public static void printString(HSSFWorkbook workbook, String sheetName, String stringToPrint) { 73 | try { 74 | HSSFCellStyle style = workbook.createCellStyle(); 75 | style.setWrapText(true); 76 | HSSFSheet sheet = workbook.createSheet(sheetName); 77 | HSSFRow row = sheet.createRow(0); 78 | HSSFCell cell = row.createCell(0); 79 | row.setRowStyle(style); 80 | cell.setCellValue("\r\n" + stringToPrint + "\r\n"); 81 | cell.setCellStyle(style); 82 | } catch (Exception ex) { 83 | log.info(ex); 84 | } 85 | } 86 | 87 | public static void printRow(HSSFSheet sheet, List columns, ExcelStyle excelStyle) { 88 | HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1); 89 | for (int i = 0; i < columns.size(); i++) { 90 | HSSFCell cell = row.createCell((short) i); 91 | cell.setCellValue(columns.get(i)); 92 | if (excelStyle != null) { 93 | cell.setCellStyle(excelStyle.getStyle(sheet.getWorkbook())); 94 | } 95 | } 96 | } 97 | 98 | public static void printRow(HSSFSheet sheet, List columns) { 99 | printRow(sheet, columns, null); 100 | } 101 | 102 | public static void printRows(HSSFSheet sheet, List> rows) { 103 | rows.stream().forEach(c -> printRow(sheet, c)); 104 | } 105 | 106 | public static void autoSizeColumns(Workbook workbook) { 107 | int numberOfSheets = workbook.getNumberOfSheets(); 108 | for (int i = 0; i < numberOfSheets; i++) { 109 | Sheet sheet = workbook.getSheetAt(i); 110 | if (sheet.getPhysicalNumberOfRows() > 0) { 111 | Row row = sheet.getRow(sheet.getFirstRowNum()); 112 | Iterator cellIterator = row.cellIterator(); 113 | while (cellIterator.hasNext()) { 114 | Cell cell = cellIterator.next(); 115 | int columnIndex = cell.getColumnIndex(); 116 | sheet.autoSizeColumn(columnIndex); 117 | } 118 | } 119 | } 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/printer/utils/ExcelStyle.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.comparators.printer.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.commons.collections4.map.HashedMap; 7 | import org.apache.log4j.Logger; 8 | import org.apache.poi.hssf.usermodel.HSSFFont; 9 | import org.apache.poi.hssf.usermodel.HSSFPalette; 10 | import org.apache.poi.hssf.usermodel.HSSFWorkbook; 11 | import org.apache.poi.hssf.util.HSSFColor; 12 | import org.apache.poi.ss.usermodel.BorderStyle; 13 | import org.apache.poi.ss.usermodel.CellStyle; 14 | import org.apache.poi.ss.usermodel.FillPatternType; 15 | import org.apache.poi.ss.usermodel.IndexedColors; 16 | 17 | public enum ExcelStyle { 18 | 19 | HEADER, GREY, GREY_BORDER, RED, RED_BORDER, GREEN, GREEN_BORDER; 20 | 21 | private final static Logger log = Logger.getLogger(ExcelStyle.class); 22 | Map> styles = new HashMap<>(); 23 | boolean colorsInitialized = false; 24 | 25 | public CellStyle getStyle(HSSFWorkbook workbook) { 26 | switch (this) { 27 | case HEADER: 28 | ensureStyleExists(workbook, HEADER); 29 | return styles.get(workbook).get(HEADER); 30 | case GREY: 31 | ensureStyleExists(workbook, GREY); 32 | return styles.get(workbook).get(GREY); 33 | case GREY_BORDER: 34 | ensureStyleExists(workbook, GREY_BORDER); 35 | return styles.get(workbook).get(GREY_BORDER); 36 | case RED: 37 | ensureStyleExists(workbook, RED); 38 | return styles.get(workbook).get(RED); 39 | case RED_BORDER: 40 | ensureStyleExists(workbook, RED_BORDER); 41 | return styles.get(workbook).get(RED_BORDER); 42 | case GREEN: 43 | ensureStyleExists(workbook, GREEN); 44 | return styles.get(workbook).get(GREEN); 45 | case GREEN_BORDER: 46 | ensureStyleExists(workbook, GREEN_BORDER); 47 | return styles.get(workbook).get(GREEN_BORDER); 48 | } 49 | return null; 50 | 51 | } 52 | 53 | private void ensureStyleExists(HSSFWorkbook workbook, ExcelStyle excelStyle) { 54 | if (!colorsInitialized) { 55 | replaceWorkbookColors(workbook); 56 | colorsInitialized = true; 57 | } 58 | if (styles.containsKey(workbook)) { 59 | if (!styles.get(workbook).containsKey(excelStyle)) { 60 | styles.get(workbook).put(excelStyle, createStyle(workbook, excelStyle)); 61 | } 62 | } else { 63 | Map styleMap = new HashedMap<>(); 64 | styleMap.put(excelStyle, createStyle(workbook, excelStyle)); 65 | styles.put(workbook, styleMap); 66 | } 67 | } 68 | 69 | private CellStyle createStyle(HSSFWorkbook workbook, ExcelStyle excelStyle) { 70 | CellStyle style = workbook.createCellStyle(); 71 | style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 72 | switch (excelStyle) { 73 | case HEADER: 74 | style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); 75 | style.setFont(getFont(workbook, IndexedColors.GREY_80_PERCENT, (short) 12, true)); 76 | style.setBorderBottom(BorderStyle.DOUBLE); 77 | break; 78 | case GREY_BORDER: 79 | style.setBorderBottom(BorderStyle.THIN); 80 | case GREY: 81 | style.setFont(getFont(workbook, IndexedColors.GREY_50_PERCENT, (short) 9, false)); 82 | style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); 83 | break; 84 | case RED_BORDER: 85 | style.setBorderBottom(BorderStyle.THIN); 86 | case RED: 87 | style.setFont(getFont(workbook, IndexedColors.RED, (short) 10, false)); 88 | style.setFillForegroundColor(IndexedColors.ROSE.getIndex()); 89 | break; 90 | case GREEN_BORDER: 91 | style.setBorderBottom(BorderStyle.THIN); 92 | case GREEN: 93 | style.setFont(getFont(workbook, IndexedColors.DARK_GREEN, (short) 10, false)); 94 | style.setFillForegroundColor(IndexedColors.GREEN.getIndex()); 95 | break; 96 | } 97 | return style; 98 | } 99 | 100 | private HSSFFont getFont(HSSFWorkbook workbook, IndexedColors indexedColors, short size, boolean bold) { 101 | HSSFFont font = workbook.createFont(); 102 | font.setFontHeightInPoints(size); 103 | font.setFontName("Arial"); 104 | font.setColor(indexedColors.getIndex()); 105 | font.setBold(bold); 106 | // font.setItalic(false); 107 | return font; 108 | } 109 | 110 | private static void replaceWorkbookColors(HSSFWorkbook workbook) { 111 | setColor(workbook, IndexedColors.ROSE.getIndex(), (byte) 255, (byte) 199, (byte) 206); 112 | setColor(workbook, IndexedColors.RED.getIndex(), (byte) 156, (byte) 0, (byte) 6); 113 | setColor(workbook, IndexedColors.DARK_GREEN.getIndex(), (byte) 0, (byte) 97, (byte) 0); 114 | setColor(workbook, IndexedColors.GREEN.getIndex(), (byte) 198, (byte) 239, (byte) 206); 115 | setColor(workbook, IndexedColors.GREY_25_PERCENT.getIndex(), (byte) 237, (byte) 237, (byte) 237); 116 | } 117 | 118 | private static HSSFColor setColor(HSSFWorkbook workbook, short colorIndex, byte r, byte g, byte b) { 119 | HSSFPalette palette = workbook.getCustomPalette(); 120 | HSSFColor hssfColor = null; 121 | try { 122 | hssfColor = palette.findColor(r, g, b); 123 | if (hssfColor == null) { 124 | palette.setColorAtIndex(colorIndex, r, g, b); 125 | hssfColor = palette.getColor(colorIndex); 126 | } 127 | } catch (Exception e) { 128 | log.error(e); 129 | } 130 | 131 | return hssfColor; 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/results/DBResults.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.comparators.results; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collection; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Optional; 10 | import java.util.TreeMap; 11 | import java.util.stream.Collectors; 12 | 13 | import org.apache.log4j.Logger; 14 | import org.testng.TestException; 15 | 16 | public class DBResults { 17 | private final static Logger log = Logger.getLogger(DBResults.class); 18 | private List duplicatesArbitratorColumns; 19 | private Integer maxArbitratorColumn = -1; 20 | private Map> dbRowsMap = new TreeMap<>(); 21 | 22 | public DBResults(List duplicatesArbitratorColumns) { 23 | this.duplicatesArbitratorColumns = duplicatesArbitratorColumns; 24 | if (!duplicatesArbitratorColumns.isEmpty()) 25 | maxArbitratorColumn = Collections.max(duplicatesArbitratorColumns); 26 | } 27 | 28 | /** 29 | * Method throws exception when adding row with the same key (key columns can 30 | * not be duplicated). When duplicatesArbitratorColumnNo != null 31 | * (isArbitratorSet()), DB results with same keys are allowed. 32 | * 33 | * @param key 34 | * @param dbRow 35 | * @throws TestException 36 | */ 37 | public void add(String key, List dbRow) throws TestException { 38 | if (dbRowsMap.containsKey(key)) { 39 | if (!isArbitratorSet()) 40 | throw new TestException("Multiple DB rows for the same key: " + key 41 | + " were returned. Check your test definition SQL!"); 42 | dbRowsMap.get(key).add(new DBRow(dbRow, key)); 43 | } else { 44 | dbRowsMap.put(key, new ArrayList<>(Arrays.asList(new DBRow(dbRow, key)))); 45 | } 46 | } 47 | 48 | public Optional> getRow(String key, List csvRow) { 49 | if (!dbRowsMap.containsKey(key)) { 50 | return Optional.empty(); 51 | } 52 | if (isArbitratorSet()) { 53 | List dbKeyRows = dbRowsMap.get(key); 54 | return dbKeyRows.stream().filter(dbRow -> dbRow.matchWith(duplicatesArbitratorColumns, csvRow)).findFirst() 55 | .map(DBRow::getRow); 56 | } 57 | DBRow dbRow = dbRowsMap.get(key).get(0); 58 | dbRow.setAsMatched(); 59 | return Optional.of(dbRow.getRow()); 60 | } 61 | 62 | public List getAll() { 63 | return dbRowsMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList()); 64 | } 65 | 66 | public List getUnmached() { 67 | // testers does not want not-matched DB results to be displayd in differences 68 | if (!isArbitratorSet()) 69 | return new ArrayList(); 70 | return dbRowsMap.values().stream().flatMap(Collection::stream).filter(DBRow::isUnmatched) 71 | .collect(Collectors.toList()); 72 | } 73 | 74 | public boolean isArbitratorSet() { 75 | return !duplicatesArbitratorColumns.isEmpty(); 76 | } 77 | 78 | public Integer getMaxArbitratorColumn() { 79 | return maxArbitratorColumn; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/comparators/results/DBRow.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.comparators.results; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | import org.apache.commons.lang3.StringUtils; 7 | 8 | public class DBRow { 9 | 10 | private List row; 11 | private String key; 12 | private boolean unmatched = true; 13 | 14 | public DBRow(List row, String key) { 15 | this.row = row; 16 | this.key = key; 17 | } 18 | 19 | public List getRow() { 20 | return row; 21 | } 22 | 23 | public boolean matchWith(List duplicatesArbitratorColumns, List csvRow) { 24 | if (!unmatched) 25 | return false; 26 | 27 | AtomicInteger matchesCount = new AtomicInteger(); 28 | duplicatesArbitratorColumns.stream() 29 | .forEach(i -> { 30 | String dbColVal = row.get(i - 1); 31 | String csvRowVal = csvRow.get(i - 1); 32 | if ((dbColVal == null && csvRowVal == null) || (dbColVal != null && dbColVal.equals(csvRowVal))) 33 | matchesCount.getAndIncrement(); 34 | }); 35 | if (matchesCount.get() == duplicatesArbitratorColumns.size()) { 36 | setAsMatched(); 37 | return true; 38 | } 39 | return false; 40 | } 41 | 42 | public boolean isUnmatched() { 43 | return unmatched; 44 | } 45 | 46 | public void setAsMatched() { 47 | unmatched = false; 48 | } 49 | 50 | public String getKey() { 51 | return key; 52 | } 53 | 54 | public String toString() { 55 | return StringUtils.join(row) + (unmatched ? " - UNMATCHED" : " - MATCHED"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/transformers/RemoveLeadingZerosTransformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.transformers; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import java.util.List; 5 | 6 | public class RemoveLeadingZerosTransformer implements Transformer { 7 | 8 | @Override 9 | public String transform(String columnValue) { 10 | String stripped = StringUtils.stripStart(columnValue, "0"); 11 | if (stripped.isEmpty() && !columnValue.isEmpty()) { 12 | return "0"; 13 | } 14 | return stripped; 15 | } 16 | 17 | @Override 18 | public RemoveLeadingZerosTransformer setParams(List noop) { 19 | return this; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/transformers/SwapTransformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.transformers; 2 | 3 | import java.util.List; 4 | import org.apache.log4j.Logger; 5 | 6 | public class SwapTransformer implements Transformer { 7 | private final static Logger log = Logger.getLogger(Transformer.class); 8 | 9 | private String from = ""; 10 | private String to = ""; 11 | 12 | @Override 13 | public String transform(String columnValue) { 14 | return columnValue.equals(from) ? to : columnValue; 15 | } 16 | 17 | @Override 18 | public SwapTransformer setParams(List params) { 19 | if (params.size() == 2) { 20 | this.from = params.get(0); 21 | this.to = params.get(1); 22 | } else { 23 | log.warn("Incorrect number of params. Expected 2, found " + params.size()); 24 | log.warn("The SWAP transformer will not work correctly"); 25 | } 26 | 27 | return this; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/transformers/Transformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.objectivity.test.db.transformers; 2 | 3 | import java.util.List; 4 | 5 | public interface Transformer { 6 | 7 | String transform(String columnValue); 8 | 9 | Transformer setParams(List params); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/transformers/TransformerType.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.transformers; 24 | 25 | import org.apache.log4j.Logger; 26 | 27 | public enum TransformerType { 28 | REMOVE_LEADING_ZEROS, SWAP; 29 | 30 | private final static Logger log = Logger.getLogger(TransformerType.class); 31 | 32 | public Transformer getTransformer() { 33 | 34 | switch (this) { 35 | case REMOVE_LEADING_ZEROS: 36 | return new RemoveLeadingZerosTransformer(); 37 | case SWAP: 38 | return new SwapTransformer(); 39 | } 40 | log.warn("Unknown transformer. Check your test configuration (Known transformers:" 41 | + "REMOVE_LEADING_ZEROS, SWAP)"); 42 | return null; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/utils/DataSource.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.utils; 24 | 25 | import java.beans.PropertyVetoException; 26 | import java.sql.Connection; 27 | import java.sql.SQLException; 28 | import java.util.HashMap; 29 | import java.util.Iterator; 30 | import java.util.Map; 31 | import java.util.NoSuchElementException; 32 | 33 | import org.apache.log4j.Logger; 34 | 35 | import com.mchange.v2.c3p0.ComboPooledDataSource; 36 | 37 | import uk.co.objectivity.test.db.beans.xml.Datasource; 38 | import uk.co.objectivity.test.db.beans.xml.Datasources; 39 | 40 | public class DataSource { 41 | 42 | private final static Logger log = Logger.getLogger(DataSource.class); 43 | 44 | private static final Map DATASOURCES_MAP = new HashMap<>(); 45 | 46 | public static void init(Datasources datasources) { 47 | if (datasources == null) { 48 | log.error("Datasources are not set (or misconfigured)"); 49 | return; 50 | } 51 | log.debug("Adding shutdown hook (closing connections)..."); 52 | Runtime.getRuntime().addShutdownHook(new Thread() { 53 | public void run() { 54 | DataSource.closeAllConnections(); 55 | } 56 | }); 57 | log.debug("Initializing data source connection pools..."); 58 | Iterator it = datasources.getDatasources().iterator(); 59 | while (it.hasNext()) { 60 | Datasource datasource = it.next(); 61 | Integer maxPoolSize = datasource.getMaxPollSize(); 62 | log.debug("Max Pool Size:" + maxPoolSize + " for datasource: " + datasource.getName()); 63 | ComboPooledDataSource cpds = new ComboPooledDataSource(); 64 | cpds.setJdbcUrl(datasource.getUrl()); 65 | cpds.setUser(datasource.getUser()); 66 | cpds.setPassword(datasource.getPassword()); 67 | 68 | cpds.setAcquireRetryAttempts(3); // default is 30 69 | cpds.setAcquireRetryDelay(10000); 70 | 71 | cpds.setInitialPoolSize(1); 72 | cpds.setMinPoolSize(1); 73 | cpds.setAcquireIncrement(1); 74 | if (maxPoolSize == null || maxPoolSize == 0 || maxPoolSize > 500) { 75 | log.warn("Poll size for '" + datasource.getName() + "' is incorrect (allowed 1-500). It will be set" + 76 | " to 1."); 77 | cpds.setMaxPoolSize(1); 78 | } else { 79 | cpds.setMaxPoolSize(maxPoolSize); 80 | } 81 | 82 | try { 83 | cpds.setDriverClass(datasource.getDriver()); 84 | DATASOURCES_MAP.put(datasource.getName(), cpds); 85 | } catch (PropertyVetoException e) { 86 | // we only log it but not quit application (even it is misconfigured) because we want to run all test 87 | // anyway and mark them as failed (instead of just one "silent" exception in logs). They will fail 88 | // while trying to getConnection (see method below). 89 | log.error(e); 90 | } 91 | } 92 | log.debug("Max Pool Size for each DataSource should be >= Threads"); 93 | } 94 | 95 | public static Connection getConnection(String datasourceName) throws SQLException, NoSuchElementException { 96 | if (!DATASOURCES_MAP.containsKey(datasourceName)) { 97 | throw new NoSuchElementException("Datasource '" + datasourceName + "' is probably misconfigured!"); 98 | } 99 | return DATASOURCES_MAP.get(datasourceName).getConnection(); 100 | } 101 | 102 | public static void closeConnection(Connection connection) { 103 | if (connection != null) { 104 | try { 105 | connection.close(); 106 | } catch (SQLException e) { 107 | log.warn(e); 108 | } 109 | } 110 | } 111 | 112 | public static void closeAllConnections() { 113 | log.info("Releasing connections ..."); 114 | Iterator it = DATASOURCES_MAP.values().iterator(); 115 | while (it.hasNext()) { 116 | it.next().close(); 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/utils/Printer.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.utils; 24 | 25 | import java.util.List; 26 | 27 | import org.apache.log4j.ConsoleAppender; 28 | import org.apache.log4j.Level; 29 | import org.apache.log4j.Logger; 30 | import org.apache.log4j.PatternLayout; 31 | import org.apache.log4j.spi.Filter; 32 | import org.apache.log4j.spi.LoggingEvent; 33 | import org.nocrala.tools.texttablefmt.BorderStyle; 34 | import org.nocrala.tools.texttablefmt.CellStyle; 35 | import org.nocrala.tools.texttablefmt.ShownBorders; 36 | import org.nocrala.tools.texttablefmt.Table; 37 | import org.testng.Reporter; 38 | 39 | import uk.co.objectivity.test.db.beans.TestResults; 40 | import uk.co.objectivity.test.db.beans.xml.CmpSqlResultsConfig; 41 | 42 | 43 | public class Printer { 44 | 45 | private final static Logger log = Logger.getLogger(Printer.class); 46 | 47 | public static void init(CmpSqlResultsConfig cmpSqlResultsConfig) { 48 | log.debug("Initializing logger / printer ..."); 49 | ConsoleAppender consoleAppender = (ConsoleAppender) Logger.getRootLogger().getAppender("stdout"); 50 | if (cmpSqlResultsConfig.getLogger() != null && cmpSqlResultsConfig.getLogger().getLogLevel() != 51 | null && !cmpSqlResultsConfig.getLogger().getLogLevel().isEmpty()) { 52 | Logger.getRootLogger().setLevel(Level.toLevel(cmpSqlResultsConfig.getLogger().getLogLevel())); 53 | } 54 | if (cmpSqlResultsConfig.getLogger().isTeamcityLogsEnabled()) { 55 | consoleAppender.setLayout(new PatternLayout("%m%n")); 56 | } 57 | consoleAppender.addFilter(new Filter() { 58 | @Override 59 | public int decide(LoggingEvent loggingEvent) { 60 | if(loggingEvent.getMessage() instanceof String == false) return ACCEPT; 61 | boolean isTCMsg = ((String) loggingEvent.getMessage()).contains(TCMessages.TC); 62 | // before threads (and buffering messages for TC) we allowed "common" logs 63 | // boolean isNotTCMsg = ((String) loggingEvent.getMessage()).contains(TCMessages.NOT_TC); 64 | if (cmpSqlResultsConfig.getLogger().isTeamcityLogsEnabled()) { 65 | return isTCMsg ? ACCEPT : DENY; 66 | // return isNotTCMsg ? DENY : ACCEPT; 67 | } else { 68 | return isTCMsg ? DENY : ACCEPT; 69 | } 70 | } 71 | }); 72 | } 73 | 74 | /** 75 | * Prints Text Table based on TestResults. Method uses library: 76 | * http://grepcode.com/snapshot/repo1.maven.org/maven2/org.ow2.sirocco/sirocco-text-table-formatter/1.0/ 77 | * 78 | * @param testResults 79 | */ 80 | public static String getTextTable(TestResults testResults) { 81 | if (testResults == null || testResults.getColumns() == null || testResults.getRows() == null || testResults.getColumns 82 | ().isEmpty() || testResults.getRows().isEmpty() || testResults.getNmbOfRows() == null || testResults 83 | .getRows().get(0).size() != testResults.getColumns().size()) { 84 | return "Incorrect TestResults. The table of differences can NOT be printed!"; 85 | } 86 | CellStyle cs = new CellStyle(CellStyle.HorizontalAlign.left, CellStyle.AbbreviationStyle.crop, 87 | CellStyle.NullStyle.emptyString); 88 | Table t = new Table(testResults.getColumns().size(), BorderStyle.DESIGN_TUBES, ShownBorders 89 | .SURROUND_HEADER_AND_COLUMNS, false, ""); 90 | for (String column : testResults.getColumns()) { 91 | t.addCell(column, cs); 92 | } 93 | for (List row : testResults.getRows()) { 94 | for (String rowVal : row) { 95 | t.addCell("'" + rowVal + "'", cs); 96 | } 97 | } 98 | String stringTable = "The table of differences (" + testResults.getRows().size() + " rows):\r\n" + t.render(); 99 | 100 | // printing to HTML report (testNG) -> generating HTML report is transparent in TestNG -> so is method call 101 | // below (we do not do this in test class itself) 102 | addReporterLog(stringTable); 103 | return stringTable; 104 | } 105 | 106 | 107 | /** 108 | * Printing to HTML report (testNG). Adds message to test-output (HTML tests report web-page created by 109 | * TestNG. This log will be visible in "Reporter output" section on web page. 110 | * 111 | * @param message 112 | */ 113 | public static void addReporterLog(String message) { 114 | Reporter.log(message.replaceAll("<", "<").replaceAll(">", ">").replaceAll("\\u0020", " ").replaceAll("(\r\n|\n)", "
") + "
"); 115 | } 116 | 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/utils/SavedTimes.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.utils; 24 | import java.util.concurrent.TimeUnit; 25 | 26 | public class SavedTimes { 27 | 28 | 29 | private String testName; 30 | private String measureType; 31 | private long startTime; 32 | private long stopTime; 33 | private long duration; 34 | private String formattedDuration; 35 | private String numberOfComparedRows="-"; 36 | 37 | public String getTestResult() { 38 | return testResult; 39 | } 40 | 41 | public void setTestResult(String testResult) { 42 | this.testResult = testResult; 43 | } 44 | 45 | private String testResult="Failed"; 46 | 47 | public long getDuration() { 48 | return duration; 49 | } 50 | 51 | public String getFormattedDuration() { 52 | return formattedDuration; 53 | } 54 | 55 | public String getTestName() { 56 | return testName; 57 | } 58 | 59 | public String getMeasureType() { 60 | return measureType; 61 | } 62 | public SavedTimes(String testName) 63 | { 64 | this.testName = testName; 65 | } 66 | 67 | public String getNumberOfComparedRows() { 68 | return numberOfComparedRows; 69 | } 70 | 71 | public void setNumberOfComparedRows(String numberOfComparedRows) 72 | { 73 | this.numberOfComparedRows = numberOfComparedRows; 74 | } 75 | 76 | public void setDuration(long loadTime) 77 | { 78 | this.duration = loadTime; 79 | this.formattedDuration = String.format("%02d:%02d:%03d min:s:ms \n", 80 | TimeUnit.MILLISECONDS.toMinutes(loadTime), 81 | TimeUnit.MILLISECONDS.toSeconds(loadTime) - 82 | TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(loadTime)) 83 | ,loadTime - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(loadTime))); 84 | } 85 | 86 | public void startMeasure(String measureType) 87 | { 88 | this.startTime = System.currentTimeMillis(); 89 | this.measureType=measureType; 90 | } 91 | 92 | public void stopMeasure() 93 | { 94 | this.stopTime = System.currentTimeMillis(); 95 | setDuration(this.stopTime - this.startTime); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/uk/co/objectivity/test/db/utils/TCMessages.java: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Objectivity Bespoke Software Specialists. All rights reserved. 3 | // 4 | // 5 | // The MIT License (MIT) 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | package uk.co.objectivity.test.db.utils; 24 | 25 | 26 | public class TCMessages { 27 | 28 | /** 29 | * Messages logged via log4j that contains the specified string will be filtered out from logs 30 | * "##notTeamcity" string will be removed from the message before it is displayed. 31 | */ 32 | // public static final String NOT_TC = "##notTeamcity"; 33 | 34 | static final String TC = "##teamcity"; 35 | 36 | private StringBuffer msgBuffer; 37 | private String testName; 38 | 39 | public TCMessages(String testName) { 40 | this(testName, false); 41 | } 42 | 43 | public TCMessages(String testName, boolean appendStarted) { 44 | msgBuffer = new StringBuffer(); 45 | this.testName = testName; 46 | if (appendStarted) { 47 | appendStarted(); 48 | } 49 | } 50 | 51 | public void appendStarted() { 52 | msgBuffer.append(TC).append("[testStarted name='").append(testName).append("' " + 53 | "captureStandardOutput='false']\r\n"); 54 | } 55 | 56 | public void appendFinished(long duration) { 57 | msgBuffer.append(TC).append("[testFinished name='").append(testName).append("' duration='").append(duration) 58 | .append("']\r\n"); 59 | } 60 | 61 | public void appendFailed(String failMsg) { 62 | this.appendFailed(failMsg, null); 63 | } 64 | 65 | public void appendFailed(String failMsg, String details) { 66 | msgBuffer.append(TC).append("[testFailed name='").append(testName).append("' message='").append( 67 | getTCFormattedMsg(failMsg)).append("'"); 68 | if (details != null && !details.isEmpty()) { 69 | msgBuffer.append(" details='").append(getTCFormattedMsg(details)).append("'"); 70 | } 71 | msgBuffer.append("]\r\n"); 72 | } 73 | 74 | public void appendIgnored(String ignoreMsg) { 75 | msgBuffer.append(TC).append("[testIgnored name='").append(testName).append("' message='").append( 76 | getTCFormattedMsg(ignoreMsg)).append("']\r\n"); 77 | } 78 | 79 | public void appendStdOut(String msg) { 80 | msgBuffer.append(TC).append("[testStdOut name='").append(testName).append("' out='").append( 81 | getTCFormattedMsg(msg)).append("']\r\n"); 82 | } 83 | 84 | public void appendStdErr(String msg) { 85 | msgBuffer.append(TC).append("[testStdErr name='").append(testName).append("' out='").append( 86 | getTCFormattedMsg(msg)).append("']\r\n"); 87 | } 88 | 89 | public String get() { 90 | return msgBuffer.toString(); 91 | } 92 | 93 | /** 94 | * Preparing message to be displayed in Teamcity comment (##teamcity). See: 95 | * https://confluence.jetbrains.com/display/TCD8/Build+Script+Interaction+with+TeamCity 96 | * 97 | * @param msg - message to format 98 | * @return message in TC format 99 | */ 100 | private static String getTCFormattedMsg(String msg) { 101 | if (msg == null) return ""; 102 | msg = msg.replace("|", "||"); 103 | msg = msg.replace("'", "|'"); 104 | msg = msg.replaceAll("\\n", "|n"); 105 | msg = msg.replaceAll("\\r", "|r"); 106 | msg = msg.replace("[", "|["); 107 | return msg.replace("]", "|]"); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j1.compatibility=true 3 | log4j.rootLogger=TRACE, stdout 4 | log4j.logger.org.nocrala.tools.texttablefmt=WARN 5 | log4j.logger.com.mchange=WARN 6 | # Direct log messages to stdout 7 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 8 | log4j.appender.stdout.Target=System.out 9 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 10 | #log4j.appender.stdout.layout=uk.co.objectivity.test.db.utils.CustomLogPattern 11 | log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d %c{1}%X{testName} - %m%n 12 | -------------------------------------------------------------------------------- /test-definitions/cmpSqlResults-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 11 | 12 | 14 | cube 15 | 16 | 17 | 18 | 5 19 | 20 | 21 | 0 22 | 23 | 24 | 26 | 27 | TERADATA_SERVER 28 | com.teradata.jdbc.TeraDriver 29 | jdbc:teradata://${TERADATADBSERVER}/DATABASE=${TERADATADBNAME},charset=UTF8 30 | ${USERNAME} 31 | ${PASSWORD} 32 | 33 | 34 | SQL_SERVER 35 | com.microsoft.sqlserver.jdbc.SQLServerDriver 36 | 37 | jdbc:sqlserver://${SQL_SERVER};databaseName=${SQL_SERVERDBNAME} 38 | ${SQL_SERVER_USERNAME} 39 | ${SQL_SERVER_PASSWORD} 40 | 41 | 42 | SQL_SERVER_WIN_AUTH 43 | com.microsoft.sqlserver.jdbc.SQLServerDriver 44 | 46 | jdbc:sqlserver://${SQL_SERVER};databaseName=master;integratedSecurity=true 47 | 48 | 49 | MySQL 50 | jdbc:mysql://${MYSQLDBSERVER}:${MYSQLDBPORT}/${MYSQLDBNAME} 51 | ${USERNAME} 52 | ${PASSWORD} 53 | 54 | 55 | MariaDB 56 | org.mariadb.jdbc.Driver 57 | jdbc:mariadb://${MYSQLDBSERVER}:${MYSQLDBPORT}/${MYSQLDBNAME} 58 | ${USERNAME} 59 | ${PASSWORD} 60 | 61 | 62 | PostgreSQL 63 | org.postgresql.Driver 64 | jdbc:postgresql://${POSTGRESSSQLDBSERVER}:5432/${POSTGRESSSQLDBNAME} 65 | ${USERNAME} 66 | ${PASSWORD} 67 | 68 | 69 | SNOWFLAKE_SERVER 70 | com.snowflake.client.jdbc.SnowflakeDriver 71 | jdbc:snowflake://${SNOWFLAKEDBSERVER}:${SNOWFLAKEDBSERVERPORT}/?db=${SNOWFLAKEDBNAME} 72 | ${USERNAME} 73 | ${PASSWORD} 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /test-definitions/compare_with_file/SQLExceptioncompare_with_file_SQL_Server.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test-definitions/compare_with_file/compare_with_file_SQL_Server.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test-definitions/compare_with_file/fileSource.csv: -------------------------------------------------------------------------------- 1 | "1","Accounting Manager","2002-06-01 00:00:00.0" 2 | "2","Assistant Sales Agent","2002-06-01 00:00:00.0" 3 | "3","Assistant Sales Representative","2002-06-01 00:00:00.0" 4 | "4","Coordinator Foreign Markets","2002-06-01 00:00:00.0" 5 | "5","Export Administrator","2002-06-01 00:00:00.0" 6 | "6","International Marketing Manager","2002-06-01 00:00:00.0" 7 | "7","Marketing Assistant","2002-06-01 00:00:00.0" 8 | "8","Marketing Manager","2002-06-01 00:00:00.0" 9 | "9","Marketing Representative","2002-06-01 00:00:00.0" 10 | "10","Order Administrator","2002-06-01 00:00:00.0" 11 | "11","Owner","2002-06-01 00:00:00.0" 12 | "12","Owner/Marketing Assistant","2002-06-01 00:00:00.0" 13 | "13","Product Manager","2002-06-01 00:00:00.0" 14 | "14","Purchasing Agent","2002-06-01 00:00:00.0" 15 | "15","Purchasing Manager","2002-06-01 00:00:00.0" 16 | "16","Regional Account Representative","2002-06-01 00:00:00.0" 17 | "17","Sales Agent","2002-06-01 00:00:00.0" 18 | "18","Sales Associate","2002-06-01 00:00:00.0" 19 | "19","Sales Manager","2002-06-01 00:00:00.0" 20 | "20","Sales Representative","2002-06-01 00:00:00.0" 21 | -------------------------------------------------------------------------------- /test-definitions/compare_with_file/sql1.sql: -------------------------------------------------------------------------------- 1 | SELECT [ContactTypeID] 2 | ,[Name] 3 | ,[ModifiedDate] 4 | FROM [AdventureWorks2008R2].[Person].[ContactType] 5 | ORDER BY [ContactTypeID]; -------------------------------------------------------------------------------- /test-definitions/compare_with_file/sql2Exception.sql: -------------------------------------------------------------------------------- 1 | SELECT [ContactTypeID] 2 | ,[Name] 3 | ,[ModifiedDate] 4 | FROM [AdventureWorks2008R2].[Person].[ContactType] 5 | ORDER BY [ContactTypeID]; 6 | --query raise SQL Exception -------------------------------------------------------------------------------- /test-definitions/compare_with_file_stucture/compare_with_db_structure_SQLServer.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test-definitions/compare_with_file_stucture/compare_with_db_structure_SQLServerFileWithHeader.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test-definitions/cube/test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test-definitions/delta/floating_point/ActualTable.sql: -------------------------------------------------------------------------------- 1 | SELECT SalesOrderID 2 | ,SalesOrderDetailID 3 | ,CarrierTrackingNumber 4 | ,OrderQty 5 | ,ProductID 6 | ,SpecialOfferID 7 | ,UnitPrice 8 | ,UnitPriceDiscount 9 | ,LineTotal 10 | ,rowguid 11 | ,ModifiedDate 12 | FROM AdventureWorks2008R2.Sales.SalesOrderDetail 13 | order by SalesOrderID; -------------------------------------------------------------------------------- /test-definitions/delta/floating_point/ExpectedTable.sql: -------------------------------------------------------------------------------- 1 | SELECT SalesOrderID 2 | ,SalesOrderDetailID 3 | ,CarrierTrackingNumber 4 | ,OrderQty 5 | ,ProductID 6 | ,SpecialOfferID 7 | ,UnitPrice 8 | ,UnitPriceDiscount 9 | ,LineTotal 10 | ,rowguid 11 | ,ModifiedDate 12 | FROM AdventureWorks2008R2.Sales.SalesOrderDetail 13 | order by SalesOrderID; -------------------------------------------------------------------------------- /test-definitions/delta/floating_point/SalesOrderDetail_SQL_SERVER.xml: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test-definitions/fetch_compare_test/Exception_inline_sql_SQL_SERVER_PostgreSQL_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 39 | 40 | 41 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /test-definitions/fetch_compare_test/from_file_sql_MySQL_PostgreSQL_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test-definitions/fetch_compare_test/inline_sql_SQL_SERVER_PostgreSQL.xml: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 38 | 39 | 40 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /test-definitions/fetch_compare_test/sql1.sql: -------------------------------------------------------------------------------- 1 | SELECT personaddress.AddressID, 2 | personaddress.AddressLine1, 3 | personaddress.City, 4 | personaddress.StateProvinceID, 5 | personaddress.PostalCode, 6 | personaddress.ModifiedDate 7 | FROM dbquality.personaddress; -------------------------------------------------------------------------------- /test-definitions/fetch_compare_test/sql2.sql: -------------------------------------------------------------------------------- 1 | select addressid, 2 | addressline1, 3 | city, 4 | stateprovinceid, 5 | postalcode, 6 | modifieddate 7 | from public.personaddress 8 | order by addressid; -------------------------------------------------------------------------------- /test-definitions/key_comparator/ContactType/ContactType.csv: -------------------------------------------------------------------------------- 1 | ThreadNumber;ContactTypeID;Name;ModifiedDate;Ignore 2 | AAA1;001;Accounting Manager;2002-06-01 00:00:00.000;50 3 | BBB1;0003;Assistant Sales Representative;2002-06-01 00:00:00.0;0 -------------------------------------------------------------------------------- /test-definitions/key_comparator/ContactType/ContactTypeActualTable.sql: -------------------------------------------------------------------------------- 1 | SELECT [ContactTypeID] 2 | ,ids.[Name] 3 | ,[ModifiedDate] 4 | FROM [AdventureWorks2008R2].[Person].[ContactType] ids 5 | --join to template table 6 | JOIN AdventureWorks2008R2.dbo.TemplateKeyComparatorContactType tcc 7 | ON tcc.[Name] = ids.[Name] COLLATE Polish_CI_AS -------------------------------------------------------------------------------- /test-definitions/key_comparator/ContactType/KeyContactType_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | REMOVE_LEADING_ZEROS 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test-definitions/key_comparator/Product/Product.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | REMOVE_LEADING_ZEROS 12 | 13 | 14 | NOT_EQUALS 15 | DATE 16 | SUM_INTEGERS 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test-definitions/key_comparator/Product/create.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[TemplateKeyComparatorProducts]( 2 | [StoreNumber] [int] NOT NULL, 3 | [ProductID] [int] NULL, 4 | [Date] [date] NOT NULL, 5 | [Quantity] [int] NOT NULL) 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test-definitions/key_comparator/Product/drop.sql: -------------------------------------------------------------------------------- 1 | drop table [dbo].[TemplateKeyComparatorProducts] -------------------------------------------------------------------------------- /test-definitions/key_comparator/Product/insert.sql: -------------------------------------------------------------------------------- 1 | 2 | INSERT INTO [dbo].[TemplateKeyComparatorProducts] 3 | ([StoreNumber] 4 | ,[ProductID] 5 | ,[Date] 6 | ,[Quantity]) 7 | VALUES 8 | (11,123 ,'2020-09-09',300), 9 | (12,124 ,'2020-09-10',400), 10 | (13,123 ,'2020-09-09',300), 11 | (14,123 ,'2020-09-09',300), 12 | (11,124 ,'2020-09-09',300), 13 | (12,123 ,'2020-09-09',300), 14 | (14,123 ,'2020-09-09',300), 15 | (15,123 ,'2020-09-09',300), 16 | (15,125 ,'2020-09-09',300) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test-definitions/key_comparator/Product/product.csv: -------------------------------------------------------------------------------- 1 | TestSet;Store;Product;Date;Qty 2 | 1;11;00123;2020-09-08;100 3 | 1;11;00123;2020-09-09;200 4 | 2;12;00124;2020-09-08;200 5 | 2;12;00124;2020-09-10;200 -------------------------------------------------------------------------------- /test-definitions/key_comparator/Product/product.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | pr.[StoreNumber] 3 | ,pr.ProductID 4 | ,pr.[Date] 5 | ,pr.[Quantity] 6 | FROM [dbo].[TemplateKeyComparatorProducts] pr 7 | inner join AdventureWorks2008R2.dbo.TemplateKeyComparatorCheckAggregators d 8 | on d.[StoreNumber]=pr.[StoreNumber] and d.ProductID=pr.ProductID -------------------------------------------------------------------------------- /test-definitions/minus_file_output/union_compare_failure_count_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /test-definitions/minus_file_output/union_compare_failure_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /test-definitions/minus_many_xml_files/ExceptionPersonAddress_SQL_SERVER_first_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 14 | --query raise SQL Exception 15 | ]]> 16 | 17 | 18 | 2 28 | ]]> 29 | 30 | 31 | -------------------------------------------------------------------------------- /test-definitions/minus_many_xml_files/PersonAddress_PostgreSQL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-definitions/minus_many_xml_files/PersonAddress_SQL_SERVER_diffTableSize_0_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 1 16 | ]]> 17 | 18 | 19 | 2 29 | ]]> 30 | 31 | 32 | -------------------------------------------------------------------------------- /test-definitions/minus_many_xml_files/PersonAddress_SQL_SERVER_first_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 14 | ]]> 15 | 16 | 17 | 2 27 | ]]> 28 | 29 | 30 | -------------------------------------------------------------------------------- /test-definitions/minus_many_xml_files/PersonAddress_SQL_SERVER_second.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test-definitions/minus_on_union/SQL_SERVER_union_noIndicator_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 14 | UNION ALL 15 | SELECT [AddressID] 16 | ,[AddressLine1] 17 | ,[AddressLine2] 18 | ,[City] 19 | ,[StateProvinceID] 20 | ,[PostalCode] 21 | ,[ModifiedDate] 22 | FROM [AdventureWorks2008R2].[Person].[Address] 23 | where AddressID <> 1) 24 | ]]> 25 | 26 | 27 | 2 37 | UNION ALL 38 | SELECT [AddressID] 39 | ,[AddressLine1] 40 | ,[AddressLine2] 41 | ,[City] 42 | ,[StateProvinceID] 43 | ,[PostalCode] 44 | ,[ModifiedDate] 45 | FROM [AdventureWorks2008R2].[Person].[Address] 46 | where AddressID <> 2) 47 | ]]> 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test-definitions/minus_on_union/SQL_SERVER_union_noIndicator_SUCCESS.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 14 | UNION ALL 15 | SELECT [AddressID] 16 | ,[AddressLine1] 17 | ,[AddressLine2] 18 | ,[City] 19 | ,[StateProvinceID] 20 | ,[PostalCode] 21 | ,[ModifiedDate] 22 | FROM [AdventureWorks2008R2].[Person].[Address] 23 | where AddressID <> 2) 24 | ]]> 25 | 26 | 27 | 1 37 | UNION ALL 38 | SELECT [AddressID] 39 | ,[AddressLine1] 40 | ,[AddressLine2] 41 | ,[City] 42 | ,[StateProvinceID] 43 | ,[PostalCode] 44 | ,[ModifiedDate] 45 | FROM [AdventureWorks2008R2].[Person].[Address] 46 | where AddressID <> 2) 47 | ]]> 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test-definitions/minus_on_union/SQL_SERVER_union_withIndicator_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 14 | UNION ALL 15 | SELECT [AddressID] 16 | ,[AddressLine1] 17 | ,[AddressLine2] 18 | ,[City] 19 | ,[StateProvinceID] 20 | ,[PostalCode] 21 | ,[ModifiedDate] 22 | FROM [AdventureWorks2008R2].[Person].[Address] 23 | where AddressID <> 1) 24 | ]]> 25 | 26 | 27 | 2 37 | UNION ALL 38 | SELECT [AddressID] 39 | ,[AddressLine1] 40 | ,[AddressLine2] 41 | ,[City] 42 | ,[StateProvinceID] 43 | ,[PostalCode] 44 | ,[ModifiedDate] 45 | FROM [AdventureWorks2008R2].[Person].[Address] 46 | where AddressID <> 2) 47 | ]]> 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test-definitions/minus_on_union/SQL_SERVER_union_withIndicator_SUCCESS.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 14 | UNION ALL 15 | SELECT [AddressID] 16 | ,[AddressLine1] 17 | ,[AddressLine2] 18 | ,[City] 19 | ,[StateProvinceID] 20 | ,[PostalCode] 21 | ,[ModifiedDate] 22 | FROM [AdventureWorks2008R2].[Person].[Address] 23 | where AddressID <> 2) 24 | ]]> 25 | 26 | 27 | 1 37 | UNION ALL 38 | SELECT [AddressID] 39 | ,[AddressLine1] 40 | ,[AddressLine2] 41 | ,[City] 42 | ,[StateProvinceID] 43 | ,[PostalCode] 44 | ,[ModifiedDate] 45 | FROM [AdventureWorks2008R2].[Person].[Address] 46 | where AddressID <> 2) 47 | ]]> 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test-definitions/multilevel_tests/Two/Three/not_from_files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-definitions/multilevel_tests/Two/lvl_two_not_from_files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-definitions/multilevel_tests/union_compare_failure_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-definitions/nmb_of_results/Exception_assert_equal_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 20 | 1 21 | 0 22 | 2 23 | 1 24 | 1 25 | 0 26 | 27 | -------------------------------------------------------------------------------- /test-definitions/nmb_of_results/assert_equal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 19 | 1 20 | 0 21 | 2 22 | 1 23 | 1 24 | 0 25 | 26 | -------------------------------------------------------------------------------- /test-definitions/sql-from-file/from_files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test-definitions/sql-from-file/misconfigured_FAIL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-definitions/sql-from-file/mixed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /test-definitions/sql-from-file/not_from_files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-definitions/sql-from-file/sql1.sql: -------------------------------------------------------------------------------- 1 | select addressid, addressline1, addressline2, city, stateprovinceid, postalcode, modifieddate 2 | from public.personaddress -------------------------------------------------------------------------------- /test-definitions/sql-from-file/sql2.sql: -------------------------------------------------------------------------------- 1 | select addressid, addressline1, addressline2, city, stateprovinceid, postalcode, modifieddate 2 | from public.personaddress --------------------------------------------------------------------------------