From b91bae30b1a4704ff1b03a784ab303e8048135ad Mon Sep 17 00:00:00 2001 From: Marios Trivyzas Date: Fri, 22 May 2020 17:49:36 +0200 Subject: [PATCH] SQL: [Tests] Move JDBC integration tests to new module (#56872) (#57072) Move the JDBC functionality integration tests from `:sql:qa` to a separate module `:sql:qa:jdbc`. This way the tests are isolated from the rest of the integration tests and they only depend to the `:sql:jdbc` module, thus removing the danger of accidentally pulling in some dependency that may hide bugs. Moreover this is a preparation for #56722, so that we can run those tests between different JDBC and ES node versions and ensure forward compatibility. Move the rest of existing tests inside a new `:sql:qa:server` project, so that the `:sql:qa` becomes the parent project for both and one can run all the integration tests by using this parent project. (cherry picked from commit c09f4a04484b8a43934fe58fbc41bd90b7dbcc76) --- docs/reference/sql/index.asciidoc | 11 +- docs/reference/sql/security.asciidoc | 2 +- x-pack/plugin/sql/qa/build.gradle | 127 -- x-pack/plugin/sql/qa/jdbc/build.gradle | 61 + .../sql/qa/jdbc/multi-node/build.gradle | 7 + .../qa/jdbc/multi_node}/JdbcConnectionIT.java | 5 +- .../qa/jdbc/multi_node}/JdbcFetchSizeIT.java | 5 +- .../qa/jdbc/multi_node/JdbcJdbcErrorsIT.java | 10 + .../multi_node/JdbcPreparedStatementIT.java | 5 +- x-pack/plugin/sql/qa/jdbc/no-sql/build.gradle | 4 + .../sql/qa/jdbc}/no_sql/JdbcNoSqlIT.java | 6 +- .../plugin/sql/qa/jdbc/security/build.gradle | 61 + .../sql/qa/{ => jdbc}/security/roles.yml | 0 .../qa/jdbc/security/JdbcConnectionIT.java | 61 + .../qa/jdbc}/security/JdbcFetchSizeIT.java | 9 +- .../qa/jdbc/security/JdbcJdbcErrorsIT.java} | 13 +- .../security/JdbcPreparedStatementIT.java | 9 +- .../qa/jdbc/security/JdbcSecurityUtils.java | 52 + .../jdbc}/security/JdbcSimpleExampleIT.java | 9 +- .../src/test/resources/plugin-security.policy | 0 .../qa/jdbc/security/with-ssl/build.gradle | 340 ++++ .../qa/jdbc/security/without-ssl/build.gradle | 7 + .../sql/qa/jdbc/single-node/build.gradle | 4 + .../qa/jdbc/single_node/JdbcConnectionIT.java | 10 + .../qa/jdbc/single_node/JdbcFetchSizeIT.java} | 7 +- .../qa/jdbc/single_node/JdbcJdbcErrorsIT.java | 10 + .../single_node/JdbcPreparedStatementIT.java | 5 +- .../qa/jdbc/single_node/JdbcResultSetIT.java | 11 + .../single_node/JdbcResultSetMetaDataIT.java | 6 +- .../jdbc/single_node/JdbcShardFailureIT.java | 52 + .../single_node/JdbcSimpleExampleIT.java | 5 +- .../xpack/sql/qa/jdbc/ConnectionTestCase.java | 5 +- .../xpack/sql/qa/jdbc/FetchSizeTestCase.java | 94 +- .../sql/qa/jdbc/JdbcErrorsTestCase.java} | 76 +- .../sql/qa/jdbc/JdbcIntegrationTestCase.java | 177 ++ .../xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java | 2 +- .../xpack/sql/qa/jdbc/JdbcTestUtils.java | 60 + .../qa/jdbc/PreparedStatementTestCase.java | 53 +- .../qa/jdbc/ResultSetMetaDataTestCase.java | 45 +- .../xpack/sql/qa/jdbc/ResultSetTestCase.java | 1446 +++++++++-------- .../sql/qa/jdbc/SimpleExampleTestCase.java | 12 +- .../xpack/sql/qa/jdbc/package-info.java | 2 +- .../src/main/resources/plugin-security.policy | 0 .../xpack/sql/qa/security/JdbcErrorsIT.java | 30 - x-pack/plugin/sql/qa/server/build.gradle | 115 ++ .../qa/{ => server}/multi-node/build.gradle | 0 .../xpack/sql/qa/multi_node/CliSelectIT.java | 3 +- .../xpack/sql/qa/multi_node/CliShowIT.java | 3 +- .../sql/qa/multi_node/CustomDateFormatIT.java | 0 .../sql/qa/multi_node/GeoJdbcCsvSpecIT.java | 0 .../sql/qa/multi_node/GeoJdbcSqlSpecIT.java | 0 .../qa/multi_node/JdbcDatabaseMetaDataIT.java | 3 +- .../sql/qa/multi_node/JdbcShowTablesIT.java | 3 +- .../xpack/sql/qa/multi_node/RestSqlIT.java | 3 +- .../sql/qa/multi_node/RestSqlMultinodeIT.java | 5 +- .../sql/qa/multi_node/SqlProtocolIT.java | 3 +- .../sql/qa/{ => server}/security/build.gradle | 2 - .../plugin/sql/qa/server/security/roles.yml | 91 ++ .../xpack/sql/qa/security/CliErrorsIT.java | 0 .../xpack/sql/qa/security/CliFetchSizeIT.java | 0 .../xpack/sql/qa/security/CliSecurityIT.java | 10 +- .../xpack/sql/qa/security/CliSelectIT.java | 0 .../xpack/sql/qa/security/CliShowIT.java | 0 .../xpack/sql/qa/security/JdbcCsvSpecIT.java | 0 .../qa/security/JdbcDatabaseMetaDataIT.java | 0 .../xpack/sql/qa/security/JdbcSecurityIT.java | 88 +- .../sql/qa/security/JdbcShowTablesIT.java | 0 .../xpack/sql/qa/security/JdbcSqlSpecIT.java | 0 .../xpack/sql/qa/security/RestSqlIT.java | 6 +- .../sql/qa/security/RestSqlSecurityIT.java | 112 +- .../sql/qa/security/SqlSecurityTestCase.java | 203 +-- .../xpack/sql/qa/security/UserFunctionIT.java | 74 +- .../src/test/resources/plugin-security.policy | 9 + .../security/with-ssl/build.gradle | 0 .../security/without-ssl/build.gradle | 0 .../single-node}/build.gradle | 0 .../xpack/sql/qa/single_node/CliErrorsIT.java | 3 +- .../sql/qa/single_node/CliExplainIT.java | 9 +- .../sql/qa/single_node/CliFetchSizeIT.java | 3 +- .../xpack/sql/qa/single_node/CliSelectIT.java | 3 +- .../xpack/sql/qa/single_node/CliShowIT.java | 3 +- .../qa/single_node/CustomDateFormatIT.java | 0 .../sql/qa/single_node/FieldExtractorIT.java | 0 .../sql/qa/single_node/GeoJdbcCsvSpecIT.java | 0 .../sql/qa/single_node/GeoJdbcSqlSpecIT.java | 0 .../sql/qa/single_node/JdbcCsvSpecIT.java | 2 +- .../single_node/JdbcDatabaseMetaDataIT.java | 3 +- .../sql/qa/single_node/JdbcDocCsvSpecIT.java | 8 +- .../qa/single_node/JdbcFrozenCsvSpecIT.java | 1 - .../qa/single_node/JdbcShardFailureIT.java | 4 +- .../sql/qa/single_node/JdbcShowTablesIT.java | 3 +- .../sql/qa/single_node/JdbcSqlSpecIT.java | 2 +- .../xpack/sql/qa/single_node/RestSqlIT.java | 50 +- .../sql/qa/single_node/RestSqlUsageIT.java | 3 +- .../sql/qa/single_node/SqlProtocolIT.java | 3 +- .../sql/qa/single_node/SysColumnsIT.java | 0 .../sql/qa/CustomDateFormatTestCase.java | 47 +- .../xpack/sql/qa/ErrorsTestCase.java | 12 + .../xpack/sql/qa/FeatureMetric.java | 0 .../xpack/sql/qa/FieldExtractorTestCase.java | 315 ++-- .../xpack/sql/qa/SqlProtocolTestCase.java | 199 ++- .../sql/qa/cli/CliIntegrationTestCase.java | 0 .../xpack/sql/qa/cli/EmbeddedCli.java | 29 +- .../xpack/sql/qa/cli/ErrorsTestCase.java | 14 +- .../xpack/sql/qa/cli/FetchSizeTestCase.java | 18 +- .../xpack/sql/qa/cli/SelectTestCase.java | 1 + .../xpack/sql/qa/cli/ShowTestCase.java | 0 .../xpack/sql/qa/cli/package-info.java | 2 +- .../xpack/sql/qa/geo/GeoCsvSpecTestCase.java | 4 +- .../xpack/sql/qa/geo/GeoDataLoader.java | 5 +- .../xpack/sql/qa/geo/GeoSqlSpecTestCase.java | 17 +- .../xpack/sql/qa/jdbc/CsvSpecTestCase.java | 0 .../xpack/sql/qa/jdbc/CsvTestUtils.java | 16 +- .../xpack/sql/qa/jdbc/DataLoader.java | 18 +- .../sql/qa/jdbc/DatabaseMetaDataTestCase.java | 72 +- .../xpack/sql/qa/jdbc/DebugSqlSpec.java | 0 .../xpack/sql/qa/jdbc/JdbcAssert.java | 77 +- .../sql/qa/jdbc/JdbcIntegrationTestCase.java | 63 +- .../xpack/sql/qa/jdbc/JdbcTestUtils.java | 50 +- .../xpack/sql/qa/jdbc/LocalH2.java | 0 .../xpack/sql/qa/jdbc/ShowTablesTestCase.java | 6 +- .../qa/jdbc/SpecBaseIntegrationTestCase.java | 11 +- .../xpack/sql/qa/jdbc/SqlSpecTestCase.java | 24 +- .../xpack/sql/qa/jdbc/SysColumnsTestCase.java | 429 +++-- .../xpack/sql/qa/jdbc/package-info.java | 11 + .../sql/qa/rest/BaseRestSqlTestCase.java | 4 +- .../xpack/sql/qa/rest/RestSqlTestCase.java | 468 +++--- .../sql/qa/rest/RestSqlUsageTestCase.java | 130 +- .../xpack/sql/qa/rest/package-info.java | 2 +- .../src/main/resources/agg-ordering.csv-spec | 0 .../src/main/resources/agg-ordering.sql-spec | 0 .../src/main/resources/agg.csv-spec | 0 .../src/main/resources/agg.sql-spec | 0 .../src/main/resources/alias.csv-spec | 0 .../src/main/resources/arithmetic.csv-spec | 0 .../src/main/resources/arithmetic.sql-spec | 0 .../main/resources/case-functions.sql-spec | 0 .../src/main/resources/columns.csv-spec | 0 .../src/main/resources/command.csv-spec | 0 .../src/main/resources/conditionals.csv-spec | 0 .../main/resources/constant-keyword.csv-spec | 0 .../src/main/resources/date.csv-spec | 0 .../main/resources/datetime-interval.csv-spec | 0 .../src/main/resources/datetime.csv-spec | 0 .../src/main/resources/datetime.sql-spec | 0 .../src/main/resources/debug/debug.csv-spec | 0 .../src/main/resources/debug/debug.sql-spec | 0 .../src/main/resources/dep_emp.csv | 0 .../src/main/resources/departments.csv | 0 .../src/main/resources/docs/docs.csv-spec | 0 .../src/main/resources/docs/geo.csv-spec | 0 .../src/main/resources/employees.csv | 0 .../main/resources/examples/example.csv-spec | 0 .../main/resources/examples/example.sql-spec | 0 .../src/main/resources/field-alias.csv-spec | 0 .../src/main/resources/filter.csv-spec | 0 .../src/main/resources/filter.sql-spec | 0 .../src/main/resources/fulltext.csv-spec | 0 .../src/main/resources/functions.csv-spec | 0 .../src/main/resources/geo/geo.csv | 0 .../src/main/resources/geo/geosql-bulk.json | 0 .../src/main/resources/geo/geosql.csv-spec | 0 .../src/main/resources/geo/geosql.json | 0 .../src/main/resources/geo/geosql.sql-spec | 0 .../src/main/resources/geo/setup_test_geo.sql | 20 +- .../src/main/resources/ip.csv-spec | 0 .../src/main/resources/library.csv | 0 .../{ => server}/src/main/resources/logs.csv | 0 .../src/main/resources/math.csv-spec | 0 .../src/main/resources/math.sql-spec | 0 .../src/main/resources/nested.csv-spec | 0 .../src/main/resources/null.csv-spec | 0 .../src/main/resources/null.sql-spec | 0 .../src/main/resources/ogc/OGC-NOTICE.txt | 0 .../src/main/resources/ogc/ogc.csv-spec | 0 .../src/main/resources/ogc/ogc.json | 0 .../src/main/resources/ogc/ogc.sql-spec | 0 .../src/main/resources/ogc/sqltsch.sql | 1342 +++++++-------- .../src/main/resources/pivot.csv-spec | 0 .../src/main/resources/plugin-security.policy | 4 + .../src/main/resources/select.csv-spec | 0 .../src/main/resources/select.sql-spec | 0 .../setup_mock_metadata_get_columns.sql | 0 .../setup_mock_metadata_get_columns_empty.sql | 0 ...up_mock_metadata_get_procedure_columns.sql | 0 .../setup_mock_metadata_get_procedures.sql | 0 .../setup_mock_metadata_get_table_types.sql | 0 .../setup_mock_metadata_get_tables.sql | 0 .../setup_mock_metadata_get_tables_empty.sql | 0 ...setup_mock_metadata_get_types_of_table.sql | 0 .../main/resources/setup_mock_show_tables.sql | 0 .../src/main/resources/setup_test_emp.sql | 0 .../single-node-only/command-sys-geo.csv-spec | 0 .../single-node-only/command-sys.csv-spec | 0 .../src/main/resources/slow/frozen.csv-spec | 0 .../src/main/resources/slow/readme.txt | 0 .../main/resources/string-functions.sql-spec | 0 .../src/main/resources/subselect.sql-spec | 0 .../src/main/resources/time.csv-spec | 0 x-pack/plugin/sql/qa/single-node/build.gradle | 4 - .../sql/qa/single_node/JdbcErrorsIT.java | 11 - .../sql/qa/single_node/JdbcResultSetIT.java | 16 - 202 files changed, 4332 insertions(+), 2858 deletions(-) create mode 100644 x-pack/plugin/sql/qa/jdbc/build.gradle create mode 100644 x-pack/plugin/sql/qa/jdbc/multi-node/build.gradle rename x-pack/plugin/sql/qa/{single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node => jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node}/JdbcConnectionIT.java (72%) rename x-pack/plugin/sql/qa/{single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node => jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node}/JdbcFetchSizeIT.java (72%) create mode 100644 x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcJdbcErrorsIT.java rename x-pack/plugin/sql/qa/{multi-node/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/multi_node/JdbcPreparedStatementIT.java (85%) create mode 100644 x-pack/plugin/sql/qa/jdbc/no-sql/build.gradle rename x-pack/plugin/sql/qa/{no-sql/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/no-sql/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/no_sql/JdbcNoSqlIT.java (74%) create mode 100644 x-pack/plugin/sql/qa/jdbc/security/build.gradle rename x-pack/plugin/sql/qa/{ => jdbc}/security/roles.yml (100%) create mode 100644 x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcConnectionIT.java rename x-pack/plugin/sql/qa/{security/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/security/JdbcFetchSizeIT.java (75%) rename x-pack/plugin/sql/qa/{security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcConnectionIT.java => jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcJdbcErrorsIT.java} (63%) rename x-pack/plugin/sql/qa/{security/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/security/JdbcPreparedStatementIT.java (76%) create mode 100644 x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcSecurityUtils.java rename x-pack/plugin/sql/qa/{security/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/security/JdbcSimpleExampleIT.java (75%) rename x-pack/plugin/sql/qa/{ => jdbc}/security/src/test/resources/plugin-security.policy (100%) create mode 100644 x-pack/plugin/sql/qa/jdbc/security/with-ssl/build.gradle create mode 100644 x-pack/plugin/sql/qa/jdbc/security/without-ssl/build.gradle create mode 100644 x-pack/plugin/sql/qa/jdbc/single-node/build.gradle create mode 100644 x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcConnectionIT.java rename x-pack/plugin/sql/qa/{multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcErrorsIT.java => jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcFetchSizeIT.java} (57%) create mode 100644 x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcJdbcErrorsIT.java rename x-pack/plugin/sql/qa/{single-node/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/single_node/JdbcPreparedStatementIT.java (84%) create mode 100644 x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcResultSetIT.java rename x-pack/plugin/sql/qa/{single-node/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/single_node/JdbcResultSetMetaDataIT.java (84%) create mode 100644 x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcShardFailureIT.java rename x-pack/plugin/sql/qa/{single-node/src/test/java/org/elasticsearch/xpack/sql/qa => jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc}/single_node/JdbcSimpleExampleIT.java (86%) rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ConnectionTestCase.java (96%) rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java (79%) rename x-pack/plugin/sql/qa/{src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ErrorsTestCase.java => jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcErrorsTestCase.java} (66%) create mode 100644 x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java (91%) create mode 100644 x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/PreparedStatementTestCase.java (90%) rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetMetaDataTestCase.java (58%) rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetTestCase.java (65%) rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SimpleExampleTestCase.java (81%) rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java (85%) rename x-pack/plugin/sql/qa/{ => jdbc}/src/main/resources/plugin-security.policy (100%) delete mode 100644 x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcErrorsIT.java create mode 100644 x-pack/plugin/sql/qa/server/build.gradle rename x-pack/plugin/sql/qa/{ => server}/multi-node/build.gradle (100%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliSelectIT.java (87%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliShowIT.java (87%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CustomDateFormatIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcCsvSpecIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcSqlSpecIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcDatabaseMetaDataIT.java (97%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcShowTablesIT.java (85%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlIT.java (90%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlMultinodeIT.java (98%) rename x-pack/plugin/sql/qa/{ => server}/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/SqlProtocolIT.java (85%) rename x-pack/plugin/sql/qa/{ => server}/security/build.gradle (97%) create mode 100644 x-pack/plugin/sql/qa/server/security/roles.yml rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliErrorsIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliFetchSizeIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSecurityIT.java (96%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSelectIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliShowIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcCsvSpecIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcDatabaseMetaDataIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSecurityIT.java (84%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcShowTablesIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSqlSpecIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlIT.java (91%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlSecurityIT.java (78%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java (82%) rename x-pack/plugin/sql/qa/{ => server}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/UserFunctionIT.java (82%) create mode 100644 x-pack/plugin/sql/qa/server/security/src/test/resources/plugin-security.policy rename x-pack/plugin/sql/qa/{ => server}/security/with-ssl/build.gradle (100%) rename x-pack/plugin/sql/qa/{ => server}/security/without-ssl/build.gradle (100%) rename x-pack/plugin/sql/qa/{no-sql => server/single-node}/build.gradle (100%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliErrorsIT.java (87%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliExplainIT.java (97%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliFetchSizeIT.java (86%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliSelectIT.java (87%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliShowIT.java (88%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CustomDateFormatIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/FieldExtractorIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcCsvSpecIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcSqlSpecIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcCsvSpecIT.java (97%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDatabaseMetaDataIT.java (97%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDocCsvSpecIT.java (98%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFrozenCsvSpecIT.java (99%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShardFailureIT.java (93%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShowTablesIT.java (85%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSqlSpecIT.java (99%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java (52%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlUsageIT.java (85%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SqlProtocolIT.java (85%) rename x-pack/plugin/sql/qa/{ => server}/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SysColumnsIT.java (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/CustomDateFormatTestCase.java (77%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/ErrorsTestCase.java (99%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/FeatureMetric.java (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/FieldExtractorTestCase.java (87%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/SqlProtocolTestCase.java (72%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/cli/CliIntegrationTestCase.java (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/cli/EmbeddedCli.java (96%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ErrorsTestCase.java (93%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/cli/FetchSizeTestCase.java (86%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/cli/SelectTestCase.java (99%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ShowTestCase.java (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/cli/package-info.java (85%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java (96%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoDataLoader.java (97%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoSqlSpecTestCase.java (85%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvSpecTestCase.java (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvTestUtils.java (95%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DataLoader.java (97%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DatabaseMetaDataTestCase.java (72%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DebugSqlSpec.java (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java (87%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java (80%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java (85%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/LocalH2.java (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ShowTablesTestCase.java (92%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SpecBaseIntegrationTestCase.java (95%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SqlSpecTestCase.java (66%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SysColumnsTestCase.java (54%) create mode 100644 x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/rest/BaseRestSqlTestCase.java (98%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java (75%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlUsageTestCase.java (86%) rename x-pack/plugin/sql/qa/{ => server}/src/main/java/org/elasticsearch/xpack/sql/qa/rest/package-info.java (83%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/agg-ordering.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/agg-ordering.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/agg.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/agg.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/alias.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/arithmetic.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/arithmetic.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/case-functions.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/columns.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/command.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/conditionals.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/constant-keyword.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/date.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/datetime-interval.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/datetime.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/datetime.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/debug/debug.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/debug/debug.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/dep_emp.csv (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/departments.csv (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/docs/docs.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/docs/geo.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/employees.csv (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/examples/example.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/examples/example.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/field-alias.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/filter.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/filter.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/fulltext.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/functions.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/geo/geo.csv (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/geo/geosql-bulk.json (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/geo/geosql.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/geo/geosql.json (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/geo/geosql.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/geo/setup_test_geo.sql (97%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/ip.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/library.csv (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/logs.csv (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/math.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/math.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/nested.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/null.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/null.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/ogc/OGC-NOTICE.txt (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/ogc/ogc.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/ogc/ogc.json (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/ogc/ogc.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/ogc/sqltsch.sql (96%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/pivot.csv-spec (100%) create mode 100644 x-pack/plugin/sql/qa/server/src/main/resources/plugin-security.policy rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/select.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/select.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_columns.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_columns_empty.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_procedure_columns.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_procedures.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_table_types.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_tables.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_tables_empty.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_metadata_get_types_of_table.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_mock_show_tables.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/setup_test_emp.sql (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/single-node-only/command-sys-geo.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/single-node-only/command-sys.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/slow/frozen.csv-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/slow/readme.txt (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/string-functions.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/subselect.sql-spec (100%) rename x-pack/plugin/sql/qa/{ => server}/src/main/resources/time.csv-spec (100%) delete mode 100644 x-pack/plugin/sql/qa/single-node/build.gradle delete mode 100644 x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcErrorsIT.java delete mode 100644 x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcResultSetIT.java diff --git a/docs/reference/sql/index.asciidoc b/docs/reference/sql/index.asciidoc index 66aceeb6244..8c9d2620c70 100644 --- a/docs/reference/sql/index.asciidoc +++ b/docs/reference/sql/index.asciidoc @@ -3,10 +3,11 @@ [[xpack-sql]] = SQL access -:sql-tests: {xes-repo-dir}/../../plugin/sql/qa -:sql-specs: {sql-tests}/src/main/resources/ -:jdbc-tests: {sql-tests}/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc -:security-tests: {sql-tests}/security/src/test/java/org/elasticsearch/xpack/sql/qa/security +:sql-tests: {xes-repo-dir}/../../plugin/sql/qa/ +:sql-specs: {sql-tests}server/src/main/resources/ +:jdbc-tests: {sql-tests}jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc +:security-tests: {sql-tests}server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security +:es-sql: Elasticsearch SQL [partintro] -- @@ -15,7 +16,7 @@ X-Pack includes a SQL feature to execute SQL queries against {es} indices and return results in tabular format. The following chapters aim to cover everything from usage, to syntax and drivers. -Experience users or those in a hurry might want to jump directly to +Experience users or those in a hurry might want to jump directly to the list of SQL <> and <>. <>:: diff --git a/docs/reference/sql/security.asciidoc b/docs/reference/sql/security.asciidoc index cbf41b46997..963bb463964 100644 --- a/docs/reference/sql/security.asciidoc +++ b/docs/reference/sql/security.asciidoc @@ -35,6 +35,6 @@ indices: [source, yaml] -------------------------------------------------- -include-tagged::{sql-tests}/security/roles.yml[cli_drivers] +include-tagged::{sql-tests}server/security/roles.yml[cli_drivers] -------------------------------------------------- diff --git a/x-pack/plugin/sql/qa/build.gradle b/x-pack/plugin/sql/qa/build.gradle index 3b779f01477..00502e17591 100644 --- a/x-pack/plugin/sql/qa/build.gradle +++ b/x-pack/plugin/sql/qa/build.gradle @@ -1,128 +1 @@ description = 'Integration tests for SQL' -apply plugin: 'elasticsearch.build' -archivesBaseName = 'qa-sql' -group = "org.elasticsearch.x-pack.qa.sql" - -dependencies { - compile project(":test:framework") - - // JDBC testing dependencies - compile project(path: xpackModule('sql:jdbc')) - - compile "net.sourceforge.csvjdbc:csvjdbc:${csvjdbcVersion}" - - // CLI testing dependencies - compile project(path: xpackModule('sql:sql-cli')) - - // H2GIS testing dependencies - compile("org.orbisgis:h2gis:${h2gisVersion}") { - exclude group: "org.locationtech.jts" - } - - // select just the parts of JLine that are needed - compile("org.jline:jline-terminal-jna:${jlineVersion}") { - exclude group: "net.java.dev.jna" - } - compile "org.jline:jline-terminal:${jlineVersion}" - compile "org.jline:jline-reader:${jlineVersion}" - compile "org.jline:jline-style:${jlineVersion}" - - testRuntime "org.elasticsearch:jna:${versions.jna}" -} - -/* disable unit tests because these are all integration tests used - * other qa projects. */ -test.enabled = false - -dependencyLicenses.enabled = false -dependenciesInfo.enabled = false - -// the main files are actually test files, so use the appropriate forbidden api sigs -tasks.named('forbiddenApisMain').configure { - replaceSignatureFiles 'es-all-signatures', 'es-test-signatures' -} - -// just a test fixture: we aren't using this jars in releases and H2GIS requires disabling a lot of checks -thirdPartyAudit.enabled = false - -subprojects { - if (subprojects.isEmpty()) { - // leaf project - apply plugin: 'elasticsearch.standalone-rest-test' - } else { - apply plugin: 'elasticsearch.build' - } - - configurations.testRuntimeClasspath { - resolutionStrategy.force "org.slf4j:slf4j-api:1.7.25" - } - configurations.testRuntime { - // This is also required to make resolveAllDependencies work - resolutionStrategy.force "org.slf4j:slf4j-api:1.7.25" - } - dependencies { - - /* Since we're a standalone rest test we actually get transitive - * dependencies but we don't really want them because they cause - * all kinds of trouble with the jar hell checks. So we suppress - * them explicitly for non-es projects. */ - testCompile(xpackProject('plugin:sql:qa')) { - transitive = false - } - testCompile project(":test:framework") - - // JDBC testing dependencies - testRuntime "net.sourceforge.csvjdbc:csvjdbc:${csvjdbcVersion}" - testRuntime "com.h2database:h2:${h2Version}" - - // H2GIS testing dependencies - testRuntime("org.orbisgis:h2gis:${h2gisVersion}") { - exclude group: "org.locationtech.jts" - exclude group: "com.fasterxml.jackson.core" - } - - testRuntime project(path: xpackModule('sql:jdbc')) - testRuntime xpackProject('plugin:sql:sql-client') - - // TODO check if needed - testRuntime("org.antlr:antlr4-runtime:${antlrVersion}") { - transitive = false - } - - // CLI testing dependencies - testRuntime project(path: xpackModule('sql:sql-cli')) - testRuntime(xpackProject('plugin:sql:sql-action')) { - transitive = false - } - - testRuntime("org.jline:jline-terminal-jna:${jlineVersion}") { - exclude group: "net.java.dev.jna" - } - testRuntime "org.jline:jline-terminal:${jlineVersion}" - testRuntime "org.jline:jline-reader:${jlineVersion}" - testRuntime "org.jline:jline-style:${jlineVersion}" - - testRuntime "org.elasticsearch:jna:${versions.jna}" - - // spatial dependency - testRuntime project(path: xpackModule('spatial')) - } - - if (project.name != 'security') { - // The security project just configures its subprojects - apply plugin: 'elasticsearch.testclusters' - apply plugin: 'elasticsearch.rest-test' - - testClusters.integTest { - testDistribution = 'DEFAULT' - setting 'xpack.ml.enabled', 'false' - setting 'xpack.watcher.enabled', 'false' - } - - task runqa { - doFirst { - println "Run with `-Dtestclusters.inspect.failure=true integTest` to leave the cluster running after failure" - } - } - } -} diff --git a/x-pack/plugin/sql/qa/jdbc/build.gradle b/x-pack/plugin/sql/qa/jdbc/build.gradle new file mode 100644 index 00000000000..3f2b503d5f7 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/build.gradle @@ -0,0 +1,61 @@ +description = 'Integration tests for SQL JDBC driver' +apply plugin: 'elasticsearch.build' + +// Avoid circular dependency +group = "org.elasticsearch.x-pack.qa.sql.jdbc" + +dependencies { + compile project(":test:framework") + + // JDBC testing dependencies + compile project(path: xpackModule('sql:jdbc')) +} + +/* disable unit tests because these are all integration tests used + * other qa projects. */ +test.enabled = false + +dependencyLicenses.enabled = false +dependenciesInfo.enabled = false + +// the main files are actually test files, so use the appropriate forbidden api sigs +tasks.named('forbiddenApisMain').configure { + replaceSignatureFiles 'es-all-signatures', 'es-test-signatures' +} + +// just a test fixture: we aren't using this jars in releases and H2GIS requires disabling a lot of checks +thirdPartyAudit.enabled = false + +subprojects { + if (subprojects.isEmpty()) { + // leaf project + apply plugin: 'elasticsearch.standalone-rest-test' + } else { + apply plugin: 'elasticsearch.build' + } + + dependencies { + /* Since we're a standalone rest test we actually get transitive + * dependencies but we don't really want them because they cause + * all kinds of trouble with the jar hell checks. So we suppress + * them explicitly for non-es projects. */ + testCompile(xpackProject('plugin:sql:qa:jdbc')) { + transitive = false + } + testCompile project(":test:framework") + + testRuntime project(path: xpackModule('sql:jdbc')) + } + + if (project.name != 'security') { + // The security project just configures its subprojects + apply plugin: 'elasticsearch.testclusters' + apply plugin: 'elasticsearch.rest-test' + + testClusters.integTest { + testDistribution = 'DEFAULT' + setting 'xpack.ml.enabled', 'false' + setting 'xpack.watcher.enabled', 'false' + } + } +} diff --git a/x-pack/plugin/sql/qa/jdbc/multi-node/build.gradle b/x-pack/plugin/sql/qa/jdbc/multi-node/build.gradle new file mode 100644 index 00000000000..4929fdffaee --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/multi-node/build.gradle @@ -0,0 +1,7 @@ +description = 'Run SQL JDBC tests against multiple nodes' + +testClusters.integTest { + numberOfNodes = 2 + setting 'xpack.security.enabled', 'false' + setting 'xpack.license.self_generated.type', 'trial' +} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcConnectionIT.java b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcConnectionIT.java similarity index 72% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcConnectionIT.java rename to x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcConnectionIT.java index fe34346458c..c175976d430 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcConnectionIT.java +++ b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcConnectionIT.java @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.single_node; +package org.elasticsearch.xpack.sql.qa.jdbc.multi_node; import org.elasticsearch.xpack.sql.qa.jdbc.ConnectionTestCase; -public class JdbcConnectionIT extends ConnectionTestCase { -} +public class JdbcConnectionIT extends ConnectionTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFetchSizeIT.java b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcFetchSizeIT.java similarity index 72% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFetchSizeIT.java rename to x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcFetchSizeIT.java index 1d08c49dae2..67e3693adbc 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFetchSizeIT.java +++ b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcFetchSizeIT.java @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.single_node; +package org.elasticsearch.xpack.sql.qa.jdbc.multi_node; import org.elasticsearch.xpack.sql.qa.jdbc.FetchSizeTestCase; -public class JdbcFetchSizeIT extends FetchSizeTestCase { -} +public class JdbcFetchSizeIT extends FetchSizeTestCase {} diff --git a/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcJdbcErrorsIT.java b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcJdbcErrorsIT.java new file mode 100644 index 00000000000..87336343762 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcJdbcErrorsIT.java @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc.multi_node; + +import org.elasticsearch.xpack.sql.qa.jdbc.JdbcErrorsTestCase; + +public class JdbcJdbcErrorsIT extends JdbcErrorsTestCase {} diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcPreparedStatementIT.java b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcPreparedStatementIT.java similarity index 85% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcPreparedStatementIT.java rename to x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcPreparedStatementIT.java index b06746acb79..c2c652e06e3 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcPreparedStatementIT.java +++ b/x-pack/plugin/sql/qa/jdbc/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/multi_node/JdbcPreparedStatementIT.java @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.multi_node; +package org.elasticsearch.xpack.sql.qa.jdbc.multi_node; import org.elasticsearch.xpack.sql.qa.jdbc.PreparedStatementTestCase; -public class JdbcPreparedStatementIT extends PreparedStatementTestCase { -} +public class JdbcPreparedStatementIT extends PreparedStatementTestCase {} diff --git a/x-pack/plugin/sql/qa/jdbc/no-sql/build.gradle b/x-pack/plugin/sql/qa/jdbc/no-sql/build.gradle new file mode 100644 index 00000000000..a8c24dc974f --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/no-sql/build.gradle @@ -0,0 +1,4 @@ +testClusters.integTest { + setting 'xpack.security.enabled', 'false' + setting 'xpack.license.self_generated.type', 'trial' +} diff --git a/x-pack/plugin/sql/qa/no-sql/src/test/java/org/elasticsearch/xpack/sql/qa/no_sql/JdbcNoSqlIT.java b/x-pack/plugin/sql/qa/jdbc/no-sql/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/no_sql/JdbcNoSqlIT.java similarity index 74% rename from x-pack/plugin/sql/qa/no-sql/src/test/java/org/elasticsearch/xpack/sql/qa/no_sql/JdbcNoSqlIT.java rename to x-pack/plugin/sql/qa/jdbc/no-sql/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/no_sql/JdbcNoSqlIT.java index c1c59877fdc..4f8c00a6afb 100644 --- a/x-pack/plugin/sql/qa/no-sql/src/test/java/org/elasticsearch/xpack/sql/qa/no_sql/JdbcNoSqlIT.java +++ b/x-pack/plugin/sql/qa/jdbc/no-sql/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/no_sql/JdbcNoSqlIT.java @@ -4,10 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.no_sql; +package org.elasticsearch.xpack.sql.qa.jdbc.no_sql; import org.elasticsearch.xpack.sql.qa.jdbc.JdbcNoSqlTestCase; -public class JdbcNoSqlIT extends JdbcNoSqlTestCase { - -} +public class JdbcNoSqlIT extends JdbcNoSqlTestCase {} diff --git a/x-pack/plugin/sql/qa/jdbc/security/build.gradle b/x-pack/plugin/sql/qa/jdbc/security/build.gradle new file mode 100644 index 00000000000..d107b61faeb --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/security/build.gradle @@ -0,0 +1,61 @@ +dependencies { + testCompile project(':x-pack:plugin:core') +} + +Project mainProject = project + +configurations.create('testArtifacts') + +TaskProvider testJar = tasks.register("testJar", Jar) { + appendix 'test' + from sourceSets.test.output +} + +artifacts { + testArtifacts testJar +} + +// Tests are pushed down to subprojects and will be checked there. +testingConventions.enabled = false + +subprojects { + // Use tests from the root security qa project in subprojects + configurations.create('testArtifacts') + + dependencies { + testCompile project(":x-pack:plugin:core") + testArtifacts project(path: mainProject.path, configuration: 'testArtifacts') + } + + testClusters.integTest { + testDistribution = 'DEFAULT' + // Setup auditing so we can use it in some tests + setting 'xpack.security.audit.enabled', 'true' + setting 'xpack.security.enabled', 'true' + setting 'xpack.license.self_generated.type', 'trial' + // Setup roles used by tests + extraConfigFile 'roles.yml', mainProject.file('roles.yml') + /* Setup the one admin user that we run the tests as. + * Tests use "run as" to get different users. */ + user username: "test_admin", password: "x-pack-test-password" + } + + File testArtifactsDir = project.file("$buildDir/testArtifacts") + TaskProvider copyTestClasses = tasks.register("copyTestClasses", Copy) { + dependsOn configurations.testArtifacts + from { zipTree(configurations.testArtifacts.singleFile) } + into testArtifactsDir + } + + integTest.runner { + dependsOn copyTestClasses + testClassesDirs += project.files(testArtifactsDir) + classpath += configurations.testArtifacts + nonInputProperties.systemProperty 'tests.audit.logfile', + "${-> testClusters.integTest.singleNode().getAuditLog()}" + nonInputProperties.systemProperty 'tests.audit.yesterday.logfile', + "${-> testClusters.integTest.singleNode().getAuditLog().getParentFile()}/integTest_audit-${new Date().format('yyyy-MM-dd')}.json" + } + + testingConventions.enabled = false +} diff --git a/x-pack/plugin/sql/qa/security/roles.yml b/x-pack/plugin/sql/qa/jdbc/security/roles.yml similarity index 100% rename from x-pack/plugin/sql/qa/security/roles.yml rename to x-pack/plugin/sql/qa/jdbc/security/roles.yml diff --git a/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcConnectionIT.java b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcConnectionIT.java new file mode 100644 index 00000000000..a5959997727 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcConnectionIT.java @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc.security; + +import org.elasticsearch.common.Booleans; +import org.elasticsearch.common.io.PathUtils; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.xpack.sql.qa.jdbc.ConnectionTestCase; + +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; + +import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; + +public class JdbcConnectionIT extends ConnectionTestCase { + + static final boolean SSL_ENABLED = Booleans.parseBoolean(System.getProperty("tests.ssl.enabled"), false); + + static Settings securitySettings() { + String token = basicAuthHeaderValue("test_admin", new SecureString("x-pack-test-password".toCharArray())); + Settings.Builder builder = Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token); + if (SSL_ENABLED) { + Path keyStore; + try { + keyStore = PathUtils.get(getTestClass().getResource("/test-node.jks").toURI()); + } catch (URISyntaxException e) { + throw new RuntimeException("exception while reading the store", e); + } + if (!Files.exists(keyStore)) { + throw new IllegalStateException("Keystore file [" + keyStore + "] does not exist."); + } + builder.put(ESRestTestCase.TRUSTSTORE_PATH, keyStore).put(ESRestTestCase.TRUSTSTORE_PASSWORD, "keypass"); + } + return builder.build(); + } + + @Override + protected Settings restClientSettings() { + return securitySettings(); + } + + @Override + protected String getProtocol() { + return SSL_ENABLED ? "https" : "http"; + } + + @Override + protected Properties connectionProperties() { + Properties properties = super.connectionProperties(); + properties.putAll(JdbcSecurityUtils.adminProperties()); + return properties; + } +} diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcFetchSizeIT.java b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcFetchSizeIT.java similarity index 75% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcFetchSizeIT.java rename to x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcFetchSizeIT.java index c75bbc1a50a..716ebd348bf 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcFetchSizeIT.java +++ b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcFetchSizeIT.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.security; +package org.elasticsearch.xpack.sql.qa.jdbc.security; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.xpack.sql.qa.jdbc.FetchSizeTestCase; @@ -11,20 +11,21 @@ import org.elasticsearch.xpack.sql.qa.jdbc.FetchSizeTestCase; import java.util.Properties; public class JdbcFetchSizeIT extends FetchSizeTestCase { + @Override protected Settings restClientSettings() { - return RestSqlIT.securitySettings(); + return JdbcConnectionIT.securitySettings(); } @Override protected String getProtocol() { - return RestSqlIT.SSL_ENABLED ? "https" : "http"; + return JdbcConnectionIT.SSL_ENABLED ? "https" : "http"; } @Override protected Properties connectionProperties() { Properties properties = super.connectionProperties(); - properties.putAll(JdbcSecurityIT.adminProperties()); + properties.putAll(JdbcSecurityUtils.adminProperties()); return properties; } } diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcConnectionIT.java b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcJdbcErrorsIT.java similarity index 63% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcConnectionIT.java rename to x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcJdbcErrorsIT.java index 8a4815a4e1e..33733032799 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcConnectionIT.java +++ b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcJdbcErrorsIT.java @@ -3,28 +3,29 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.security; +package org.elasticsearch.xpack.sql.qa.jdbc.security; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.sql.qa.jdbc.ConnectionTestCase; +import org.elasticsearch.xpack.sql.qa.jdbc.JdbcErrorsTestCase; import java.util.Properties; -public class JdbcConnectionIT extends ConnectionTestCase { +public class JdbcJdbcErrorsIT extends JdbcErrorsTestCase { + @Override protected Settings restClientSettings() { - return RestSqlIT.securitySettings(); + return JdbcConnectionIT.securitySettings(); } @Override protected String getProtocol() { - return RestSqlIT.SSL_ENABLED ? "https" : "http"; + return JdbcConnectionIT.SSL_ENABLED ? "https" : "http"; } @Override protected Properties connectionProperties() { Properties properties = super.connectionProperties(); - properties.putAll(JdbcSecurityIT.adminProperties()); + properties.putAll(JdbcSecurityUtils.adminProperties()); return properties; } } diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcPreparedStatementIT.java b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcPreparedStatementIT.java similarity index 76% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcPreparedStatementIT.java rename to x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcPreparedStatementIT.java index 36a65f88a6f..a9184435203 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcPreparedStatementIT.java +++ b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcPreparedStatementIT.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.security; +package org.elasticsearch.xpack.sql.qa.jdbc.security; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.xpack.sql.qa.jdbc.PreparedStatementTestCase; @@ -11,20 +11,21 @@ import org.elasticsearch.xpack.sql.qa.jdbc.PreparedStatementTestCase; import java.util.Properties; public class JdbcPreparedStatementIT extends PreparedStatementTestCase { + @Override protected Settings restClientSettings() { - return RestSqlIT.securitySettings(); + return JdbcConnectionIT.securitySettings(); } @Override protected String getProtocol() { - return RestSqlIT.SSL_ENABLED ? "https" : "http"; + return JdbcConnectionIT.SSL_ENABLED ? "https" : "http"; } @Override protected Properties connectionProperties() { Properties sp = super.connectionProperties(); - sp.putAll(JdbcSecurityIT.adminProperties()); + sp.putAll(JdbcSecurityUtils.adminProperties()); return sp; } } diff --git a/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcSecurityUtils.java b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcSecurityUtils.java new file mode 100644 index 00000000000..a0189442625 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcSecurityUtils.java @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc.security; + +import org.elasticsearch.common.io.PathUtils; + +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; + +import static org.apache.lucene.util.LuceneTestCase.getTestClass; + +final class JdbcSecurityUtils { + + private JdbcSecurityUtils() {} + + static Properties adminProperties() { + // tag::admin_properties + Properties properties = new Properties(); + properties.put("user", "test_admin"); + properties.put("password", "x-pack-test-password"); + // end::admin_properties + addSslPropertiesIfNeeded(properties); + return properties; + } + + private static void addSslPropertiesIfNeeded(Properties properties) { + if (false == JdbcConnectionIT.SSL_ENABLED) { + return; + } + Path keyStore; + try { + keyStore = PathUtils.get(getTestClass().getResource("/test-node.jks").toURI()); + } catch (URISyntaxException e) { + throw new RuntimeException("exception while reading the store", e); + } + if (!Files.exists(keyStore)) { + throw new IllegalStateException("Keystore file [" + keyStore + "] does not exist."); + } + String keyStoreStr = keyStore.toAbsolutePath().toString(); + + properties.put("ssl", "true"); + properties.put("ssl.keystore.location", keyStoreStr); + properties.put("ssl.keystore.pass", "keypass"); + properties.put("ssl.truststore.location", keyStoreStr); + properties.put("ssl.truststore.pass", "keypass"); + } +} diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSimpleExampleIT.java b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcSimpleExampleIT.java similarity index 75% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSimpleExampleIT.java rename to x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcSimpleExampleIT.java index d7aeff61947..d7ce4c3463e 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSimpleExampleIT.java +++ b/x-pack/plugin/sql/qa/jdbc/security/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/security/JdbcSimpleExampleIT.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.security; +package org.elasticsearch.xpack.sql.qa.jdbc.security; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.xpack.sql.qa.jdbc.SimpleExampleTestCase; @@ -11,20 +11,21 @@ import org.elasticsearch.xpack.sql.qa.jdbc.SimpleExampleTestCase; import java.util.Properties; public class JdbcSimpleExampleIT extends SimpleExampleTestCase { + @Override protected Settings restClientSettings() { - return RestSqlIT.securitySettings(); + return JdbcConnectionIT.securitySettings(); } @Override protected String getProtocol() { - return RestSqlIT.SSL_ENABLED ? "https" : "http"; + return JdbcConnectionIT.SSL_ENABLED ? "https" : "http"; } @Override protected Properties connectionProperties() { Properties properties = super.connectionProperties(); - properties.putAll(JdbcSecurityIT.adminProperties()); + properties.putAll(JdbcSecurityUtils.adminProperties()); return properties; } } diff --git a/x-pack/plugin/sql/qa/security/src/test/resources/plugin-security.policy b/x-pack/plugin/sql/qa/jdbc/security/src/test/resources/plugin-security.policy similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/resources/plugin-security.policy rename to x-pack/plugin/sql/qa/jdbc/security/src/test/resources/plugin-security.policy diff --git a/x-pack/plugin/sql/qa/jdbc/security/with-ssl/build.gradle b/x-pack/plugin/sql/qa/jdbc/security/with-ssl/build.gradle new file mode 100644 index 00000000000..7a4e25770aa --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/security/with-ssl/build.gradle @@ -0,0 +1,340 @@ +import org.elasticsearch.gradle.LoggedExec +import org.elasticsearch.gradle.info.BuildParams + +// Tell the tests we're running with ssl enabled +integTest.runner { + systemProperty 'tests.ssl.enabled', 'true' +} + +// needed to be consistent with ssl host checking +Object san = new SanEvaluator() + +// needed to be consistent with ssl host checking +String host = InetAddress.getLoopbackAddress().getHostAddress(); + +// location of generated keystores and certificates +File keystoreDir = new File(project.buildDir, 'keystore') + +// Generate the node's keystore +File nodeKeystore = file("$keystoreDir/test-node.jks") +task createNodeKeyStore(type: LoggedExec) { + doFirst { + if (nodeKeystore.parentFile.exists() == false) { + nodeKeystore.parentFile.mkdirs() + } + if (nodeKeystore.exists()) { + delete nodeKeystore + } + } + executable = "${BuildParams.compilerJavaHome}/bin/keytool" + standardInput = new ByteArrayInputStream('FirstName LastName\nUnit\nOrganization\nCity\nState\nNL\nyes\n\n'.getBytes('UTF-8')) + args '-genkey', + '-alias', 'test-node', + '-keystore', nodeKeystore, + '-keyalg', 'RSA', + '-keysize', '2048', + '-validity', '712', + '-dname', 'CN=' + host, + '-keypass', 'keypass', + '-storepass', 'keypass', + '-ext', san +} + +// Generate the client's keystore +File clientKeyStore = file("$keystoreDir/test-client.jks") +task createClientKeyStore(type: LoggedExec) { + doFirst { + if (clientKeyStore.parentFile.exists() == false) { + clientKeyStore.parentFile.mkdirs() + } + if (clientKeyStore.exists()) { + delete clientKeyStore + } + } + executable = "${BuildParams.runtimeJavaHome}/bin/keytool" + standardInput = new ByteArrayInputStream('FirstName LastName\nUnit\nOrganization\nCity\nState\nNL\nyes\n\n'.getBytes('UTF-8')) + args '-genkey', + '-alias', 'test-client', + '-keystore', clientKeyStore, + '-keyalg', 'RSA', + '-keysize', '2048', + '-validity', '712', + '-dname', 'CN=' + host, + '-keypass', 'keypass', + '-storepass', 'keypass', + '-ext', san +} + +// Export the node's certificate +File nodeCertificate = file("$keystoreDir/test-node.cert") +task exportNodeCertificate(type: LoggedExec) { + dependsOn createNodeKeyStore + doFirst { + if (nodeCertificate.parentFile.exists() == false) { + nodeCertificate.parentFile.mkdirs() + } + if (nodeCertificate.exists()) { + delete nodeCertificate + } + } + executable = "${BuildParams.runtimeJavaHome}/bin/keytool" + args '-export', + '-alias', 'test-node', + '-keystore', nodeKeystore, + '-storepass', 'keypass', + '-file', nodeCertificate +} + +// Import the node certificate in the client's keystore +task importNodeCertificateInClientKeyStore(type: LoggedExec) { + dependsOn createClientKeyStore, exportNodeCertificate + executable = "${BuildParams.runtimeJavaHome}/bin/keytool" + args '-import', + '-alias', 'test-node', + '-keystore', clientKeyStore, + '-storepass', 'keypass', + '-file', nodeCertificate, + '-noprompt' +} + +// Export the client's certificate +File clientCertificate = file("$keystoreDir/test-client.cert") +task exportClientCertificate(type: LoggedExec) { + dependsOn createClientKeyStore + doFirst { + if (clientCertificate.parentFile.exists() == false) { + clientCertificate.parentFile.mkdirs() + } + if (clientCertificate.exists()) { + delete clientCertificate + } + } + executable = "${BuildParams.runtimeJavaHome}/bin/keytool" + args '-export', + '-alias', 'test-client', + '-keystore', clientKeyStore, + '-storepass', 'keypass', + '-file', clientCertificate +} + +// Import the client certificate in the node's keystore +task importClientCertificateInNodeKeyStore(type: LoggedExec) { + dependsOn createNodeKeyStore, exportClientCertificate + executable = "${BuildParams.runtimeJavaHome}/bin/keytool" + args '-import', + '-alias', 'test-client', + '-keystore', nodeKeystore, + '-storepass', 'keypass', + '-file', clientCertificate, + '-noprompt' +} + +forbiddenPatterns { + exclude '**/*.cert' +} + +// Add keystores to test classpath: it expects it there +sourceSets.test.resources.srcDir(keystoreDir) +processTestResources.dependsOn(importNodeCertificateInClientKeyStore, importClientCertificateInNodeKeyStore) + +integTest.runner { + dependsOn(importClientCertificateInNodeKeyStore) + onlyIf { + // Do not attempt to form a cluster in a FIPS JVM, as doing so with a JKS keystore will fail. + // TODO Revisit this when SQL CLI client can handle key/certificate instead of only Keystores. + // https://github.com/elastic/elasticsearch/issues/32306 + BuildParams.inFipsJvm == false + } +} + +testClusters.integTest { + // The setup that we actually want + setting 'xpack.license.self_generated.type', 'trial' + setting 'xpack.security.http.ssl.enabled', 'true' + setting 'xpack.security.transport.ssl.enabled', 'true' + + // ceremony to set up ssl + setting 'xpack.security.transport.ssl.keystore.path', 'test-node.jks' + setting 'xpack.security.http.ssl.keystore.path', 'test-node.jks' + keystore 'xpack.security.transport.ssl.keystore.secure_password', 'keypass' + keystore 'xpack.security.http.ssl.keystore.secure_password', 'keypass' + + + // copy keystores into config/ + extraConfigFile nodeKeystore.name, nodeKeystore + extraConfigFile clientKeyStore.name, clientKeyStore +} + + +/** A lazy evaluator to find the san to use for certificate generation. */ +class SanEvaluator { + + private static String san = null + + String toString() { + synchronized (SanEvaluator.class) { + if (san == null) { + san = getSubjectAlternativeNameString() + } + } + return san + } + + // Code stolen from NetworkUtils/InetAddresses/NetworkAddress to support SAN + /** Return all interfaces (and subinterfaces) on the system */ + private static List getInterfaces() throws SocketException { + List all = new ArrayList<>(); + addAllInterfaces(all, Collections.list(NetworkInterface.getNetworkInterfaces())); + Collections.sort(all, new Comparator() { + @Override + public int compare(NetworkInterface left, NetworkInterface right) { + return Integer.compare(left.getIndex(), right.getIndex()); + } + }); + return all; + } + + /** Helper for getInterfaces, recursively adds subinterfaces to {@code target} */ + private static void addAllInterfaces(List target, List level) { + if (!level.isEmpty()) { + target.addAll(level); + for (NetworkInterface intf : level) { + addAllInterfaces(target, Collections.list(intf.getSubInterfaces())); + } + } + } + + private static String getSubjectAlternativeNameString() { + List list = new ArrayList<>(); + for (NetworkInterface intf : getInterfaces()) { + for (final InetAddress address : Collections.list(intf.getInetAddresses())) { + /* + * Some OS (e.g., BSD) assign a link-local address to the loopback interface. While technically not a loopback interface, some of + * these OS treat them as one (e.g., localhost on macOS), so we must too. Otherwise, things just won't work out of the box. So we + * include all addresses from loopback interfaces. + * + * By checking if the interface is a loopback interface or the address is a loopback address first, we avoid having to check if the + * interface is up unless necessary. This means we can avoid checking if the interface is up for virtual ethernet devices which have + * a tendency to disappear outside of our control (e.g., due to Docker). + */ + if ((intf.isLoopback() || address.isLoopbackAddress()) && isUp(intf, address)) { + list.add(address) + } + } + } + if (list.isEmpty()) { + throw new IllegalArgumentException("no up-and-running loopback addresses found, got " + getInterfaces()); + } + + StringBuilder builder = new StringBuilder("san="); + for (int i = 0; i < list.size(); i++) { + InetAddress address = list.get(i); + String hostAddress; + if (address instanceof Inet6Address) { + hostAddress = compressedIPV6Address((Inet6Address) address); + } else { + hostAddress = address.getHostAddress(); + } + builder.append("ip:").append(hostAddress); + String hostname = address.getHostName(); + if (hostname.equals(address.getHostAddress()) == false) { + builder.append(",dns:").append(hostname); + } + + if (i != (list.size() - 1)) { + builder.append(","); + } + } + + return builder.toString(); + } + + private static boolean isUp(final NetworkInterface intf, final InetAddress address) throws IOException { + try { + return intf.isUp(); + } catch (final SocketException e) { + /* + * In Elasticsearch production code (NetworkUtils) we suppress this if the device is a virtual ethernet device. That should not happen + * here since the interface must be a loopback device or the address a loopback address to get here to begin with. + */ + assert intf.isLoopback() || address.isLoopbackAddress() + throw new IOException("failed to check if interface [" + intf.getName() + "] is up", e) + } + } + + private static String compressedIPV6Address(Inet6Address inet6Address) { + byte[] bytes = inet6Address.getAddress(); + int[] hextets = new int[8]; + for (int i = 0; i < hextets.length; i++) { + hextets[i] = (bytes[2 * i] & 255) << 8 | bytes[2 * i + 1] & 255; + } + compressLongestRunOfZeroes(hextets); + return hextetsToIPv6String(hextets); + } + + /** + * Identify and mark the longest run of zeroes in an IPv6 address. + * + *

Only runs of two or more hextets are considered. In case of a tie, the + * leftmost run wins. If a qualifying run is found, its hextets are replaced + * by the sentinel value -1. + * + * @param hextets {@code int[]} mutable array of eight 16-bit hextets + */ + private static void compressLongestRunOfZeroes(int[] hextets) { + int bestRunStart = -1; + int bestRunLength = -1; + int runStart = -1; + for (int i = 0; i < hextets.length + 1; i++) { + if (i < hextets.length && hextets[i] == 0) { + if (runStart < 0) { + runStart = i; + } + } else if (runStart >= 0) { + int runLength = i - runStart; + if (runLength > bestRunLength) { + bestRunStart = runStart; + bestRunLength = runLength; + } + runStart = -1; + } + } + if (bestRunLength >= 2) { + Arrays.fill(hextets, bestRunStart, bestRunStart + bestRunLength, -1); + } + } + + /** + * Convert a list of hextets into a human-readable IPv6 address. + * + *

In order for "::" compression to work, the input should contain negative + * sentinel values in place of the elided zeroes. + * + * @param hextets {@code int[]} array of eight 16-bit hextets, or -1s + */ + private static String hextetsToIPv6String(int[] hextets) { + /* + * While scanning the array, handle these state transitions: + * start->num => "num" start->gap => "::" + * num->num => ":num" num->gap => "::" + * gap->num => "num" gap->gap => "" + */ + StringBuilder buf = new StringBuilder(39); + boolean lastWasNumber = false; + for (int i = 0; i < hextets.length; i++) { + boolean thisIsNumber = hextets[i] >= 0; + if (thisIsNumber) { + if (lastWasNumber) { + buf.append(':'); + } + buf.append(Integer.toHexString(hextets[i])); + } else { + if (i == 0 || lastWasNumber) { + buf.append("::"); + } + } + lastWasNumber = thisIsNumber; + } + return buf.toString(); + } +} diff --git a/x-pack/plugin/sql/qa/jdbc/security/without-ssl/build.gradle b/x-pack/plugin/sql/qa/jdbc/security/without-ssl/build.gradle new file mode 100644 index 00000000000..9639b809f46 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/security/without-ssl/build.gradle @@ -0,0 +1,7 @@ +integTest.runner { + systemProperty 'tests.ssl.enabled', 'false' +} + +testClusters.integTest { + setting 'xpack.license.self_generated.type', 'trial' +} diff --git a/x-pack/plugin/sql/qa/jdbc/single-node/build.gradle b/x-pack/plugin/sql/qa/jdbc/single-node/build.gradle new file mode 100644 index 00000000000..a8c24dc974f --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/single-node/build.gradle @@ -0,0 +1,4 @@ +testClusters.integTest { + setting 'xpack.security.enabled', 'false' + setting 'xpack.license.self_generated.type', 'trial' +} diff --git a/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcConnectionIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcConnectionIT.java new file mode 100644 index 00000000000..2b31e32a45d --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcConnectionIT.java @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; + +import org.elasticsearch.xpack.sql.qa.jdbc.ConnectionTestCase; + +public class JdbcConnectionIT extends ConnectionTestCase {} diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcErrorsIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcFetchSizeIT.java similarity index 57% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcErrorsIT.java rename to x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcFetchSizeIT.java index fec89fac11f..a904085fd34 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcErrorsIT.java +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcFetchSizeIT.java @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.multi_node; +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; -import org.elasticsearch.xpack.sql.qa.jdbc.ErrorsTestCase; +import org.elasticsearch.xpack.sql.qa.jdbc.FetchSizeTestCase; -public class JdbcErrorsIT extends ErrorsTestCase { -} +public class JdbcFetchSizeIT extends FetchSizeTestCase {} diff --git a/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcJdbcErrorsIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcJdbcErrorsIT.java new file mode 100644 index 00000000000..8c1af737a9e --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcJdbcErrorsIT.java @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; + +import org.elasticsearch.xpack.sql.qa.jdbc.JdbcErrorsTestCase; + +public class JdbcJdbcErrorsIT extends JdbcErrorsTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcPreparedStatementIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcPreparedStatementIT.java similarity index 84% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcPreparedStatementIT.java rename to x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcPreparedStatementIT.java index 9a986a33afd..e2916dd0eb9 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcPreparedStatementIT.java +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcPreparedStatementIT.java @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.single_node; +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; import org.elasticsearch.xpack.sql.qa.jdbc.PreparedStatementTestCase; -public class JdbcPreparedStatementIT extends PreparedStatementTestCase { -} +public class JdbcPreparedStatementIT extends PreparedStatementTestCase {} diff --git a/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcResultSetIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcResultSetIT.java new file mode 100644 index 00000000000..7630cf92218 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcResultSetIT.java @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; + +import org.elasticsearch.xpack.sql.qa.jdbc.ResultSetTestCase; + +public class JdbcResultSetIT extends ResultSetTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcResultSetMetaDataIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcResultSetMetaDataIT.java similarity index 84% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcResultSetMetaDataIT.java rename to x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcResultSetMetaDataIT.java index 85b85f2b0a6..9511a45669b 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcResultSetMetaDataIT.java +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcResultSetMetaDataIT.java @@ -4,10 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.single_node; +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; import org.elasticsearch.xpack.sql.qa.jdbc.ResultSetMetaDataTestCase; -public class JdbcResultSetMetaDataIT extends ResultSetMetaDataTestCase { - -} +public class JdbcResultSetMetaDataIT extends ResultSetMetaDataTestCase {} diff --git a/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcShardFailureIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcShardFailureIT.java new file mode 100644 index 00000000000..c91ccdea8df --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcShardFailureIT.java @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; + +import org.elasticsearch.client.Request; +import org.elasticsearch.xpack.sql.qa.jdbc.JdbcIntegrationTestCase; +import org.junit.Before; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import static org.hamcrest.Matchers.containsString; + +public class JdbcShardFailureIT extends JdbcIntegrationTestCase { + + @Before + public void createTestIndex() throws IOException { + Request createTest1 = new Request("PUT", "/test1"); + String body1 = "{\"aliases\":{\"test\":{}}, \"mappings\": {\"properties\": {\"test_field\":{\"type\":\"integer\"}}}}"; + createTest1.setJsonEntity(body1); + client().performRequest(createTest1); + + Request createTest2 = new Request("PUT", "/test2"); + String body2 = "{\"aliases\":{\"test\":{}}, \"mappings\": {\"properties\": {\"test_field\":{\"type\":\"integer\"}}}," + + "\"settings\": {\"index.routing.allocation.include.node\": \"nowhere\"}}"; + createTest2.setJsonEntity(body2); + createTest2.addParameter("timeout", "100ms"); + client().performRequest(createTest2); + + Request request = new Request("PUT", "/test1/_bulk"); + request.addParameter("refresh", "true"); + StringBuilder bulk = new StringBuilder(); + for (int i = 0; i < 20; i++) { + bulk.append("{\"index\":{}}\n"); + bulk.append("{\"test_field\":").append(i).append("}\n"); + } + request.setJsonEntity(bulk.toString()); + client().performRequest(request); + } + + public void testPartialResponseHandling() throws SQLException { + try (Connection c = esJdbc(); Statement s = c.createStatement()) { + SQLException exception = expectThrows(SQLException.class, () -> s.executeQuery("SELECT * FROM test ORDER BY test_field ASC")); + assertThat(exception.getMessage(), containsString("Search rejected due to missing shards")); + } + } +} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSimpleExampleIT.java b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcSimpleExampleIT.java similarity index 86% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSimpleExampleIT.java rename to x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcSimpleExampleIT.java index ca79257fc5c..f510ad86569 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSimpleExampleIT.java +++ b/x-pack/plugin/sql/qa/jdbc/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/jdbc/single_node/JdbcSimpleExampleIT.java @@ -3,9 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.sql.qa.single_node; +package org.elasticsearch.xpack.sql.qa.jdbc.single_node; import org.elasticsearch.xpack.sql.qa.jdbc.SimpleExampleTestCase; -public class JdbcSimpleExampleIT extends SimpleExampleTestCase { -} +public class JdbcSimpleExampleIT extends SimpleExampleTestCase {} diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ConnectionTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ConnectionTestCase.java similarity index 96% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ConnectionTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ConnectionTestCase.java index d416d10854b..ee4520230b3 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ConnectionTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ConnectionTestCase.java @@ -15,6 +15,7 @@ import java.sql.SQLException; * Test the jdbc {@link Connection} implementation. */ public abstract class ConnectionTestCase extends JdbcIntegrationTestCase { + public void testConnectionProperties() throws SQLException { try (Connection c = esJdbc()) { assertFalse(c.isClosed()); @@ -34,7 +35,7 @@ public abstract class ConnectionTestCase extends JdbcIntegrationTestCase { /** * Tests that we throw report no transaction isolation and throw sensible errors if you ask for any. */ - public void testTransactionIsolation() throws Exception { + public void testTransactionIsolation() throws SQLException { try (Connection c = esJdbc()) { assertEquals(Connection.TRANSACTION_NONE, c.getTransactionIsolation()); SQLException e = expectThrows(SQLException.class, () -> c.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)); @@ -42,4 +43,4 @@ public abstract class ConnectionTestCase extends JdbcIntegrationTestCase { assertEquals(Connection.TRANSACTION_NONE, c.getTransactionIsolation()); } } -} \ No newline at end of file +} diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java similarity index 79% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java index 4d1d55c1b37..ba4dd5b8a23 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/FetchSizeTestCase.java @@ -21,14 +21,12 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Properties; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.JDBC_TIMEZONE; -import static org.elasticsearch.xpack.sql.qa.rest.RestSqlTestCase.assertNoSearchContexts; - /** * Tests for setting {@link Statement#setFetchSize(int)} and * {@link ResultSet#getFetchSize()}. */ -public class FetchSizeTestCase extends JdbcIntegrationTestCase { +public abstract class FetchSizeTestCase extends JdbcIntegrationTestCase { + @Before public void createTestIndex() throws IOException { Request request = new Request("PUT", "/test"); @@ -48,7 +46,7 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { createIndex.endObject().endObject(); request.setJsonEntity(Strings.toString(createIndex)); client().performRequest(request); - + request = new Request("PUT", "/test/_bulk"); request.addParameter("refresh", "true"); StringBuilder bulk = new StringBuilder(); @@ -59,7 +57,7 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { bulkLine.append(", \"nested\":["); // each document will have a nested field with 1 - 5 values for (int j = 0; j <= i % 5; j++) { - bulkLine.append("{\"inner_field\":" + j + "}" + ((j == i % 5) ? "" : ",")); + bulkLine.append("{\"inner_field\":").append(j).append("}").append((j == i % 5) ? "" : ","); } bulkLine.append("]"); bulk.append(bulkLine).append("}\n"); @@ -73,8 +71,7 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { * In this case the fetch size should be entirely respected. */ public void testScroll() throws SQLException { - try (Connection c = esJdbc(); - Statement s = c.createStatement()) { + try (Connection c = esJdbc(); Statement s = c.createStatement()) { s.setFetchSize(4); try (ResultSet rs = s.executeQuery("SELECT * FROM test ORDER BY test_field ASC")) { for (int i = 0; i < 20; i++) { @@ -91,9 +88,8 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { * Test for {@code SELECT} that is implemented as a scroll query. * In this test we don't retrieve all records and rely on close() to clean the cursor */ - public void testIncompleteScroll() throws Exception { - try (Connection c = esJdbc(); - Statement s = c.createStatement()) { + public void testIncompleteScroll() throws SQLException { + try (Connection c = esJdbc(); Statement s = c.createStatement()) { s.setFetchSize(4); try (ResultSet rs = s.executeQuery("SELECT * FROM test ORDER BY test_field ASC")) { for (int i = 0; i < 10; i++) { @@ -104,7 +100,6 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { assertTrue(rs.next()); } } - assertNoSearchContexts(); } public void testScrollWithDatetimeAndTimezoneParam() throws IOException, SQLException { @@ -136,17 +131,17 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { ZoneId zoneId = randomZone(); Properties connectionProperties = connectionProperties(); - connectionProperties.put(JDBC_TIMEZONE, zoneId.toString()); - try (Connection c = esJdbc(connectionProperties); - Statement s = c.createStatement()) { + connectionProperties.put(JdbcTestUtils.JDBC_TIMEZONE, zoneId.toString()); + try (Connection c = esJdbc(connectionProperties); Statement s = c.createStatement()) { s.setFetchSize(2); - try (ResultSet rs = - s.executeQuery("SELECT DATE_PART('TZOFFSET', date) FROM test_date_timezone ORDER BY date")) { + try (ResultSet rs = s.executeQuery("SELECT DATE_PART('TZOFFSET', date) FROM test_date_timezone ORDER BY date")) { for (int i = 0; i < datetimes.length; i++) { assertEquals(2, rs.getFetchSize()); assertTrue("No more entries left at " + i, rs.next()); - assertEquals(ZonedDateTime.ofInstant(Instant.ofEpochMilli(datetimes[i]), zoneId).getOffset() - .getTotalSeconds()/ 60, rs.getInt(1)); + assertEquals( + ZonedDateTime.ofInstant(Instant.ofEpochMilli(datetimes[i]), zoneId).getOffset().getTotalSeconds() / 60, + rs.getInt(1) + ); } assertFalse(rs.next()); } @@ -157,8 +152,7 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { * Test for {@code SELECT} that is implemented as an aggregation. */ public void testAggregation() throws SQLException { - try (Connection c = esJdbc(); - Statement s = c.createStatement()) { + try (Connection c = esJdbc(); Statement s = c.createStatement()) { s.setFetchSize(4); try (ResultSet rs = s.executeQuery("SELECT test_field, COUNT(*) FROM test GROUP BY test_field")) { for (int i = 0; i < 20; i++) { @@ -171,13 +165,12 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { } } } - + /** * Test for nested documents. */ - public void testNestedDocuments() throws Exception { - try (Connection c = esJdbc(); - Statement s = c.createStatement()) { + public void testNestedDocuments() throws SQLException { + try (Connection c = esJdbc(); Statement s = c.createStatement()) { s.setFetchSize(5); try (ResultSet rs = s.executeQuery("SELECT test_field, nested.* FROM test ORDER BY test_field ASC")) { assertTrue("Empty result set!", rs.next()); @@ -188,7 +181,6 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { assertFalse(rs.next()); } } - assertNoSearchContexts(); } private void assertNestedDocuments(ResultSet rs, int i) throws SQLException { @@ -196,24 +188,23 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { assertEquals(i, rs.getInt(1)); assertEquals(j, rs.getInt(2)); // don't check the very last row in the result set - assertTrue("No more entries left after row " + rs.getRow(), (i+j == 23 || rs.next())); + assertTrue("No more entries left after row " + rs.getRow(), (i + j == 23 || rs.next())); } } - + /** * Explicit pagination test for PIVOT. * Checks that the paging properly consumes the necessary amount of aggregations and the * page size affects the result not the intermediate query. */ - public void testPivotPaging() throws Exception { + public void testPivotPaging() throws IOException, SQLException { addPivotData(); - - try (Connection c = esJdbc(); - Statement s = c.createStatement()) { - + + try (Connection c = esJdbc(); Statement s = c.createStatement()) { + String query = "SELECT * FROM " - + "(SELECT item, amount, location FROM test_pivot)" - + " PIVOT (AVG(amount) FOR location IN ( 'AF', 'AS', 'EU', 'NA', 'SA', 'AQ', 'AU') )"; + + "(SELECT item, amount, location FROM test_pivot)" + + " PIVOT (AVG(amount) FOR location IN ( 'AF', 'AS', 'EU', 'NA', 'SA', 'AQ', 'AU') )"; // set size smaller than an agg page s.setFetchSize(3); try (ResultSet rs = s.executeQuery(query)) { @@ -226,7 +217,7 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { } assertFalse(rs.next()); } - + // now try with a larger fetch size (8 * 2 + something) - should be 2 s.setFetchSize(20); try (ResultSet rs = s.executeQuery(query)) { @@ -239,20 +230,17 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { assertFalse(rs.next()); } } - assertNoSearchContexts(); } - - - public void testPivotPagingWithLimit() throws Exception { + + public void testPivotPagingWithLimit() throws IOException, SQLException { addPivotData(); - try (Connection c = esJdbc(); - Statement s = c.createStatement()) { - + try (Connection c = esJdbc(); Statement s = c.createStatement()) { + // run a query with a limit that is not a multiple of the fetch size String query = "SELECT * FROM " - + "(SELECT item, amount, location FROM test_pivot)" - + " PIVOT (AVG(amount) FOR location IN ( 'EU', 'NA' ) ) LIMIT 5"; + + "(SELECT item, amount, location FROM test_pivot)" + + " PIVOT (AVG(amount) FOR location IN ( 'EU', 'NA' ) ) LIMIT 5"; // set size smaller than an agg page s.setFetchSize(20); try (ResultSet rs = s.executeQuery(query)) { @@ -268,20 +256,24 @@ public class FetchSizeTestCase extends JdbcIntegrationTestCase { assertFalse("LIMIT should be reached", rs.next()); } } - assertNoSearchContexts(); } - private void addPivotData() throws Exception { + private void addPivotData() throws IOException { Request request = new Request("PUT", "/test_pivot/_bulk"); request.addParameter("refresh", "true"); StringBuilder bulk = new StringBuilder(); String[] continent = new String[] { "AF", "AS", "EU", "NA", "SA", "AQ", "AU" }; for (int i = 0; i <= 100; i++) { bulk.append("{\"index\":{}}\n"); - bulk.append("{\"item\":").append(i % 10) - .append(", \"entry\":").append(i) - .append(", \"amount\" : ").append(randomInt(999)) - .append(", \"location\" : \"").append(continent[i % (continent.length)]).append("\"") + bulk.append("{\"item\":") + .append(i % 10) + .append(", \"entry\":") + .append(i) + .append(", \"amount\" : ") + .append(randomInt(999)) + .append(", \"location\" : \"") + .append(continent[i % (continent.length)]) + .append("\"") .append("}\n"); } request.setJsonEntity(bulk.toString()); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ErrorsTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcErrorsTestCase.java similarity index 66% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ErrorsTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcErrorsTestCase.java index 9f7eca0c90a..b885dedcfec 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ErrorsTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcErrorsTestCase.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.sql.qa.jdbc; import org.elasticsearch.client.Request; +import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; @@ -15,16 +16,15 @@ import static org.hamcrest.Matchers.startsWith; /** * Tests for exceptions and their messages. */ -public class ErrorsTestCase extends JdbcIntegrationTestCase implements org.elasticsearch.xpack.sql.qa.ErrorsTestCase { - @Override - public void testSelectInvalidSql() throws Exception { +public abstract class JdbcErrorsTestCase extends JdbcIntegrationTestCase { + + public void testSelectInvalidSql() throws SQLException { try (Connection c = esJdbc()) { SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * FRO").executeQuery()); assertEquals("Found 1 problem\nline 1:8: Cannot determine columns for [*]", e.getMessage()); } } - @Override public void testSelectFromMissingIndex() throws SQLException { try (Connection c = esJdbc()) { SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * FROM test").executeQuery()); @@ -32,16 +32,14 @@ public class ErrorsTestCase extends JdbcIntegrationTestCase implements org.elast } } - @Override - public void testSelectColumnFromMissingIndex() throws Exception { + public void testSelectColumnFromMissingIndex() throws SQLException { try (Connection c = esJdbc()) { SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT abc FROM test").executeQuery()); assertEquals("Found 1 problem\nline 1:17: Unknown index [test]", e.getMessage()); } } - @Override - public void testSelectFromEmptyIndex() throws Exception { + public void testSelectFromEmptyIndex() throws IOException, SQLException { // Create an index without any types Request request = new Request("PUT", "/test"); request.setJsonEntity("{}"); @@ -53,8 +51,7 @@ public class ErrorsTestCase extends JdbcIntegrationTestCase implements org.elast } } - @Override - public void testSelectColumnFromEmptyIndex() throws Exception { + public void testSelectColumnFromEmptyIndex() throws IOException, SQLException { Request request = new Request("PUT", "/test"); request.setJsonEntity("{}"); client().performRequest(request); @@ -65,8 +62,7 @@ public class ErrorsTestCase extends JdbcIntegrationTestCase implements org.elast } } - @Override - public void testSelectMissingField() throws Exception { + public void testSelectMissingField() throws IOException, SQLException { index("test", body -> body.field("test", "test")); try (Connection c = esJdbc()) { SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT missing FROM test").executeQuery()); @@ -74,8 +70,7 @@ public class ErrorsTestCase extends JdbcIntegrationTestCase implements org.elast } } - @Override - public void testSelectMissingFunction() throws Exception { + public void testSelectMissingFunction() throws IOException, SQLException { index("test", body -> body.field("foo", 1)); try (Connection c = esJdbc()) { SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT missing(foo) FROM test").executeQuery()); @@ -83,64 +78,65 @@ public class ErrorsTestCase extends JdbcIntegrationTestCase implements org.elast } } - @Override - public void testSelectProjectScoreInAggContext() throws Exception { + public void testSelectProjectScoreInAggContext() throws IOException, SQLException { index("test", body -> body.field("foo", 1)); try (Connection c = esJdbc()) { - SQLException e = expectThrows(SQLException.class, () -> - c.prepareStatement("SELECT foo, SCORE(), COUNT(*) FROM test GROUP BY foo").executeQuery()); + SQLException e = expectThrows( + SQLException.class, + () -> c.prepareStatement("SELECT foo, SCORE(), COUNT(*) FROM test GROUP BY foo").executeQuery() + ); assertEquals("Found 1 problem\nline 1:13: Cannot use non-grouped column [SCORE()], expected [foo]", e.getMessage()); } } - @Override - public void testSelectOrderByScoreInAggContext() throws Exception { + public void testSelectOrderByScoreInAggContext() throws IOException, SQLException { index("test", body -> body.field("foo", 1)); try (Connection c = esJdbc()) { - SQLException e = expectThrows(SQLException.class, () -> - c.prepareStatement("SELECT foo, COUNT(*) FROM test GROUP BY foo ORDER BY SCORE()").executeQuery()); + SQLException e = expectThrows( + SQLException.class, + () -> c.prepareStatement("SELECT foo, COUNT(*) FROM test GROUP BY foo ORDER BY SCORE()").executeQuery() + ); assertEquals( - "Found 1 problem\nline 1:54: Cannot order by non-grouped column [SCORE()], expected [foo] or an aggregate function", - e.getMessage()); + "Found 1 problem\nline 1:54: Cannot order by non-grouped column [SCORE()], expected [foo] or an aggregate function", + e.getMessage() + ); } } - @Override - public void testSelectGroupByScore() throws Exception { + public void testSelectGroupByScore() throws IOException, SQLException { index("test", body -> body.field("foo", 1)); try (Connection c = esJdbc()) { - SQLException e = expectThrows(SQLException.class, () -> - c.prepareStatement("SELECT COUNT(*) FROM test GROUP BY SCORE()").executeQuery()); + SQLException e = expectThrows( + SQLException.class, + () -> c.prepareStatement("SELECT COUNT(*) FROM test GROUP BY SCORE()").executeQuery() + ); assertEquals("Found 1 problem\nline 1:36: Cannot use [SCORE()] for grouping", e.getMessage()); } } - @Override - public void testSelectScoreSubField() throws Exception { + public void testSelectScoreSubField() throws IOException, SQLException { index("test", body -> body.field("foo", 1)); try (Connection c = esJdbc()) { - SQLException e = expectThrows(SQLException.class, () -> - c.prepareStatement("SELECT SCORE().bar FROM test").executeQuery()); + SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT SCORE().bar FROM test").executeQuery()); assertThat(e.getMessage(), startsWith("line 1:15: extraneous input '.' expecting {, ','")); } } - @Override - public void testSelectScoreInScalar() throws Exception { + public void testSelectScoreInScalar() throws IOException, SQLException { index("test", body -> body.field("foo", 1)); try (Connection c = esJdbc()) { - SQLException e = expectThrows(SQLException.class, () -> - c.prepareStatement("SELECT SIN(SCORE()) FROM test").executeQuery()); + SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT SIN(SCORE()) FROM test").executeQuery()); assertThat(e.getMessage(), startsWith("Found 1 problem\nline 1:12: [SCORE()] cannot be an argument to a function")); } } - @Override - public void testHardLimitForSortOnAggregate() throws Exception { + public void testHardLimitForSortOnAggregate() throws IOException, SQLException { index("test", body -> body.field("a", 1).field("b", 2)); try (Connection c = esJdbc()) { - SQLException e = expectThrows(SQLException.class, () -> - c.prepareStatement("SELECT max(a) max FROM test GROUP BY b ORDER BY max LIMIT 12000").executeQuery()); + SQLException e = expectThrows( + SQLException.class, + () -> c.prepareStatement("SELECT max(a) max FROM test GROUP BY b ORDER BY max LIMIT 12000").executeQuery() + ); assertEquals("The maximum LIMIT for aggregate sorting is [10000], received [12000]", e.getMessage()); } } diff --git a/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java new file mode 100644 index 00000000000..5c96f9d2705 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java @@ -0,0 +1,177 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc; + +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.common.CheckedConsumer; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.xpack.sql.jdbc.EsDataSource; +import org.junit.After; + +import java.io.IOException; +import java.io.InputStream; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +public abstract class JdbcIntegrationTestCase extends ESRestTestCase { + + public static final String JDBC_ES_URL_PREFIX = "jdbc:es://"; + + @After + public void checkSearchContent() throws IOException { + // Some context might linger due to fire and forget nature of scroll cleanup + assertNoSearchContexts(); + } + + /** + * Read an address for Elasticsearch suitable for the JDBC driver from the system properties. + */ + public static String elasticsearchAddress() { + String cluster = System.getProperty("tests.rest.cluster"); + // JDBC only supports a single node at a time so we just give it one. + return cluster.split(",")[0]; + /* This doesn't include "jdbc:es://" because we want the example in + * esJdbc to be obvious and because we want to use getProtocol to add + * https if we are running against https. */ + } + + public Connection esJdbc() throws SQLException { + return esJdbc(connectionProperties()); + } + + public Connection esJdbc(Properties props) throws SQLException { + return createConnection(props); + } + + protected Connection createConnection(Properties connectionProperties) throws SQLException { + String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress(); + String address = JDBC_ES_URL_PREFIX + elasticsearchAddress; + Connection connection; + if (randomBoolean()) { + connection = DriverManager.getConnection(address, connectionProperties); + } else { + EsDataSource dataSource = new EsDataSource(); + dataSource.setUrl(address); + dataSource.setProperties(connectionProperties); + connection = dataSource.getConnection(); + } + + assertNotNull("The timezone should be specified", connectionProperties.getProperty("timezone")); + return connection; + } + + // + // methods below are used inside the documentation only + // + protected Connection useDriverManager() throws SQLException { + String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress(); + // tag::connect-dm + String address = "jdbc:es://" + elasticsearchAddress; // <1> + Properties connectionProperties = connectionProperties(); // <2> + Connection connection = + DriverManager.getConnection(address, connectionProperties); + // end::connect-dm + assertNotNull("The timezone should be specified", connectionProperties.getProperty("timezone")); + return connection; + } + + protected Connection useDataSource() throws SQLException { + String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress(); + // tag::connect-ds + EsDataSource dataSource = new EsDataSource(); + String address = "jdbc:es://" + elasticsearchAddress; // <1> + dataSource.setUrl(address); + Properties connectionProperties = connectionProperties(); // <2> + dataSource.setProperties(connectionProperties); + Connection connection = dataSource.getConnection(); + // end::connect-ds + assertNotNull("The timezone should be specified", connectionProperties.getProperty("timezone")); + return connection; + } + + public static void index(String index, CheckedConsumer body) throws IOException { + index(index, "1", body); + } + + public static void index(String index, String documentId, CheckedConsumer body) throws IOException { + Request request = new Request("PUT", "/" + index + "/_doc/" + documentId); + request.addParameter("refresh", "true"); + XContentBuilder builder = JsonXContent.contentBuilder().startObject(); + body.accept(builder); + builder.endObject(); + request.setJsonEntity(Strings.toString(builder)); + client().performRequest(request); + } + + public static void delete(String index, String documentId) throws IOException { + Request request = new Request("DELETE", "/" + index + "/_doc/" + documentId); + request.addParameter("refresh", "true"); + client().performRequest(request); + } + + /** + * The properties used to build the connection. + */ + protected Properties connectionProperties() { + Properties connectionProperties = new Properties(); + connectionProperties.put(JdbcTestUtils.JDBC_TIMEZONE, randomKnownTimeZone()); + // in the tests, don't be lenient towards multi values + connectionProperties.put("field.multi.value.leniency", "false"); + return connectionProperties; + } + + public static String randomKnownTimeZone() { + // We use system default timezone for the connection that is selected randomly by TestRuleSetupAndRestoreClassEnv + // from all available JDK timezones. While Joda and JDK are generally in sync, some timezones might not be known + // to the current version of Joda and in this case the test might fail. To avoid that, we specify a timezone + // known for both Joda and JDK + Set timeZones = new HashSet<>(JODA_TIMEZONE_IDS); + timeZones.retainAll(JAVA_TIMEZONE_IDS); + List ids = new ArrayList<>(timeZones); + Collections.sort(ids); + return randomFrom(ids); + } + + private static Map searchStats() throws IOException { + Response response = client().performRequest(new Request("GET", "/_stats/search")); + try (InputStream content = response.getEntity().getContent()) { + return XContentHelper.convertToMap(JsonXContent.jsonXContent, content, false); + } + } + + @SuppressWarnings("unchecked") + private static int getOpenContexts(Map stats, String index) { + stats = (Map) stats.get("indices"); + stats = (Map) stats.get(index); + stats = (Map) stats.get("total"); + stats = (Map) stats.get("search"); + return (Integer) stats.get("open_contexts"); + } + + static void assertNoSearchContexts() throws IOException { + Map stats = searchStats(); + @SuppressWarnings("unchecked") + Map indicesStats = (Map) stats.get("indices"); + for (String index : indicesStats.keySet()) { + if (index.startsWith(".") == false) { // We are not interested in internal indices + assertEquals(index + " should have no search contexts", 0, getOpenContexts(stats, index)); + } + } + } +} diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java similarity index 91% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java index 7fbe2dd8b05..f992928cd86 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcNoSqlTestCase.java @@ -11,7 +11,7 @@ import java.sql.SQLException; import static org.hamcrest.Matchers.startsWith; -public class JdbcNoSqlTestCase extends JdbcIntegrationTestCase { +public abstract class JdbcNoSqlTestCase extends JdbcIntegrationTestCase { public void testJdbcExceptionMessage() throws SQLException { try (Connection c = esJdbc()) { diff --git a/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java new file mode 100644 index 00000000000..b437b86aa53 --- /dev/null +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.qa.jdbc; + +import org.elasticsearch.xpack.sql.proto.StringUtils; + +import java.sql.Date; +import java.sql.Time; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Calendar; + +final class JdbcTestUtils { + + private JdbcTestUtils() {} + + static final ZoneId UTC = ZoneId.of("Z"); + static final String JDBC_TIMEZONE = "timezone"; + static final LocalDate EPOCH = LocalDate.of(1970, 1, 1); + + static String of(long millis, String zoneId) { + return StringUtils.toString(ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.of(zoneId))); + } + + static Date asDate(long millis, ZoneId zoneId) { + return new java.sql.Date( + ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), zoneId).toLocalDate().atStartOfDay(zoneId).toInstant().toEpochMilli() + ); + } + + static Time asTime(long millis, ZoneId zoneId) { + return new Time( + ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), zoneId) + .toLocalTime() + .atDate(JdbcTestUtils.EPOCH) + .atZone(zoneId) + .toInstant() + .toEpochMilli() + ); + } + + static long convertFromCalendarToUTC(long value, Calendar cal) { + if (cal == null) { + return value; + } + Calendar c = (Calendar) cal.clone(); + c.setTimeInMillis(value); + + ZonedDateTime convertedDateTime = ZonedDateTime.ofInstant(c.toInstant(), c.getTimeZone().toZoneId()) + .withZoneSameLocal(ZoneOffset.UTC); + + return convertedDateTime.toInstant().toEpochMilli(); + } +} diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/PreparedStatementTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/PreparedStatementTestCase.java similarity index 90% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/PreparedStatementTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/PreparedStatementTestCase.java index c2927ed7ec4..3f57af6327d 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/PreparedStatementTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/PreparedStatementTestCase.java @@ -27,14 +27,10 @@ import java.util.Calendar; import java.util.Locale; import java.util.StringJoiner; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.UTC; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.asDate; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.asTime; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.convertFromCalendarToUTC; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.startsWith; -public class PreparedStatementTestCase extends JdbcIntegrationTestCase { +public abstract class PreparedStatementTestCase extends JdbcIntegrationTestCase { public void testSupportedTypes() throws SQLException { String stringVal = randomAlphaOfLength(randomIntBetween(0, 1000)); @@ -49,13 +45,19 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { long millis = randomNonNegativeLong(); Calendar calendarVal = Calendar.getInstance(randomTimeZone(), Locale.ROOT); Timestamp timestampVal = new Timestamp(millis); - Timestamp timestampValWithCal = new Timestamp(convertFromCalendarToUTC(timestampVal.getTime(), calendarVal)); - Date dateVal = asDate(millis, UTC); - Date dateValWithCal = asDate(convertFromCalendarToUTC(dateVal.getTime(), calendarVal), UTC); - Time timeVal = asTime(millis, UTC); - Time timeValWithCal = asTime(convertFromCalendarToUTC(timeVal.getTime(), calendarVal), UTC); + Timestamp timestampValWithCal = new Timestamp(JdbcTestUtils.convertFromCalendarToUTC(timestampVal.getTime(), calendarVal)); + Date dateVal = JdbcTestUtils.asDate(millis, JdbcTestUtils.UTC); + Date dateValWithCal = JdbcTestUtils.asDate( + JdbcTestUtils.convertFromCalendarToUTC(dateVal.getTime(), calendarVal), + JdbcTestUtils.UTC + ); + Time timeVal = JdbcTestUtils.asTime(millis, JdbcTestUtils.UTC); + Time timeValWithCal = JdbcTestUtils.asTime( + JdbcTestUtils.convertFromCalendarToUTC(timeVal.getTime(), calendarVal), + JdbcTestUtils.UTC + ); java.util.Date utilDateVal = new java.util.Date(millis); - LocalDateTime localDateTimeVal = LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), UTC); + LocalDateTime localDateTimeVal = LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), JdbcTestUtils.UTC); try (Connection connection = esJdbc()) { StringJoiner sql = new StringJoiner(",", "SELECT ", ""); @@ -140,10 +142,13 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { setupIndexForDateTimeTests(randomMillis); try (Connection connection = esJdbc()) { - try (PreparedStatement statement = connection.prepareStatement("SELECT id, birth_date FROM emps WHERE birth_date::date = ? " + - "ORDER BY id")) { + try ( + PreparedStatement statement = connection.prepareStatement( + "SELECT id, birth_date FROM emps WHERE birth_date::date = ? " + "ORDER BY id" + ) + ) { - statement.setDate(1, new Date(asDate(randomMillis, UTC).getTime())); + statement.setDate(1, new Date(JdbcTestUtils.asDate(randomMillis, JdbcTestUtils.UTC).getTime())); try (ResultSet results = statement.executeQuery()) { for (int i = 1; i <= 3; i++) { assertTrue(results.next()); @@ -162,7 +167,7 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { try (Connection connection = esJdbc()) { try (PreparedStatement statement = connection.prepareStatement("SELECT id, birth_date FROM emps WHERE birth_date::time = ?")) { - Time time = JdbcTestUtils.asTime(randomMillis, UTC); + Time time = JdbcTestUtils.asTime(randomMillis, JdbcTestUtils.UTC); statement.setObject(1, time); try (ResultSet results = statement.executeQuery()) { assertTrue(results.next()); @@ -184,7 +189,7 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { } } - public void testUnsupportedParameterUse() throws Exception { + public void testUnsupportedParameterUse() throws IOException, SQLException { index("library", builder -> { builder.field("name", "Don Quixote"); builder.field("page_count", 1072); @@ -202,7 +207,7 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { } } - public void testTooMayParameters() throws Exception { + public void testTooMayParameters() throws IOException, SQLException { index("library", builder -> { builder.field("name", "Don Quixote"); builder.field("page_count", 1072); @@ -221,10 +226,9 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { } } - public void testStringEscaping() throws Exception { + public void testStringEscaping() throws SQLException { try (Connection connection = esJdbc()) { - try (PreparedStatement statement = connection.prepareStatement( - "SELECT ?, ?, ?, ?")) { + try (PreparedStatement statement = connection.prepareStatement("SELECT ?, ?, ?, ?")) { statement.setString(1, "foo --"); statement.setString(2, "/* foo */"); statement.setString(3, "\"foo"); @@ -246,10 +250,9 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { } } - public void testCommentsHandling() throws Exception { + public void testCommentsHandling() throws SQLException { try (Connection connection = esJdbc()) { - try (PreparedStatement statement = connection.prepareStatement( - "SELECT ?, /* ?, */ ? -- ?")) { + try (PreparedStatement statement = connection.prepareStatement("SELECT ?, /* ?, */ ? -- ?")) { assertEquals(2, statement.getParameterMetaData().getParameterCount()); statement.setString(1, "foo"); statement.setString(2, "bar"); @@ -265,7 +268,7 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { } } - public void testSingleParameterMultipleTypes() throws Exception { + public void testSingleParameterMultipleTypes() throws SQLException { String stringVal = randomAlphaOfLength(randomIntBetween(0, 1000)); int intVal = randomInt(); long longVal = randomLong(); @@ -300,7 +303,7 @@ public class PreparedStatementTestCase extends JdbcIntegrationTestCase { } } - private Tuple execute(PreparedStatement statement) throws Exception { + private Tuple execute(PreparedStatement statement) throws SQLException { try (ResultSet results = statement.executeQuery()) { ResultSetMetaData resultSetMetaData = results.getMetaData(); assertTrue(results.next()); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetMetaDataTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetMetaDataTestCase.java similarity index 58% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetMetaDataTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetMetaDataTestCase.java index a5f3a2737de..2bad7ea0e35 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetMetaDataTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetMetaDataTestCase.java @@ -8,34 +8,43 @@ package org.elasticsearch.xpack.sql.qa.jdbc; import org.elasticsearch.common.CheckedConsumer; +import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; -public class ResultSetMetaDataTestCase extends JdbcIntegrationTestCase { - - private final String[] fieldsNames = new String[] {"test_byte", "test_integer", "test_long", "test_short", - "test_double", "test_float", "test_keyword", "test_boolean", "test_date"}; - - public void testValidGetObjectCalls() throws Exception { +public abstract class ResultSetMetaDataTestCase extends JdbcIntegrationTestCase { + + private final String[] fieldsNames = new String[] { + "test_byte", + "test_integer", + "test_long", + "test_short", + "test_double", + "test_float", + "test_keyword", + "test_boolean", + "test_date" }; + + public void testValidGetObjectCalls() throws IOException, SQLException { ResultSetTestCase.createIndex("test"); ResultSetTestCase.updateMapping("test", builder -> { - for(String field : fieldsNames) { + for (String field : fieldsNames) { builder.startObject(field).field("type", field.substring(5)).endObject(); } }); - + String q = "SELECT test_byte, test_integer, test_long, test_short, test_double, test_float, test_keyword, " - + "test_boolean, test_date FROM test"; - doWithQuery(q, (r) -> assertColumnNamesAndLabels(r.getMetaData(), fieldsNames)); + + "test_boolean, test_date FROM test"; + doWithQuery(q, r -> assertColumnNamesAndLabels(r.getMetaData(), fieldsNames)); q = "SELECT test_byte AS b, test_integer AS i, test_long AS l, test_short AS s, test_double AS d, test_float AS f, " - + "test_keyword AS k, test_boolean AS bool, test_date AS dt FROM test"; - doWithQuery(q, (r) -> assertColumnNamesAndLabels(r.getMetaData(), new String[] {"b", "i", "l", "s", "d", "f", "k", "bool", "dt"})); + + "test_keyword AS k, test_boolean AS bool, test_date AS dt FROM test"; + doWithQuery(q, r -> assertColumnNamesAndLabels(r.getMetaData(), new String[] { "b", "i", "l", "s", "d", "f", "k", "bool", "dt" })); } - + private void doWithQuery(String query, CheckedConsumer consumer) throws SQLException { try (Connection connection = esJdbc()) { try (PreparedStatement statement = connection.prepareStatement(query)) { @@ -46,11 +55,11 @@ public class ResultSetMetaDataTestCase extends JdbcIntegrationTestCase { } } } - - private void assertColumnNamesAndLabels(ResultSetMetaData metadata, String[] names) throws SQLException { - for(int i = 0; i < fieldsNames.length; i++) { - assertEquals(names[i], metadata.getColumnName(i + 1)); - assertEquals(names[i], metadata.getColumnLabel(i + 1)); + + private void assertColumnNamesAndLabels(ResultSetMetaData metaData, String[] names) throws SQLException { + for (int i = 0; i < fieldsNames.length; i++) { + assertEquals(names[i], metaData.getColumnName(i + 1)); + assertEquals(names[i], metaData.getColumnLabel(i + 1)); } } } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetTestCase.java similarity index 65% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetTestCase.java index 546d243bc47..1f86a34eed1 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ResultSetTestCase.java @@ -64,29 +64,31 @@ import static java.util.Calendar.MINUTE; import static java.util.Calendar.MONTH; import static java.util.Calendar.SECOND; import static java.util.Calendar.YEAR; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.JDBC_TIMEZONE; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.asDate; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.asTime; -import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.of; -public class ResultSetTestCase extends JdbcIntegrationTestCase { - - static final Set fieldsNames = Stream.of("test_byte", "test_integer", "test_long", "test_short", "test_double", - "test_float", "test_keyword") - .collect(Collectors.toCollection(HashSet::new)); +public abstract class ResultSetTestCase extends JdbcIntegrationTestCase { + + static final Set fieldsNames = Stream.of( + "test_byte", + "test_integer", + "test_long", + "test_short", + "test_double", + "test_float", + "test_keyword" + ).collect(Collectors.toCollection(HashSet::new)); static final Map, SQLType> dateTimeTestingFields = new HashMap<>(); static final String SELECT_ALL_FIELDS = "SELECT test_boolean, test_byte, test_integer," - + "test_long, test_short, test_double, test_float, test_keyword, test_date FROM test"; + + "test_long, test_short, test_double, test_float, test_keyword, test_date FROM test"; static final String SELECT_WILDCARD = "SELECT * FROM test"; static { - dateTimeTestingFields.put(new Tuple("test_boolean", true), EsType.BOOLEAN); - dateTimeTestingFields.put(new Tuple("test_byte", 1), EsType.BYTE); - dateTimeTestingFields.put(new Tuple("test_integer", 1), EsType.INTEGER); - dateTimeTestingFields.put(new Tuple("test_long", 1L), EsType.LONG); - dateTimeTestingFields.put(new Tuple("test_short", 1), EsType.SHORT); - dateTimeTestingFields.put(new Tuple("test_double", 1d), EsType.DOUBLE); - dateTimeTestingFields.put(new Tuple("test_float", 1f), EsType.FLOAT); - dateTimeTestingFields.put(new Tuple("test_keyword", "true"), EsType.KEYWORD); + dateTimeTestingFields.put(new Tuple<>("test_boolean", true), EsType.BOOLEAN); + dateTimeTestingFields.put(new Tuple<>("test_byte", 1), EsType.BYTE); + dateTimeTestingFields.put(new Tuple<>("test_integer", 1), EsType.INTEGER); + dateTimeTestingFields.put(new Tuple<>("test_long", 1L), EsType.LONG); + dateTimeTestingFields.put(new Tuple<>("test_short", 1), EsType.SHORT); + dateTimeTestingFields.put(new Tuple<>("test_double", 1d), EsType.DOUBLE); + dateTimeTestingFields.put(new Tuple<>("test_float", 1f), EsType.FLOAT); + dateTimeTestingFields.put(new Tuple<>("test_keyword", "true"), EsType.KEYWORD); } private String timeZoneId; @@ -96,10 +98,10 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { this.timeZoneId = randomKnownTimeZone(); } - public void testMultiValueFieldWithMultiValueLeniencyEnabled() throws Exception { + public void testMultiValueFieldWithMultiValueLeniencyEnabled() throws IOException, SQLException { createTestDataForMultiValueTests(); - doWithQuery(() -> esWithLeniency(true), "SELECT int, keyword FROM test", (results) -> { + doWithQuery(() -> esWithLeniency(true), "SELECT int, keyword FROM test", results -> { results.next(); Object number = results.getObject(1); Object string = results.getObject(2); @@ -109,60 +111,66 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testMultiValueFieldWithMultiValueLeniencyDisabled() throws Exception { + public void testMultiValueFieldWithMultiValueLeniencyDisabled() throws IOException { createTestDataForMultiValueTests(); - SQLException expected = expectThrows(SQLException.class, - () -> doWithQuery(() -> esWithLeniency(false), "SELECT int, keyword FROM test", (results) -> { - })); + SQLException expected = expectThrows( + SQLException.class, + () -> doWithQuery(() -> esWithLeniency(false), "SELECT int, keyword FROM test", results -> {}) + ); assertTrue(expected.getMessage().contains("Arrays (returned by [int]) are not supported")); - + // default has multi value disabled - expected = expectThrows(SQLException.class, - () -> doWithQuery(() -> esJdbc(), "SELECT int, keyword FROM test", (results) -> { - })); + expectThrows(SQLException.class, () -> doWithQuery(this::esJdbc, "SELECT int, keyword FROM test", results -> {})); } - - public void testMultiValueFields_InsideObjects_WithMultiValueLeniencyEnabled() throws Exception { + + public void testMultiValueFields_InsideObjects_WithMultiValueLeniencyEnabled() throws IOException, SQLException { createTestDataForMultiValuesInObjectsTests(); - doWithQuery(() -> esWithLeniency(true), "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword FROM test", - (results) -> { - results.next(); - Object number = results.getObject(1); - Object text = results.getObject(2); - Object keyword = results.getObject(3); - assertEquals(-25, number); - assertEquals("-25", text); - assertEquals("-25", keyword); - assertFalse(results.next()); - }); + doWithQuery( + () -> esWithLeniency(true), + "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword FROM test", + results -> { + results.next(); + Object number = results.getObject(1); + Object text = results.getObject(2); + Object keyword = results.getObject(3); + assertEquals(-25, number); + assertEquals("-25", text); + assertEquals("-25", keyword); + assertFalse(results.next()); + } + ); } - - public void testMultiValueFields_InsideObjects_WithMultiValueLeniencyDisabled() throws Exception { + + public void testMultiValueFields_InsideObjects_WithMultiValueLeniencyDisabled() throws IOException { createTestDataForMultiValuesInObjectsTests(); - SQLException expected = expectThrows(SQLException.class, - () -> doWithQuery(() -> esWithLeniency(false), "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword" - + " FROM test", (results) -> { - })); + SQLException expected = expectThrows( + SQLException.class, + () -> doWithQuery( + () -> esWithLeniency(false), + "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword" + " FROM test", + results -> {} + ) + ); assertTrue(expected.getMessage().contains("Arrays (returned by [object.intsubfield]) are not supported")); - + // default has multi value disabled - expected = expectThrows(SQLException.class, - () -> doWithQuery(() -> esJdbc(), "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword", - (results) -> { - })); + expectThrows( + SQLException.class, + () -> doWithQuery(this::esJdbc, "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword", results -> {}) + ); } // Byte values testing - public void testGettingValidByteWithoutCasting() throws Exception { + public void testGettingValidByteWithoutCasting() throws IOException, SQLException { List byteTestValues = createTestDataForNumericValueTests(ESTestCase::randomByte); byte random1 = byteTestValues.get(0); byte random2 = byteTestValues.get(1); byte random3 = byteTestValues.get(2); - doWithQuery("SELECT test_byte, test_null_byte, test_keyword FROM test", (results) -> { + doWithQuery("SELECT test_byte, test_null_byte, test_keyword FROM test", results -> { ResultSetMetaData resultSetMetaData = results.getMetaData(); results.next(); @@ -173,28 +181,28 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(random1, results.getByte("test_byte")); assertEquals(random1, (byte) results.getObject("test_byte", Byte.class)); assertTrue(results.getObject(1) instanceof Byte); - + assertEquals(0, results.getByte(2)); assertTrue(results.wasNull()); - assertEquals(null, results.getObject("test_null_byte")); + assertNull(results.getObject("test_null_byte")); assertTrue(results.wasNull()); - + assertTrue(results.next()); assertEquals(random2, results.getByte(1)); assertEquals(random2, results.getByte("test_byte")); assertTrue(results.getObject(1) instanceof Byte); assertEquals(random3, results.getByte("test_keyword")); - + assertFalse(results.next()); }); } - - public void testGettingValidByteWithCasting() throws Exception { - Map map = createTestDataForNumericValueTypes(() -> randomByte()); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + public void testGettingValidByteWithCasting() throws IOException, SQLException { + Map map = createTestDataForNumericValueTypes(ESTestCase::randomByte); + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - for(Entry e : map.entrySet()) { + for (Entry e : map.entrySet()) { byte actual = results.getObject(e.getKey(), Byte.class); if (e.getValue() instanceof Double) { assertEquals("For field " + e.getKey(), Math.round(e.getValue().doubleValue()), results.getByte(e.getKey())); @@ -210,14 +218,14 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testGettingInvalidByte() throws Exception { + public void testGettingInvalidByte() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_keyword").field("type", "keyword").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - + int intNotByte = randomIntBetween(Byte.MAX_VALUE + 1, Integer.MAX_VALUE); long longNotByte = randomLongBetween(Byte.MAX_VALUE + 1, Long.MAX_VALUE); short shortNotByte = (short) randomIntBetween(Byte.MAX_VALUE + 1, Short.MAX_VALUE); @@ -225,10 +233,11 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { float floatNotByte = randomFloatBetween(Byte.MAX_VALUE + 1, Float.MAX_VALUE); String randomString = randomUnicodeOfCodepointLengthBetween(128, 256); long randomDate = randomNonNegativeLong(); - - String doubleErrorMessage = (doubleNotByte > Long.MAX_VALUE || doubleNotByte < Long.MIN_VALUE) ? - Double.toString(doubleNotByte) : Long.toString(Math.round(doubleNotByte)); - + + String doubleErrorMessage = (doubleNotByte > Long.MAX_VALUE || doubleNotByte < Long.MIN_VALUE) + ? Double.toString(doubleNotByte) + : Long.toString(Math.round(doubleNotByte)); + index("test", "1", builder -> { builder.field("test_integer", intNotByte); builder.field("test_long", longNotByte); @@ -238,59 +247,67 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", randomString); builder.field("test_date", randomDate); }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - + SQLException sqle = expectThrows(SQLException.class, () -> results.getByte("test_integer")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", intNotByte), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_integer", Byte.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", intNotByte), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getByte("test_short")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", shortNotByte), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_short", Byte.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", shortNotByte), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getByte("test_long")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Long.toString(longNotByte)), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_long", Byte.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Long.toString(longNotByte)), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getByte("test_double")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", doubleErrorMessage), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_double", Byte.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", doubleErrorMessage), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getByte("test_float")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotByte)), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_float", Byte.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotByte)), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getByte("test_keyword")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Byte]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Byte]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_keyword", Byte.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Byte]", randomString), - sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Byte]", randomString), + sqle.getMessage() + ); + sqle = expectThrows(SQLException.class, () -> results.getByte("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Byte]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Byte]", asDateString(randomDate)), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", Byte.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Byte]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Byte]", asDateString(randomDate)), + sqle.getMessage() + ); }); } - + // Short values testing - public void testGettingValidShortWithoutCasting() throws Exception { + public void testGettingValidShortWithoutCasting() throws IOException, SQLException { List shortTestValues = createTestDataForNumericValueTests(ESTestCase::randomShort); short random1 = shortTestValues.get(0); short random2 = shortTestValues.get(1); short random3 = shortTestValues.get(2); - doWithQuery("SELECT test_short, test_null_short, test_keyword FROM test", (results) -> { + doWithQuery("SELECT test_short, test_null_short, test_keyword FROM test", results -> { ResultSetMetaData resultSetMetaData = results.getMetaData(); results.next(); @@ -301,28 +318,28 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(random1, results.getShort("test_short")); assertEquals(random1, results.getObject("test_short")); assertTrue(results.getObject(1) instanceof Short); - + assertEquals(0, results.getShort(2)); assertTrue(results.wasNull()); - assertEquals(null, results.getObject("test_null_short")); + assertNull(results.getObject("test_null_short")); assertTrue(results.wasNull()); - + assertTrue(results.next()); assertEquals(random2, results.getShort(1)); assertEquals(random2, results.getShort("test_short")); assertTrue(results.getObject(1) instanceof Short); assertEquals(random3, results.getShort("test_keyword")); - + assertFalse(results.next()); }); } - - public void testGettingValidShortWithCasting() throws Exception { - Map map = createTestDataForNumericValueTypes(() -> randomShort()); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + public void testGettingValidShortWithCasting() throws IOException, SQLException { + Map map = createTestDataForNumericValueTypes(ESTestCase::randomShort); + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - for(Entry e : map.entrySet()) { + for (Entry e : map.entrySet()) { short actual = results.getObject(e.getKey(), Short.class); if (e.getValue() instanceof Double) { assertEquals("For field " + e.getKey(), Math.round(e.getValue().doubleValue()), results.getShort(e.getKey())); @@ -331,31 +348,31 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals("For field " + e.getKey(), Math.round(e.getValue().floatValue()), results.getShort(e.getKey())); assertEquals("For field " + e.getKey(), Math.round(e.getValue().floatValue()), actual); } else { - assertEquals("For field " + e.getKey(), - e.getValue().shortValue(), results.getShort(e.getKey())); + assertEquals("For field " + e.getKey(), e.getValue().shortValue(), results.getShort(e.getKey())); assertEquals("For field " + e.getKey(), e.getValue().shortValue(), actual); } } }); } - public void testGettingInvalidShort() throws Exception { + public void testGettingInvalidShort() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_keyword").field("type", "keyword").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - + int intNotShort = randomIntBetween(Short.MAX_VALUE + 1, Integer.MAX_VALUE); long longNotShort = randomLongBetween(Short.MAX_VALUE + 1, Long.MAX_VALUE); double doubleNotShort = randomDoubleBetween(Short.MAX_VALUE + 1, Double.MAX_VALUE, true); float floatNotShort = randomFloatBetween(Short.MAX_VALUE + 1, Float.MAX_VALUE); String randomString = randomUnicodeOfCodepointLengthBetween(128, 256); long randomDate = randomNonNegativeLong(); - - String doubleErrorMessage = (doubleNotShort > Long.MAX_VALUE || doubleNotShort < Long.MIN_VALUE) ? - Double.toString(doubleNotShort) : Long.toString(Math.round(doubleNotShort)); + + String doubleErrorMessage = (doubleNotShort > Long.MAX_VALUE || doubleNotShort < Long.MIN_VALUE) + ? Double.toString(doubleNotShort) + : Long.toString(Math.round(doubleNotShort)); index("test", "1", builder -> { builder.field("test_integer", intNotShort); @@ -365,54 +382,62 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", randomString); builder.field("test_date", randomDate); }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - + SQLException sqle = expectThrows(SQLException.class, () -> results.getShort("test_integer")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", intNotShort), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_integer", Short.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", intNotShort), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getShort("test_long")); - assertEquals(format(Locale.ROOT, "Numeric %s out of range", Long.toString(longNotShort)), sqle.getMessage()); + assertEquals(format(Locale.ROOT, "Numeric %s out of range", longNotShort), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_long", Short.class)); - assertEquals(format(Locale.ROOT, "Numeric %s out of range", Long.toString(longNotShort)), sqle.getMessage()); - + assertEquals(format(Locale.ROOT, "Numeric %s out of range", longNotShort), sqle.getMessage()); + sqle = expectThrows(SQLException.class, () -> results.getShort("test_double")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", doubleErrorMessage), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_double", Short.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", doubleErrorMessage), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getShort("test_float")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotShort)), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_float", Short.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotShort)), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getShort("test_keyword")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Short]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Short]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_keyword", Short.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Short]", randomString), - sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Short]", randomString), + sqle.getMessage() + ); + sqle = expectThrows(SQLException.class, () -> results.getShort("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Short]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Short]", asDateString(randomDate)), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", Short.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Short]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Short]", asDateString(randomDate)), + sqle.getMessage() + ); }); } - + // Integer values testing - public void testGettingValidIntegerWithoutCasting() throws Exception { + public void testGettingValidIntegerWithoutCasting() throws IOException, SQLException { List integerTestValues = createTestDataForNumericValueTests(ESTestCase::randomInt); int random1 = integerTestValues.get(0); int random2 = integerTestValues.get(1); int random3 = integerTestValues.get(2); - doWithQuery("SELECT test_integer,test_null_integer,test_keyword FROM test", (results) -> { + doWithQuery("SELECT test_integer,test_null_integer,test_keyword FROM test", results -> { ResultSetMetaData resultSetMetaData = results.getMetaData(); results.next(); @@ -423,28 +448,28 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(random1, results.getInt("test_integer")); assertEquals(random1, (int) results.getObject("test_integer", Integer.class)); assertTrue(results.getObject(1) instanceof Integer); - + assertEquals(0, results.getInt(2)); assertTrue(results.wasNull()); - assertEquals(null, results.getObject("test_null_integer")); + assertNull(results.getObject("test_null_integer")); assertTrue(results.wasNull()); - + assertTrue(results.next()); assertEquals(random2, results.getInt(1)); assertEquals(random2, results.getInt("test_integer")); assertTrue(results.getObject(1) instanceof Integer); assertEquals(random3, results.getInt("test_keyword")); - + assertFalse(results.next()); }); } - - public void testGettingValidIntegerWithCasting() throws Exception { - Map map = createTestDataForNumericValueTypes(() -> randomInt()); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + public void testGettingValidIntegerWithCasting() throws IOException, SQLException { + Map map = createTestDataForNumericValueTypes(ESTestCase::randomInt); + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - for(Entry e : map.entrySet()) { + for (Entry e : map.entrySet()) { int actual = results.getObject(e.getKey(), Integer.class); if (e.getValue() instanceof Double) { assertEquals("For field " + e.getKey(), Math.round(e.getValue().doubleValue()), results.getInt(e.getKey())); @@ -460,22 +485,23 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testGettingInvalidInteger() throws Exception { + public void testGettingInvalidInteger() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_keyword").field("type", "keyword").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - + long longNotInt = randomLongBetween(getMaxIntPlusOne(), Long.MAX_VALUE); double doubleNotInt = randomDoubleBetween(getMaxIntPlusOne().doubleValue(), Double.MAX_VALUE, true); float floatNotInt = randomFloatBetween(getMaxIntPlusOne().floatValue(), Float.MAX_VALUE); String randomString = randomUnicodeOfCodepointLengthBetween(128, 256); long randomDate = randomNonNegativeLong(); - - String doubleErrorMessage = (doubleNotInt > Long.MAX_VALUE || doubleNotInt < Long.MIN_VALUE) ? - Double.toString(doubleNotInt) : Long.toString(Math.round(doubleNotInt)); + + String doubleErrorMessage = (doubleNotInt > Long.MAX_VALUE || doubleNotInt < Long.MIN_VALUE) + ? Double.toString(doubleNotInt) + : Long.toString(Math.round(doubleNotInt)); index("test", "1", builder -> { builder.field("test_long", longNotInt); @@ -484,49 +510,57 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", randomString); builder.field("test_date", randomDate); }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - + SQLException sqle = expectThrows(SQLException.class, () -> results.getInt("test_long")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Long.toString(longNotInt)), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_long", Integer.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Long.toString(longNotInt)), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getInt("test_double")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", doubleErrorMessage), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_double", Integer.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", doubleErrorMessage), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getInt("test_float")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotInt)), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_float", Integer.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotInt)), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getInt("test_keyword")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Integer]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Integer]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_keyword", Integer.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Integer]", randomString), - sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Integer]", randomString), + sqle.getMessage() + ); + sqle = expectThrows(SQLException.class, () -> results.getInt("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Integer]", - asDateString(randomDate)), sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Integer]", asDateString(randomDate)), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", Integer.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Integer]", - asDateString(randomDate)), sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Integer]", asDateString(randomDate)), + sqle.getMessage() + ); }); } - + // Long values testing - public void testGettingValidLongWithoutCasting() throws Exception { + public void testGettingValidLongWithoutCasting() throws IOException, SQLException { List longTestValues = createTestDataForNumericValueTests(ESTestCase::randomLong); long random1 = longTestValues.get(0); long random2 = longTestValues.get(1); long random3 = longTestValues.get(2); - doWithQuery("SELECT test_long, test_null_long, test_keyword FROM test", (results) -> { + doWithQuery("SELECT test_long, test_null_long, test_keyword FROM test", results -> { ResultSetMetaData resultSetMetaData = results.getMetaData(); results.next(); @@ -537,28 +571,28 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(random1, results.getLong("test_long")); assertEquals(random1, (long) results.getObject("test_long", Long.class)); assertTrue(results.getObject(1) instanceof Long); - + assertEquals(0, results.getLong(2)); assertTrue(results.wasNull()); - assertEquals(null, results.getObject("test_null_long")); + assertNull(results.getObject("test_null_long")); assertTrue(results.wasNull()); - + assertTrue(results.next()); assertEquals(random2, results.getLong(1)); assertEquals(random2, results.getLong("test_long")); assertTrue(results.getObject(1) instanceof Long); assertEquals(random3, results.getLong("test_keyword")); - + assertFalse(results.next()); }); } - - public void testGettingValidLongWithCasting() throws Exception { - Map map = createTestDataForNumericValueTypes(() -> randomLong()); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + public void testGettingValidLongWithCasting() throws IOException, SQLException { + Map map = createTestDataForNumericValueTypes(ESTestCase::randomLong); + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - for(Entry e : map.entrySet()) { + for (Entry e : map.entrySet()) { long actual = results.getObject(e.getKey(), Long.class); if (e.getValue() instanceof Float) { assertEquals("For field " + e.getKey(), e.getValue(), Long.valueOf(results.getLong(e.getKey())).floatValue()); @@ -571,15 +605,15 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testGettingInvalidLong() throws Exception { + public void testGettingInvalidLong() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_keyword").field("type", "keyword").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - - double doubleNotLong = randomDoubleBetween(getMaxLongPlusOne().doubleValue(), Double.MAX_VALUE, true); + + double doubleNotLong = randomDoubleBetween(getMaxLongPlusOne(), Double.MAX_VALUE, true); float floatNotLong = randomFloatBetween(getMaxLongPlusOne().floatValue(), Float.MAX_VALUE); String randomString = randomUnicodeOfCodepointLengthBetween(128, 256); long randomDate = randomNonNegativeLong(); @@ -590,44 +624,52 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", randomString); builder.field("test_date", randomDate); }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - + SQLException sqle = expectThrows(SQLException.class, () -> results.getLong("test_double")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(doubleNotLong)), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_double", Long.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(doubleNotLong)), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getLong("test_float")); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotLong)), sqle.getMessage()); sqle = expectThrows(SQLException.class, () -> results.getObject("test_float", Long.class)); assertEquals(format(Locale.ROOT, "Numeric %s out of range", Double.toString(floatNotLong)), sqle.getMessage()); - + sqle = expectThrows(SQLException.class, () -> results.getLong("test_keyword")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Long]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Long]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_keyword", Long.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Long]", randomString), - sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Long]", randomString), + sqle.getMessage() + ); + sqle = expectThrows(SQLException.class, () -> results.getLong("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Long]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Long]", asDateString(randomDate)), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", Long.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Long]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Long]", asDateString(randomDate)), + sqle.getMessage() + ); }); } - + // Double values testing - public void testGettingValidDoubleWithoutCasting() throws Exception { + public void testGettingValidDoubleWithoutCasting() throws IOException, SQLException { List doubleTestValues = createTestDataForNumericValueTests(ESTestCase::randomDouble); double random1 = doubleTestValues.get(0); double random2 = doubleTestValues.get(1); double random3 = doubleTestValues.get(2); - doWithQuery("SELECT test_double, test_null_double, test_keyword FROM test", (results) -> { + doWithQuery("SELECT test_double, test_null_double, test_keyword FROM test", results -> { ResultSetMetaData resultSetMetaData = results.getMetaData(); results.next(); @@ -638,49 +680,51 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(random1, results.getDouble("test_double"), 0.0d); assertEquals(random1, results.getObject("test_double", Double.class), 0.0d); assertTrue(results.getObject(1) instanceof Double); - + assertEquals(0, results.getDouble(2), 0.0d); assertTrue(results.wasNull()); - assertEquals(null, results.getObject("test_null_double")); + assertNull(results.getObject("test_null_double")); assertTrue(results.wasNull()); - + assertTrue(results.next()); assertEquals(random2, results.getDouble(1), 0.0d); assertEquals(random2, results.getDouble("test_double"), 0.0d); assertTrue(results.getObject(1) instanceof Double); assertEquals(random3, results.getDouble("test_keyword"), 0.0d); - + assertFalse(results.next()); }); } - - public void testGettingValidDoubleWithCasting() throws Exception { - Map map = createTestDataForNumericValueTypes(() -> randomDouble()); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + public void testGettingValidDoubleWithCasting() throws IOException, SQLException { + Map map = createTestDataForNumericValueTypes(ESTestCase::randomDouble); + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - for(Entry e : map.entrySet()) { + for (Entry e : map.entrySet()) { if (e.getValue() instanceof Float) { assertEquals("For field " + e.getKey(), e.getValue(), Double.valueOf(results.getDouble(e.getKey())).floatValue()); - assertEquals("For field " + e.getKey(), - e.getValue(), Double.valueOf(results.getObject(e.getKey(), Double.class)).floatValue()); + assertEquals( + "For field " + e.getKey(), + e.getValue(), + Double.valueOf(results.getObject(e.getKey(), Double.class)).floatValue() + ); } else { assertEquals("For field " + e.getKey(), e.getValue().doubleValue(), results.getDouble(e.getKey()), 0.0d); - assertEquals("For field " + e.getKey(), - e.getValue().doubleValue(), results.getObject(e.getKey(), Double.class), 0.0d); + assertEquals("For field " + e.getKey(), e.getValue().doubleValue(), results.getObject(e.getKey(), Double.class), 0.0d); } } }); } - public void testGettingInvalidDouble() throws Exception { + public void testGettingInvalidDouble() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_keyword").field("type", "keyword").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - + String randomString = randomUnicodeOfCodepointLengthBetween(128, 256); long randomDate = randomNonNegativeLong(); @@ -688,36 +732,44 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", randomString); builder.field("test_date", randomDate); }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - + SQLException sqle = expectThrows(SQLException.class, () -> results.getDouble("test_keyword")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Double]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Double]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_keyword", Double.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Double]", randomString), - sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Double]", randomString), + sqle.getMessage() + ); + sqle = expectThrows(SQLException.class, () -> results.getDouble("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Double]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Double]", asDateString(randomDate)), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", Double.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Double]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Double]", asDateString(randomDate)), + sqle.getMessage() + ); }); } - + // Float values testing - public void testGettingValidFloatWithoutCasting() throws Exception { + public void testGettingValidFloatWithoutCasting() throws IOException, SQLException { List floatTestValues = createTestDataForNumericValueTests(ESTestCase::randomFloat); float random1 = floatTestValues.get(0); float random2 = floatTestValues.get(1); float random3 = floatTestValues.get(2); - doWithQuery("SELECT test_float, test_null_float, test_keyword FROM test", (results) -> { + doWithQuery("SELECT test_float, test_null_float, test_keyword FROM test", results -> { ResultSetMetaData resultSetMetaData = results.getMetaData(); - + results.next(); assertEquals(3, resultSetMetaData.getColumnCount()); assertEquals(Types.REAL, resultSetMetaData.getColumnType(1)); @@ -726,43 +778,42 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(random1, results.getFloat("test_float"), 0.0f); assertEquals(random1, results.getObject("test_float", Float.class), 0.0f); assertTrue(results.getObject(1) instanceof Float); - + assertEquals(0, results.getFloat(2), 0.0d); assertTrue(results.wasNull()); - assertEquals(null, results.getObject("test_null_float")); + assertNull(results.getObject("test_null_float")); assertTrue(results.wasNull()); - + assertTrue(results.next()); assertEquals(random2, results.getFloat(1), 0.0d); assertEquals(random2, results.getFloat("test_float"), 0.0d); assertTrue(results.getObject(1) instanceof Float); assertEquals(random3, results.getFloat("test_keyword"), 0.0d); - + assertFalse(results.next()); }); } - - public void testGettingValidFloatWithCasting() throws Exception { - Map map = createTestDataForNumericValueTypes(() -> randomFloat()); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + public void testGettingValidFloatWithCasting() throws IOException, SQLException { + Map map = createTestDataForNumericValueTypes(ESTestCase::randomFloat); + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - for(Entry e : map.entrySet()) { + for (Entry e : map.entrySet()) { assertEquals("For field " + e.getKey(), e.getValue().floatValue(), results.getFloat(e.getKey()), 0.0f); - assertEquals("For field " + e.getKey(), - e.getValue().floatValue(), results.getObject(e.getKey(), Float.class), 0.0f); + assertEquals("For field " + e.getKey(), e.getValue().floatValue(), results.getObject(e.getKey(), Float.class), 0.0f); } }); } - public void testGettingInvalidFloat() throws Exception { + public void testGettingInvalidFloat() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_keyword").field("type", "keyword").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - + String randomString = randomUnicodeOfCodepointLengthBetween(128, 256); long randomDate = randomNonNegativeLong(); @@ -770,41 +821,50 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", randomString); builder.field("test_date", randomDate); }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); SQLException sqle = expectThrows(SQLException.class, () -> results.getFloat("test_keyword")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Float]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Float]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_keyword", Float.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Float]", randomString), - sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [Float]", randomString), + sqle.getMessage() + ); + sqle = expectThrows(SQLException.class, () -> results.getFloat("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Float]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Float]", asDateString(randomDate)), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", Float.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Float]", asDateString(randomDate)), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Float]", asDateString(randomDate)), + sqle.getMessage() + ); }); } // // BigDecimal fetching testing // - static final Map, Integer> JAVA_TO_SQL_NUMERIC_TYPES_MAP = new HashMap, Integer>() {{ - put(Byte.class, Types.TINYINT); - put(Short.class, Types.SMALLINT); - put(Integer.class, Types.INTEGER); - put(Long.class, Types.BIGINT); - put(Float.class, Types.REAL); - put(Double.class, Types.DOUBLE); - // TODO: no half & scaled float testing - }}; + static final Map, Integer> JAVA_TO_SQL_NUMERIC_TYPES_MAP = new HashMap, Integer>() { + { + put(Byte.class, Types.TINYINT); + put(Short.class, Types.SMALLINT); + put(Integer.class, Types.INTEGER); + put(Long.class, Types.BIGINT); + put(Float.class, Types.REAL); + put(Double.class, Types.DOUBLE); + // TODO: no half & scaled float testing + } + }; - private static void validateBigDecimalWithoutCasting(ResultSet results, List testValues) - throws SQLException { + private static void validateBigDecimalWithoutCasting(ResultSet results, List testValues) throws SQLException { ResultSetMetaData resultSetMetaData = results.getMetaData(); @@ -841,7 +901,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertFalse(results.next()); } - public void testGettingValidBigDecimalFromBooleanWithoutCasting() throws Exception { + public void testGettingValidBigDecimalFromBooleanWithoutCasting() throws IOException, SQLException { createTestDataForBooleanValueTests(); doWithQuery("SELECT test_boolean, test_null_boolean, test_keyword FROM test", results -> { @@ -881,41 +941,65 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertFalse(results.next()); }); } - public void testGettingValidBigDecimalFromByteWithoutCasting() throws Exception { + + public void testGettingValidBigDecimalFromByteWithoutCasting() throws IOException, SQLException { List byteTestValues = createTestDataForNumericValueTests(ESTestCase::randomByte); - doWithQuery("SELECT test_byte, test_null_byte, test_keyword FROM test", byteTestValues, - ResultSetTestCase::validateBigDecimalWithoutCasting); + doWithQuery( + "SELECT test_byte, test_null_byte, test_keyword FROM test", + byteTestValues, + ResultSetTestCase::validateBigDecimalWithoutCasting + ); } - public void testGettingValidBigDecimalFromShortWithoutCasting() throws Exception { + + public void testGettingValidBigDecimalFromShortWithoutCasting() throws IOException, SQLException { List shortTestValues = createTestDataForNumericValueTests(ESTestCase::randomShort); - doWithQuery("SELECT test_short, test_null_short, test_keyword FROM test", shortTestValues, - ResultSetTestCase::validateBigDecimalWithoutCasting); + doWithQuery( + "SELECT test_short, test_null_short, test_keyword FROM test", + shortTestValues, + ResultSetTestCase::validateBigDecimalWithoutCasting + ); } - public void testGettingValidBigDecimalFromIntegerWithoutCasting() throws Exception { + + public void testGettingValidBigDecimalFromIntegerWithoutCasting() throws IOException, SQLException { List integerTestValues = createTestDataForNumericValueTests(ESTestCase::randomInt); - doWithQuery("SELECT test_integer, test_null_integer, test_keyword FROM test", integerTestValues, - ResultSetTestCase::validateBigDecimalWithoutCasting); + doWithQuery( + "SELECT test_integer, test_null_integer, test_keyword FROM test", + integerTestValues, + ResultSetTestCase::validateBigDecimalWithoutCasting + ); } - public void testGettingValidBigDecimalFromLongWithoutCasting() throws Exception { + + public void testGettingValidBigDecimalFromLongWithoutCasting() throws IOException, SQLException { List longTestValues = createTestDataForNumericValueTests(ESTestCase::randomLong); - doWithQuery("SELECT test_long, test_null_long, test_keyword FROM test", longTestValues, - ResultSetTestCase::validateBigDecimalWithoutCasting); + doWithQuery( + "SELECT test_long, test_null_long, test_keyword FROM test", + longTestValues, + ResultSetTestCase::validateBigDecimalWithoutCasting + ); } - public void testGettingValidBigDecimalFromFloatWithoutCasting() throws Exception { + + public void testGettingValidBigDecimalFromFloatWithoutCasting() throws IOException, SQLException { List floatTestValues = createTestDataForNumericValueTests(ESTestCase::randomFloat); - doWithQuery("SELECT test_float, test_null_float, test_keyword FROM test", floatTestValues, - ResultSetTestCase::validateBigDecimalWithoutCasting); + doWithQuery( + "SELECT test_float, test_null_float, test_keyword FROM test", + floatTestValues, + ResultSetTestCase::validateBigDecimalWithoutCasting + ); } - public void testGettingValidBigDecimalFromDoubleWithoutCasting() throws Exception { + + public void testGettingValidBigDecimalFromDoubleWithoutCasting() throws IOException, SQLException { List doubleTestValues = createTestDataForNumericValueTests(ESTestCase::randomDouble); - doWithQuery("SELECT test_double, test_null_double, test_keyword FROM test", doubleTestValues, - ResultSetTestCase::validateBigDecimalWithoutCasting); + doWithQuery( + "SELECT test_double, test_null_double, test_keyword FROM test", + doubleTestValues, + ResultSetTestCase::validateBigDecimalWithoutCasting + ); } - public void testGettingValidBigDecimalWithCasting() throws Exception { - Map map = createTestDataForNumericValueTypes(() -> randomDouble()); + public void testGettingValidBigDecimalWithCasting() throws IOException, SQLException { + Map map = createTestDataForNumericValueTypes(ESTestCase::randomDouble); - doWithQuery(SELECT_WILDCARD, (results) -> { + doWithQuery(SELECT_WILDCARD, results -> { results.next(); for (Entry e : map.entrySet()) { BigDecimal actualByObj = results.getObject(e.getKey(), BigDecimal.class); @@ -936,7 +1020,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testGettingInvalidBigDecimal() throws Exception { + public void testGettingInvalidBigDecimal() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { @@ -952,26 +1036,34 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_date", randomDate); }); - doWithQuery(SELECT_WILDCARD, (results) -> { + doWithQuery(SELECT_WILDCARD, results -> { results.next(); SQLException sqle = expectThrows(SQLException.class, () -> results.getBigDecimal("test_keyword")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [BigDecimal]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [BigDecimal]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_keyword", BigDecimal.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [BigDecimal]", randomString), - sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [KEYWORD] to [BigDecimal]", randomString), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getBigDecimal("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [BigDecimal]", - asDateString(randomDate)), sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [BigDecimal]", asDateString(randomDate)), + sqle.getMessage() + ); sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", BigDecimal.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [BigDecimal]", - asDateString(randomDate)), sqle.getMessage()); + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [BigDecimal]", asDateString(randomDate)), + sqle.getMessage() + ); }); } - public void testGettingBooleanValues() throws Exception { + public void testGettingBooleanValues() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { @@ -980,10 +1072,10 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); long randomDate1 = randomNonNegativeLong(); long randomDate2 = randomNonNegativeLong(); - + // true values indexSimpleDocumentWithTrueValues(randomDate1); - + // false values index("test", "2", builder -> { builder.field("test_boolean", false); @@ -996,78 +1088,90 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", "false"); builder.field("test_date", randomDate2); }); - + // other (non 0 = true) values index("test", "3", builder -> { - builder.field("test_byte", randomValueOtherThan((byte) 0, () -> randomByte())); - builder.field("test_integer", randomValueOtherThan(0, () -> randomInt())); - builder.field("test_long", randomValueOtherThan(0L, () -> randomLong())); - builder.field("test_short", randomValueOtherThan((short) 0, () -> randomShort())); - builder.field("test_double", randomValueOtherThanMany(i -> i < 1.0d && i > -1.0d && i < Double.MAX_VALUE - && i > Double.MIN_VALUE, - () -> randomDouble() * randomInt())); - builder.field("test_float", randomValueOtherThanMany(i -> i < 1.0f && i > -1.0f && i < Float.MAX_VALUE && i > Float.MIN_VALUE, - () -> randomFloat() * randomInt())); + builder.field("test_byte", randomValueOtherThan((byte) 0, ESTestCase::randomByte)); + builder.field("test_integer", randomValueOtherThan(0, ESTestCase::randomInt)); + builder.field("test_long", randomValueOtherThan(0L, ESTestCase::randomLong)); + builder.field("test_short", randomValueOtherThan((short) 0, ESTestCase::randomShort)); + builder.field( + "test_double", + randomValueOtherThanMany( + i -> i < 1.0d && i > -1.0d && i < Double.MAX_VALUE && i > Double.MIN_VALUE, + () -> randomDouble() * randomInt() + ) + ); + builder.field( + "test_float", + randomValueOtherThanMany( + i -> i < 1.0f && i > -1.0f && i < Float.MAX_VALUE && i > Float.MIN_VALUE, + () -> randomFloat() * randomInt() + ) + ); builder.field("test_keyword", "1"); }); - + // other false values - index("test", "4", builder -> { - builder.field("test_keyword", "0"); - }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + index("test", "4", builder -> builder.field("test_keyword", "0")); + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - assertEquals(true, results.getBoolean("test_boolean")); - for(String fld : fieldsNames) { - assertEquals("Expected: but was: for field " + fld, true, results.getBoolean(fld)); + assertTrue(results.getBoolean("test_boolean")); + for (String fld : fieldsNames) { + assertTrue("Expected: but was: for field " + fld, results.getBoolean(fld)); assertEquals("Expected: but was: for field " + fld, true, results.getObject(fld, Boolean.class)); } SQLException sqle = expectThrows(SQLException.class, () -> results.getBoolean("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Boolean]", - asDateString(randomDate1)), sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Boolean]", asDateString(randomDate1)), + sqle.getMessage() + ); + results.next(); - assertEquals(false, results.getBoolean("test_boolean")); - for(String fld : fieldsNames) { - assertEquals("Expected: but was: for field " + fld, false, results.getBoolean(fld)); + assertFalse(results.getBoolean("test_boolean")); + for (String fld : fieldsNames) { + assertFalse("Expected: but was: for field " + fld, results.getBoolean(fld)); assertEquals("Expected: but was: for field " + fld, false, results.getObject(fld, Boolean.class)); } sqle = expectThrows(SQLException.class, () -> results.getBoolean("test_date")); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Boolean]", - asDateString(randomDate2)), sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Boolean]", asDateString(randomDate2)), + sqle.getMessage() + ); + sqle = expectThrows(SQLException.class, () -> results.getObject("test_date", Boolean.class)); - assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Boolean]", - asDateString(randomDate2)), sqle.getMessage()); - + assertEquals( + format(Locale.ROOT, "Unable to convert value [%.128s] of type [DATETIME] to [Boolean]", asDateString(randomDate2)), + sqle.getMessage() + ); + results.next(); - for(String fld : fieldsNames.stream() - .filter((f) -> !f.equals("test_keyword")).collect(Collectors.toCollection(HashSet::new))) { - assertEquals("Expected: but was: for field " + fld, true, results.getBoolean(fld)); + for (String fld : fieldsNames.stream().filter(f -> !f.equals("test_keyword")).collect(Collectors.toCollection(HashSet::new))) { + assertTrue("Expected: but was: for field " + fld, results.getBoolean(fld)); assertEquals("Expected: but was: for field " + fld, true, results.getObject(fld, Boolean.class)); } - + results.next(); - assertEquals(false, results.getBoolean("test_keyword")); + assertFalse(results.getBoolean("test_keyword")); assertEquals(false, results.getObject("test_keyword", Boolean.class)); }); } - - public void testGettingDateWithoutCalendar() throws Exception { + + public void testGettingDateWithoutCalendar() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_boolean").field("type", "boolean").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - Long randomLongDate = randomNonNegativeLong(); + long randomLongDate = randomNonNegativeLong(); indexSimpleDocumentWithTrueValues(randomLongDate); - - doWithQuery(SELECT_ALL_FIELDS, (results) -> { + + doWithQuery(SELECT_ALL_FIELDS, results -> { results.next(); - java.sql.Date expectedDate = asDate(randomLongDate, getZoneFromOffset(randomLongDate)); + java.sql.Date expectedDate = JdbcTestUtils.asDate(randomLongDate, getZoneFromOffset(randomLongDate)); assertEquals(expectedDate, results.getDate("test_date")); assertEquals(expectedDate, results.getDate(9)); @@ -1078,24 +1182,22 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { validateErrorsForDateTestsWithoutCalendar(results::getDate); }); } - - public void testGettingDateWithCalendar() throws Exception { + + public void testGettingDateWithCalendar() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_boolean").field("type", "boolean").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - Long randomLongDate = randomNonNegativeLong(); + long randomLongDate = randomNonNegativeLong(); indexSimpleDocumentWithTrueValues(randomLongDate); - index("test", "2", builder -> { - builder.timeField("test_date", null); - }); - - String anotherTZId = randomValueOtherThan(timeZoneId, () -> randomKnownTimeZone()); + index("test", "2", builder -> builder.timeField("test_date", null)); + + String anotherTZId = randomValueOtherThan(timeZoneId, JdbcIntegrationTestCase::randomKnownTimeZone); Calendar c = Calendar.getInstance(TimeZone.getTimeZone(anotherTZId), Locale.ROOT); - - doWithQuery(SELECT_ALL_FIELDS, (results) -> { + + doWithQuery(SELECT_ALL_FIELDS, results -> { results.next(); c.setTimeInMillis(randomLongDate); c.set(HOUR_OF_DAY, 0); @@ -1105,16 +1207,16 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(results.getDate("test_date", c), new java.sql.Date(c.getTimeInMillis())); assertEquals(results.getDate(9, c), new java.sql.Date(c.getTimeInMillis())); - + // bulk validation for all fields which are not of type date validateErrorsForDateTimeTestsWithCalendar(c, results::getDate); - + results.next(); assertNull(results.getDate("test_date")); }); } - - public void testGettingTimeWithoutCalendar() throws Exception { + + public void testGettingTimeWithoutCalendar() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { @@ -1124,10 +1226,10 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { Long randomLongDate = randomNonNegativeLong(); indexSimpleDocumentWithTrueValues(randomLongDate); - doWithQuery(SELECT_ALL_FIELDS, (results) -> { + doWithQuery(SELECT_ALL_FIELDS, results -> { results.next(); - java.sql.Time expectedTime = asTime(randomLongDate, getZoneFromOffset(randomLongDate)); + java.sql.Time expectedTime = JdbcTestUtils.asTime(randomLongDate, getZoneFromOffset(randomLongDate)); assertEquals(expectedTime, results.getTime("test_date")); assertEquals(expectedTime, results.getTime(9)); @@ -1138,41 +1240,39 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testGettingTimeWithCalendar() throws Exception { + public void testGettingTimeWithCalendar() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_boolean").field("type", "boolean").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - Long randomLongDate = randomNonNegativeLong(); + long randomLongDate = randomNonNegativeLong(); indexSimpleDocumentWithTrueValues(randomLongDate); - index("test", "2", builder -> { - builder.timeField("test_date", null); - }); - - String anotherTZId = randomValueOtherThan(timeZoneId, () -> randomKnownTimeZone()); + index("test", "2", builder -> builder.timeField("test_date", null)); + + String anotherTZId = randomValueOtherThan(timeZoneId, JdbcIntegrationTestCase::randomKnownTimeZone); Calendar c = Calendar.getInstance(TimeZone.getTimeZone(anotherTZId), Locale.ROOT); - - doWithQuery(SELECT_ALL_FIELDS, (results) -> { + + doWithQuery(SELECT_ALL_FIELDS, results -> { results.next(); c.setTimeInMillis(randomLongDate); c.set(ERA, GregorianCalendar.AD); c.set(YEAR, 1970); c.set(MONTH, 0); c.set(DAY_OF_MONTH, 1); - + assertEquals(results.getTime("test_date", c), new java.sql.Time(c.getTimeInMillis())); assertEquals(results.getTime(9, c), new java.sql.Time(c.getTimeInMillis())); - + validateErrorsForDateTimeTestsWithCalendar(c, results::getTime); - + results.next(); assertNull(results.getTime("test_date")); }); } - - public void testGettingTimestampWithoutCalendar() throws Exception { + + public void testGettingTimestampWithoutCalendar() throws IOException, SQLException { createIndex("library"); updateMapping("library", builder -> { builder.startObject("release_date").field("type", "date").endObject(); @@ -1193,7 +1293,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("republish_date", 599616000000L); }); - doWithQuery("SELECT name, release_date, republish_date FROM library", (results) -> { + doWithQuery("SELECT name, release_date, republish_date FROM library", results -> { ResultSetMetaData resultSetMetaData = results.getMetaData(); results.next(); @@ -1202,7 +1302,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(randomMillis, results.getTimestamp(2).getTime()); assertTrue(results.getObject(2) instanceof Timestamp); assertEquals(randomMillis, ((Timestamp) results.getObject("release_date")).getTime()); - + assertNull(results.getTimestamp(3)); assertNull(results.getObject("republish_date")); @@ -1213,30 +1313,28 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertFalse(results.next()); }); } - - public void testGettingTimestampWithCalendar() throws Exception { + + public void testGettingTimestampWithCalendar() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_boolean").field("type", "boolean").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - Long randomLongDate = randomNonNegativeLong(); + long randomLongDate = randomNonNegativeLong(); indexSimpleDocumentWithTrueValues(randomLongDate); - index("test", "2", builder -> { - builder.timeField("test_date", null); - }); - - String anotherTZId = randomValueOtherThan(timeZoneId, () -> randomKnownTimeZone()); + index("test", "2", builder -> builder.timeField("test_date", null)); + + String anotherTZId = randomValueOtherThan(timeZoneId, JdbcIntegrationTestCase::randomKnownTimeZone); Calendar c = Calendar.getInstance(TimeZone.getTimeZone(anotherTZId), Locale.ROOT); - - doWithQuery(SELECT_ALL_FIELDS, (results) -> { + + doWithQuery(SELECT_ALL_FIELDS, results -> { results.next(); c.setTimeInMillis(randomLongDate); - + assertEquals(results.getTimestamp("test_date", c), new java.sql.Timestamp(c.getTimeInMillis())); assertEquals(results.getTimestamp(9, c), new java.sql.Timestamp(c.getTimeInMillis())); - + validateErrorsForDateTimeTestsWithCalendar(c, results::getTimestamp); results.next(); @@ -1244,12 +1342,12 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testScalarOnDates() throws Exception { + public void testScalarOnDates() throws IOException, SQLException { createIndex("test"); updateMapping("test", builder -> builder.startObject("test_date").field("type", "date").endObject()); // 2018-03-12 17:00:00 UTC - Long dateInMillis = 1520874000000L; + long dateInMillis = 1520874000000L; index("test", "1", builder -> builder.field("test_date", dateInMillis)); // UTC +10 hours @@ -1277,14 +1375,13 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { delete("test", "1"); // 2018-03-12 05:00:00 UTC - Long dateInMillis2 = 1520830800000L; + long dateInMillis2 = 1520830800000L; index("test", "1", builder -> builder.field("test_date", dateInMillis2)); // UTC -10 hours String timeZoneId2 = "Etc/GMT+10"; Calendar connCalendar2 = Calendar.getInstance(TimeZone.getTimeZone(timeZoneId2), Locale.ROOT); - doWithQueryAndTimezone("SELECT test_date, DAY_OF_MONTH(test_date) as day FROM test", timeZoneId2, results -> { results.next(); connCalendar2.setTimeInMillis(dateInMillis2); @@ -1304,12 +1401,12 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testGetDateType() throws Exception { + public void testGetDateType() throws IOException, SQLException { createIndex("test"); updateMapping("test", builder -> builder.startObject("test_date").field("type", "date").endObject()); // 2018-03-12 17:00:00 UTC - Long timeInMillis = 1520874000123L; + long timeInMillis = 1520874000123L; index("test", "1", builder -> builder.field("test_date", timeInMillis)); // UTC +10 hours @@ -1337,19 +1434,20 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(expectedTimestamp, results.getObject("date", java.sql.Timestamp.class)); }); } - - public void testGetDateTypeFromAggregation() throws Exception { + + public void testGetDateTypeFromAggregation() throws IOException, SQLException { createIndex("test"); updateMapping("test", builder -> builder.startObject("test_date").field("type", "date").endObject()); // 1984-05-02 14:59:12 UTC - Long timeInMillis = 452357952000L; + long timeInMillis = 452357952000L; index("test", "1", builder -> builder.field("test_date", timeInMillis)); doWithQueryAndTimezone("SELECT CONVERT(test_date, DATE) AS converted FROM test GROUP BY converted", "UTC", results -> { results.next(); ZonedDateTime zdt = ZonedDateTime.ofInstant(Instant.ofEpochMilli(timeInMillis), ZoneId.of("Z")) - .toLocalDate().atStartOfDay(ZoneId.of("Z")); + .toLocalDate() + .atStartOfDay(ZoneId.of("Z")); java.sql.Date expectedDate = new java.sql.Date(zdt.toInstant().toEpochMilli()); assertEquals(expectedDate, results.getDate("converted")); @@ -1365,12 +1463,12 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testGetTimeType() throws Exception { + public void testGetTimeType() throws IOException, SQLException { createIndex("test"); updateMapping("test", builder -> builder.startObject("test_date").field("type", "date").endObject()); // 2018-03-12 17:20:30.123 UTC - Long timeInMillis = 1520875230123L; + long timeInMillis = 1520875230123L; index("test", "1", builder -> builder.field("test_date", timeInMillis)); // UTC +10 hours @@ -1383,7 +1481,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { assertEquals(expectedDate, results.getDate("time")); assertEquals(expectedDate, results.getObject("time", java.sql.Date.class)); - java.sql.Time expectedTime = asTime(timeInMillis, ZoneId.of("Etc/GMT-10")); + java.sql.Time expectedTime = JdbcTestUtils.asTime(timeInMillis, ZoneId.of("Etc/GMT-10")); assertEquals(expectedTime, results.getTime("time")); assertEquals(expectedTime, results.getObject("time", java.sql.Time.class)); @@ -1393,14 +1491,14 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { }); } - public void testValidGetObjectCalls() throws Exception { + public void testValidGetObjectCalls() throws IOException, SQLException { createIndex("test"); updateMappingForNumericValuesTests("test"); updateMapping("test", builder -> { builder.startObject("test_boolean").field("type", "boolean").endObject(); builder.startObject("test_date").field("type", "date").endObject(); }); - + byte b = randomByte(); int i = randomInt(); long l = randomLong(); @@ -1408,9 +1506,9 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { double d = randomDouble(); float f = randomFloat(); boolean randomBool = randomBoolean(); - Long randomLongDate = randomNonNegativeLong(); + long randomLongDate = randomNonNegativeLong(); String randomString = randomUnicodeOfCodepointLengthBetween(128, 256); - + index("test", "1", builder -> { builder.field("test_byte", b); builder.field("test_integer", i); @@ -1422,81 +1520,81 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_date", randomLongDate); builder.field("test_boolean", randomBool); }); - - doWithQuery(SELECT_WILDCARD, (results) -> { + + doWithQuery(SELECT_WILDCARD, results -> { results.next(); - + assertEquals(b, results.getObject("test_byte")); assertTrue(results.getObject("test_byte") instanceof Byte); - + assertEquals(i, results.getObject("test_integer")); assertTrue(results.getObject("test_integer") instanceof Integer); - + assertEquals(l, results.getObject("test_long")); assertTrue(results.getObject("test_long") instanceof Long); - + assertEquals(s, results.getObject("test_short")); assertTrue(results.getObject("test_short") instanceof Short); - + assertEquals(d, results.getObject("test_double")); assertTrue(results.getObject("test_double") instanceof Double); - + assertEquals(f, results.getObject("test_float")); assertTrue(results.getObject("test_float") instanceof Float); - + assertEquals(randomString, results.getObject("test_keyword")); assertTrue(results.getObject("test_keyword") instanceof String); - + assertEquals(new Date(randomLongDate), results.getObject("test_date")); assertTrue(results.getObject("test_date") instanceof Timestamp); - + assertEquals(randomBool, results.getObject("test_boolean")); assertTrue(results.getObject("test_boolean") instanceof Boolean); }); } - - public void testGettingNullValues() throws Exception { + + public void testGettingNullValues() throws SQLException { String query = "SELECT CAST(NULL AS BOOLEAN) b, CAST(NULL AS TINYINT) t, CAST(NULL AS SMALLINT) s, CAST(NULL AS INTEGER) i," - + "CAST(NULL AS BIGINT) bi, CAST(NULL AS DOUBLE) d, CAST(NULL AS REAL) r, CAST(NULL AS FLOAT) f, CAST(NULL AS VARCHAR) v," - + "CAST(NULL AS DATE) dt, CAST(NULL AS TIME) tm, CAST(NULL AS TIMESTAMP) ts"; - doWithQuery(query, (results) -> { + + "CAST(NULL AS BIGINT) bi, CAST(NULL AS DOUBLE) d, CAST(NULL AS REAL) r, CAST(NULL AS FLOAT) f, CAST(NULL AS VARCHAR) v," + + "CAST(NULL AS DATE) dt, CAST(NULL AS TIME) tm, CAST(NULL AS TIMESTAMP) ts"; + doWithQuery(query, results -> { results.next(); - + assertNull(results.getObject("b")); assertFalse(results.getBoolean("b")); - + assertNull(results.getObject("t")); assertEquals(0, results.getByte("t")); - + assertNull(results.getObject("s")); assertEquals(0, results.getShort("s")); - + assertNull(results.getObject("i")); assertEquals(0, results.getInt("i")); - + assertNull(results.getObject("bi")); assertEquals(0, results.getLong("bi")); - + assertNull(results.getObject("d")); assertEquals(0.0d, results.getDouble("d"), 0d); - + assertNull(results.getObject("r")); assertEquals(0.0f, results.getFloat("r"), 0f); - + assertNull(results.getObject("f")); assertEquals(0.0f, results.getFloat("f"), 0f); - + assertNull(results.getObject("v")); assertNull(results.getString("v")); - + assertNull(results.getObject("dt")); assertNull(results.getDate("dt")); assertNull(results.getDate("dt", randomCalendar())); - + assertNull(results.getObject("tm")); assertNull(results.getTime("tm")); assertNull(results.getTime("tm", randomCalendar())); - + assertNull(results.getObject("ts")); assertNull(results.getTimestamp("ts")); assertNull(results.getTimestamp("ts", randomCalendar())); @@ -1506,212 +1604,211 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { /* * Checks StackOverflowError fix for https://github.com/elastic/elasticsearch/pull/31735 */ - public void testNoInfiniteRecursiveGetObjectCalls() throws Exception { + public void testNoInfiniteRecursiveGetObjectCalls() throws IOException, SQLException { index("library", "1", builder -> { builder.field("name", "Don Quixote"); builder.field("page_count", 1072); }); - Connection conn = esJdbc(); - PreparedStatement statement = conn.prepareStatement("SELECT * FROM library"); - ResultSet results = statement.executeQuery(); - - try { - results.next(); - results.getObject("name"); - results.getObject("page_count"); - results.getObject(1); - results.getObject(1, String.class); - results.getObject("page_count", Integer.class); - } catch (StackOverflowError soe) { - fail("Infinite recursive call on getObject() method"); + try ( + Connection conn = esJdbc(); + PreparedStatement statement = conn.prepareStatement("SELECT * FROM library"); + ResultSet results = statement.executeQuery() + ) { + try { + results.next(); + results.getObject("name"); + results.getObject("page_count"); + results.getObject(1); + results.getObject(1, String.class); + results.getObject("page_count", Integer.class); + } catch (StackOverflowError soe) { + fail("Infinite recursive call on getObject() method"); + } } } - - public void testUnsupportedGetMethods() throws IOException, SQLException { - index("test", "1", builder -> { - builder.field("test", "test"); - }); - Connection conn = esJdbc(); - PreparedStatement statement = conn.prepareStatement("SELECT * FROM test"); - ResultSet r = statement.executeQuery(); - - r.next(); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getAsciiStream("test"), "AsciiStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getAsciiStream(1), "AsciiStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getArray("test"), "Array not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getArray(1), "Array not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBinaryStream("test"), "BinaryStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBinaryStream(1), "BinaryStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBlob("test"), "Blob not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBlob(1), "Blob not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getCharacterStream("test"), "CharacterStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getCharacterStream(1), "CharacterStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getClob("test"), "Clob not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getClob(1), "Clob not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNCharacterStream("test"), "NCharacterStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNCharacterStream(1), "NCharacterStream not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNClob("test"), "NClob not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNClob(1), "NClob not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNString("test"), "NString not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNString(1), "NString not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRef("test"), "Ref not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRef(1), "Ref not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRowId("test"), "RowId not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRowId(1), "RowId not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getSQLXML("test"), "SQLXML not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getSQLXML(1), "SQLXML not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getURL("test"), "URL not supported"); - assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getURL(1), "URL not supported"); - } - - public void testUnsupportedUpdateMethods() throws IOException, SQLException { - index("test", "1", builder -> { - builder.field("test", "test"); - }); - Connection conn = esJdbc(); - PreparedStatement statement = conn.prepareStatement("SELECT * FROM test"); - ResultSet r = statement.executeQuery(); - - r.next(); - Blob b = null; - InputStream i = null; - Clob c = null; - NClob nc = null; - Reader rd = null; - - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBytes(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBytes("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateArray(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateArray("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream("", null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream("", null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBigDecimal(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBigDecimal("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream("", null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream("", null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob(1, b)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob(1, i)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob("", b)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob("", i)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob("", null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBoolean(1, false)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateBoolean("", false)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateByte(1, (byte) 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateByte("", (byte) 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream(1, null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream("", null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream("", null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob(1, c)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob(1, rd)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob("", c)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob("", rd)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob(1, null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob("", null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateDate(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateDate("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateDouble(1, 0d)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateDouble("", 0d)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateFloat(1, 0f)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateFloat("", 0f)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateInt(1, 0)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateInt("", 0)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateLong(1, 0L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateLong("", 0L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream(1, null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream("", null, 1L)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob(1, nc)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob(1, rd)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob("", nc)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob("", rd)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob("", null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNString(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNString("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNull(1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateNull("")); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject(1, null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject("", null, 1)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateRef(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateRef("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateRow()); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateRowId(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateRowId("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateSQLXML(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateSQLXML("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateShort(1, (short) 0)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateShort("", (short) 0)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateString(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateString("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateTime(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateTime("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateTimestamp(1, null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateTimestamp("", null)); - assertThrowsWritesUnsupportedForUpdate(() -> r.insertRow()); - assertThrowsWritesUnsupportedForUpdate(() -> r.updateRow()); - assertThrowsWritesUnsupportedForUpdate(() -> r.deleteRow()); - assertThrowsWritesUnsupportedForUpdate(() -> r.cancelRowUpdates()); - assertThrowsWritesUnsupportedForUpdate(() -> r.moveToInsertRow()); - assertThrowsWritesUnsupportedForUpdate(() -> r.refreshRow()); - assertThrowsWritesUnsupportedForUpdate(() -> r.moveToCurrentRow()); - assertThrowsWritesUnsupportedForUpdate(() -> r.rowUpdated()); - assertThrowsWritesUnsupportedForUpdate(() -> r.rowInserted()); - assertThrowsWritesUnsupportedForUpdate(() -> r.rowDeleted()); - } - - public void testResultSetNotInitialized() throws Exception { - createTestDataForNumericValueTypes(() -> randomInt()); - SQLException sqle = expectThrows(SQLException.class, () -> { - doWithQuery(SELECT_WILDCARD, rs -> { - assertFalse(rs.isAfterLast()); - rs.getObject(1); - }); - }); + public void testUnsupportedGetMethods() throws IOException, SQLException { + index("test", "1", builder -> builder.field("test", "test")); + try ( + Connection conn = esJdbc(); + PreparedStatement statement = conn.prepareStatement("SELECT * FROM test"); + ResultSet r = statement.executeQuery() + ) { + + r.next(); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getAsciiStream("test"), "AsciiStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getAsciiStream(1), "AsciiStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getArray("test"), "Array not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getArray(1), "Array not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBinaryStream("test"), "BinaryStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBinaryStream(1), "BinaryStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBlob("test"), "Blob not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getBlob(1), "Blob not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getCharacterStream("test"), "CharacterStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getCharacterStream(1), "CharacterStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getClob("test"), "Clob not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getClob(1), "Clob not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNCharacterStream("test"), "NCharacterStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNCharacterStream(1), "NCharacterStream not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNClob("test"), "NClob not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNClob(1), "NClob not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNString("test"), "NString not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getNString(1), "NString not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRef("test"), "Ref not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRef(1), "Ref not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRowId("test"), "RowId not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getRowId(1), "RowId not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getSQLXML("test"), "SQLXML not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getSQLXML(1), "SQLXML not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getURL("test"), "URL not supported"); + assertThrowsUnsupportedAndExpectErrorMessage(() -> r.getURL(1), "URL not supported"); + } + } + + public void testUnsupportedUpdateMethods() throws IOException, SQLException { + index("test", "1", builder -> builder.field("test", "test")); + try ( + Connection conn = esJdbc(); + PreparedStatement statement = conn.prepareStatement("SELECT * FROM test"); + ResultSet r = statement.executeQuery() + ) { + r.next(); + Blob b = null; + InputStream i = null; + Clob c = null; + NClob nc = null; + Reader rd = null; + + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBytes(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBytes("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateArray(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateArray("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream("", null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateAsciiStream("", null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBigDecimal(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBigDecimal("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream("", null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBinaryStream("", null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob(1, b)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob(1, i)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob("", b)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob("", i)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBlob("", null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBoolean(1, false)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateBoolean("", false)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateByte(1, (byte) 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateByte("", (byte) 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream(1, null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream("", null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateCharacterStream("", null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob(1, c)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob(1, rd)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob("", c)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob("", rd)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob(1, null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateClob("", null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateDate(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateDate("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateDouble(1, 0d)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateDouble("", 0d)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateFloat(1, 0f)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateFloat("", 0f)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateInt(1, 0)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateInt("", 0)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateLong(1, 0L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateLong("", 0L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream(1, null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNCharacterStream("", null, 1L)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob(1, nc)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob(1, rd)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob("", nc)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob("", rd)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNClob("", null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNString(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNString("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNull(1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateNull("")); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject(1, null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateObject("", null, 1)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateRef(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateRef("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateRow()); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateRowId(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateRowId("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateSQLXML(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateSQLXML("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateShort(1, (short) 0)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateShort("", (short) 0)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateString(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateString("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateTime(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateTime("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateTimestamp(1, null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateTimestamp("", null)); + assertThrowsWritesUnsupportedForUpdate(() -> r.insertRow()); + assertThrowsWritesUnsupportedForUpdate(() -> r.updateRow()); + assertThrowsWritesUnsupportedForUpdate(() -> r.deleteRow()); + assertThrowsWritesUnsupportedForUpdate(() -> r.cancelRowUpdates()); + assertThrowsWritesUnsupportedForUpdate(() -> r.moveToInsertRow()); + assertThrowsWritesUnsupportedForUpdate(() -> r.refreshRow()); + assertThrowsWritesUnsupportedForUpdate(() -> r.moveToCurrentRow()); + assertThrowsWritesUnsupportedForUpdate(() -> r.rowUpdated()); + assertThrowsWritesUnsupportedForUpdate(() -> r.rowInserted()); + assertThrowsWritesUnsupportedForUpdate(() -> r.rowDeleted()); + } + } + + public void testResultSetNotInitialized() throws IOException { + createTestDataForNumericValueTypes(ESTestCase::randomInt); + + SQLException sqle = expectThrows(SQLException.class, () -> doWithQuery(SELECT_WILDCARD, rs -> { + assertFalse(rs.isAfterLast()); + rs.getObject(1); + })); assertEquals("No row available", sqle.getMessage()); } - public void testResultSetConsumed() throws Exception { - createTestDataForNumericValueTypes(() -> randomInt()); + public void testResultSetConsumed() throws IOException { + createTestDataForNumericValueTypes(ESTestCase::randomInt); - SQLException sqle = expectThrows(SQLException.class, () -> { - doWithQuery("SELECT * FROM test LIMIT 1", rs -> { - assertFalse(rs.isAfterLast()); - assertTrue(rs.next()); - assertFalse(rs.isAfterLast()); - assertFalse(rs.next()); - assertTrue(rs.isAfterLast()); - rs.getObject(1); - }); - }); + SQLException sqle = expectThrows(SQLException.class, () -> doWithQuery("SELECT * FROM test LIMIT 1", rs -> { + assertFalse(rs.isAfterLast()); + assertTrue(rs.next()); + assertFalse(rs.isAfterLast()); + assertFalse(rs.next()); + assertTrue(rs.isAfterLast()); + rs.getObject(1); + })); assertEquals("No row available", sqle.getMessage()); } private void doWithQuery(String query, CheckedConsumer consumer) throws SQLException { doWithQuery(() -> esJdbc(timeZoneId), query, consumer); } - + private void doWithQueryAndTimezone(String query, String tz, CheckedConsumer consumer) throws SQLException { doWithQuery(() -> esJdbc(tz), query, consumer); } - + private void doWithQuery(CheckedSupplier con, String query, CheckedConsumer consumer) - throws SQLException { + throws SQLException { try (Connection connection = con.get()) { try (PreparedStatement statement = connection.prepareStatement(query)) { try (ResultSet results = statement.executeQuery()) { @@ -1721,14 +1818,20 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { } } - private void doWithQuery(String query, List testValues, - CheckedBiConsumer, SQLException> biConsumer) throws SQLException { + private void doWithQuery( + String query, + List testValues, + CheckedBiConsumer, SQLException> biConsumer + ) throws SQLException { doWithQuery(() -> esJdbc(timeZoneId), query, testValues, biConsumer); } - private void doWithQuery(CheckedSupplier con, String query, List testValues, - CheckedBiConsumer, SQLException> biConsumer) - throws SQLException { + private void doWithQuery( + CheckedSupplier con, + String query, + List testValues, + CheckedBiConsumer, SQLException> biConsumer + ) throws SQLException { try (Connection connection = con.get()) { try (PreparedStatement statement = connection.prepareStatement(query)) { try (ResultSet results = statement.executeQuery()) { @@ -1738,7 +1841,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { } } - protected static void createIndex(String index) throws Exception { + protected static void createIndex(String index) throws IOException { Request request = new Request("PUT", "/" + index); XContentBuilder createIndex = JsonXContent.contentBuilder().startObject(); createIndex.startObject("settings"); @@ -1750,7 +1853,6 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { createIndex.startObject("mappings"); { createIndex.startObject("properties"); - {} createIndex.endObject(); } createIndex.endObject().endObject(); @@ -1758,7 +1860,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { client().performRequest(request); } - protected static void updateMapping(String index, CheckedConsumer body) throws Exception { + protected static void updateMapping(String index, CheckedConsumer body) throws IOException { Request request = new Request("PUT", "/" + index + "/_mapping"); XContentBuilder updateMapping = JsonXContent.contentBuilder().startObject(); updateMapping.startObject("properties"); @@ -1771,16 +1873,16 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { client().performRequest(request); } - private void createTestDataForMultiValueTests() throws Exception { + private void createTestDataForMultiValueTests() throws IOException { createIndex("test"); updateMapping("test", builder -> { builder.startObject("int").field("type", "integer").endObject(); builder.startObject("keyword").field("type", "keyword").endObject(); }); - Integer[] values = randomArray(3, 15, s -> new Integer[s], () -> Integer.valueOf(randomInt(50))); + Integer[] values = randomArray(3, 15, Integer[]::new, () -> randomInt(50)); // add the known value as the first one in list. Parsing from _source the value will pick up the first value in the array. - values[0] = Integer.valueOf(-10); + values[0] = -10; String[] stringValues = new String[values.length]; for (int i = 0; i < values.length; i++) { @@ -1792,25 +1894,31 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.array("keyword", stringValues); }); } - - private void createTestDataForMultiValuesInObjectsTests() throws Exception { + + private void createTestDataForMultiValuesInObjectsTests() throws IOException { createIndex("test"); updateMapping("test", builder -> { builder.startObject("object") .startObject("properties") - .startObject("intsubfield").field("type", "integer").endObject() - .startObject("textsubfield") - .field("type", "text") - .startObject("fields").startObject("keyword").field("type", "keyword").endObject().endObject() - .endObject() + .startObject("intsubfield") + .field("type", "integer") .endObject() - .endObject(); + .startObject("textsubfield") + .field("type", "text") + .startObject("fields") + .startObject("keyword") + .field("type", "keyword") + .endObject() + .endObject() + .endObject() + .endObject() + .endObject(); builder.startObject("keyword").field("type", "keyword").endObject(); }); - Integer[] values = randomArray(3, 15, s -> new Integer[s], () -> Integer.valueOf(randomInt(50))); + Integer[] values = randomArray(3, 15, Integer[]::new, () -> randomInt(50)); // add the known value as the first one in list. Parsing from _source the value will pick up the first value in the array. - values[0] = Integer.valueOf(-25); + values[0] = -25; String[] stringValues = new String[values.length]; for (int i = 0; i < values.length; i++) { @@ -1820,12 +1928,9 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { index("test", "1", builder -> { builder.startArray("object"); - for (int i = 0; i < values.length; i++) { - builder.startObject() - .field("intsubfield", values[i]) - .field("textsubfield", stringValues[i]) - .endObject(); - } + for (int i = 0; i < values.length; i++) { + builder.startObject().field("intsubfield", values[i]).field("textsubfield", stringValues[i]).endObject(); + } builder.endArray(); }); } @@ -1833,7 +1938,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { /** * Creates test data for type specific get* method. It returns a list with the randomly generated test values. */ - private List createTestDataForNumericValueTests(Supplier numberGenerator) throws Exception { + private List createTestDataForNumericValueTests(Supplier numberGenerator) throws IOException { T random1 = numberGenerator.get(); T random2 = randomValueOtherThan(random1, numberGenerator); T random3 = randomValueOtherThanMany(Arrays.asList(random1, random2)::contains, numberGenerator); @@ -1860,14 +1965,14 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { return Arrays.asList(random1, random2, random3); } - private void createTestDataForBooleanValueTests() throws Exception { + private void createTestDataForBooleanValueTests() throws IOException { createIndex("test"); updateMapping("test", builder -> { builder.startObject("test_boolean").field("type", "boolean").endObject(); builder.startObject("test_null_boolean").field("type", "boolean").endObject(); builder.startObject("test_keyword").field("type", "keyword").endObject(); }); - + index("test", "1", builder -> { builder.field("test_boolean", Boolean.TRUE); builder.field("test_null_boolean", (Boolean) null); @@ -1879,7 +1984,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { builder.field("test_keyword", "0"); }); } - + private void indexSimpleDocumentWithTrueValues(Long randomLongDate) throws IOException { index("test", "1", builder -> { builder.field("test_boolean", true); @@ -1898,37 +2003,37 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { * Creates test data for all numeric get* methods. All values random and different from the other numeric fields already generated. * It returns a map containing the field name and its randomly generated value to be later used in checking the returned values. */ - private Map createTestDataForNumericValueTypes(Supplier randomGenerator) throws Exception { - Map map = new HashMap<>(); + private Map createTestDataForNumericValueTypes(Supplier randomGenerator) throws IOException { + Map map = new HashMap<>(); createIndex("test"); updateMappingForNumericValuesTests("test"); - + index("test", "1", builder -> { // random Byte byte test_byte = randomValueOtherThanMany(map::containsValue, randomGenerator).byteValue(); builder.field("test_byte", test_byte); map.put("test_byte", test_byte); - + // random Integer int test_integer = randomValueOtherThanMany(map::containsValue, randomGenerator).intValue(); builder.field("test_integer", test_integer); map.put("test_integer", test_integer); - + // random Short int test_short = randomValueOtherThanMany(map::containsValue, randomGenerator).shortValue(); builder.field("test_short", test_short); map.put("test_short", test_short); - + // random Long long test_long = randomValueOtherThanMany(map::containsValue, randomGenerator).longValue(); builder.field("test_long", test_long); map.put("test_long", test_long); - + // random Double double test_double = randomValueOtherThanMany(map::containsValue, randomGenerator).doubleValue(); builder.field("test_double", test_double); map.put("test_double", test_double); - + // random Float float test_float = randomValueOtherThanMany(map::containsValue, randomGenerator).floatValue(); builder.field("test_float", test_float); @@ -1937,14 +2042,14 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { return map; } - private static void updateMappingForNumericValuesTests(String indexName) throws Exception { + private static void updateMappingForNumericValuesTests(String indexName) throws IOException { updateMapping(indexName, builder -> { - for(String field : fieldsNames) { + for (String field : fieldsNames) { builder.startObject(field).field("type", field.substring(5)).endObject(); } }); } - + private void assertThrowsUnsupportedAndExpectErrorMessage(ThrowingRunnable runnable, String message) { SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, runnable); assertEquals(message, sqle.getMessage()); @@ -1953,43 +2058,46 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { private void assertThrowsWritesUnsupportedForUpdate(ThrowingRunnable r) { assertThrowsUnsupportedAndExpectErrorMessage(r, "Writes not supported"); } - - private void validateErrorsForDateTestsWithoutCalendar(CheckedFunction method) { + + private void validateErrorsForDateTestsWithoutCalendar(CheckedFunction method) { SQLException sqle; for (Entry, SQLType> field : dateTimeTestingFields.entrySet()) { sqle = expectThrows(SQLException.class, () -> method.apply(field.getKey().v1())); assertEquals( - format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Date", - field.getKey().v2(), field.getValue()), sqle.getMessage()); + format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Date", field.getKey().v2(), field.getValue()), + sqle.getMessage() + ); } } - private void validateErrorsForTimeTestsWithoutCalendar(CheckedFunction method) { + private void validateErrorsForTimeTestsWithoutCalendar(CheckedFunction method) { SQLException sqle; for (Entry, SQLType> field : dateTimeTestingFields.entrySet()) { sqle = expectThrows(SQLException.class, () -> method.apply(field.getKey().v1())); assertEquals( - format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Time", - field.getKey().v2(), field.getValue()), sqle.getMessage()); + format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Time", field.getKey().v2(), field.getValue()), + sqle.getMessage() + ); } } - - private void validateErrorsForDateTimeTestsWithCalendar(Calendar c, CheckedBiFunction method) { + + private void validateErrorsForDateTimeTestsWithCalendar(Calendar c, CheckedBiFunction method) { SQLException sqle; for (Entry, SQLType> field : dateTimeTestingFields.entrySet()) { sqle = expectThrows(SQLException.class, () -> method.apply(field.getKey().v1(), c)); assertEquals( - format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Long", - field.getKey().v2(), field.getValue()), sqle.getMessage()); + format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Long", field.getKey().v2(), field.getValue()), + sqle.getMessage() + ); } } - + private float randomFloatBetween(float start, float end) { float result = 0.0f; while (result < start || result > end || Float.isNaN(result)) { result = start + randomFloat() * (end - start); } - + return result; } @@ -2003,9 +2111,9 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { private Connection esJdbc(String timeZoneId) throws SQLException { Properties connectionProperties = connectionProperties(); - connectionProperties.put(JDBC_TIMEZONE, timeZoneId); + connectionProperties.put(JdbcTestUtils.JDBC_TIMEZONE, timeZoneId); Connection connection = esJdbc(connectionProperties); - assertNotNull("The timezone should be specified", connectionProperties.getProperty(JDBC_TIMEZONE)); + assertNotNull("The timezone should be specified", connectionProperties.getProperty(JdbcTestUtils.JDBC_TIMEZONE)); return connection; } @@ -2019,13 +2127,13 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase { } private String asDateString(long millis) { - return of(millis, timeZoneId); + return JdbcTestUtils.of(millis, timeZoneId); } private ZoneId getZoneFromOffset(Long randomLongDate) { return ZoneId.of(ZoneId.of(timeZoneId).getRules().getOffset(Instant.ofEpochMilli(randomLongDate)).toString()); } - + private Calendar randomCalendar() { return Calendar.getInstance(randomTimeZone(), Locale.ROOT); } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SimpleExampleTestCase.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SimpleExampleTestCase.java similarity index 81% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SimpleExampleTestCase.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SimpleExampleTestCase.java index ddf5ef88a43..b401a42f777 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SimpleExampleTestCase.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SimpleExampleTestCase.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.sql.qa.jdbc; +import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -12,8 +13,9 @@ import java.sql.Statement; import static org.hamcrest.Matchers.containsString; -public class SimpleExampleTestCase extends JdbcIntegrationTestCase { - public void testSimpleExample() throws Exception { +public abstract class SimpleExampleTestCase extends JdbcIntegrationTestCase { + + public void testSimpleExample() throws SQLException, IOException { index("library", builder -> { builder.field("name", "Don Quixote"); builder.field("page_count", 1072); @@ -22,10 +24,10 @@ public class SimpleExampleTestCase extends JdbcIntegrationTestCase { // tag::simple_example try (Statement statement = connection.createStatement(); ResultSet results = statement.executeQuery( - " SELECT name, page_count" - + " FROM library" + " SELECT name, page_count" + + " FROM library" + " ORDER BY page_count DESC" - + " LIMIT 1")) { + + " LIMIT 1")) { assertTrue(results.next()); assertEquals("Don Quixote", results.getString(1)); assertEquals(1072, results.getInt(2)); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java similarity index 85% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java rename to x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java index d326b0ab9da..a2eb37eac60 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java +++ b/x-pack/plugin/sql/qa/jdbc/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java @@ -6,6 +6,6 @@ /** * Support for integration tests for the Elasticsearch SQL JDBC client - * and integration tests shared between multiple qa projects. + * and integration tests shared between multiple qa projects. */ package org.elasticsearch.xpack.sql.qa.jdbc; diff --git a/x-pack/plugin/sql/qa/src/main/resources/plugin-security.policy b/x-pack/plugin/sql/qa/jdbc/src/main/resources/plugin-security.policy similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/plugin-security.policy rename to x-pack/plugin/sql/qa/jdbc/src/main/resources/plugin-security.policy diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcErrorsIT.java b/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcErrorsIT.java deleted file mode 100644 index d6a3a557334..00000000000 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcErrorsIT.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.qa.security; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.sql.qa.jdbc.ErrorsTestCase; - -import java.util.Properties; - -public class JdbcErrorsIT extends ErrorsTestCase { - @Override - protected Settings restClientSettings() { - return RestSqlIT.securitySettings(); - } - - @Override - protected String getProtocol() { - return RestSqlIT.SSL_ENABLED ? "https" : "http"; - } - - @Override - protected Properties connectionProperties() { - Properties properties = super.connectionProperties(); - properties.putAll(JdbcSecurityIT.adminProperties()); - return properties; - } -} diff --git a/x-pack/plugin/sql/qa/server/build.gradle b/x-pack/plugin/sql/qa/server/build.gradle new file mode 100644 index 00000000000..d3c2eb7fa8c --- /dev/null +++ b/x-pack/plugin/sql/qa/server/build.gradle @@ -0,0 +1,115 @@ +description = 'Integration tests for SQL' +apply plugin: 'elasticsearch.build' + +// the main files are actually test files, so use the appropriate forbidden api sigs +tasks.named('forbiddenApisMain').configure { + replaceSignatureFiles 'es-all-signatures', 'es-test-signatures' +} + +dependencies { + compile project(":test:framework") + + // JDBC testing dependencies + compile project(path: xpackModule('sql:jdbc')) + + compile "net.sourceforge.csvjdbc:csvjdbc:${csvjdbcVersion}" + + // CLI testing dependencies + compile project(path: xpackModule('sql:sql-cli')) + + // H2GIS testing dependencies + compile("org.orbisgis:h2gis:${h2gisVersion}") { + exclude group: "org.locationtech.jts" + } + + // select just the parts of JLine that are needed + compile("org.jline:jline-terminal-jna:${jlineVersion}") { + exclude group: "net.java.dev.jna" + } + compile "org.jline:jline-terminal:${jlineVersion}" + compile "org.jline:jline-reader:${jlineVersion}" + compile "org.jline:jline-style:${jlineVersion}" + + testRuntime "org.elasticsearch:jna:${versions.jna}" +} + +/* disable unit tests because these are all integration tests used + * other qa projects. */ +test.enabled = false + +dependencyLicenses.enabled = false +dependenciesInfo.enabled = false + +// just a test fixture: we aren't using this jars in releases and H2GIS requires disabling a lot of checks +thirdPartyAudit.enabled = false + +subprojects { + if (subprojects.isEmpty()) { + // leaf project + apply plugin: 'elasticsearch.standalone-rest-test' + } else { + apply plugin: 'elasticsearch.build' + } + + dependencies { + configurations.testRuntimeClasspath { + resolutionStrategy.force "org.slf4j:slf4j-api:1.7.25" + } + configurations.testRuntime { + // This is also required to make resolveAllDependencies work + resolutionStrategy.force "org.slf4j:slf4j-api:1.7.25" + } + + /* Since we're a standalone rest test we actually get transitive + * dependencies but we don't really want them because they cause + * all kinds of trouble with the jar hell checks. So we suppress + * them explicitly for non-es projects. */ + testCompile(xpackProject('plugin:sql:qa:server')) { + transitive = false + } + testCompile project(":test:framework") + + // JDBC testing dependencies + testRuntime "net.sourceforge.csvjdbc:csvjdbc:${csvjdbcVersion}" + testRuntime "com.h2database:h2:${h2Version}" + + // H2GIS testing dependencies + testRuntime("org.orbisgis:h2gis:${h2gisVersion}") { + exclude group: "org.locationtech.jts" + exclude group: "com.fasterxml.jackson.core" + } + + testRuntime project(path: xpackModule('sql:jdbc')) + testRuntime xpackProject('plugin:sql:sql-client') + + // CLI testing dependencies + testRuntime project(path: xpackModule('sql:sql-cli')) + testRuntime(xpackProject('plugin:sql:sql-action')) { + transitive = false + } + + testRuntime("org.jline:jline-terminal-jna:${jlineVersion}") { + exclude group: "net.java.dev.jna" + } + testRuntime "org.jline:jline-terminal:${jlineVersion}" + testRuntime "org.jline:jline-reader:${jlineVersion}" + testRuntime "org.jline:jline-style:${jlineVersion}" + + testRuntime "org.elasticsearch:jna:${versions.jna}" + + // spatial dependency + testRuntime project(path: xpackModule('spatial')) + } + + if (project.name != 'security') { + // The security project just configures its subprojects + apply plugin: 'elasticsearch.testclusters' + apply plugin: 'elasticsearch.rest-test' + + testClusters.integTest { + testDistribution = 'DEFAULT' + setting 'xpack.ml.enabled', 'false' + setting 'xpack.watcher.enabled', 'false' + } + } +} diff --git a/x-pack/plugin/sql/qa/multi-node/build.gradle b/x-pack/plugin/sql/qa/server/multi-node/build.gradle similarity index 100% rename from x-pack/plugin/sql/qa/multi-node/build.gradle rename to x-pack/plugin/sql/qa/server/multi-node/build.gradle diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliSelectIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliSelectIT.java similarity index 87% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliSelectIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliSelectIT.java index 9e5c7821910..f72a52ae3e5 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliSelectIT.java +++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliSelectIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.multi_node; import org.elasticsearch.xpack.sql.qa.cli.SelectTestCase; -public class CliSelectIT extends SelectTestCase { -} +public class CliSelectIT extends SelectTestCase {} diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliShowIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliShowIT.java similarity index 87% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliShowIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliShowIT.java index 0b5e97bf534..f9b4791ced1 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliShowIT.java +++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CliShowIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.multi_node; import org.elasticsearch.xpack.sql.qa.cli.ShowTestCase; -public class CliShowIT extends ShowTestCase { -} +public class CliShowIT extends ShowTestCase {} diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CustomDateFormatIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CustomDateFormatIT.java similarity index 100% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CustomDateFormatIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/CustomDateFormatIT.java diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcCsvSpecIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcCsvSpecIT.java similarity index 100% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcCsvSpecIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcCsvSpecIT.java diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcSqlSpecIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcSqlSpecIT.java similarity index 100% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcSqlSpecIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/GeoJdbcSqlSpecIT.java diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcDatabaseMetaDataIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcDatabaseMetaDataIT.java similarity index 97% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcDatabaseMetaDataIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcDatabaseMetaDataIT.java index 344ae01f5b9..80f0a43cf9f 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcDatabaseMetaDataIT.java +++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcDatabaseMetaDataIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.multi_node; import org.elasticsearch.xpack.sql.qa.jdbc.DatabaseMetaDataTestCase; -public class JdbcDatabaseMetaDataIT extends DatabaseMetaDataTestCase { -} +public class JdbcDatabaseMetaDataIT extends DatabaseMetaDataTestCase {} diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcShowTablesIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcShowTablesIT.java similarity index 85% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcShowTablesIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcShowTablesIT.java index 0936dfabf2b..201ce7d168c 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcShowTablesIT.java +++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/JdbcShowTablesIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.multi_node; import org.elasticsearch.xpack.sql.qa.jdbc.ShowTablesTestCase; -public class JdbcShowTablesIT extends ShowTablesTestCase { -} +public class JdbcShowTablesIT extends ShowTablesTestCase {} diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlIT.java similarity index 90% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlIT.java index ad81bc380d3..419516cae72 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlIT.java +++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlIT.java @@ -11,5 +11,4 @@ import org.elasticsearch.xpack.sql.qa.rest.RestSqlTestCase; * Integration test for the rest sql action. The one that speaks json directly to a * user rather than to the JDBC driver or CLI. */ -public class RestSqlIT extends RestSqlTestCase { -} +public class RestSqlIT extends RestSqlTestCase {} diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlMultinodeIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlMultinodeIT.java similarity index 98% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlMultinodeIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlMultinodeIT.java index 0dd7c1eb5d8..b4ff002c517 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlMultinodeIT.java +++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/RestSqlMultinodeIT.java @@ -66,7 +66,8 @@ public class RestSqlMultinodeIT extends ESRestTestCase { assertNotNull("Didn't find first host among published addresses", firstHostName); XContentBuilder index = JsonXContent.contentBuilder().prettyPrint().startObject(); - index.startObject("settings"); { + index.startObject("settings"); + { index.field("routing.allocation.exclude._name", firstHostName); } index.endObject(); @@ -77,7 +78,7 @@ public class RestSqlMultinodeIT extends ESRestTestCase { int documents = between(10, 100); createTestData(documents); - try (RestClient firstNodeClient = buildClient(restClientSettings(), new HttpHost[] {firstHost})) { + try (RestClient firstNodeClient = buildClient(restClientSettings(), new HttpHost[] { firstHost })) { assertCount(firstNodeClient, documents); } } diff --git a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/SqlProtocolIT.java b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/SqlProtocolIT.java similarity index 85% rename from x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/SqlProtocolIT.java rename to x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/SqlProtocolIT.java index 474d53ef0c7..7d27168e51e 100644 --- a/x-pack/plugin/sql/qa/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/SqlProtocolIT.java +++ b/x-pack/plugin/sql/qa/server/multi-node/src/test/java/org/elasticsearch/xpack/sql/qa/multi_node/SqlProtocolIT.java @@ -8,5 +8,4 @@ package org.elasticsearch.xpack.sql.qa.multi_node; import org.elasticsearch.xpack.sql.qa.SqlProtocolTestCase; -public class SqlProtocolIT extends SqlProtocolTestCase { -} +public class SqlProtocolIT extends SqlProtocolTestCase {} diff --git a/x-pack/plugin/sql/qa/security/build.gradle b/x-pack/plugin/sql/qa/server/security/build.gradle similarity index 97% rename from x-pack/plugin/sql/qa/security/build.gradle rename to x-pack/plugin/sql/qa/server/security/build.gradle index 3d77c345723..8c2bc24795f 100644 --- a/x-pack/plugin/sql/qa/security/build.gradle +++ b/x-pack/plugin/sql/qa/server/security/build.gradle @@ -4,8 +4,6 @@ dependencies { Project mainProject = project -group = "${group}.x-pack.qa.sql.security" - configurations.create('testArtifacts') TaskProvider testJar = tasks.register("testJar", Jar) { diff --git a/x-pack/plugin/sql/qa/server/security/roles.yml b/x-pack/plugin/sql/qa/server/security/roles.yml new file mode 100644 index 00000000000..141314e23f0 --- /dev/null +++ b/x-pack/plugin/sql/qa/server/security/roles.yml @@ -0,0 +1,91 @@ +# tag::rest +rest_minimal: + indices: + - names: test + privileges: [read, "indices:admin/get"] + - names: bort + privileges: [read, "indices:admin/get"] +# end::rest + +# tag::cli_drivers +cli_or_drivers_minimal: + cluster: + - "cluster:monitor/main" + indices: + - names: test + privileges: [read, "indices:admin/get"] + - names: bort + privileges: [read, "indices:admin/get"] +# end::cli_drivers + +read_nothing: + cluster: + - "cluster:monitor/main" + +read_something_else: + cluster: + - "cluster:monitor/main" + indices: + - names: something_that_isnt_test + privileges: [read, "indices:admin/get"] + +read_test_a: + cluster: + - "cluster:monitor/main" + indices: + - names: test + privileges: [read, "indices:admin/get"] + field_security: + grant: [a] + +read_test_a_and_b: + cluster: + - "cluster:monitor/main" + indices: + - names: test + privileges: [read, "indices:admin/get"] + field_security: + grant: ["*"] + except: [c] + +read_test_without_c_3: + cluster: + - "cluster:monitor/main" + indices: + - names: test + privileges: [read, "indices:admin/get"] + query: | + { + "bool": { + "must_not": [ + { + "match": { + "c": 3 + } + } + ] + } + } + +read_bort: + cluster: + - "cluster:monitor/main" + indices: + - names: bort + privileges: [read, "indices:admin/get"] + +no_monitor_main: + indices: + - names: test + privileges: [read, "indices:admin/get"] + - names: bort + privileges: [read, "indices:admin/get"] + +no_get_index: + cluster: + - "cluster:monitor/main" + indices: + - names: test + privileges: [monitor] + - names: bort + privileges: [monitor] diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliErrorsIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliErrorsIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliErrorsIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliErrorsIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliFetchSizeIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliFetchSizeIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliFetchSizeIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliFetchSizeIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSecurityIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSecurityIT.java similarity index 96% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSecurityIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSecurityIT.java index ce665f9d1b9..498a858897e 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSecurityIT.java +++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSecurityIT.java @@ -84,13 +84,15 @@ public class CliSecurityIT extends SqlSecurityTestCase { public void expectScrollMatchesAdmin(String adminSql, String user, String userSql) throws Exception { expectMatchesAdmin(adminSql, user, userSql, cli -> { assertEquals("[?1l>[?1000l[?2004lfetch size set to [90m1[0m", cli.command("fetch size = 1")); - assertEquals("[?1l>[?1000l[?2004lfetch separator set to \"[90m -- fetch sep -- [0m\"", - cli.command("fetch separator = \" -- fetch sep -- \"")); + assertEquals( + "[?1l>[?1000l[?2004lfetch separator set to \"[90m -- fetch sep -- [0m\"", + cli.command("fetch separator = \" -- fetch sep -- \"") + ); }); } - public void expectMatchesAdmin(String adminSql, String user, String userSql, - CheckedConsumer customizer) throws Exception { + public void expectMatchesAdmin(String adminSql, String user, String userSql, CheckedConsumer customizer) + throws Exception { List adminResult = new ArrayList<>(); try (EmbeddedCli cli = new EmbeddedCli(elasticsearchAddress(), true, adminSecurityConfig())) { customizer.accept(cli); diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSelectIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSelectIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSelectIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliSelectIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliShowIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliShowIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliShowIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/CliShowIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcCsvSpecIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcCsvSpecIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcCsvSpecIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcCsvSpecIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcDatabaseMetaDataIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcDatabaseMetaDataIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcDatabaseMetaDataIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcDatabaseMetaDataIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSecurityIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSecurityIT.java similarity index 84% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSecurityIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSecurityIT.java index 1f04d6fb99c..2c7513f08ce 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSecurityIT.java +++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSecurityIT.java @@ -82,10 +82,12 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { properties.put("ssl.truststore.pass", "keypass"); } - static void expectActionMatchesAdmin(CheckedFunction adminAction, - String user, CheckedFunction userAction) throws Exception { - try (Connection adminConnection = es(adminProperties()); - Connection userConnection = es(userProperties(user))) { + static void expectActionMatchesAdmin( + CheckedFunction adminAction, + String user, + CheckedFunction userAction + ) throws Exception { + try (Connection adminConnection = es(adminProperties()); Connection userConnection = es(userProperties(user))) { assertResultSets(adminAction.apply(adminConnection), userAction.apply(userConnection)); } } @@ -106,8 +108,8 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { assertThat(e.getMessage(), containsString(errorMessage)); } - static void expectActionThrowsUnknownColumn(String user, - CheckedConsumer action, String column) throws Exception { + static void expectActionThrowsUnknownColumn(String user, CheckedConsumer action, String column) + throws Exception { SQLException e; try (Connection connection = es(userProperties(user))) { e = expectThrows(SQLException.class, () -> action.accept(connection)); @@ -123,8 +125,7 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { @Override public void queryWorksAsAdmin() throws Exception { - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = es(adminProperties())) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = es(adminProperties())) { h2.createStatement().executeUpdate("CREATE TABLE test (a BIGINT, b BIGINT, c BIGINT)"); h2.createStatement().executeUpdate("INSERT INTO test (a, b, c) VALUES (1, 2, 3), (4, 5, 6)"); @@ -138,29 +139,26 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { expectActionMatchesAdmin( con -> con.createStatement().executeQuery(adminSql), user, - con -> con.createStatement().executeQuery(userSql)); + con -> con.createStatement().executeQuery(userSql) + ); } @Override public void expectScrollMatchesAdmin(String adminSql, String user, String userSql) throws Exception { - expectActionMatchesAdmin( - con -> { - Statement st = con.createStatement(); - st.setFetchSize(1); - return st.executeQuery(adminSql); - }, - user, - con -> { - Statement st = con.createStatement(); - st.setFetchSize(1); - return st.executeQuery(userSql); - }); + expectActionMatchesAdmin(con -> { + Statement st = con.createStatement(); + st.setFetchSize(1); + return st.executeQuery(adminSql); + }, user, con -> { + Statement st = con.createStatement(); + st.setFetchSize(1); + return st.executeQuery(userSql); + }); } @Override public void expectDescribe(Map> columns, String user) throws Exception { - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = es(userProperties(user))) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = es(userProperties(user))) { // h2 doesn't have the same sort of DESCRIBE that we have so we emulate it h2.createStatement().executeUpdate("CREATE TABLE mock (column VARCHAR, type VARCHAR, mapping VARCHAR)"); if (columns.size() > 0) { @@ -222,10 +220,7 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { @Override public void expectUnknownColumn(String user, String sql, String column) throws Exception { - expectActionThrowsUnknownColumn( - user, - con -> con.createStatement().executeQuery(sql), - column); + expectActionThrowsUnknownColumn(user, con -> con.createStatement().executeQuery(sql), column); } @Override @@ -236,12 +231,12 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { expectUnauthorized("cluster:monitor/main", user, () -> es(userProperties(user)).getMetaData().getDatabaseMinorVersion()); // by moving to field caps these calls do not require the monitor permission - // expectUnauthorized("cluster:monitor/main", user, - // () -> es(userProperties(user)).createStatement().executeQuery("SELECT * FROM test")); - // expectUnauthorized("cluster:monitor/main", user, - // () -> es(userProperties(user)).createStatement().executeQuery("SHOW TABLES LIKE 'test'")); - // expectUnauthorized("cluster:monitor/main", user, - // () -> es(userProperties(user)).createStatement().executeQuery("DESCRIBE test")); + // expectUnauthorized("cluster:monitor/main", user, + // () -> es(userProperties(user)).createStatement().executeQuery("SELECT * FROM test")); + // expectUnauthorized("cluster:monitor/main", user, + // () -> es(userProperties(user)).createStatement().executeQuery("SHOW TABLES LIKE 'test'")); + // expectUnauthorized("cluster:monitor/main", user, + // () -> es(userProperties(user)).createStatement().executeQuery("DESCRIBE test")); } private void expectUnauthorized(String action, String user, ThrowingRunnable r) { @@ -261,7 +256,8 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { expectActionMatchesAdmin( con -> con.getMetaData().getTables("%", "%", "%t", null), "full_access", - con -> con.getMetaData().getTables("%", "%", "%", null)); + con -> con.getMetaData().getTables("%", "%", "%", null) + ); } public void testMetaDataGetTablesWithNoAccess() throws Exception { @@ -276,7 +272,8 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { expectActionMatchesAdmin( con -> con.getMetaData().getTables("%", "%", "bort", null), "read_bort", - con -> con.getMetaData().getTables("%", "%", "%", null)); + con -> con.getMetaData().getTables("%", "%", "%", null) + ); } public void testMetaDataGetTablesWithInAccessibleIndex() throws Exception { @@ -285,16 +282,18 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { expectActionMatchesAdmin( con -> con.getMetaData().getTables("%", "%", "not_created", null), "read_bort", - con -> con.getMetaData().getTables("%", "%", "test", null)); + con -> con.getMetaData().getTables("%", "%", "test", null) + ); } public void testMetaDataGetColumnsWorksAsFullAccess() throws Exception { createUser("full_access", "cli_or_drivers_minimal"); expectActionMatchesAdmin( - con -> con.getMetaData().getColumns(null, "%", "%t", "%"), + con -> con.getMetaData().getColumns(null, "%", "%t", "%"), "full_access", - con -> con.getMetaData().getColumns(null, "%", "%t", "%")); + con -> con.getMetaData().getColumns(null, "%", "%t", "%") + ); } public void testMetaDataGetColumnsWithNoAccess() throws Exception { @@ -307,18 +306,20 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { createUser("wrong_access", "read_something_else"); expectActionMatchesAdmin( - con -> con.getMetaData().getColumns(null, "%", "not_created", "%"), + con -> con.getMetaData().getColumns(null, "%", "not_created", "%"), "wrong_access", - con -> con.getMetaData().getColumns(null, "%", "test", "%")); + con -> con.getMetaData().getColumns(null, "%", "test", "%") + ); } public void testMetaDataGetColumnsSingleFieldGranted() throws Exception { createUser("only_a", "read_test_a"); expectActionMatchesAdmin( - con -> con.getMetaData().getColumns(null, "%", "test", "a"), + con -> con.getMetaData().getColumns(null, "%", "test", "a"), "only_a", - con -> con.getMetaData().getColumns(null, "%", "test", "%")); + con -> con.getMetaData().getColumns(null, "%", "test", "%") + ); } public void testMetaDataGetColumnsSingleFieldExcepted() throws Exception { @@ -345,6 +346,7 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { expectActionMatchesAdmin( con -> con.getMetaData().getColumns(null, "%", "test", "%"), "no_3s", - con -> con.getMetaData().getColumns(null, "%", "test", "%")); + con -> con.getMetaData().getColumns(null, "%", "test", "%") + ); } } diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcShowTablesIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcShowTablesIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcShowTablesIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcShowTablesIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSqlSpecIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSqlSpecIT.java similarity index 100% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSqlSpecIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/JdbcSqlSpecIT.java diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlIT.java similarity index 91% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlIT.java index 362b3a93211..c38cf8d2abd 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlIT.java +++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlIT.java @@ -28,8 +28,7 @@ public class RestSqlIT extends RestSqlTestCase { static Settings securitySettings() { String token = basicAuthHeaderValue("test_admin", new SecureString("x-pack-test-password".toCharArray())); - Settings.Builder builder = Settings.builder() - .put(ThreadContext.PREFIX + ".Authorization", token); + Settings.Builder builder = Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token); if (SSL_ENABLED) { Path keyStore; try { @@ -40,8 +39,7 @@ public class RestSqlIT extends RestSqlTestCase { if (!Files.exists(keyStore)) { throw new IllegalStateException("Keystore file [" + keyStore + "] does not exist."); } - builder.put(ESRestTestCase.TRUSTSTORE_PATH, keyStore) - .put(ESRestTestCase.TRUSTSTORE_PASSWORD, "keypass"); + builder.put(ESRestTestCase.TRUSTSTORE_PATH, keyStore).put(ESRestTestCase.TRUSTSTORE_PASSWORD, "keypass"); } return builder.build(); } diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlSecurityIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlSecurityIT.java similarity index 78% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlSecurityIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlSecurityIT.java index 57fefac377f..abb12a32122 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlSecurityIT.java +++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/RestSqlSecurityIT.java @@ -50,13 +50,15 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase { public void queryWorksAsAdmin() throws Exception { String mode = randomMode(); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo(mode, "a", "long", JDBCType.BIGINT, 20), columnInfo(mode, "b", "long", JDBCType.BIGINT, 20), - columnInfo(mode, "c", "long", JDBCType.BIGINT, 20))); - expected.put("rows", Arrays.asList( - Arrays.asList(1, 2, 3), - Arrays.asList(4, 5, 6))); + columnInfo(mode, "c", "long", JDBCType.BIGINT, 20) + ) + ); + expected.put("rows", Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6))); assertResponse(expected, runSql(null, mode, "SELECT * FROM test ORDER BY a")); } @@ -70,10 +72,16 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase { @Override public void expectScrollMatchesAdmin(String adminSql, String user, String userSql) throws Exception { String mode = randomMode(); - Map adminResponse = runSql(null, - new StringEntity(query(adminSql).mode(mode).fetchSize(1).toString(), ContentType.APPLICATION_JSON), mode); - Map otherResponse = runSql(user, - new StringEntity(query(adminSql).mode(mode).fetchSize(1).toString(), ContentType.APPLICATION_JSON), mode); + Map adminResponse = runSql( + null, + new StringEntity(query(adminSql).mode(mode).fetchSize(1).toString(), ContentType.APPLICATION_JSON), + mode + ); + Map otherResponse = runSql( + user, + new StringEntity(query(adminSql).mode(mode).fetchSize(1).toString(), ContentType.APPLICATION_JSON), + mode + ); String adminCursor = (String) adminResponse.remove("cursor"); String otherCursor = (String) otherResponse.remove("cursor"); @@ -81,10 +89,16 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase { assertNotNull(otherCursor); assertResponse(adminResponse, otherResponse); while (true) { - adminResponse = runSql(null, new StringEntity(cursor(adminCursor).mode(mode).toString(), - ContentType.APPLICATION_JSON), mode); - otherResponse = runSql(user, new StringEntity(cursor(otherCursor).mode(mode).toString(), - ContentType.APPLICATION_JSON), mode); + adminResponse = runSql( + null, + new StringEntity(cursor(adminCursor).mode(mode).toString(), ContentType.APPLICATION_JSON), + mode + ); + otherResponse = runSql( + user, + new StringEntity(cursor(otherCursor).mode(mode).toString(), ContentType.APPLICATION_JSON), + mode + ); adminCursor = (String) adminResponse.remove("cursor"); otherCursor = (String) otherResponse.remove("cursor"); assertResponse(adminResponse, otherResponse); @@ -100,10 +114,14 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase { public void expectDescribe(Map> columns, String user) throws Exception { String mode = randomMode(); Map expected = new HashMap<>(3); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo(mode, "column", "keyword", JDBCType.VARCHAR, 32766), columnInfo(mode, "type", "keyword", JDBCType.VARCHAR, 32766), - columnInfo(mode, "mapping", "keyword", JDBCType.VARCHAR, 32766))); + columnInfo(mode, "mapping", "keyword", JDBCType.VARCHAR, 32766) + ) + ); List> rows = new ArrayList<>(columns.size()); for (Map.Entry> column : columns.entrySet()) { List cols = new ArrayList<>(); @@ -142,10 +160,9 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase { * by the time the test runs. */ @SuppressWarnings("unchecked") - List> rowsNoSecurity = ((List>) actual.get("rows")) - .stream() - .filter(ls -> ls.get(0).startsWith(".security") == false) - .collect(Collectors.toList()); + List> rowsNoSecurity = ((List>) actual.get("rows")).stream() + .filter(ls -> ls.get(0).startsWith(".security") == false) + .collect(Collectors.toList()); actual.put("rows", rowsNoSecurity); assertResponse(expected, actual); } @@ -231,20 +248,28 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase { createUser("full_access", "rest_minimal"); final String mode = randomMode(); - Map adminResponse = RestActions.runSql(null, - new StringEntity(query("SELECT * FROM test").mode(mode).fetchSize(1).toString(), ContentType.APPLICATION_JSON), mode); + Map adminResponse = RestActions.runSql( + null, + new StringEntity(query("SELECT * FROM test").mode(mode).fetchSize(1).toString(), ContentType.APPLICATION_JSON), + mode + ); String cursor = (String) adminResponse.remove("cursor"); assertNotNull(cursor); - ResponseException e = expectThrows(ResponseException.class, () -> RestActions.runSql("full_access", - new StringEntity(cursor(cursor).mode(mode).toString(), ContentType.APPLICATION_JSON), mode)); + ResponseException e = expectThrows( + ResponseException.class, + () -> RestActions.runSql( + "full_access", + new StringEntity(cursor(cursor).mode(mode).toString(), ContentType.APPLICATION_JSON), + mode + ) + ); // TODO return a better error message for bad scrolls assertThat(e.getMessage(), containsString("No search context found for id")); assertEquals(404, e.getResponse().getStatusLine().getStatusCode()); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") .expect(true, SQL_ACTION_NAME, "full_access", empty()) // one scroll access denied per shard .expect("access_denied", SQL_ACTION_NAME, "full_access", "default_native", empty(), "InternalScrollSearchRequest") @@ -253,21 +278,30 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase { protected class RestAuditLogAsserter extends AuditLogAsserter { @Override - public AuditLogAsserter expect(String eventType, String action, String principal, String realm, - Matcher> indicesMatcher, String request) { - final Matcher runByPrincipalMatcher = principal.equals("test_admin") ? Matchers.nullValue(String.class) - : Matchers.is("test_admin"); - final Matcher runByRealmMatcher = realm.equals("default_file") ? Matchers.nullValue(String.class) - : Matchers.is("default_file"); + public AuditLogAsserter expect( + String eventType, + String action, + String principal, + String realm, + Matcher> indicesMatcher, + String request + ) { + final Matcher runByPrincipalMatcher = principal.equals("test_admin") + ? Matchers.nullValue(String.class) + : Matchers.is("test_admin"); + final Matcher runByRealmMatcher = realm.equals("default_file") + ? Matchers.nullValue(String.class) + : Matchers.is("default_file"); logCheckers.add( - m -> eventType.equals(m.get("event.action")) - && action.equals(m.get("action")) - && principal.equals(m.get("user.name")) - && realm.equals(m.get("user.realm")) - && runByPrincipalMatcher.matches(m.get("user.run_by.name")) - && runByRealmMatcher.matches(m.get("user.run_by.realm")) - && indicesMatcher.matches(m.get("indices")) - && request.equals(m.get("request.name"))); + m -> eventType.equals(m.get("event.action")) + && action.equals(m.get("action")) + && principal.equals(m.get("user.name")) + && realm.equals(m.get("user.realm")) + && runByPrincipalMatcher.matches(m.get("user.run_by.name")) + && runByRealmMatcher.matches(m.get("user.run_by.realm")) + && indicesMatcher.matches(m.get("indices")) + && request.equals(m.get("request.name")) + ); return this; } diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java similarity index 82% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java index abd2026d437..0c046a2aaac 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java +++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java @@ -58,22 +58,31 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { */ protected interface Actions { String minimalPermissionsForAllActions(); + void queryWorksAsAdmin() throws Exception; + /** * Assert that running some sql as a user returns the same result as running it as * the administrator. */ void expectMatchesAdmin(String adminSql, String user, String userSql) throws Exception; + /** * Same as {@link #expectMatchesAdmin(String, String, String)} but sets the scroll size * to 1 and completely scrolls the results. */ void expectScrollMatchesAdmin(String adminSql, String user, String userSql) throws Exception; + void expectDescribe(Map> columns, String user) throws Exception; + void expectShowTables(List tables, String user) throws Exception; + void expectForbidden(String user, String sql) throws Exception; + void expectUnknownIndex(String user, String sql) throws Exception; + void expectUnknownColumn(String user, String sql, String column) throws Exception; + void checkNoMonitorMain(String user) throws Exception; } @@ -87,23 +96,26 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { private static final Path AUDIT_LOG_FILE = lookupAuditLog(); private static final Path ROLLED_OVER_AUDIT_LOG_FILE = lookupRolledOverAuditLog(); - @SuppressForbidden(reason="security doesn't work with mock filesystem") + @SuppressForbidden(reason = "security doesn't work with mock filesystem") private static Path lookupAuditLog() { String auditLogFileString = System.getProperty("tests.audit.logfile"); if (null == auditLogFileString) { - throw new IllegalStateException("tests.audit.logfile must be set to run this test. It is automatically " + throw new IllegalStateException( + "tests.audit.logfile must be set to run this test. It is automatically " + "set by gradle. If you must set it yourself then it should be the absolute path to the audit " - + "log file generated by running x-pack with audit logging enabled."); + + "log file generated by running x-pack with audit logging enabled." + ); } return Paths.get(auditLogFileString); } - @SuppressForbidden(reason="security doesn't work with mock filesystem") + @SuppressForbidden(reason = "security doesn't work with mock filesystem") private static Path lookupRolledOverAuditLog() { String auditLogFileString = System.getProperty("tests.audit.yesterday.logfile"); if (null == auditLogFileString) { - throw new IllegalStateException("tests.audit.yesterday.logfile must be set to run this test. It should be automatically " - + "set by gradle."); + throw new IllegalStateException( + "tests.audit.yesterday.logfile must be set to run this test. It should be automatically " + "set by gradle." + ); } return Paths.get(auditLogFileString); } @@ -205,7 +217,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { @AfterClass public static void wipeIndicesAfterTests() throws IOException { try { - wipeAllIndices(); + wipeAllIndices(); } finally { // Clear the static state so other subclasses can reuse it later oneTimeSetup = false; @@ -220,17 +232,14 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { public void testQueryWorksAsAdmin() throws Exception { actions.queryWorksAsAdmin(); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") - .assertLogs(); + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test").assertLogs(); } public void testQueryWithFullAccess() throws Exception { createUser("full_access", actions.minimalPermissionsForAllActions()); actions.expectMatchesAdmin("SELECT * FROM test ORDER BY a", "full_access", "SELECT * FROM test ORDER BY a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") .expectSqlCompositeActionFieldCaps("full_access", "test") .assertLogs(); } @@ -239,8 +248,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("full_access", actions.minimalPermissionsForAllActions()); actions.expectScrollMatchesAdmin("SELECT * FROM test ORDER BY a", "full_access", "SELECT * FROM test ORDER BY a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") /* Scrolling doesn't have to access the index again, at least not through sql. * If we asserted query and scroll logs then we would see the scroll. */ .expect(true, SQL_ACTION_NAME, "test_admin", empty()) @@ -255,9 +263,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("no_access", "read_nothing"); actions.expectForbidden("no_access", "SELECT * FROM test"); - createAuditLogAsserter() - .expect(false, SQL_ACTION_NAME, "no_access", empty()) - .assertLogs(); + createAuditLogAsserter().expect(false, SQL_ACTION_NAME, "no_access", empty()).assertLogs(); } public void testQueryWrongAccess() throws Exception { @@ -265,9 +271,9 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { actions.expectUnknownIndex("wrong_access", "SELECT * FROM test"); createAuditLogAsserter() - //This user has permission to run sql queries so they are given preliminary authorization + // This user has permission to run sql queries so they are given preliminary authorization .expect(true, SQL_ACTION_NAME, "wrong_access", empty()) - //the following get index is granted too but against the no indices placeholder, as ignore_unavailable=true + // the following get index is granted too but against the no indices placeholder, as ignore_unavailable=true .expect(true, FieldCapabilitiesAction.NAME, "wrong_access", hasItems("*", "-*")) .assertLogs(); } @@ -276,8 +282,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("only_a", "read_test_a"); actions.expectMatchesAdmin("SELECT a FROM test ORDER BY a", "only_a", "SELECT * FROM test ORDER BY a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") .expectSqlCompositeActionFieldCaps("only_a", "test") .assertLogs(); } @@ -286,8 +291,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("only_a", "read_test_a"); actions.expectScrollMatchesAdmin("SELECT a FROM test ORDER BY a", "only_a", "SELECT * FROM test ORDER BY a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") /* Scrolling doesn't have to access the index again, at least not through sql. * If we asserted query and scroll logs then we would see the scroll. */ .expect(true, SQL_ACTION_NAME, "test_admin", empty()) @@ -308,17 +312,14 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { * query from the audit side because all the permissions checked * out but it failed in SQL because it couldn't compile the * query without the metadata for the missing field. */ - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("only_a", "test") - .assertLogs(); + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("only_a", "test").assertLogs(); } public void testQuerySingleFieldExcepted() throws Exception { createUser("not_c", "read_test_a_and_b"); actions.expectMatchesAdmin("SELECT a, b FROM test ORDER BY a", "not_c", "SELECT * FROM test ORDER BY a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") .expectSqlCompositeActionFieldCaps("not_c", "test") .assertLogs(); } @@ -327,8 +328,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("not_c", "read_test_a_and_b"); actions.expectScrollMatchesAdmin("SELECT a, b FROM test ORDER BY a", "not_c", "SELECT * FROM test ORDER BY a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") /* Scrolling doesn't have to access the index again, at least not through sql. * If we asserted query and scroll logs then we would see the scroll. */ .expect(true, SQL_ACTION_NAME, "test_admin", empty()) @@ -349,34 +349,28 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { * query from the audit side because all the permissions checked * out but it failed in SQL because it couldn't compile the * query without the metadata for the missing field. */ - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("not_c", "test") - .assertLogs(); + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("not_c", "test").assertLogs(); } public void testQueryDocumentExcluded() throws Exception { createUser("no_3s", "read_test_without_c_3"); actions.expectMatchesAdmin("SELECT * FROM test WHERE c != 3 ORDER BY a", "no_3s", "SELECT * FROM test ORDER BY a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") .expectSqlCompositeActionFieldCaps("no_3s", "test") .assertLogs(); } public void testShowTablesWorksAsAdmin() throws Exception { actions.expectShowTables(Arrays.asList("bort", "test"), null); - createAuditLogAsserter() - .expectSqlCompositeActionGetIndex("test_admin", "bort", "test") - .assertLogs(); + createAuditLogAsserter().expectSqlCompositeActionGetIndex("test_admin", "bort", "test").assertLogs(); } public void testShowTablesWorksAsFullAccess() throws Exception { createUser("full_access", actions.minimalPermissionsForAllActions()); actions.expectMatchesAdmin("SHOW TABLES LIKE '%t'", "full_access", "SHOW TABLES"); - createAuditLogAsserter() - .expectSqlCompositeActionGetIndex("test_admin", "bort", "test") + createAuditLogAsserter().expectSqlCompositeActionGetIndex("test_admin", "bort", "test") .expectSqlCompositeActionGetIndex("full_access", "bort", "test") .assertLogs(); } @@ -385,17 +379,15 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("no_access", "read_nothing"); actions.expectForbidden("no_access", "SHOW TABLES"); - createAuditLogAsserter() - .expect(false, SQL_ACTION_NAME, "no_access", empty()) - .assertLogs(); + createAuditLogAsserter().expect(false, SQL_ACTION_NAME, "no_access", empty()).assertLogs(); } public void testShowTablesWithLimitedAccess() throws Exception { createUser("read_bort", "read_bort"); actions.expectMatchesAdmin("SHOW TABLES LIKE 'bort'", "read_bort", "SHOW TABLES"); - createAuditLogAsserter() - .expectSqlCompositeActionGetIndex("test_admin", "bort").expectSqlCompositeActionGetIndex("read_bort", "bort") + createAuditLogAsserter().expectSqlCompositeActionGetIndex("test_admin", "bort") + .expectSqlCompositeActionGetIndex("read_bort", "bort") .assertLogs(); } @@ -403,8 +395,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("read_bort", "read_bort"); actions.expectMatchesAdmin("SHOW TABLES LIKE 'not-created'", "read_bort", "SHOW TABLES LIKE 'test'"); - createAuditLogAsserter() - .expect(true, SQL_ACTION_NAME, "test_admin", empty()) + createAuditLogAsserter().expect(true, SQL_ACTION_NAME, "test_admin", empty()) .expect(true, GetIndexAction.NAME, "test_admin", contains("*", "-*")) .expect(true, SQL_ACTION_NAME, "read_bort", empty()) .expect(true, GetIndexAction.NAME, "read_bort", contains("*", "-*")) @@ -417,17 +408,14 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { expected.put("b", asList("BIGINT", "long")); expected.put("c", asList("BIGINT", "long")); actions.expectDescribe(expected, null); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") - .assertLogs(); + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test").assertLogs(); } public void testDescribeWorksAsFullAccess() throws Exception { createUser("full_access", actions.minimalPermissionsForAllActions()); actions.expectMatchesAdmin("DESCRIBE test", "full_access", "DESCRIBE test"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") .expectSqlCompositeActionFieldCaps("full_access", "test") .assertLogs(); } @@ -436,9 +424,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("no_access", "read_nothing"); actions.expectForbidden("no_access", "DESCRIBE test"); - createAuditLogAsserter() - .expect(false, SQL_ACTION_NAME, "no_access", empty()) - .assertLogs(); + createAuditLogAsserter().expect(false, SQL_ACTION_NAME, "no_access", empty()).assertLogs(); } public void testDescribeWithWrongAccess() throws Exception { @@ -446,9 +432,9 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { actions.expectDescribe(Collections.emptyMap(), "wrong_access"); createAuditLogAsserter() - //This user has permission to run sql queries so they are given preliminary authorization + // This user has permission to run sql queries so they are given preliminary authorization .expect(true, SQL_ACTION_NAME, "wrong_access", empty()) - //the following get index is granted too but against the no indices placeholder, as ignore_unavailable=true + // the following get index is granted too but against the no indices placeholder, as ignore_unavailable=true .expect(true, FieldCapabilitiesAction.NAME, "wrong_access", hasItems("*", "-*")) .assertLogs(); } @@ -457,9 +443,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { createUser("only_a", "read_test_a"); actions.expectDescribe(singletonMap("a", asList("BIGINT", "long")), "only_a"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("only_a", "test") - .assertLogs(); + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("only_a", "test").assertLogs(); } public void testDescribeSingleFieldExcepted() throws Exception { @@ -469,17 +453,14 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { expected.put("a", asList("BIGINT", "long")); expected.put("b", asList("BIGINT", "long")); actions.expectDescribe(expected, "not_c"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("not_c", "test") - .assertLogs(); + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("not_c", "test").assertLogs(); } public void testDescribeDocumentExcluded() throws Exception { createUser("no_3s", "read_test_without_c_3"); actions.expectMatchesAdmin("DESCRIBE test", "no_3s", "DESCRIBE test"); - createAuditLogAsserter() - .expectSqlCompositeActionFieldCaps("test_admin", "test") + createAuditLogAsserter().expectSqlCompositeActionFieldCaps("test_admin", "test") .expectSqlCompositeActionFieldCaps("no_3s", "test") .assertLogs(); } @@ -500,7 +481,8 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { protected static void createUser(String name, String role) throws IOException { Request request = new Request("PUT", "/_security/user/" + name); XContentBuilder user = JsonXContent.contentBuilder().prettyPrint(); - user.startObject(); { + user.startObject(); + { user.field("password", "testpass"); user.field("roles", role); } @@ -533,45 +515,58 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { return this; } - public AuditLogAsserter expect(boolean granted, String action, String principal, - Matcher> indicesMatcher) { + public AuditLogAsserter expect( + boolean granted, + String action, + String principal, + Matcher> indicesMatcher + ) { String request; switch (action) { - case SQL_ACTION_NAME: - request = "SqlQueryRequest"; - break; - case GetIndexAction.NAME: - request = GetIndexRequest.class.getSimpleName(); - break; + case SQL_ACTION_NAME: + request = "SqlQueryRequest"; + break; + case GetIndexAction.NAME: + request = GetIndexRequest.class.getSimpleName(); + break; case FieldCapabilitiesAction.NAME: request = FieldCapabilitiesRequest.class.getSimpleName(); break; - default: - throw new IllegalArgumentException("Unknown action [" + action + "]"); + default: + throw new IllegalArgumentException("Unknown action [" + action + "]"); } final String eventAction = granted ? "access_granted" : "access_denied"; final String realm = principal.equals("test_admin") ? "default_file" : "default_native"; return expect(eventAction, action, principal, realm, indicesMatcher, request); } - public AuditLogAsserter expect(String eventAction, String action, String principal, String realm, - Matcher> indicesMatcher, String request) { - logCheckers.add(m -> - eventAction.equals(m.get("event.action")) - && action.equals(m.get("action")) - && principal.equals(m.get("user.name")) - && realm.equals(m.get("user.realm")) - && Matchers.nullValue(String.class).matches(m.get("user.run_by.name")) - && Matchers.nullValue(String.class).matches(m.get("user.run_by.realm")) - && indicesMatcher.matches(m.get("indices")) - && request.equals(m.get("request.name")) + public AuditLogAsserter expect( + String eventAction, + String action, + String principal, + String realm, + Matcher> indicesMatcher, + String request + ) { + logCheckers.add( + m -> eventAction.equals(m.get("event.action")) + && action.equals(m.get("action")) + && principal.equals(m.get("user.name")) + && realm.equals(m.get("user.realm")) + && Matchers.nullValue(String.class).matches(m.get("user.run_by.name")) + && Matchers.nullValue(String.class).matches(m.get("user.run_by.realm")) + && indicesMatcher.matches(m.get("indices")) + && request.equals(m.get("request.name")) ); return this; } public void assertLogs() throws Exception { - assertFalse("Previous test had an audit-related failure. All subsequent audit related assertions are bogus because we can't " - + "guarantee that we fully cleaned up after the last test.", auditFailure); + assertFalse( + "Previous test had an audit-related failure. All subsequent audit related assertions are bogus because we can't " + + "guarantee that we fully cleaned up after the last test.", + auditFailure + ); try { // use a second variable since the `assertBusy()` block can be executed multiple times and the // static auditFileRolledOver value can change and mess up subsequent calls of this code block @@ -624,18 +619,17 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { if (++index == 2) { break; } - } - else { + } else { try { final Map log = XContentHelper.convertToMap(JsonXContent.jsonXContent, line, false); if (false == ("access_denied".equals(log.get("event.action")) - || "access_granted".equals(log.get("event.action")))) { + || "access_granted".equals(log.get("event.action")))) { continue; } assertThat(log.containsKey("action"), is(true)); if (false == (SQL_ACTION_NAME.equals(log.get("action")) - || GetIndexAction.NAME.equals(log.get("action")) - || FieldCapabilitiesAction.NAME.equals(log.get("action")))) { + || GetIndexAction.NAME.equals(log.get("action")) + || FieldCapabilitiesAction.NAME.equals(log.get("action")))) { // TODO we may want to extend this and the assertions to SearchAction.NAME as well continue; } @@ -651,8 +645,9 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { * SQL drops them from the interface. So we might have access to them, but we * don't show them. */ - indices = indices.stream().filter( - idx -> false == RestrictedIndicesNames.isRestricted(idx)).collect(Collectors.toList()); + indices = indices.stream() + .filter(idx -> false == RestrictedIndicesNames.isRestricted(idx)) + .collect(Collectors.toList()); } } // Use a sorted list for indices for consistent error reporting @@ -678,8 +673,14 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { notMatching.add(c); } if (false == notMatching.isEmpty()) { - fail("Some checkers " + notMatching + " didn't match any logs. All logs:" + logsMessage(allLogs) - + "\nRemaining logs:" + logsMessage(logs)); + fail( + "Some checkers " + + notMatching + + " didn't match any logs. All logs:" + + logsMessage(allLogs) + + "\nRemaining logs:" + + logsMessage(logs) + ); } if (false == logs.isEmpty()) { fail("Not all logs matched. Unmatched logs:" + logsMessage(logs)); @@ -687,8 +688,10 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase { }); } catch (AssertionError e) { auditFailure = true; - logger.warn("Failed to find an audit log. Skipping remaining tests in this class after this the missing audit" - + "logs could turn up later."); + logger.warn( + "Failed to find an audit log. Skipping remaining tests in this class after this the missing audit" + + "logs could turn up later." + ); throw e; } } diff --git a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/UserFunctionIT.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/UserFunctionIT.java similarity index 82% rename from x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/UserFunctionIT.java rename to x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/UserFunctionIT.java index ff4a1df9149..fca0ef3248d 100644 --- a/x-pack/plugin/sql/qa/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/UserFunctionIT.java +++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/UserFunctionIT.java @@ -44,20 +44,20 @@ public class UserFunctionIT extends ESRestTestCase { private List users; @Rule public TestName name = new TestName(); - + @Override protected Settings restClientSettings() { return RestSqlIT.securitySettings(); } - + @Override protected String getProtocol() { return RestSqlIT.SSL_ENABLED ? "https" : "http"; } - + @Before private void setUpUsers() throws IOException { - int usersCount = name.getMethodName().startsWith("testSingle") ? 1 : randomIntBetween(5, 15); + int usersCount = name.getMethodName().startsWith("testSingle") ? 1 : randomIntBetween(5, 15); users = new ArrayList<>(usersCount); users.addAll(randomUnique(() -> randomAlphaOfLengthBetween(1, 15), usersCount)); for (String user : users) { @@ -71,53 +71,44 @@ public class UserFunctionIT extends ESRestTestCase { deleteUser(user); } } - + public void testSingleRandomUser() throws IOException { String mode = randomMode().toString(); String randomUserName = users.get(0); - + Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); + expected.put("columns", Arrays.asList(columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); expected.put("rows", Arrays.asList(Arrays.asList(randomUserName))); Map actual = runSql(randomUserName, mode, SQL); - + assertResponse(expected, actual); } - + public void testSingleRandomUserWithWhereEvaluatingTrue() throws IOException { - index("{\"test\":\"doc1\"}", - "{\"test\":\"doc2\"}", - "{\"test\":\"doc3\"}"); + index("{\"test\":\"doc1\"}", "{\"test\":\"doc2\"}", "{\"test\":\"doc3\"}"); String mode = randomMode().toString(); String randomUserName = users.get(0); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); - expected.put("rows", Arrays.asList(Arrays.asList(randomUserName), - Arrays.asList(randomUserName), - Arrays.asList(randomUserName))); + expected.put("columns", Arrays.asList(columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); + expected.put("rows", Arrays.asList(Arrays.asList(randomUserName), Arrays.asList(randomUserName), Arrays.asList(randomUserName))); Map actual = runSql(randomUserName, mode, SQL + " FROM test WHERE USER()='" + randomUserName + "' LIMIT 3"); assertResponse(expected, actual); } - + public void testSingleRandomUserWithWhereEvaluatingFalse() throws IOException { - index("{\"test\":\"doc1\"}", - "{\"test\":\"doc2\"}", - "{\"test\":\"doc3\"}"); + index("{\"test\":\"doc1\"}", "{\"test\":\"doc2\"}", "{\"test\":\"doc3\"}"); String mode = randomMode().toString(); String randomUserName = users.get(0); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); + expected.put("columns", Arrays.asList(columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); expected.put("rows", Collections.>emptyList()); String anotherRandomUserName = randomValueOtherThan(randomUserName, () -> randomAlphaOfLengthBetween(1, 15)); Map actual = runSql(randomUserName, mode, SQL + " FROM test WHERE USER()='" + anotherRandomUserName + "' LIMIT 3"); assertResponse(expected, actual); } - + public void testMultipleRandomUsersAccess() throws IOException { // run 30 queries and pick randomly each time one of the 5-15 users created previously for (int i = 0; i < 30; i++) { @@ -125,38 +116,33 @@ public class UserFunctionIT extends ESRestTestCase { String randomlyPickedUsername = randomFrom(users); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); + expected.put("columns", Arrays.asList(columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); expected.put("rows", Arrays.asList(Arrays.asList(randomlyPickedUsername))); Map actual = runSql(randomlyPickedUsername, mode, SQL); - + // expect the user that ran the query to be the same as the one returned by the `USER()` function assertResponse(expected, actual); } } - + public void testSingleUserSelectFromIndex() throws IOException { - index("{\"test\":\"doc1\"}", - "{\"test\":\"doc2\"}", - "{\"test\":\"doc3\"}"); + index("{\"test\":\"doc1\"}", "{\"test\":\"doc2\"}", "{\"test\":\"doc3\"}"); String mode = randomMode().toString(); String randomUserName = users.get(0); - + Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); - expected.put("rows", Arrays.asList(Arrays.asList(randomUserName), - Arrays.asList(randomUserName), - Arrays.asList(randomUserName))); + expected.put("columns", Arrays.asList(columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 32766))); + expected.put("rows", Arrays.asList(Arrays.asList(randomUserName), Arrays.asList(randomUserName), Arrays.asList(randomUserName))); Map actual = runSql(randomUserName, mode, "SELECT USER() FROM test LIMIT 3"); - + assertResponse(expected, actual); } - + private void createUser(String name, String role) throws IOException { Request request = new Request("PUT", "/_security/user/" + name); XContentBuilder user = JsonXContent.contentBuilder().prettyPrint(); - user.startObject(); { + user.startObject(); + { user.field("password", "testpass"); user.field("roles", role); } @@ -164,12 +150,12 @@ public class UserFunctionIT extends ESRestTestCase { request.setJsonEntity(Strings.toString(user)); client().performRequest(request); } - + private void deleteUser(String name) throws IOException { Request request = new Request("DELETE", "/_security/user/" + name); client().performRequest(request); } - + private Map runSql(String asUser, String mode, String sql) throws IOException { Request request = new Request("POST", SQL_QUERY_REST_ENDPOINT); if (asUser != null) { @@ -180,7 +166,7 @@ public class UserFunctionIT extends ESRestTestCase { request.setEntity(new StringEntity(query(sql).mode(mode).toString(), ContentType.APPLICATION_JSON)); return toMap(client().performRequest(request), mode); } - + private void assertResponse(Map expected, Map actual) { if (false == expected.equals(actual)) { NotEqualMessageBuilder message = new NotEqualMessageBuilder(); diff --git a/x-pack/plugin/sql/qa/server/security/src/test/resources/plugin-security.policy b/x-pack/plugin/sql/qa/server/security/src/test/resources/plugin-security.policy new file mode 100644 index 00000000000..434fdee0a8d --- /dev/null +++ b/x-pack/plugin/sql/qa/server/security/src/test/resources/plugin-security.policy @@ -0,0 +1,9 @@ +grant { + // Needed to read the audit log file + permission java.io.FilePermission "${tests.audit.logfile}", "read"; + permission java.io.FilePermission "${tests.audit.yesterday.logfile}", "read"; + + //// Required by ssl subproject: + // Required for the net client to setup ssl rather than use global ssl. + permission java.lang.RuntimePermission "setFactory"; +}; diff --git a/x-pack/plugin/sql/qa/security/with-ssl/build.gradle b/x-pack/plugin/sql/qa/server/security/with-ssl/build.gradle similarity index 100% rename from x-pack/plugin/sql/qa/security/with-ssl/build.gradle rename to x-pack/plugin/sql/qa/server/security/with-ssl/build.gradle diff --git a/x-pack/plugin/sql/qa/security/without-ssl/build.gradle b/x-pack/plugin/sql/qa/server/security/without-ssl/build.gradle similarity index 100% rename from x-pack/plugin/sql/qa/security/without-ssl/build.gradle rename to x-pack/plugin/sql/qa/server/security/without-ssl/build.gradle diff --git a/x-pack/plugin/sql/qa/no-sql/build.gradle b/x-pack/plugin/sql/qa/server/single-node/build.gradle similarity index 100% rename from x-pack/plugin/sql/qa/no-sql/build.gradle rename to x-pack/plugin/sql/qa/server/single-node/build.gradle diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliErrorsIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliErrorsIT.java similarity index 87% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliErrorsIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliErrorsIT.java index d8817d23efe..641d1344448 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliErrorsIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliErrorsIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.cli.ErrorsTestCase; -public class CliErrorsIT extends ErrorsTestCase { -} +public class CliErrorsIT extends ErrorsTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliExplainIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliExplainIT.java similarity index 97% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliExplainIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliExplainIT.java index c7069f18e02..a54cf3f9440 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliExplainIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliExplainIT.java @@ -68,8 +68,10 @@ public class CliExplainIT extends CliIntegrationTestCase { assertThat(readLine(), startsWith(" \\_UnresolvedRelation[test]")); assertEquals("", readLine()); - assertThat(command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT * FROM test WHERE i = 2"), - containsString("plan")); + assertThat( + command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT * FROM test WHERE i = 2"), + containsString("plan") + ); assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("Project[[test.i{f}#")); assertThat(readLine(), startsWith("\\_Filter[test.i{f}#")); @@ -123,8 +125,7 @@ public class CliExplainIT extends CliIntegrationTestCase { assertThat(readLine(), startsWith(" \\_UnresolvedRelation[test]")); assertEquals("", readLine()); - assertThat(command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT COUNT(*) FROM test"), - containsString("plan")); + assertThat(command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT COUNT(*) FROM test"), containsString("plan")); assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("Aggregate[[],[COUNT(*)")); assertThat(readLine(), startsWith("\\_EsRelation[test][i{f}#")); diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliFetchSizeIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliFetchSizeIT.java similarity index 86% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliFetchSizeIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliFetchSizeIT.java index eb1e8d32a6b..676f11d99a4 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliFetchSizeIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliFetchSizeIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.cli.FetchSizeTestCase; -public class CliFetchSizeIT extends FetchSizeTestCase { -} +public class CliFetchSizeIT extends FetchSizeTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliSelectIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliSelectIT.java similarity index 87% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliSelectIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliSelectIT.java index 76c2a324ed8..e42b741f585 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliSelectIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliSelectIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.cli.SelectTestCase; -public class CliSelectIT extends SelectTestCase { -} +public class CliSelectIT extends SelectTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliShowIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliShowIT.java similarity index 88% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliShowIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliShowIT.java index d3557d1afa4..fb6d6310932 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliShowIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CliShowIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.cli.ShowTestCase; -public class CliShowIT extends ShowTestCase { -} +public class CliShowIT extends ShowTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CustomDateFormatIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CustomDateFormatIT.java similarity index 100% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CustomDateFormatIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/CustomDateFormatIT.java diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/FieldExtractorIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/FieldExtractorIT.java similarity index 100% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/FieldExtractorIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/FieldExtractorIT.java diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcCsvSpecIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcCsvSpecIT.java similarity index 100% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcCsvSpecIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcCsvSpecIT.java diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcSqlSpecIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcSqlSpecIT.java similarity index 100% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcSqlSpecIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/GeoJdbcSqlSpecIT.java diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcCsvSpecIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcCsvSpecIT.java similarity index 97% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcCsvSpecIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcCsvSpecIT.java index 685a36f483b..73ca2641f95 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcCsvSpecIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcCsvSpecIT.java @@ -33,6 +33,6 @@ public class JdbcCsvSpecIT extends CsvSpecTestCase { protected int fetchSize() { // using a smaller fetchSize for nested documents' tests to uncover bugs // similar to https://github.com/elastic/elasticsearch/issues/35176 quicker - return fileName.startsWith("nested") && randomBoolean() ? randomIntBetween(1,5) : super.fetchSize(); + return fileName.startsWith("nested") && randomBoolean() ? randomIntBetween(1, 5) : super.fetchSize(); } } diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDatabaseMetaDataIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDatabaseMetaDataIT.java similarity index 97% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDatabaseMetaDataIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDatabaseMetaDataIT.java index 13bc7c36950..7f70351d0fb 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDatabaseMetaDataIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDatabaseMetaDataIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.jdbc.DatabaseMetaDataTestCase; -public class JdbcDatabaseMetaDataIT extends DatabaseMetaDataTestCase { -} +public class JdbcDatabaseMetaDataIT extends DatabaseMetaDataTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDocCsvSpecIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDocCsvSpecIT.java similarity index 98% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDocCsvSpecIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDocCsvSpecIT.java index 839da92483e..3c2f2515b11 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDocCsvSpecIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcDocCsvSpecIT.java @@ -30,9 +30,9 @@ import static org.elasticsearch.xpack.sql.qa.jdbc.CsvTestUtils.specParser; * gets reflected in the dataset structure. * The doc tests while redundant, try to be expressive first and foremost and sometimes * the dataset isn't exactly convenient. - * + * * Also looking around for the tests across the test files isn't trivial. - * + * * That's not to say the two cannot be merged however that felt like too much of an effort * at this stage and, to not keep things stalling, started with this approach. */ @@ -68,7 +68,7 @@ public class JdbcDocCsvSpecIT extends SpecBaseIntegrationTestCase { // // uncomment this to printout the result set and create new CSV tests // - //JdbcTestUtils.logLikeCLI(elastic, log); + // JdbcTestUtils.logLikeCLI(elastic, log); JdbcAssert.assertResultSets(expected, elastic, log, true, true); } @@ -87,4 +87,4 @@ public class JdbcDocCsvSpecIT extends SpecBaseIntegrationTestCase { assertResults(expected, elasticResults); } } -} \ No newline at end of file +} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFrozenCsvSpecIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFrozenCsvSpecIT.java similarity index 99% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFrozenCsvSpecIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFrozenCsvSpecIT.java index b8506cc5e1e..c2959bfc7fc 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFrozenCsvSpecIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcFrozenCsvSpecIT.java @@ -35,7 +35,6 @@ public class JdbcFrozenCsvSpecIT extends CsvSpecTestCase { return props; } - public JdbcFrozenCsvSpecIT(String fileName, String groupName, String testName, Integer lineNumber, CsvTestCase testCase) { super(fileName, groupName, testName, lineNumber, testCase); } diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShardFailureIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShardFailureIT.java similarity index 93% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShardFailureIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShardFailureIT.java index 19e16d1de2e..35bfc1d4d20 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShardFailureIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShardFailureIT.java @@ -25,8 +25,8 @@ public class JdbcShardFailureIT extends JdbcIntegrationTestCase { client().performRequest(createTest1); Request createTest2 = new Request("PUT", "/test2"); - String body2 = "{\"aliases\":{\"test\":{}}, \"mappings\": {\"properties\": {\"test_field\":{\"type\":\"integer\"}}}," + - "\"settings\": {\"index.routing.allocation.include.node\": \"nowhere\"}}"; + String body2 = "{\"aliases\":{\"test\":{}}, \"mappings\": {\"properties\": {\"test_field\":{\"type\":\"integer\"}}}," + + "\"settings\": {\"index.routing.allocation.include.node\": \"nowhere\"}}"; createTest2.setJsonEntity(body2); createTest2.addParameter("timeout", "100ms"); client().performRequest(createTest2); diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShowTablesIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShowTablesIT.java similarity index 85% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShowTablesIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShowTablesIT.java index f5ceefc35c1..8f736f2586e 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShowTablesIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcShowTablesIT.java @@ -7,5 +7,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.jdbc.ShowTablesTestCase; -public class JdbcShowTablesIT extends ShowTablesTestCase { -} +public class JdbcShowTablesIT extends ShowTablesTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSqlSpecIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSqlSpecIT.java similarity index 99% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSqlSpecIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSqlSpecIT.java index 0e1867b26df..5a6c300db54 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSqlSpecIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcSqlSpecIT.java @@ -11,4 +11,4 @@ public class JdbcSqlSpecIT extends SqlSpecTestCase { public JdbcSqlSpecIT(String fileName, String groupName, String testName, Integer lineNumber, String query) { super(fileName, groupName, testName, lineNumber, query); } -} \ No newline at end of file +} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java similarity index 52% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java index fc43c0de976..64394a135fe 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java @@ -17,40 +17,56 @@ import static org.hamcrest.Matchers.containsString; */ public class RestSqlIT extends RestSqlTestCase { - public void testErrorMessageForTranslatingQueryWithWhereEvaluatingToFalse() throws IOException { index("{\"foo\":1}"); - expectBadRequest(() -> runTranslateSql(query("SELECT * FROM test WHERE foo = 1 AND foo = 2").toString()), - containsString("Cannot generate a query DSL for an SQL query that either its WHERE clause evaluates " + - "to FALSE or doesn't operate on a table (missing a FROM clause), sql statement: " + - "[SELECT * FROM test WHERE foo = 1 AND foo = 2]")); + expectBadRequest( + () -> runTranslateSql(query("SELECT * FROM test WHERE foo = 1 AND foo = 2").toString()), + containsString( + "Cannot generate a query DSL for an SQL query that either its WHERE clause evaluates " + + "to FALSE or doesn't operate on a table (missing a FROM clause), sql statement: " + + "[SELECT * FROM test WHERE foo = 1 AND foo = 2]" + ) + ); } public void testErrorMessageForTranslatingQueryWithLocalExecution() throws IOException { index("{\"foo\":1}"); - expectBadRequest(() -> runTranslateSql(query("SELECT SIN(PI())").toString()), - containsString("Cannot generate a query DSL for an SQL query that either its WHERE clause evaluates " + - "to FALSE or doesn't operate on a table (missing a FROM clause), sql statement: [SELECT SIN(PI())]")); + expectBadRequest( + () -> runTranslateSql(query("SELECT SIN(PI())").toString()), + containsString( + "Cannot generate a query DSL for an SQL query that either its WHERE clause evaluates " + + "to FALSE or doesn't operate on a table (missing a FROM clause), sql statement: [SELECT SIN(PI())]" + ) + ); } public void testErrorMessageForTranslatingSQLCommandStatement() throws IOException { index("{\"foo\":1}"); - expectBadRequest(() -> runTranslateSql(query("SHOW FUNCTIONS").toString()), - containsString("Cannot generate a query DSL for a special SQL command " + - "(e.g.: DESCRIBE, SHOW), sql statement: [SHOW FUNCTIONS]")); + expectBadRequest( + () -> runTranslateSql(query("SHOW FUNCTIONS").toString()), + containsString( + "Cannot generate a query DSL for a special SQL command " + "(e.g.: DESCRIBE, SHOW), sql statement: [SHOW FUNCTIONS]" + ) + ); } public void testErrorMessageForInvalidParamDataType() throws IOException { // proto.Mode not available - expectBadRequest(() -> runTranslateSql( - query("SELECT null WHERE 0 = ?").mode("odbc").params("[{\"type\":\"invalid\", \"value\":\"irrelevant\"}]").toString()), - containsString("Invalid parameter data type [invalid]")); + expectBadRequest( + () -> runTranslateSql( + query("SELECT null WHERE 0 = ?").mode("odbc").params("[{\"type\":\"invalid\", \"value\":\"irrelevant\"}]").toString() + ), + containsString("Invalid parameter data type [invalid]") + ); } public void testErrorMessageForInvalidParamSpec() throws IOException { - expectBadRequest(() -> runTranslateSql( - query("SELECT null WHERE 0 = ?").mode("odbc").params("[{\"type\":\"SHAPE\", \"value\":false}]").toString()), - containsString("Cannot cast value [false] of type [BOOLEAN] to parameter type [SHAPE]")); + expectBadRequest( + () -> runTranslateSql( + query("SELECT null WHERE 0 = ?").mode("odbc").params("[{\"type\":\"SHAPE\", \"value\":false}]").toString() + ), + containsString("Cannot cast value [false] of type [BOOLEAN] to parameter type [SHAPE]") + ); } } diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlUsageIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlUsageIT.java similarity index 85% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlUsageIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlUsageIT.java index 61d8cca2171..0dfd8f9d1a0 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlUsageIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlUsageIT.java @@ -8,5 +8,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.rest.RestSqlUsageTestCase; -public class RestSqlUsageIT extends RestSqlUsageTestCase { -} +public class RestSqlUsageIT extends RestSqlUsageTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SqlProtocolIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SqlProtocolIT.java similarity index 85% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SqlProtocolIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SqlProtocolIT.java index ec0cbe3f2ce..5e698075974 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SqlProtocolIT.java +++ b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SqlProtocolIT.java @@ -8,5 +8,4 @@ package org.elasticsearch.xpack.sql.qa.single_node; import org.elasticsearch.xpack.sql.qa.SqlProtocolTestCase; -public class SqlProtocolIT extends SqlProtocolTestCase { -} +public class SqlProtocolIT extends SqlProtocolTestCase {} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SysColumnsIT.java b/x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SysColumnsIT.java similarity index 100% rename from x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SysColumnsIT.java rename to x-pack/plugin/sql/qa/server/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/SysColumnsIT.java diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/CustomDateFormatTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/CustomDateFormatTestCase.java similarity index 77% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/CustomDateFormatTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/CustomDateFormatTestCase.java index 0052b91b6de..e5c25144a76 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/CustomDateFormatTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/CustomDateFormatTestCase.java @@ -30,31 +30,37 @@ import java.util.Locale; * with different timezones and custom date formats for the date fields in ES. */ public abstract class CustomDateFormatTestCase extends BaseRestSqlTestCase { - - private static String[] customFormats = new String[] {"HH:mm yyyy-MM-dd", "HH:mm:ss yyyy-dd-MM", "HH:mm:ss VV", "HH:mm:ss VV z", - "yyyy-MM-dd'T'HH:mm:ss'T'VV'T'z"}; - private static String[] nowFunctions = new String[] {"NOW()", "CURRENT_DATE()", "CURRENT_TIME()", "CURRENT_TIMESTAMP()"}; - private static String[] operators = new String[] {" < ", " > ", " <= ", " >= ", " = ", " != "}; - + + private static String[] customFormats = new String[] { + "HH:mm yyyy-MM-dd", + "HH:mm:ss yyyy-dd-MM", + "HH:mm:ss VV", + "HH:mm:ss VV z", + "yyyy-MM-dd'T'HH:mm:ss'T'VV'T'z" }; + private static String[] nowFunctions = new String[] { "NOW()", "CURRENT_DATE()", "CURRENT_TIME()", "CURRENT_TIMESTAMP()" }; + private static String[] operators = new String[] { " < ", " > ", " <= ", " >= ", " = ", " != " }; + public void testCustomDateFormatsWithNowFunctions() throws IOException { createIndex(); String[] docs = new String[customFormats.length]; String zID = JdbcIntegrationTestCase.randomKnownTimeZone(); StringBuilder datesConditions = new StringBuilder(); - + for (int i = 0; i < customFormats.length; i++) { String field = "date_" + i; - docs[i] = "{\"" + field + "\":\"" + - DateTimeFormatter.ofPattern(customFormats[i], Locale.ROOT).format(DateUtils.nowWithMillisResolution()) + "\"}"; + docs[i] = "{\"" + + field + + "\":\"" + + DateTimeFormatter.ofPattern(customFormats[i], Locale.ROOT).format(DateUtils.nowWithMillisResolution()) + + "\"}"; datesConditions.append(i > 0 ? " OR " : "").append(field + randomFrom(operators) + randomFrom(nowFunctions)); } - + index(docs); - + Request request = new Request("POST", RestSqlTestCase.SQL_QUERY_REST_ENDPOINT); final String query = "SELECT COUNT(*) AS c FROM test WHERE " + datesConditions.toString(); - request.setEntity(new StringEntity(query(query).mode(Mode.PLAIN).timeZone(zID).toString(), - ContentType.APPLICATION_JSON)); + request.setEntity(new StringEntity(query(query).mode(Mode.PLAIN).timeZone(zID).toString(), ContentType.APPLICATION_JSON)); Response response = client().performRequest(request); String expectedJsonSnippet = "{\"columns\":[{\"name\":\"c\",\"type\":\"long\"}],\"rows\":[["; @@ -70,22 +76,25 @@ public abstract class CustomDateFormatTestCase extends BaseRestSqlTestCase { assertTrue(actualJson.startsWith(expectedJsonSnippet)); } } - + private void createIndex() throws IOException { - Request request = new Request("PUT", "/test"); + Request request = new Request("PUT", "/test"); XContentBuilder index = JsonXContent.contentBuilder().prettyPrint().startObject(); - index.startObject("mappings"); { - index.startObject("properties"); { + index.startObject("mappings"); + { + index.startObject("properties"); + { for (int i = 0; i < customFormats.length; i++) { String fieldName = "date_" + i; - index.startObject(fieldName); { + index.startObject(fieldName); + { index.field("type", "date"); index.field("format", customFormats[i]); } index.endObject(); } - index.endObject(); + index.endObject(); } } index.endObject(); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/ErrorsTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/ErrorsTestCase.java similarity index 99% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/ErrorsTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/ErrorsTestCase.java index 68ae50a4299..8be83f6091e 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/ErrorsTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/ErrorsTestCase.java @@ -12,16 +12,28 @@ package org.elasticsearch.xpack.sql.qa; */ public interface ErrorsTestCase { void testSelectInvalidSql() throws Exception; + void testSelectFromMissingIndex() throws Exception; + void testSelectColumnFromMissingIndex() throws Exception; + void testSelectFromEmptyIndex() throws Exception; + void testSelectColumnFromEmptyIndex() throws Exception; + void testSelectMissingField() throws Exception; + void testSelectMissingFunction() throws Exception; + void testSelectProjectScoreInAggContext() throws Exception; + void testSelectOrderByScoreInAggContext() throws Exception; + void testSelectGroupByScore() throws Exception; + void testSelectScoreSubField() throws Exception; + void testSelectScoreInScalar() throws Exception; + void testHardLimitForSortOnAggregate() throws Exception; } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/FeatureMetric.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/FeatureMetric.java similarity index 100% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/FeatureMetric.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/FeatureMetric.java diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/FieldExtractorTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/FieldExtractorTestCase.java similarity index 87% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/FieldExtractorTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/FieldExtractorTestCase.java index 91f4156c2c5..bcc060b3567 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/FieldExtractorTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/FieldExtractorTestCase.java @@ -49,18 +49,16 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { String text = randomAlphaOfLength(20); boolean explicitSourceSetting = randomBoolean(); // default (no _source setting) or explicit setting boolean enableSource = randomBoolean(); // enable _source at index level - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + createIndexWithFieldTypeAndProperties("text", null, explicitSourceSetting ? indexProps : null); index("{\"text_field\":\"" + text + "\"}"); - + if (explicitSourceSetting == false || enableSource) { Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", "text_field", "text", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + expected.put("columns", Arrays.asList(columnInfo("plain", "text_field", "text", JDBCType.VARCHAR, Integer.MAX_VALUE))); expected.put("rows", singletonList(singletonList(text))); assertResponse(expected, runSql(query)); } else { @@ -80,10 +78,10 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { boolean explicitSourceSetting = randomBoolean(); // default (no _source setting) or explicit setting boolean enableSource = randomBoolean(); // enable _source at index level boolean ignoreAbove = randomBoolean(); - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> fieldProps = null; if (ignoreAbove) { fieldProps = new HashMap<>(1); @@ -91,14 +89,12 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProp.put("ignore_above", 10); fieldProps.put("keyword_field", fieldProp); } - + createIndexWithFieldTypeAndProperties("keyword", fieldProps, explicitSourceSetting ? indexProps : null); index("{\"keyword_field\":\"" + keyword + "\"}"); - + Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", "keyword_field", "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + expected.put("columns", Arrays.asList(columnInfo("plain", "keyword_field", "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE))); expected.put("rows", singletonList(singletonList(ignoreAbove ? null : keyword))); assertResponse(expected, runSql("SELECT keyword_field FROM test")); } @@ -114,10 +110,10 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { // _source for `constant_keyword` fields doesn't matter, as they should be taken from docvalue_fields boolean explicitSourceSetting = randomBoolean(); // default (no _source setting) or explicit setting boolean enableSource = randomBoolean(); // enable _source at index level - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> fieldProps = null; if (randomBoolean()) { fieldProps = new HashMap<>(1); @@ -125,14 +121,15 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProp.put("value", value); fieldProps.put("constant_keyword_field", fieldProp); } - + createIndexWithFieldTypeAndProperties("constant_keyword", fieldProps, explicitSourceSetting ? indexProps : null); index("{\"constant_keyword_field\":\"" + value + "\"}"); - + Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", "constant_keyword_field", "constant_keyword", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + expected.put( + "columns", + Arrays.asList(columnInfo("plain", "constant_keyword_field", "constant_keyword", JDBCType.VARCHAR, Integer.MAX_VALUE)) + ); expected.put("rows", singletonList(singletonList(value))); assertResponse(expected, runSql("SELECT constant_keyword_field FROM test")); } @@ -145,15 +142,16 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { public void testFractionsForNonFloatingPointTypes() throws IOException { String floatingPointNumber = "123.456"; String fieldType = randomFrom("long", "integer", "short", "byte"); - + createIndexWithFieldTypeAndProperties(fieldType, null, null); index("{\"" + fieldType + "_field\":\"" + floatingPointNumber + "\"}"); - + Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", fieldType + "_field", fieldType, jdbcTypeFor(fieldType), Integer.MAX_VALUE) - )); - + expected.put( + "columns", + Arrays.asList(columnInfo("plain", fieldType + "_field", fieldType, jdbcTypeFor(fieldType), Integer.MAX_VALUE)) + ); + // because "coerce" is true, a "123.456" floating point number STRING should be converted to 123, no matter the numeric field type expected.put("rows", singletonList(singletonList(123))); assertResponse(expected, runSql("SELECT " + fieldType + "_field FROM test")); @@ -169,7 +167,7 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { String floatingPointNumber = "123.456"; String fieldType = randomFrom("double", "float", "half_float", "scaled_float"); boolean isScaledFloat = fieldType == "scaled_float"; - + Map> fieldProps = null; if (isScaledFloat) { fieldProps = new HashMap<>(1); @@ -177,20 +175,27 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProp.put("scaling_factor", 10); // scaling_factor is required for "scaled_float" fieldProps.put(fieldType + "_field", fieldProp); } - + createIndexWithFieldTypeAndProperties(fieldType, fieldProps, null); // important here is to pass floatingPointNumber as a string: "float_field": "123.456" index("{\"" + fieldType + "_field\":\"" + floatingPointNumber + "\"}"); - + Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", fieldType + "_field", fieldType, jdbcTypeFor(fieldType), Integer.MAX_VALUE) - )); - + expected.put( + "columns", + Arrays.asList(columnInfo("plain", fieldType + "_field", fieldType, jdbcTypeFor(fieldType), Integer.MAX_VALUE)) + ); + // because "coerce" is true, a "123.456" floating point number STRING should be converted to 123.456 as number // and converted to 123.5 for "scaled_float" type - expected.put("rows", singletonList(singletonList( - isScaledFloat ? 123.5 : (fieldType != "double" ? Double.valueOf(123.456f) : Double.valueOf(floatingPointNumber))))); + expected.put( + "rows", + singletonList( + singletonList( + isScaledFloat ? 123.5 : (fieldType != "double" ? Double.valueOf(123.456f) : Double.valueOf(floatingPointNumber)) + ) + ) + ); assertResponse(expected, runSql("SELECT " + fieldType + "_field FROM test")); } @@ -237,7 +242,7 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { // Integers for short and byte values testField("byte", ((Number) randomByte()).intValue()); } - + private void testField(String fieldType, Object value) throws IOException { String fieldName = fieldType + "_field"; String query = "SELECT " + fieldName + " FROM test"; @@ -245,10 +250,10 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { boolean explicitSourceSetting = randomBoolean(); // default (no _source setting) or explicit setting boolean enableSource = randomBoolean(); // enable _source at index level boolean ignoreMalformed = randomBoolean(); // ignore_malformed is true, thus test a non-number value - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> fieldProps = null; if (ignoreMalformed) { fieldProps = new HashMap<>(1); @@ -258,15 +263,13 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProps.put(fieldName, fieldProp); actualValue = "\"foo\""; } - + createIndexWithFieldTypeAndProperties(fieldType, fieldProps, explicitSourceSetting ? indexProps : null); index("{\"" + fieldName + "\":" + actualValue + "}"); if (explicitSourceSetting == false || enableSource) { Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", fieldName, fieldType, jdbcTypeFor(fieldType), Integer.MAX_VALUE) - )); + expected.put("columns", Arrays.asList(columnInfo("plain", fieldName, fieldType, jdbcTypeFor(fieldType), Integer.MAX_VALUE))); expected.put("rows", singletonList(singletonList(ignoreMalformed ? null : actualValue))); assertResponse(expected, runSql(query)); } else { @@ -285,22 +288,20 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { boolean explicitSourceSetting = randomBoolean(); // default (no _source setting) or explicit setting boolean enableSource = randomBoolean(); // enable _source at index level boolean asString = randomBoolean(); // pass true or false as string "true" or "false - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + createIndexWithFieldTypeAndProperties("boolean", null, explicitSourceSetting ? indexProps : null); if (asString) { index("{\"boolean_field\":\"" + booleanField + "\"}"); } else { index("{\"boolean_field\":" + booleanField + "}"); } - + if (explicitSourceSetting == false || enableSource) { Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", "boolean_field", "boolean", JDBCType.BOOLEAN, Integer.MAX_VALUE) - )); + expected.put("columns", Arrays.asList(columnInfo("plain", "boolean_field", "boolean", JDBCType.BOOLEAN, Integer.MAX_VALUE))); // adding the boolean as a String here because parsing the response will yield a "true"/"false" String expected.put("rows", singletonList(singletonList(asString ? String.valueOf(booleanField) : booleanField))); assertResponse(expected, runSql(query)); @@ -319,18 +320,16 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { String ipField = "192.168.1.1"; boolean explicitSourceSetting = randomBoolean(); // default (no _source setting) or explicit setting boolean enableSource = randomBoolean(); // enable _source at index level - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + createIndexWithFieldTypeAndProperties("ip", null, explicitSourceSetting ? indexProps : null); index("{\"ip_field\":\"" + ipField + "\"}"); - + if (explicitSourceSetting == false || enableSource) { Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", "ip_field", "ip", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + expected.put("columns", Arrays.asList(columnInfo("plain", "ip_field", "ip", JDBCType.VARCHAR, Integer.MAX_VALUE))); expected.put("rows", singletonList(singletonList(ipField))); assertResponse(expected, runSql(query)); } else { @@ -353,16 +352,19 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { */ public void testAliasFromDocValueField() throws IOException { String keyword = randomAlphaOfLength(20); - + createIndexWithFieldTypeAndAlias("keyword", null, null); index("{\"keyword_field\":\"" + keyword + "\"}"); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", "keyword_field", "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo("plain", "keyword_field_alias", "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo("plain", "a.b.c.keyword_field_alias", "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + ) + ); expected.put("rows", singletonList(Arrays.asList(keyword, keyword, keyword))); assertResponse(expected, runSql("SELECT keyword_field, keyword_field_alias, a.b.c.keyword_field_alias FROM test")); } @@ -382,16 +384,19 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { */ public void testAliasFromSourceField() throws IOException { String text = randomAlphaOfLength(20); - + createIndexWithFieldTypeAndAlias("text", null, null); index("{\"text_field\":\"" + text + "\"}"); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", "text_field", "text", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo("plain", "text_field_alias", "text", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo("plain", "a.b.c.text_field_alias", "text", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + ) + ); expected.put("rows", singletonList(Arrays.asList(text, null, null))); assertResponse(expected, runSql("SELECT text_field, text_field_alias, a.b.c.text_field_alias FROM test")); } @@ -411,16 +416,19 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { */ public void testAliasAggregatableFromSourceField() throws IOException { int number = randomInt(); - + createIndexWithFieldTypeAndAlias("integer", null, null); index("{\"integer_field\":" + number + "}"); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", "integer_field", "integer", JDBCType.INTEGER, Integer.MAX_VALUE), columnInfo("plain", "integer_field_alias", "integer", JDBCType.INTEGER, Integer.MAX_VALUE), columnInfo("plain", "a.b.c.integer_field_alias", "integer", JDBCType.INTEGER, Integer.MAX_VALUE) - )); + ) + ); expected.put("rows", singletonList(Arrays.asList(number, null, number))); assertResponse(expected, runSql("SELECT integer_field, integer_field_alias, a.b.c.integer_field_alias FROM test")); } @@ -445,10 +453,10 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { String fieldName = "text_field"; String subFieldName = "text_field.keyword_subfield"; String query = "SELECT " + fieldName + "," + subFieldName + " FROM test"; - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> subFieldsProps = null; if (ignoreAbove) { subFieldsProps = new HashMap<>(1); @@ -456,27 +464,28 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProp.put("ignore_above", 10); subFieldsProps.put(subFieldName, fieldProp); } - + createIndexWithFieldTypeAndSubFields("text", null, explicitSourceSetting ? indexProps : null, subFieldsProps, "keyword"); index("{\"" + fieldName + "\":\"" + text + "\"}"); if (explicitSourceSetting == false || enableSource) { Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", fieldName, "text", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo("plain", subFieldName, "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + ) + ); expected.put("rows", singletonList(Arrays.asList(text, ignoreAbove ? null : text))); assertResponse(expected, runSql(query)); } else { expectSourceDisabledError(query); - + // even if the _source is disabled, selecting only the keyword sub-field should work as expected Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( - columnInfo("plain", subFieldName, "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + expected.put("columns", Arrays.asList(columnInfo("plain", subFieldName, "keyword", JDBCType.VARCHAR, Integer.MAX_VALUE))); expected.put("rows", singletonList(singletonList(ignoreAbove ? null : text))); assertResponse(expected, runSql("SELECT text_field.keyword_subfield FROM test")); @@ -502,11 +511,11 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { Object actualValue = number; String fieldName = "text_field"; String subFieldName = "text_field.integer_subfield"; - String query = "SELECT " + fieldName + "," + subFieldName +" FROM test"; - + String query = "SELECT " + fieldName + "," + subFieldName + " FROM test"; + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> subFieldsProps = null; if (ignoreMalformed) { subFieldsProps = new HashMap<>(1); @@ -516,16 +525,19 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { subFieldsProps.put(subFieldName, fieldProp); actualValue = "foo"; } - + createIndexWithFieldTypeAndSubFields("text", null, explicitSourceSetting ? indexProps : null, subFieldsProps, "integer"); index("{\"" + fieldName + "\":\"" + actualValue + "\"}"); if (explicitSourceSetting == false || enableSource) { Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", fieldName, "text", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo("plain", subFieldName, "integer", JDBCType.INTEGER, Integer.MAX_VALUE) - )); + ) + ); if (ignoreMalformed) { expected.put("rows", singletonList(Arrays.asList("foo", null))); } else { @@ -559,11 +571,11 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { Object actualValue = number; String fieldName = "integer_field"; String subFieldName = "integer_field." + (isKeyword ? "keyword_subfield" : "text_subfield"); - String query = "SELECT " + fieldName + "," + subFieldName +" FROM test"; - + String query = "SELECT " + fieldName + "," + subFieldName + " FROM test"; + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> fieldProps = null; if (ignoreMalformed) { fieldProps = new HashMap<>(1); @@ -573,17 +585,25 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProps.put(fieldName, fieldProp); actualValue = "foo"; } - - createIndexWithFieldTypeAndSubFields("integer", fieldProps, explicitSourceSetting ? indexProps : null, null, - isKeyword ? "keyword" : "text"); + + createIndexWithFieldTypeAndSubFields( + "integer", + fieldProps, + explicitSourceSetting ? indexProps : null, + null, + isKeyword ? "keyword" : "text" + ); index("{\"" + fieldName + "\":\"" + actualValue + "\"}"); if (explicitSourceSetting == false || enableSource) { Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", fieldName, "integer", JDBCType.INTEGER, Integer.MAX_VALUE), columnInfo("plain", subFieldName, isKeyword ? "keyword" : "text", JDBCType.VARCHAR, Integer.MAX_VALUE) - )); + ) + ); if (ignoreMalformed) { expected.put("rows", singletonList(Arrays.asList(null, "foo"))); } else { @@ -609,7 +629,7 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { expectSourceDisabledError("SELECT " + fieldName + " FROM test"); } } - + /* * "integer_field": { * "type": "integer", @@ -632,10 +652,10 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { String fieldName = "integer_field"; String subFieldName = "integer_field.byte_subfield"; String query = "SELECT " + fieldName + "," + subFieldName + " FROM test"; - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> fieldProps = null; if (rootIgnoreMalformed) { fieldProps = new HashMap<>(1); @@ -650,15 +670,18 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProp.put("ignore_malformed", true); subFieldProps.put(subFieldName, fieldProp); } - + createIndexWithFieldTypeAndSubFields("integer", fieldProps, explicitSourceSetting ? indexProps : null, subFieldProps, "byte"); index("{\"" + fieldName + "\":" + number + "}"); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", fieldName, "integer", JDBCType.INTEGER, Integer.MAX_VALUE), columnInfo("plain", subFieldName, "byte", JDBCType.TINYINT, Integer.MAX_VALUE) - )); + ) + ); if (explicitSourceSetting == false || enableSource) { if (isByte || subFieldIgnoreMalformed) { expected.put("rows", singletonList(Arrays.asList(number, isByte ? number : null))); @@ -698,10 +721,10 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { String fieldName = "byte_field"; String subFieldName = "byte_field.integer_subfield"; String query = "SELECT " + fieldName + "," + subFieldName + " FROM test"; - + Map indexProps = new HashMap<>(1); indexProps.put("_source", enableSource); - + Map> fieldProps = null; if (rootIgnoreMalformed) { fieldProps = new HashMap<>(1); @@ -716,15 +739,18 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { fieldProp.put("ignore_malformed", true); subFieldProps.put(subFieldName, fieldProp); } - + createIndexWithFieldTypeAndSubFields("byte", fieldProps, explicitSourceSetting ? indexProps : null, subFieldProps, "integer"); index("{\"" + fieldName + "\":" + number + "}"); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo("plain", fieldName, "byte", JDBCType.TINYINT, Integer.MAX_VALUE), columnInfo("plain", subFieldName, "integer", JDBCType.INTEGER, Integer.MAX_VALUE) - )); + ) + ); if (explicitSourceSetting == false || enableSource) { if (isByte || rootIgnoreMalformed) { expected.put("rows", singletonList(Arrays.asList(isByte ? number : null, number))); @@ -748,77 +774,96 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { return Collections.emptyMap(); }, containsString("unable to fetch fields from _source field: _source is disabled in the mappings for index [test]")); } - - private void createIndexWithFieldTypeAndAlias(String type, Map> fieldProps, - Map indexProps) throws IOException { + + private void createIndexWithFieldTypeAndAlias(String type, Map> fieldProps, Map indexProps) + throws IOException { createIndexWithFieldTypeAndProperties(type, fieldProps, indexProps, true, false, null); } - - private void createIndexWithFieldTypeAndProperties(String type, Map> fieldProps, - Map indexProps) throws IOException { + + private void createIndexWithFieldTypeAndProperties( + String type, + Map> fieldProps, + Map indexProps + ) throws IOException { createIndexWithFieldTypeAndProperties(type, fieldProps, indexProps, false, false, null); } - - private void createIndexWithFieldTypeAndSubFields(String type, Map> fieldProps, - Map indexProps, Map> subFieldsProps, - String... subFieldsTypes) throws IOException { + + private void createIndexWithFieldTypeAndSubFields( + String type, + Map> fieldProps, + Map indexProps, + Map> subFieldsProps, + String... subFieldsTypes + ) throws IOException { createIndexWithFieldTypeAndProperties(type, fieldProps, indexProps, false, true, subFieldsProps, subFieldsTypes); } - - private void createIndexWithFieldTypeAndProperties(String type, Map> fieldProps, - Map indexProps, boolean withAlias, boolean withSubFields, Map> subFieldsProps, - String... subFieldsTypes) throws IOException { - Request request = new Request("PUT", "/test"); + + private void createIndexWithFieldTypeAndProperties( + String type, + Map> fieldProps, + Map indexProps, + boolean withAlias, + boolean withSubFields, + Map> subFieldsProps, + String... subFieldsTypes + ) throws IOException { + Request request = new Request("PUT", "/test"); XContentBuilder index = JsonXContent.contentBuilder().prettyPrint().startObject(); - index.startObject("mappings"); { + index.startObject("mappings"); + { if (indexProps != null) { for (Entry prop : indexProps.entrySet()) { if (prop.getValue() instanceof Boolean) { - index.startObject(prop.getKey()); { + index.startObject(prop.getKey()); + { index.field("enabled", prop.getValue()); } index.endObject(); } } } - index.startObject("properties"); { + index.startObject("properties"); + { String fieldName = type + "_field"; - index.startObject(fieldName); { + index.startObject(fieldName); + { index.field("type", type); if (fieldProps != null && fieldProps.containsKey(fieldName)) { for (Entry prop : fieldProps.get(fieldName).entrySet()) { index.field(prop.getKey(), prop.getValue()); } } - + if (withSubFields) { index.startObject("fields"); - for (String subFieldType : subFieldsTypes) { - String subFieldName = subFieldType + "_subfield"; - String fullSubFieldName = fieldName + "." + subFieldName; - index.startObject(subFieldName); - index.field("type", subFieldType); - if (subFieldsProps != null && subFieldsProps.containsKey(fullSubFieldName)) { - for (Entry prop : subFieldsProps.get(fullSubFieldName).entrySet()) { - index.field(prop.getKey(), prop.getValue()); - } - } - index.endObject(); + for (String subFieldType : subFieldsTypes) { + String subFieldName = subFieldType + "_subfield"; + String fullSubFieldName = fieldName + "." + subFieldName; + index.startObject(subFieldName); + index.field("type", subFieldType); + if (subFieldsProps != null && subFieldsProps.containsKey(fullSubFieldName)) { + for (Entry prop : subFieldsProps.get(fullSubFieldName).entrySet()) { + index.field(prop.getKey(), prop.getValue()); + } } + index.endObject(); + } index.endObject(); } } index.endObject(); - + if (withAlias) { // create two aliases - one within a hierarchy, the other just a simple field w/o hierarchy - index.startObject(fieldName + "_alias"); { + index.startObject(fieldName + "_alias"); + { index.field("type", "alias"); index.field("path", fieldName); } index.endObject(); - index.startObject("a.b.c." + fieldName + "_alias"); { + index.startObject("a.b.c." + fieldName + "_alias"); + { index.field("type", "alias"); index.field("path", fieldName); } @@ -833,7 +878,7 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { request.setJsonEntity(Strings.toString(index)); client().performRequest(request); } - + private Request buildRequest(String query) { Request request = new Request("POST", RestSqlTestCase.SQL_QUERY_REST_ENDPOINT); request.addParameter("error_trace", "true"); @@ -842,16 +887,16 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase { return request; } - + private Map runSql(String query) throws IOException { Response response = client().performRequest(buildRequest(query)); try (InputStream content = response.getEntity().getContent()) { return XContentHelper.convertToMap(JsonXContent.jsonXContent, content, false); } } - + private JDBCType jdbcTypeFor(String esType) { - switch(esType) { + switch (esType) { case "long": return JDBCType.BIGINT; case "integer": diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/SqlProtocolTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/SqlProtocolTestCase.java similarity index 72% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/SqlProtocolTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/SqlProtocolTestCase.java index ada4eaa1cd6..c17c0c8086f 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/SqlProtocolTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/SqlProtocolTestCase.java @@ -38,12 +38,12 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { public void testNulls() throws IOException { assertQuery("SELECT NULL", "NULL", "null", null, 0); } - + public void testBooleanType() throws IOException { assertQuery("SELECT TRUE", "TRUE", "boolean", true, 1); assertQuery("SELECT FALSE", "FALSE", "boolean", false, 1); } - + public void testNumericTypes() throws IOException { assertQuery("SELECT CAST(3 AS TINYINT)", "CAST(3 AS TINYINT)", "byte", 3, 5); assertQuery("SELECT CAST(-123 AS TINYINT)", "CAST(-123 AS TINYINT)", "byte", -123, 5); @@ -60,38 +60,59 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { assertQuery("SELECT CAST(1234567890123.34 AS FLOAT)", "CAST(1234567890123.34 AS FLOAT)", "double", 1234567890123.34, 25); assertQuery("SELECT CAST(-1234567890123.34 AS FLOAT)", "CAST(-1234567890123.34 AS FLOAT)", "double", -1234567890123.34, 25); } - + public void testTextualType() throws IOException { assertQuery("SELECT 'abc123'", "'abc123'", "keyword", "abc123", 32766); } - + public void testDateTimes() throws IOException { - assertQuery("SELECT CAST('2019-01-14T12:29:25.000Z' AS DATETIME)", "CAST('2019-01-14T12:29:25.000Z' AS DATETIME)", - "datetime", "2019-01-14T12:29:25.000Z", 29); - assertQuery("SELECT CAST(-26853765751000 AS DATETIME)", "CAST(-26853765751000 AS DATETIME)", - "datetime", "1119-01-15T12:37:29.000Z", 29); - assertQuery("SELECT CAST(CAST('-26853765751000' AS BIGINT) AS DATETIME)", "CAST(CAST('-26853765751000' AS BIGINT) AS DATETIME)", - "datetime", "1119-01-15T12:37:29.000Z", 29); + assertQuery( + "SELECT CAST('2019-01-14T12:29:25.000Z' AS DATETIME)", + "CAST('2019-01-14T12:29:25.000Z' AS DATETIME)", + "datetime", + "2019-01-14T12:29:25.000Z", + 29 + ); + assertQuery( + "SELECT CAST(-26853765751000 AS DATETIME)", + "CAST(-26853765751000 AS DATETIME)", + "datetime", + "1119-01-15T12:37:29.000Z", + 29 + ); + assertQuery( + "SELECT CAST(CAST('-26853765751000' AS BIGINT) AS DATETIME)", + "CAST(CAST('-26853765751000' AS BIGINT) AS DATETIME)", + "datetime", + "1119-01-15T12:37:29.000Z", + 29 + ); - assertQuery("SELECT CAST('2019-01-14' AS DATE)", "CAST('2019-01-14' AS DATE)", - "date", "2019-01-14T00:00:00.000Z", 29); - assertQuery("SELECT CAST(-26853765751000 AS DATE)", "CAST(-26853765751000 AS DATE)", - "date", "1119-01-15T00:00:00.000Z", 29); + assertQuery("SELECT CAST('2019-01-14' AS DATE)", "CAST('2019-01-14' AS DATE)", "date", "2019-01-14T00:00:00.000Z", 29); + assertQuery("SELECT CAST(-26853765751000 AS DATE)", "CAST(-26853765751000 AS DATE)", "date", "1119-01-15T00:00:00.000Z", 29); - assertQuery("SELECT CAST('12:29:25.123Z' AS TIME)", "CAST('12:29:25.123Z' AS TIME)", - "time", "12:29:25.123Z", 18); - assertQuery("SELECT CAST('12:29:25.123456789+05:00' AS TIME)", "CAST('12:29:25.123456789+05:00' AS TIME)", - "time", "12:29:25.123+05:00", 18); - assertQuery("SELECT CAST(-26853765751000 AS TIME)", "CAST(-26853765751000 AS TIME)", - "time", "12:37:29.000Z", 18); + assertQuery("SELECT CAST('12:29:25.123Z' AS TIME)", "CAST('12:29:25.123Z' AS TIME)", "time", "12:29:25.123Z", 18); + assertQuery( + "SELECT CAST('12:29:25.123456789+05:00' AS TIME)", + "CAST('12:29:25.123456789+05:00' AS TIME)", + "time", + "12:29:25.123+05:00", + 18 + ); + assertQuery("SELECT CAST(-26853765751000 AS TIME)", "CAST(-26853765751000 AS TIME)", "time", "12:37:29.000Z", 18); } - + public void testIPs() throws IOException { assertQuery("SELECT CAST('12.13.14.15' AS IP)", "CAST('12.13.14.15' AS IP)", "ip", "12.13.14.15", 45); - assertQuery("SELECT CAST('2001:0db8:0000:0000:0000:ff00:0042:8329' AS IP)", "CAST('2001:0db8:0000:0000:0000:ff00:0042:8329' AS IP)", - "ip", "2001:0db8:0000:0000:0000:ff00:0042:8329", 45); + assertQuery( + "SELECT CAST('2001:0db8:0000:0000:0000:ff00:0042:8329' AS IP)", + "CAST('2001:0db8:0000:0000:0000:ff00:0042:8329' AS IP)", + "ip", + "2001:0db8:0000:0000:0000:ff00:0042:8329", + 45 + ); } - + public void testDateTimeIntervals() throws IOException { assertQuery("SELECT INTERVAL '326' YEAR", "INTERVAL '326' YEAR", "interval_year", "P326Y", "+326-0", 7); assertQuery("SELECT INTERVAL '50' MONTH", "INTERVAL '50' MONTH", "interval_month", "P50M", "+0-50", 7); @@ -99,24 +120,72 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { assertQuery("SELECT INTERVAL '163' HOUR", "INTERVAL '163' HOUR", "interval_hour", "PT163H", "+6 19:00:00", 23); assertQuery("SELECT INTERVAL '163' MINUTE", "INTERVAL '163' MINUTE", "interval_minute", "PT2H43M", "+0 02:43:00", 23); assertQuery("SELECT INTERVAL '223.16' SECOND", "INTERVAL '223.16' SECOND", "interval_second", "PT3M43.16S", "+0 00:03:43.16", 23); - assertQuery("SELECT INTERVAL '163-11' YEAR TO MONTH", "INTERVAL '163-11' YEAR TO MONTH", "interval_year_to_month", "P163Y11M", - "+163-11", 7); - assertQuery("SELECT INTERVAL '163 12' DAY TO HOUR", "INTERVAL '163 12' DAY TO HOUR", "interval_day_to_hour", "PT3924H", - "+163 12:00:00", 23); - assertQuery("SELECT INTERVAL '163 12:39' DAY TO MINUTE", "INTERVAL '163 12:39' DAY TO MINUTE", "interval_day_to_minute", - "PT3924H39M", "+163 12:39:00", 23); - assertQuery("SELECT INTERVAL '163 12:39:59.163' DAY TO SECOND", "INTERVAL '163 12:39:59.163' DAY TO SECOND", - "interval_day_to_second", "PT3924H39M59.163S", "+163 12:39:59.163", 23); - assertQuery("SELECT INTERVAL -'163 23:39:56.23' DAY TO SECOND", "INTERVAL -'163 23:39:56.23' DAY TO SECOND", - "interval_day_to_second", "PT-3935H-39M-56.23S", "-163 23:39:56.23", 23); - assertQuery("SELECT INTERVAL '163:39' HOUR TO MINUTE", "INTERVAL '163:39' HOUR TO MINUTE", "interval_hour_to_minute", - "PT163H39M", "+6 19:39:00", 23); - assertQuery("SELECT INTERVAL '163:39:59.163' HOUR TO SECOND", "INTERVAL '163:39:59.163' HOUR TO SECOND", "interval_hour_to_second", - "PT163H39M59.163S", "+6 19:39:59.163", 23); - assertQuery("SELECT INTERVAL '163:59.163' MINUTE TO SECOND", "INTERVAL '163:59.163' MINUTE TO SECOND", "interval_minute_to_second", - "PT2H43M59.163S", "+0 02:43:59.163", 23); + assertQuery( + "SELECT INTERVAL '163-11' YEAR TO MONTH", + "INTERVAL '163-11' YEAR TO MONTH", + "interval_year_to_month", + "P163Y11M", + "+163-11", + 7 + ); + assertQuery( + "SELECT INTERVAL '163 12' DAY TO HOUR", + "INTERVAL '163 12' DAY TO HOUR", + "interval_day_to_hour", + "PT3924H", + "+163 12:00:00", + 23 + ); + assertQuery( + "SELECT INTERVAL '163 12:39' DAY TO MINUTE", + "INTERVAL '163 12:39' DAY TO MINUTE", + "interval_day_to_minute", + "PT3924H39M", + "+163 12:39:00", + 23 + ); + assertQuery( + "SELECT INTERVAL '163 12:39:59.163' DAY TO SECOND", + "INTERVAL '163 12:39:59.163' DAY TO SECOND", + "interval_day_to_second", + "PT3924H39M59.163S", + "+163 12:39:59.163", + 23 + ); + assertQuery( + "SELECT INTERVAL -'163 23:39:56.23' DAY TO SECOND", + "INTERVAL -'163 23:39:56.23' DAY TO SECOND", + "interval_day_to_second", + "PT-3935H-39M-56.23S", + "-163 23:39:56.23", + 23 + ); + assertQuery( + "SELECT INTERVAL '163:39' HOUR TO MINUTE", + "INTERVAL '163:39' HOUR TO MINUTE", + "interval_hour_to_minute", + "PT163H39M", + "+6 19:39:00", + 23 + ); + assertQuery( + "SELECT INTERVAL '163:39:59.163' HOUR TO SECOND", + "INTERVAL '163:39:59.163' HOUR TO SECOND", + "interval_hour_to_second", + "PT163H39M59.163S", + "+6 19:39:59.163", + 23 + ); + assertQuery( + "SELECT INTERVAL '163:59.163' MINUTE TO SECOND", + "INTERVAL '163:59.163' MINUTE TO SECOND", + "interval_minute_to_second", + "PT2H43M59.163S", + "+0 02:43:59.163", + 23 + ); } - + /** * Method that tests that a binary response (CBOR) will return either Float or Double, depending on the SQL data type, for floating * point numbers, while JSON will always return Double for floating point numbers. @@ -130,13 +199,15 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { @SuppressWarnings({ "unchecked" }) private void assertFloatingPointNumbersReturnTypes(Request request, Mode mode) throws IOException { - String requestContent = query("SELECT " + String requestContent = query( + "SELECT " + "CAST(1234.34 AS REAL) AS float_positive," + "CAST(-1234.34 AS REAL) AS float_negative," + "1234567890123.34 AS double_positive," - + "-1234567890123.34 AS double_negative").mode(mode).toString(); + + "-1234567890123.34 AS double_negative" + ).mode(mode).toString(); request.setEntity(new StringEntity(requestContent, ContentType.APPLICATION_JSON)); - + Map map; boolean isBinaryResponse = mode != Mode.PLAIN; Response response = client().performRequest(request); @@ -147,12 +218,12 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { } List columns = (ArrayList) map.get("columns"); - assertEquals(4, columns.size()); + assertEquals(4, columns.size()); List rows = (ArrayList) map.get("rows"); assertEquals(1, rows.size()); List row = (ArrayList) rows.get(0); assertEquals(4, row.size()); - + if (isBinaryResponse) { assertTrue(row.get(0) instanceof Float); assertEquals(row.get(0), 1234.34f); @@ -170,22 +241,21 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { assertEquals(row.get(3), -1234567890123.34d); } - private void assertQuery(String sql, String columnName, String columnType, Object columnValue, int displaySize) - throws IOException { + private void assertQuery(String sql, String columnName, String columnType, Object columnValue, int displaySize) throws IOException { assertQuery(sql, columnName, columnType, columnValue, null, displaySize); } - + private void assertQuery(String sql, String columnName, String columnType, Object columnValue, Object cliColumnValue, int displaySize) - throws IOException { + throws IOException { for (Mode mode : Mode.values()) { boolean isCliCheck = mode == CLI && cliColumnValue != null; assertQuery(sql, columnName, columnType, isCliCheck ? cliColumnValue : columnValue, displaySize, mode); } } - + @SuppressWarnings({ "unchecked" }) private void assertQuery(String sql, String columnName, String columnType, Object columnValue, int displaySize, Mode mode) - throws IOException { + throws IOException { boolean columnar = randomBoolean(); Map response = runSql(mode, sql, columnar); List columns = (ArrayList) response.get("columns"); @@ -200,7 +270,7 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { } else { assertEquals(2, column.size()); } - + List rows = (ArrayList) response.get(columnar ? "values" : "rows"); assertEquals(1, rows.size()); List row = (ArrayList) rows.get(0); @@ -209,7 +279,7 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { // from xcontent we can get float or double, depending on the conversion // method of the specific xcontent format implementation if (columnValue instanceof Float && row.get(0) instanceof Double) { - assertEquals(columnValue, (float)((Number) row.get(0)).doubleValue()); + assertEquals(columnValue, (float) ((Number) row.get(0)).doubleValue()); } else { assertEquals(columnValue, row.get(0)); } @@ -217,14 +287,14 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { private Map runSql(Mode mode, String sql, boolean columnar) throws IOException { Request request = new Request("POST", SQL_QUERY_REST_ENDPOINT); - String requestContent = query(sql).mode(mode).toString(); + String requestContent = query(sql).mode(mode).toString(); String format = randomFrom(XContentType.values()).name().toLowerCase(Locale.ROOT); // add a client_id to the request if (randomBoolean()) { String clientId = randomFrom(randomFrom(CLIENT_IDS), randomAlphaOfLengthBetween(10, 20)); - requestContent = new StringBuilder(requestContent) - .insert(requestContent.length() - 1, ",\"client_id\":\"" + clientId + "\"").toString(); + requestContent = new StringBuilder(requestContent).insert(requestContent.length() - 1, ",\"client_id\":\"" + clientId + "\"") + .toString(); } if (randomBoolean()) { request.addParameter("error_trace", "true"); @@ -245,21 +315,22 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { } if ((false == columnar && randomBoolean()) || columnar) { // randomly set the "columnar" parameter, either "true" (non-default) or explicit "false" (the default anyway) - requestContent = new StringBuilder(requestContent) - .insert(requestContent.length() - 1, ",\"columnar\":" + columnar).toString(); + requestContent = new StringBuilder(requestContent).insert(requestContent.length() - 1, ",\"columnar\":" + columnar).toString(); } // randomize binary response enforcement for drivers (ODBC/JDBC) and CLI boolean binaryCommunication = randomBoolean(); if (randomBoolean()) { // set it explicitly or leave the default (null) as is - requestContent = new StringBuilder(requestContent) - .insert(requestContent.length() - 1, ",\"binary_format\":" + binaryCommunication).toString(); + requestContent = new StringBuilder(requestContent).insert( + requestContent.length() - 1, + ",\"binary_format\":" + binaryCommunication + ).toString(); binaryCommunication = Mode.isDedicatedClient(mode) && binaryCommunication; } else { binaryCommunication = Mode.isDedicatedClient(mode); } - + // send the query either as body or as request parameter if (randomBoolean()) { request.setEntity(new StringEntity(requestContent, ContentType.APPLICATION_JSON)); @@ -277,7 +348,7 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { if (binaryCommunication) { return XContentHelper.convertToMap(CborXContent.cborXContent, content, false); } - switch(format) { + switch (format) { case "cbor": { return XContentHelper.convertToMap(CborXContent.cborXContent, content, false); } @@ -288,7 +359,7 @@ public abstract class SqlProtocolTestCase extends ESRestTestCase { return XContentHelper.convertToMap(SmileXContent.smileXContent, content, false); } default: - return XContentHelper.convertToMap(JsonXContent.jsonXContent, content, false); + return XContentHelper.convertToMap(JsonXContent.jsonXContent, content, false); } } } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/CliIntegrationTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/CliIntegrationTestCase.java similarity index 100% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/CliIntegrationTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/CliIntegrationTestCase.java diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/EmbeddedCli.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/EmbeddedCli.java similarity index 96% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/EmbeddedCli.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/EmbeddedCli.java index a1f7e53ca36..466c959721b 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/EmbeddedCli.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/EmbeddedCli.java @@ -62,15 +62,16 @@ public class EmbeddedCli implements Closeable { */ private boolean closed = false; - public EmbeddedCli(String elasticsearchAddress, boolean checkConnectionOnStartup, - @Nullable SecurityConfig security) throws IOException { + public EmbeddedCli(String elasticsearchAddress, boolean checkConnectionOnStartup, @Nullable SecurityConfig security) + throws IOException { PipedOutputStream outgoing = new PipedOutputStream(); PipedInputStream cliIn = new PipedInputStream(outgoing); PipedInputStream incoming = new PipedInputStream(); PipedOutputStream cliOut = new PipedOutputStream(incoming); CliTerminal cliTerminal = new JLineTerminal( new ExternalTerminal("test", "xterm-256color", cliIn, cliOut, StandardCharsets.UTF_8), - false); + false + ); cli = new Cli(cliTerminal) { @Override protected boolean addShutdownHook() { @@ -101,12 +102,12 @@ public class EmbeddedCli implements Closeable { args.add("false"); } args.add("-debug"); - + if (randomBoolean()) { args.add("-binary"); args.add(Boolean.toString(randomBoolean())); } - + exec = new Thread(() -> { try { /* @@ -170,7 +171,7 @@ public class EmbeddedCli implements Closeable { isLogoOrException = true; } } - + assertConnectionTest(); } catch (IOException e) { try { @@ -267,6 +268,7 @@ public class EmbeddedCli implements Closeable { } return readLine(); } + /** * Create the "echo" that we expect jLine to send to the terminal * while we're typing a command. @@ -335,15 +337,20 @@ public class EmbeddedCli implements Closeable { @Nullable private final String keystorePassword; - public SecurityConfig(boolean https, String user, String password, - @Nullable String keystoreLocation, @Nullable String keystorePassword) { + public SecurityConfig( + boolean https, + String user, + String password, + @Nullable String keystoreLocation, + @Nullable String keystorePassword + ) { if (user == null) { - throw new IllegalArgumentException( - "[user] is required. Send [null] instead of a SecurityConfig to run without security."); + throw new IllegalArgumentException("[user] is required. Send [null] instead of a SecurityConfig to run without security."); } if (password == null) { throw new IllegalArgumentException( - "[password] is required. Send [null] instead of a SecurityConfig to run without security."); + "[password] is required. Send [null] instead of a SecurityConfig to run without security." + ); } if (keystoreLocation == null) { if (keystorePassword != null) { diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ErrorsTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ErrorsTestCase.java similarity index 93% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ErrorsTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ErrorsTestCase.java index 6e2ebc87dbe..5cae19fc69b 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ErrorsTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ErrorsTestCase.java @@ -58,7 +58,7 @@ public abstract class ErrorsTestCase extends CliIntegrationTestCase implements o Request request = new Request("PUT", "/test"); request.setJsonEntity("{}"); client().performRequest(request); - + assertFoundOneProblem(command("SELECT abc FROM test")); assertEquals("line 1:8: Unknown column [abc]" + END, readLine()); } @@ -101,8 +101,10 @@ public abstract class ErrorsTestCase extends CliIntegrationTestCase implements o @Override public void testSelectScoreSubField() throws Exception { index("test", body -> body.field("foo", 1)); - assertThat(command("SELECT SCORE().bar FROM test"), - startsWith(START + "Bad request [[3;33;22mline 1:15: extraneous input '.' expecting {, ',',")); + assertThat( + command("SELECT SCORE().bar FROM test"), + startsWith(START + "Bad request [[3;33;22mline 1:15: extraneous input '.' expecting {, ',',") + ); } @Override @@ -116,8 +118,10 @@ public abstract class ErrorsTestCase extends CliIntegrationTestCase implements o public void testHardLimitForSortOnAggregate() throws Exception { index("test", body -> body.field("a", 1).field("b", 2)); String commandResult = command("SELECT max(a) max FROM test GROUP BY b ORDER BY max LIMIT 12000"); - assertEquals(START + "Bad request [[3;33;22mThe maximum LIMIT for aggregate sorting is [10000], received [12000]" + END, - commandResult); + assertEquals( + START + "Bad request [[3;33;22mThe maximum LIMIT for aggregate sorting is [10000], received [12000]" + END, + commandResult + ); } public static void assertFoundOneProblem(String commandResult) { diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/FetchSizeTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/FetchSizeTestCase.java similarity index 86% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/FetchSizeTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/FetchSizeTestCase.java index 02de2dff4f7..6cb8353abb1 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/FetchSizeTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/FetchSizeTestCase.java @@ -27,8 +27,10 @@ public abstract class FetchSizeTestCase extends CliIntegrationTestCase { client().performRequest(request); assertEquals("[?1l>[?1000l[?2004lfetch size set to [90m4[0m", command("fetch size = 4")); - assertEquals("[?1l>[?1000l[?2004lfetch separator set to \"[90m -- fetch sep -- [0m\"", - command("fetch separator = \" -- fetch sep -- \"")); + assertEquals( + "[?1l>[?1000l[?2004lfetch separator set to \"[90m -- fetch sep -- [0m\"", + command("fetch separator = \" -- fetch sep -- \"") + ); assertThat(command("SELECT * FROM test ORDER BY test_field ASC"), containsString("test_field")); assertThat(readLine(), containsString("----------")); int i = 0; @@ -46,8 +48,10 @@ public abstract class FetchSizeTestCase extends CliIntegrationTestCase { assertEquals(ErrorsTestCase.START + "Invalid fetch size [[3;33;22mcat" + ErrorsTestCase.END, command("fetch size = cat")); assertEquals(ErrorsTestCase.START + "Invalid fetch size [[3;33;22m0[23;31;1m]. Must be > 0.[0m", command("fetch size = 0")); assertEquals(ErrorsTestCase.START + "Invalid fetch size [[3;33;22m-1231[23;31;1m]. Must be > 0.[0m", command("fetch size = -1231")); - assertEquals(ErrorsTestCase.START + "Invalid fetch size [[3;33;22m" + Long.MAX_VALUE + ErrorsTestCase.END, - command("fetch size = " + Long.MAX_VALUE)); + assertEquals( + ErrorsTestCase.START + "Invalid fetch size [[3;33;22m" + Long.MAX_VALUE + ErrorsTestCase.END, + command("fetch size = " + Long.MAX_VALUE) + ); } // Test for issue: https://github.com/elastic/elasticsearch/issues/42851 @@ -65,8 +69,10 @@ public abstract class FetchSizeTestCase extends CliIntegrationTestCase { client().performRequest(request); assertEquals("[?1l>[?1000l[?2004lfetch size set to [90m4[0m", command("fetch size = 4")); - assertEquals("[?1l>[?1000l[?2004lfetch separator set to \"[90m -- fetch sep -- [0m\"", - command("fetch separator = \" -- fetch sep -- \"")); + assertEquals( + "[?1l>[?1000l[?2004lfetch separator set to \"[90m -- fetch sep -- [0m\"", + command("fetch separator = \" -- fetch sep -- \"") + ); assertThat(command("SELECT max(b) FROM test GROUP BY a ORDER BY max(b) DESC LIMIT 20"), containsString("max(b)")); assertThat(readLine(), containsString("----------")); for (int i = 100; i > 80; i--) { diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/SelectTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/SelectTestCase.java similarity index 99% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/SelectTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/SelectTestCase.java index cad607f8948..3d940caca0d 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/SelectTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/SelectTestCase.java @@ -19,6 +19,7 @@ public abstract class SelectTestCase extends CliIntegrationTestCase { assertThat(readLine(), containsString("test_value")); assertEquals("", readLine()); } + public void testMultiLineSelect() throws IOException { index("test", body -> body.field("test_field", "test_value")); assertThat(command("SELECT *\nFROM\ntest"), containsString("test_field")); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ShowTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ShowTestCase.java similarity index 100% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ShowTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/ShowTestCase.java diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/package-info.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/package-info.java similarity index 85% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/package-info.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/package-info.java index 7eed43371d8..a9826f862c4 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/cli/package-info.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/cli/package-info.java @@ -6,6 +6,6 @@ /** * Support for integration tests for the Elasticsearch SQL CLI client - * and integration tests shared between multiple qa projects. + * and integration tests shared between multiple qa projects. */ package org.elasticsearch.xpack.sql.qa.cli; diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java similarity index 96% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java index e40e6de9e3a..7cd0292a43a 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoCsvSpecTestCase.java @@ -45,7 +45,6 @@ public abstract class GeoCsvSpecTestCase extends SpecBaseIntegrationTestCase { this.testCase = testCase; } - @Before public void setupTestGeoDataIfNeeded() throws Exception { if (client().performRequest(new Request("HEAD", "/ogc")).getStatusLine().getStatusCode() == 404) { @@ -58,8 +57,7 @@ public abstract class GeoCsvSpecTestCase extends SpecBaseIntegrationTestCase { @Override protected final void doTest() throws Throwable { - try (Connection csv = csvConnection(testCase); - Connection es = esJdbc()) { + try (Connection csv = csvConnection(testCase); Connection es = esJdbc()) { // pass the testName as table for debugging purposes (in case the underlying reader is missing) ResultSet expected = executeCsvQuery(csv, testName); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoDataLoader.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoDataLoader.java similarity index 97% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoDataLoader.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoDataLoader.java index dfee527a331..2209fab8bce 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoDataLoader.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoDataLoader.java @@ -122,14 +122,13 @@ public class GeoDataLoader { } String bulkResponseStr = EntityUtils.toString(response.getEntity()); - Map bulkResponseMap = XContentHelper.convertToMap(JsonXContent.jsonXContent, bulkResponseStr, false); + Map bulkResponseMap = XContentHelper.convertToMap(JsonXContent.jsonXContent, bulkResponseStr, false); if ((boolean) bulkResponseMap.get("errors")) { throw new RuntimeException("Failed to load bulk data " + bulkResponseStr); } } - public static void makeFilteredAlias(RestClient client, String aliasName, String index, String filter) throws Exception { Request request = new Request("POST", "/" + index + "/_alias/" + aliasName); request.setJsonEntity("{\"filter\" : { " + filter + " } }"); @@ -144,7 +143,7 @@ public class GeoDataLoader { StringBuilder builder = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(readFromJarUrl(dataSet), StandardCharsets.UTF_8))) { String line = reader.readLine(); - while(line != null) { + while (line != null) { if (line.trim().startsWith("//") == false) { builder.append(line); builder.append('\n'); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoSqlSpecTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoSqlSpecTestCase.java similarity index 85% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoSqlSpecTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoSqlSpecTestCase.java index 025b04d66ce..43b152159bf 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoSqlSpecTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/geo/GeoSqlSpecTestCase.java @@ -48,10 +48,15 @@ public abstract class GeoSqlSpecTestCase extends SpecBaseIntegrationTestCase { @Before public void setupTestGeoDataIfNeeded() throws Exception { - assumeTrue("Cannot support locales that don't use Hindu-Arabic numerals and non-ascii - sign due to H2", - "-42".equals(NumberFormat.getInstance(Locale.getDefault()).format(-42))); - assumeTrue("JTS inside H2 is using default local for toUpperCase() in string comparison making it fail to parse WKT on certain" + - " locales", "point".toUpperCase(Locale.getDefault()).equals("POINT")); + assumeTrue( + "Cannot support locales that don't use Hindu-Arabic numerals and non-ascii - sign due to H2", + "-42".equals(NumberFormat.getInstance(Locale.getDefault()).format(-42)) + ); + assumeTrue( + "JTS inside H2 is using default local for toUpperCase() in string comparison making it fail to parse WKT on certain" + + " locales", + "point".toUpperCase(Locale.getDefault()).equals("POINT") + ); if (client().performRequest(new Request("HEAD", "/ogc")).getStatusLine().getStatusCode() == 404) { GeoDataLoader.loadOGCDatasetIntoEs(client(), "ogc"); } @@ -60,7 +65,6 @@ public abstract class GeoSqlSpecTestCase extends SpecBaseIntegrationTestCase { } } - private static class SqlSpecParser implements Parser { @Override public Object parse(String line) { @@ -75,8 +79,7 @@ public abstract class GeoSqlSpecTestCase extends SpecBaseIntegrationTestCase { @Override protected final void doTest() throws Throwable { - try (Connection h2 = H2.get(); - Connection es = esJdbc()) { + try (Connection h2 = H2.get(); Connection es = esJdbc()) { ResultSet expected, elasticResults; expected = executeJdbcQuery(h2, query); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvSpecTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvSpecTestCase.java similarity index 100% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvSpecTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvSpecTestCase.java diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvTestUtils.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvTestUtils.java similarity index 95% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvTestUtils.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvTestUtils.java index 46af9c425b2..3e4e9cc29e7 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvTestUtils.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/CsvTestUtils.java @@ -81,10 +81,12 @@ public final class CsvTestUtils { } private static Tuple extractColumnTypesAndStripCli(String schema, String expectedResults) throws IOException { - try (StringReader reader = new StringReader(expectedResults); - BufferedReader bufferedReader = new BufferedReader(reader); - StringWriter writer = new StringWriter(); - BufferedWriter bufferedWriter = new BufferedWriter(writer)) { + try ( + StringReader reader = new StringReader(expectedResults); + BufferedReader bufferedReader = new BufferedReader(reader); + StringWriter writer = new StringWriter(); + BufferedWriter bufferedWriter = new BufferedWriter(writer) + ) { String header = bufferedReader.readLine(); Tuple headerAndTypes; @@ -184,8 +186,7 @@ public final class CsvTestUtils { if (line.startsWith(SCHEMA_PREFIX)) { assertThat("Early schema already declared " + earlySchema, earlySchema.length(), is(0)); earlySchema.append(line.substring(SCHEMA_PREFIX.length()).trim()); - } - else { + } else { if (line.endsWith(";")) { // pick up the query testCase = new CsvTestCase(); @@ -212,8 +213,7 @@ public final class CsvTestUtils { testCase = null; data.setLength(0); return result; - } - else { + } else { data.append(line); data.append("\r\n"); } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DataLoader.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DataLoader.java similarity index 97% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DataLoader.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DataLoader.java index e362349f332..bc9c87238e2 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DataLoader.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DataLoader.java @@ -28,7 +28,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; - public class DataLoader { public static void main(String[] args) throws Exception { @@ -55,8 +54,7 @@ public class DataLoader { createIndex.startObject("mappings"); { createIndex.startObject("properties"); - { - } + {} createIndex.endObject(); } createIndex.endObject().endObject(); @@ -85,11 +83,14 @@ public class DataLoader { } public static void createString(String name, XContentBuilder builder) throws Exception { - builder.startObject(name).field("type", "text") + builder.startObject(name) + .field("type", "text") .startObject("fields") - .startObject("keyword").field("type", "keyword").endObject() + .startObject("keyword") + .field("type", "keyword") .endObject() - .endObject(); + .endObject() + .endObject(); } protected static void loadEmpDatasetIntoEs(RestClient client, String index, String fileName) throws Exception { @@ -128,10 +129,7 @@ public class DataLoader { if (extraFields) { createIndex.startObject("extra_gender").field("type", "constant_keyword").endObject(); createIndex.startObject("null_constant").field("type", "constant_keyword").endObject(); - createIndex.startObject("extra.info.gender") - .field("type", "alias") - .field("path", "gender") - .endObject(); + createIndex.startObject("extra.info.gender").field("type", "alias").field("path", "gender").endObject(); } createIndex.startObject("birth_date").field("type", "date").endObject(); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DatabaseMetaDataTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DatabaseMetaDataTestCase.java similarity index 72% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DatabaseMetaDataTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DatabaseMetaDataTestCase.java index 12c64a5539b..f814c8ab0c5 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DatabaseMetaDataTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DatabaseMetaDataTestCase.java @@ -23,15 +23,19 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { * {@link DatabaseMetaData#getProcedures(String, String, String)}. */ public void testGetProcedures() throws Exception { - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = esJdbc()) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_procedures.sql'"); ResultSet expected = h2.createStatement().executeQuery("SELECT * FROM mock"); - assertResultSets(expected, es.getMetaData().getProcedures( - randomBoolean() ? null : randomAlphaOfLength(5), - randomBoolean() ? null : randomAlphaOfLength(5), - randomBoolean() ? null : randomAlphaOfLength(5))); + assertResultSets( + expected, + es.getMetaData() + .getProcedures( + randomBoolean() ? null : randomAlphaOfLength(5), + randomBoolean() ? null : randomAlphaOfLength(5), + randomBoolean() ? null : randomAlphaOfLength(5) + ) + ); } } @@ -40,16 +44,20 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { * {@link DatabaseMetaData#getProcedureColumns(String, String, String, String)}. */ public void testGetProcedureColumns() throws Exception { - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = esJdbc()) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_procedure_columns.sql'"); ResultSet expected = h2.createStatement().executeQuery("SELECT * FROM mock"); - assertResultSets(expected, es.getMetaData().getProcedureColumns( - randomBoolean() ? null : randomAlphaOfLength(5), - randomBoolean() ? null : randomAlphaOfLength(5), - randomBoolean() ? null : randomAlphaOfLength(5), - randomBoolean() ? null : randomAlphaOfLength(5))); + assertResultSets( + expected, + es.getMetaData() + .getProcedureColumns( + randomBoolean() ? null : randomAlphaOfLength(5), + randomBoolean() ? null : randomAlphaOfLength(5), + randomBoolean() ? null : randomAlphaOfLength(5), + randomBoolean() ? null : randomAlphaOfLength(5) + ) + ); } } @@ -57,17 +65,17 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { index("test1", body -> body.field("name", "bob")); index("test2", body -> body.field("name", "bob")); - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = esJdbc()) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_tables.sql'"); - CheckedSupplier all = () -> - h2.createStatement().executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock"); + CheckedSupplier all = () -> h2.createStatement() + .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock"); assertResultSets(all.get(), es.getMetaData().getTables("%", "%", "%", null)); assertResultSets(all.get(), es.getMetaData().getTables("%", "%", "te%", null)); assertResultSets( h2.createStatement().executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock WHERE TABLE_NAME = 'test1'"), - es.getMetaData().getTables("%", "%", "test1", null)); + es.getMetaData().getTables("%", "%", "test1", null) + ); } } @@ -79,13 +87,14 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_tables_empty.sql'"); CheckedSupplier all = () -> h2.createStatement() - .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock"); + .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock"); assertResultSets(all.get(), es.getMetaData().getTables("%", "%", "%", null)); assertResultSets(all.get(), es.getMetaData().getTables("%", "%", "te%", null)); assertResultSets( - h2.createStatement() - .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock WHERE TABLE_NAME = 'test_empty'"), - es.getMetaData().getTables("%", "%", "test_empty", null)); + h2.createStatement() + .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock WHERE TABLE_NAME = 'test_empty'"), + es.getMetaData().getTables("%", "%", "test_empty", null) + ); } } @@ -97,12 +106,12 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_types_of_table.sql'"); CheckedSupplier all = () -> h2.createStatement() - .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock"); + .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock"); assertResultSets(all.get(), es.getMetaData().getTables("%", "%", "%", new String[] { "TABLE" })); assertResultSets( - h2.createStatement() - .executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock WHERE TABLE_NAME = 'test1'"), - es.getMetaData().getTables("%", "%", "test1", new String[] { "TABLE" })); + h2.createStatement().executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock WHERE TABLE_NAME = 'test1'"), + es.getMetaData().getTables("%", "%", "test1", new String[] { "TABLE" }) + ); } } @@ -118,8 +127,10 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { public void testGetCatalogs() throws Exception { try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) { - assertResultSets(h2.createStatement().executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT"), - es.getMetaData().getCatalogs()); + assertResultSets( + h2.createStatement().executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT"), + es.getMetaData().getCatalogs() + ); } } @@ -131,8 +142,7 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { body.field("float", 42.0); }); - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = esJdbc()) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_columns.sql'"); ResultSet expected = h2.createStatement().executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock"); @@ -148,4 +158,4 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase { assertResultSets(expected, es.getMetaData().getColumns(null, "%", "%", null)); } } -} \ No newline at end of file +} diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DebugSqlSpec.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DebugSqlSpec.java similarity index 100% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DebugSqlSpec.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/DebugSqlSpec.java diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java similarity index 87% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java index 2bf4752f4a9..c1a4c472ea4 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java @@ -93,8 +93,13 @@ public class JdbcAssert { * Also, has the option of treating the numeric results for floating point numbers in a leninent way, if chosen to. Usually, * we would want lenient treatment for floating point numbers in sql-spec tests where the comparison is being made with H2. */ - public static void assertResultSets(ResultSet expected, ResultSet actual, Logger logger, boolean lenientDataType, - boolean lenientFloatingNumbers) throws SQLException { + public static void assertResultSets( + ResultSet expected, + ResultSet actual, + Logger logger, + boolean lenientDataType, + boolean lenientFloatingNumbers + ) throws SQLException { try (ResultSet ex = expected; ResultSet ac = actual) { assertResultSetMetadata(ex, ac, logger, lenientDataType); assertResultSetData(ex, ac, logger, lenientDataType, lenientFloatingNumbers); @@ -107,7 +112,7 @@ public class JdbcAssert { // metadata doesn't consume a ResultSet thus it shouldn't close it public static void assertResultSetMetadata(ResultSet expected, ResultSet actual, Logger logger, boolean lenientDataType) - throws SQLException { + throws SQLException { ResultSetMetaData expectedMeta = expected.getMetaData(); ResultSetMetaData actualMeta = actual.getMetaData(); @@ -127,9 +132,16 @@ public class JdbcAssert { actualCols.add(actualMeta.getColumnName(i)); } - assertEquals(format(Locale.ROOT, "Different number of columns returned (expected %d but was %d);", - expectedMeta.getColumnCount(), actualMeta.getColumnCount()), - expectedCols.toString(), actualCols.toString()); + assertEquals( + format( + Locale.ROOT, + "Different number of columns returned (expected %d but was %d);", + expectedMeta.getColumnCount(), + actualMeta.getColumnCount() + ), + expectedCols.toString(), + actualCols.toString() + ); } for (int column = 1; column <= expectedMeta.getColumnCount(); column++) { @@ -158,7 +170,7 @@ public class JdbcAssert { } // H2 treats GEOMETRY as OTHER - if (expectedType == Types.OTHER && nameOf(actualType).startsWith("GEO_") ) { + if (expectedType == Types.OTHER && nameOf(actualType).startsWith("GEO_")) { actualType = Types.OTHER; } @@ -178,8 +190,10 @@ public class JdbcAssert { // when lenient is used, an int is equivalent to a short, etc... assertEquals( - "Different column type for column [" + expectedName + "] (" + nameOf(expectedType) + " != " + nameOf(actualType) + ")", - expectedType, actualType); + "Different column type for column [" + expectedName + "] (" + nameOf(expectedType) + " != " + nameOf(actualType) + ")", + expectedType, + actualType + ); } } @@ -193,21 +207,31 @@ public class JdbcAssert { } public static void assertResultSetData(ResultSet expected, ResultSet actual, Logger logger, boolean lenientDataType) - throws SQLException { + throws SQLException { assertResultSetData(expected, actual, logger, lenientDataType, true); } - public static void assertResultSetData(ResultSet expected, ResultSet actual, Logger logger, boolean lenientDataType, - boolean lenientFloatingNumbers) throws SQLException { + public static void assertResultSetData( + ResultSet expected, + ResultSet actual, + Logger logger, + boolean lenientDataType, + boolean lenientFloatingNumbers + ) throws SQLException { try (ResultSet ex = expected; ResultSet ac = actual) { doAssertResultSetData(ex, ac, logger, lenientDataType, lenientFloatingNumbers); } } - private static void doAssertResultSetData(ResultSet expected, ResultSet actual, Logger logger, boolean lenientDataType, - boolean lenientFloatingNumbers) throws SQLException { - ResultSetMetaData metadata = expected.getMetaData(); - int columns = metadata.getColumnCount(); + private static void doAssertResultSetData( + ResultSet expected, + ResultSet actual, + Logger logger, + boolean lenientDataType, + boolean lenientFloatingNumbers + ) throws SQLException { + ResultSetMetaData metaData = expected.getMetaData(); + int columns = metaData.getColumnCount(); long count = 0; try { @@ -219,10 +243,10 @@ public class JdbcAssert { } for (int column = 1; column <= columns; column++) { - int type = metadata.getColumnType(column); + int type = metaData.getColumnType(column); Class expectedColumnClass = null; try { - String columnClassName = metadata.getColumnClassName(column); + String columnClassName = metaData.getColumnClassName(column); // fix for CSV which returns the shortName not fully-qualified name if (columnClassName != null && !columnClassName.contains(".")) { @@ -253,12 +277,16 @@ public class JdbcAssert { } Object expectedObject = expected.getObject(column); - Object actualObject = (lenientDataType && expectedColumnClass != null) - ? actual.getObject(column, expectedColumnClass) - : actual.getObject(column); + Object actualObject = (lenientDataType && expectedColumnClass != null) + ? actual.getObject(column, expectedColumnClass) + : actual.getObject(column); - String msg = format(Locale.ROOT, "Different result for column [%s], entry [%d]", - metadata.getColumnName(column), count + 1); + String msg = format( + Locale.ROOT, + "Different result for column [%s], entry [%d]", + metaData.getColumnName(column), + count + 1 + ); // handle nulls first if (expectedObject == null || actualObject == null) { @@ -320,8 +348,7 @@ public class JdbcAssert { } if (actual.next()) { - fail("Elasticsearch [" + actual + "] still has data after [" + count + "] entries:\n" - + resultSetCurrentData(actual)); + fail("Elasticsearch [" + actual + "] still has data after [" + count + "] entries:\n" + resultSetCurrentData(actual)); } } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java similarity index 80% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java index 4d07815b49f..5036613a7f4 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcIntegrationTestCase.java @@ -31,7 +31,7 @@ import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.JDBC_TIMEZONE; import static org.elasticsearch.xpack.sql.qa.rest.RestSqlTestCase.assertNoSearchContexts; public abstract class JdbcIntegrationTestCase extends ESRestTestCase { - + @After public void checkSearchContent() throws Exception { // Some context might linger due to fire and forget nature of scroll cleanup @@ -75,35 +75,6 @@ public abstract class JdbcIntegrationTestCase extends ESRestTestCase { return connection; } - // - // methods below are used inside the documentation only - // - protected Connection useDriverManager() throws SQLException { - String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress(); - // tag::connect-dm - String address = "jdbc:es://" + elasticsearchAddress; // <1> - Properties connectionProperties = connectionProperties(); // <2> - Connection connection = - DriverManager.getConnection(address, connectionProperties); - // end::connect-dm - assertNotNull("The timezone should be specified", connectionProperties.getProperty("timezone")); - return connection; - } - - protected Connection useDataSource() throws SQLException { - String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress(); - // tag::connect-ds - EsDataSource dataSource = new EsDataSource(); - String address = "jdbc:es://" + elasticsearchAddress; // <1> - dataSource.setUrl(address); - Properties connectionProperties = connectionProperties(); // <2> - dataSource.setProperties(connectionProperties); - Connection connection = dataSource.getConnection(); - // end::connect-ds - assertNotNull("The timezone should be specified", connectionProperties.getProperty("timezone")); - return connection; - } - public static void index(String index, CheckedConsumer body) throws IOException { index(index, "1", body); } @@ -144,6 +115,38 @@ public abstract class JdbcIntegrationTestCase extends ESRestTestCase { return connectionProperties; } + protected static void createIndex(String index) throws IOException { + Request request = new Request("PUT", "/" + index); + XContentBuilder createIndex = JsonXContent.contentBuilder().startObject(); + createIndex.startObject("settings"); + { + createIndex.field("number_of_shards", 1); + createIndex.field("number_of_replicas", 1); + } + createIndex.endObject(); + createIndex.startObject("mappings"); + { + createIndex.startObject("properties"); + createIndex.endObject(); + } + createIndex.endObject().endObject(); + request.setJsonEntity(Strings.toString(createIndex)); + client().performRequest(request); + } + + protected static void updateMapping(String index, CheckedConsumer body) throws IOException { + Request request = new Request("PUT", "/" + index + "/_mapping"); + XContentBuilder updateMapping = JsonXContent.contentBuilder().startObject(); + updateMapping.startObject("properties"); + { + body.accept(updateMapping); + } + updateMapping.endObject().endObject(); + + request.setJsonEntity(Strings.toString(updateMapping)); + client().performRequest(request); + } + public static String randomKnownTimeZone() { // We use system default timezone for the connection that is selected randomly by TestRuleSetupAndRestoreClassEnv // from all available JDK timezones. While Joda and JDK are generally in sync, some timezones might not be known diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java similarity index 85% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java index e1e4de03e90..3f69d830045 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcTestUtils.java @@ -23,18 +23,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; -import java.sql.Date; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; -import java.sql.Time; import java.time.Instant; -import java.time.LocalDate; import java.time.ZoneId; -import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.ArrayList; -import java.util.Calendar; import java.util.EnumSet; import java.util.List; import java.util.jar.JarInputStream; @@ -48,10 +43,8 @@ final class JdbcTestUtils { private static final int MAX_WIDTH = 20; - static final ZoneId UTC = ZoneId.of("Z"); static final String SQL_TRACE = "org.elasticsearch.xpack.sql:TRACE"; static final String JDBC_TIMEZONE = "timezone"; - static final LocalDate EPOCH = LocalDate.of(1970, 1, 1); static void logResultSetMetadata(ResultSet rs, Logger logger) throws SQLException { ResultSetMetaData metadata = rs.getMetaData(); @@ -115,8 +108,7 @@ final class JdbcTestUtils { if (buffer.length() > MAX_WIDTH) { buffer.setLength(MAX_WIDTH - 1); buffer.append("~"); - } - else { + } else { for (int i = buffer.length(); i < MAX_WIDTH; i++) { buffer.append(" "); } @@ -131,11 +123,16 @@ final class JdbcTestUtils { List cols = new ArrayList<>(columns); for (int i = 1; i <= columns; i++) { - cols.add(new ColumnInfo(metadata.getTableName(i), metadata.getColumnName(i), metadata.getColumnTypeName(i), - metadata.getColumnDisplaySize(i))); + cols.add( + new ColumnInfo( + metadata.getTableName(i), + metadata.getColumnName(i), + metadata.getColumnTypeName(i), + metadata.getColumnDisplaySize(i) + ) + ); } - List> data = new ArrayList<>(); while (rs.next()) { @@ -149,7 +146,7 @@ final class JdbcTestUtils { BasicFormatter formatter = new BasicFormatter(cols, data, CLI); logger.info("\n" + formatter.formatWithHeader(cols, data)); } - + static String of(long millis, String zoneId) { return StringUtils.toString(ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.of(zoneId))); } @@ -157,7 +154,7 @@ final class JdbcTestUtils { /** * Returns the classpath resources matching a simple pattern ("*.csv"). * It supports folders separated by "/" (e.g. "/some/folder/*.txt"). - * + * * Currently able to resolve resources inside the classpath either from: * folders in the file-system (typically IDEs) or * inside jars (gradle). @@ -232,29 +229,4 @@ final class JdbcTestUtils { } return new Tuple<>(folder, file); } - - static Date asDate(long millis, ZoneId zoneId) { - return new java.sql.Date( - ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), zoneId) - .toLocalDate().atStartOfDay(zoneId).toInstant().toEpochMilli()); - } - - static Time asTime(long millis, ZoneId zoneId) { - return new Time(ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), zoneId) - .toLocalTime().atDate(JdbcTestUtils.EPOCH).atZone(zoneId).toInstant().toEpochMilli()); - } - - static long convertFromCalendarToUTC(long value, Calendar cal) { - if (cal == null) { - return value; - } - Calendar c = (Calendar) cal.clone(); - c.setTimeInMillis(value); - - ZonedDateTime convertedDateTime = ZonedDateTime - .ofInstant(c.toInstant(), c.getTimeZone().toZoneId()) - .withZoneSameLocal(ZoneOffset.UTC); - - return convertedDateTime.toInstant().toEpochMilli(); - } } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/LocalH2.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/LocalH2.java similarity index 100% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/LocalH2.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/LocalH2.java diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ShowTablesTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ShowTablesTestCase.java similarity index 92% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ShowTablesTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ShowTablesTestCase.java index 3c094180155..bfd2beb260f 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ShowTablesTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/ShowTablesTestCase.java @@ -13,8 +13,7 @@ import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcAssert.assertResultSets; public class ShowTablesTestCase extends JdbcIntegrationTestCase { public void testShowTablesWithoutAnyIndexes() throws Exception { - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = esJdbc()) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_show_tables.sql'"); ResultSet expected = h2.createStatement().executeQuery("SELECT * FROM mock"); @@ -23,8 +22,7 @@ public class ShowTablesTestCase extends JdbcIntegrationTestCase { } public void testShowTablesWithManyIndices() throws Exception { - try (Connection h2 = LocalH2.anonymousDb(); - Connection es = esJdbc()) { + try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) { h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_show_tables.sql'"); int indices = between(2, 20); for (int i = 0; i < indices; i++) { diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SpecBaseIntegrationTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SpecBaseIntegrationTestCase.java similarity index 95% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SpecBaseIntegrationTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SpecBaseIntegrationTestCase.java index b03fb71141e..62f6aaac5e3 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SpecBaseIntegrationTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SpecBaseIntegrationTestCase.java @@ -185,8 +185,15 @@ public abstract class SpecBaseIntegrationTestCase extends JdbcIntegrationTestCas // parse test name if (testName == null) { if (testNames.keySet().contains(line)) { - throw new IllegalStateException("Duplicate test name '" + line + "' at line " + lineNumber - + " (previously seen at line " + testNames.get(line) + ")"); + throw new IllegalStateException( + "Duplicate test name '" + + line + + "' at line " + + lineNumber + + " (previously seen at line " + + testNames.get(line) + + ")" + ); } else { testName = Strings.capitalize(line); testNames.put(testName, Integer.valueOf(lineNumber)); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SqlSpecTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SqlSpecTestCase.java similarity index 66% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SqlSpecTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SqlSpecTestCase.java index cd6dc271f60..c8200ac1441 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SqlSpecTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SqlSpecTestCase.java @@ -13,21 +13,23 @@ import org.junit.ClassRule; import java.net.URL; import java.sql.Connection; import java.sql.ResultSet; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.TimeZone; /** * Tests comparing sql queries executed against our jdbc client * with those executed against H2's jdbc client. */ public abstract class SqlSpecTestCase extends SpecBaseIntegrationTestCase { + private final int TZSYNC_MINUTE_THRESHOLD = 55; private String query; @ClassRule - public static LocalH2 H2 = new LocalH2((c) -> { - c.createStatement().execute("RUNSCRIPT FROM 'classpath:/setup_test_emp.sql'"); - }); + public static LocalH2 H2 = new LocalH2(c -> c.createStatement().execute("RUNSCRIPT FROM 'classpath:/setup_test_emp.sql'")); @ParametersFactory(argumentFormatting = PARAM_FORMATTING) public static List readScriptSpec() throws Exception { @@ -76,16 +78,22 @@ public abstract class SqlSpecTestCase extends SpecBaseIntegrationTestCase { protected final void doTest() throws Throwable { // we skip the tests in case of these locales because ES-SQL is Locale-insensitive for now // while H2 does take the Locale into consideration - String[] h2IncompatibleLocales = new String[] {"tr", "az", "tr-TR", "tr-CY", "az-Latn", "az-Cyrl", "az-Latn-AZ", "az-Cyrl-AZ"}; + String[] h2IncompatibleLocales = new String[] { "tr", "az", "tr-TR", "tr-CY", "az-Latn", "az-Cyrl", "az-Latn-AZ", "az-Cyrl-AZ" }; boolean goodLocale = !Arrays.stream(h2IncompatibleLocales) - .anyMatch((l) -> Locale.getDefault().equals(new Locale.Builder().setLanguageTag(l).build())); + .anyMatch((l) -> Locale.getDefault().equals(new Locale.Builder().setLanguageTag(l).build())); if (fileName.startsWith("case-functions")) { Assume.assumeTrue(goodLocale); } - - try (Connection h2 = H2.get(); - Connection es = esJdbc()) { + // For those tests requiring time zone synchronization, skip the test if the test-random timezone or UTC are about (i.e. + // TZSYNC_MINUTE_THREASHOLD minutes away) to change hour, and thus possibly day/month/year. Since vast majority of timezones are + // whole hours apart from the UTC, check also that timezone against being within the "rolling" interval. (This won't catch the case + // when the random TZ and the local machine's are both having hour-fractional deltas from UTC, but this case should be negligible). + if (testName.toUpperCase(Locale.ROOT).endsWith("TZSYNC")) { + Assume.assumeTrue(LocalDateTime.now(TimeZone.getDefault().toZoneId()).getMinute() <= TZSYNC_MINUTE_THRESHOLD); + Assume.assumeTrue(LocalDateTime.now(ZoneId.of("UTC")).getMinute() <= TZSYNC_MINUTE_THRESHOLD); + } + try (Connection h2 = H2.get(); Connection es = esJdbc()) { ResultSet expected, elasticResults; expected = executeJdbcQuery(h2, query); elasticResults = executeJdbcQuery(es, query); diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SysColumnsTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SysColumnsTestCase.java similarity index 54% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SysColumnsTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SysColumnsTestCase.java index 12a30834caf..1dfe36738ba 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SysColumnsTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/SysColumnsTestCase.java @@ -18,16 +18,14 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import static org.elasticsearch.xpack.sql.qa.jdbc.ResultSetTestCase.updateMapping; - public class SysColumnsTestCase extends JdbcIntegrationTestCase { - + public void testAliasWithIncompatibleTypes() throws Exception { createIndexWithMapping("test1", builder -> { builder.startObject("id").field("type", "keyword").endObject(); builder.startObject("value").field("type", "double").endObject(); }); - + createIndexWithMapping("test2", builder -> { builder.startObject("id").field("type", "text").endObject(); builder.startObject("value").field("type", "double").endObject(); @@ -35,16 +33,18 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { createAliases(builder -> { builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject(); - builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); - }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"test1" ,"id" ,"KEYWORD"}, - {"test1" ,"value" ,"DOUBLE"}, - {"test2" ,"id" ,"TEXT"}, - {"test2" ,"value" ,"DOUBLE"}, - {"test_alias" ,"value" ,"DOUBLE"} + builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "test1", "id", "KEYWORD" }, + { "test1", "value", "DOUBLE" }, + { "test2", "id", "TEXT" }, + { "test2", "value", "DOUBLE" }, + { "test_alias", "value", "DOUBLE" } } + ); } public void testAliasWithIncompatibleSearchableProperty() throws Exception { @@ -52,17 +52,17 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { builder.startObject("id").field("type", "keyword").endObject(); builder.startObject("value").field("type", "boolean").endObject(); }); - + createIndexWithMapping("test2", builder -> { builder.startObject("id").field("type", "keyword").field("index", false).endObject(); builder.startObject("value").field("type", "boolean").endObject(); }); - + createIndexWithMapping("test3", builder -> { builder.startObject("id").field("type", "keyword").field("index", false).endObject(); builder.startObject("value").field("type", "boolean").endObject(); }); - + createIndexWithMapping("test4", builder -> { builder.startObject("id").field("type", "keyword").field("index", false).endObject(); builder.startObject("value").field("type", "boolean").endObject(); @@ -74,38 +74,40 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { builder.startObject().startObject("add").field("index", "test3").field("alias", "test_alias2").endObject().endObject(); builder.startObject().startObject("add").field("index", "test4").field("alias", "test_alias2").endObject().endObject(); }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"test1" ,"id" ,"KEYWORD"}, - {"test1" ,"value" ,"BOOLEAN"}, - {"test2" ,"id" ,"KEYWORD"}, - {"test2" ,"value" ,"BOOLEAN"}, - {"test3" ,"id" ,"KEYWORD"}, - {"test3" ,"value" ,"BOOLEAN"}, - {"test4" ,"id" ,"KEYWORD"}, - {"test4" ,"value" ,"BOOLEAN"}, - {"test_alias" ,"value" ,"BOOLEAN"}, - {"test_alias2" ,"id" ,"KEYWORD"}, - {"test_alias2" ,"value" ,"BOOLEAN"} - }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "test1", "id", "KEYWORD" }, + { "test1", "value", "BOOLEAN" }, + { "test2", "id", "KEYWORD" }, + { "test2", "value", "BOOLEAN" }, + { "test3", "id", "KEYWORD" }, + { "test3", "value", "BOOLEAN" }, + { "test4", "id", "KEYWORD" }, + { "test4", "value", "BOOLEAN" }, + { "test_alias", "value", "BOOLEAN" }, + { "test_alias2", "id", "KEYWORD" }, + { "test_alias2", "value", "BOOLEAN" } } + ); } - + public void testAliasWithIncompatibleAggregatableProperty() throws Exception { createIndexWithMapping("test1", builder -> { builder.startObject("id").field("type", "text").field("fielddata", true).endObject(); builder.startObject("value").field("type", "date").endObject(); }); - + createIndexWithMapping("test2", builder -> { builder.startObject("id").field("type", "text").endObject(); builder.startObject("value").field("type", "date").endObject(); }); - + createIndexWithMapping("test3", builder -> { builder.startObject("id").field("type", "text").field("fielddata", true).endObject(); builder.startObject("value").field("type", "date").endObject(); }); - + createIndexWithMapping("test4", builder -> { builder.startObject("id").field("type", "text").field("fielddata", true).endObject(); builder.startObject("value").field("type", "date").endObject(); @@ -117,157 +119,254 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { builder.startObject().startObject("add").field("index", "test3").field("alias", "test_alias2").endObject().endObject(); builder.startObject().startObject("add").field("index", "test4").field("alias", "test_alias2").endObject().endObject(); }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"test1" ,"id" ,"TEXT"}, - {"test1" ,"value" ,"DATETIME"}, - {"test2" ,"id" ,"TEXT"}, - {"test2" ,"value" ,"DATETIME"}, - {"test3" ,"id" ,"TEXT"}, - {"test3" ,"value" ,"DATETIME"}, - {"test4" ,"id" ,"TEXT"}, - {"test4" ,"value" ,"DATETIME"}, - {"test_alias" ,"value" ,"DATETIME"}, - {"test_alias2","id" ,"TEXT"}, - {"test_alias2","value" ,"DATETIME"}, - }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "test1", "id", "TEXT" }, + { "test1", "value", "DATETIME" }, + { "test2", "id", "TEXT" }, + { "test2", "value", "DATETIME" }, + { "test3", "id", "TEXT" }, + { "test3", "value", "DATETIME" }, + { "test4", "id", "TEXT" }, + { "test4", "value", "DATETIME" }, + { "test_alias", "value", "DATETIME" }, + { "test_alias2", "id", "TEXT" }, + { "test_alias2", "value", "DATETIME" }, } + ); } public void testAliasWithIncompatibleTypesInSubfield() throws Exception { createIndexWithMapping("test1", builder -> { - builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "keyword") - .endObject().endObject().endObject(); - builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long") - .endObject().endObject().endObject(); + builder.startObject("id") + .field("type", "text") + .startObject("fields") + .startObject("raw") + .field("type", "keyword") + .endObject() + .endObject() + .endObject(); + builder.startObject("value") + .field("type", "date") + .startObject("fields") + .startObject("raw") + .field("type", "long") + .endObject() + .endObject() + .endObject(); }); - + createIndexWithMapping("test2", builder -> { - builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer") - .endObject().endObject().endObject(); - builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long") - .endObject().endObject().endObject(); + builder.startObject("id") + .field("type", "text") + .startObject("fields") + .startObject("raw") + .field("type", "integer") + .endObject() + .endObject() + .endObject(); + builder.startObject("value") + .field("type", "date") + .startObject("fields") + .startObject("raw") + .field("type", "long") + .endObject() + .endObject() + .endObject(); }); createAliases(builder -> { builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject(); - builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); - }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"test1" ,"id" ,"TEXT"}, - {"test1" ,"id.raw" ,"KEYWORD"}, - {"test1" ,"value" ,"DATETIME"}, - {"test1" ,"value.raw","LONG"}, - {"test2" ,"id" ,"TEXT"}, - {"test2" ,"id.raw" ,"INTEGER"}, - {"test2" ,"value" ,"DATETIME"}, - {"test2" ,"value.raw","LONG"}, - {"test_alias" ,"id" ,"TEXT"}, - {"test_alias" ,"value" ,"DATETIME"}, - {"test_alias" ,"value.raw","LONG"}, + builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "test1", "id", "TEXT" }, + { "test1", "id.raw", "KEYWORD" }, + { "test1", "value", "DATETIME" }, + { "test1", "value.raw", "LONG" }, + { "test2", "id", "TEXT" }, + { "test2", "id.raw", "INTEGER" }, + { "test2", "value", "DATETIME" }, + { "test2", "value.raw", "LONG" }, + { "test_alias", "id", "TEXT" }, + { "test_alias", "value", "DATETIME" }, + { "test_alias", "value.raw", "LONG" }, } + ); } public void testAliasWithIncompatibleSearchablePropertyInSubfield() throws Exception { createIndexWithMapping("test1", builder -> { - builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer") - .endObject().endObject().endObject(); - builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long") - .endObject().endObject().endObject(); + builder.startObject("id") + .field("type", "text") + .startObject("fields") + .startObject("raw") + .field("type", "integer") + .endObject() + .endObject() + .endObject(); + builder.startObject("value") + .field("type", "date") + .startObject("fields") + .startObject("raw") + .field("type", "long") + .endObject() + .endObject() + .endObject(); }); - + createIndexWithMapping("test2", builder -> { - builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer") - .field("index", false).endObject().endObject().endObject(); - builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long") - .endObject().endObject().endObject(); + builder.startObject("id") + .field("type", "text") + .startObject("fields") + .startObject("raw") + .field("type", "integer") + .field("index", false) + .endObject() + .endObject() + .endObject(); + builder.startObject("value") + .field("type", "date") + .startObject("fields") + .startObject("raw") + .field("type", "long") + .endObject() + .endObject() + .endObject(); }); createAliases(builder -> { builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject(); - builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); - }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"test1" ,"id" ,"TEXT"}, - {"test1" ,"id.raw" ,"INTEGER"}, - {"test1" ,"value" ,"DATETIME"}, - {"test1" ,"value.raw","LONG"}, - {"test2" ,"id" ,"TEXT"}, - {"test2" ,"id.raw" ,"INTEGER"}, - {"test2" ,"value" ,"DATETIME"}, - {"test2" ,"value.raw","LONG"}, - {"test_alias" ,"id" ,"TEXT"}, - {"test_alias" ,"value" ,"DATETIME"}, - {"test_alias" ,"value.raw","LONG"}, + builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "test1", "id", "TEXT" }, + { "test1", "id.raw", "INTEGER" }, + { "test1", "value", "DATETIME" }, + { "test1", "value.raw", "LONG" }, + { "test2", "id", "TEXT" }, + { "test2", "id.raw", "INTEGER" }, + { "test2", "value", "DATETIME" }, + { "test2", "value.raw", "LONG" }, + { "test_alias", "id", "TEXT" }, + { "test_alias", "value", "DATETIME" }, + { "test_alias", "value.raw", "LONG" }, } + ); } - + public void testAliasWithIncompatibleAggregatablePropertyInSubfield() throws Exception { createIndexWithMapping("test1", builder -> { - builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer") - .field("doc_values", false).endObject().endObject().endObject(); - builder.startObject("value").field("type", "ip").startObject("fields").startObject("raw").field("type", "text") - .endObject().endObject().endObject(); + builder.startObject("id") + .field("type", "text") + .startObject("fields") + .startObject("raw") + .field("type", "integer") + .field("doc_values", false) + .endObject() + .endObject() + .endObject(); + builder.startObject("value") + .field("type", "ip") + .startObject("fields") + .startObject("raw") + .field("type", "text") + .endObject() + .endObject() + .endObject(); }); - + createIndexWithMapping("test2", builder -> { - builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer") - .endObject().endObject().endObject(); - builder.startObject("value").field("type", "ip").startObject("fields").startObject("raw").field("type", "text") - .endObject().endObject().endObject(); + builder.startObject("id") + .field("type", "text") + .startObject("fields") + .startObject("raw") + .field("type", "integer") + .endObject() + .endObject() + .endObject(); + builder.startObject("value") + .field("type", "ip") + .startObject("fields") + .startObject("raw") + .field("type", "text") + .endObject() + .endObject() + .endObject(); }); createAliases(builder -> { builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject(); - builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); - }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"test1" ,"id" ,"TEXT"}, - {"test1" ,"id.raw" ,"INTEGER"}, - {"test1" ,"value" ,"IP"}, - {"test1" ,"value.raw","TEXT"}, - {"test2" ,"id" ,"TEXT"}, - {"test2" ,"id.raw" ,"INTEGER"}, - {"test2" ,"value" ,"IP"}, - {"test2" ,"value.raw","TEXT"}, - {"test_alias" ,"id" ,"TEXT"}, - {"test_alias" ,"value" ,"IP"}, - {"test_alias" ,"value.raw","TEXT"}, + builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "test1", "id", "TEXT" }, + { "test1", "id.raw", "INTEGER" }, + { "test1", "value", "IP" }, + { "test1", "value.raw", "TEXT" }, + { "test2", "id", "TEXT" }, + { "test2", "id.raw", "INTEGER" }, + { "test2", "value", "IP" }, + { "test2", "value.raw", "TEXT" }, + { "test_alias", "id", "TEXT" }, + { "test_alias", "value", "IP" }, + { "test_alias", "value.raw", "TEXT" }, } + ); } - + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/53445") public void testAliasWithSubfieldsAndDifferentRootFields() throws Exception { createIndexWithMapping("test1", builder -> { builder.startObject("id").field("type", "keyword").endObject(); - builder.startObject("name").field("type", "text").startObject("fields").startObject("raw").field("type", "keyword") - .endObject().endObject().endObject(); + builder.startObject("name") + .field("type", "text") + .startObject("fields") + .startObject("raw") + .field("type", "keyword") + .endObject() + .endObject() + .endObject(); }); - + createIndexWithMapping("test2", builder -> { builder.startObject("id").field("type", "keyword").endObject(); - builder.startObject("name").field("type", "keyword").field("index", false).startObject("fields").startObject("raw") - .field("type", "keyword").endObject().endObject().endObject(); + builder.startObject("name") + .field("type", "keyword") + .field("index", false) + .startObject("fields") + .startObject("raw") + .field("type", "keyword") + .endObject() + .endObject() + .endObject(); }); createAliases(builder -> { builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject(); - builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); - }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"test1" ,"id" ,"KEYWORD"}, - {"test1" ,"name" ,"TEXT"}, - {"test1" ,"name.raw","KEYWORD"}, - {"test2" ,"id" ,"KEYWORD"}, - {"test2" ,"name" ,"KEYWORD"}, - {"test2" ,"name.raw","KEYWORD"}, - {"test_alias" ,"id" ,"KEYWORD"} + builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject(); }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "test1", "id", "KEYWORD" }, + { "test1", "name", "TEXT" }, + { "test1", "name.raw", "KEYWORD" }, + { "test2", "id", "KEYWORD" }, + { "test2", "name", "KEYWORD" }, + { "test2", "name.raw", "KEYWORD" }, + { "test_alias", "id", "KEYWORD" } } + ); } - + public void testMultiIndicesMultiAlias() throws Exception { createIndexWithMapping("test2", builder -> { builder.startObject("id").field("type", "keyword").endObject(); @@ -287,7 +386,7 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { builder.startObject("name").field("type", "keyword").endObject(); builder.startObject("number").field("type", "long").endObject(); }); - + createAliases(builder -> { builder.startObject().startObject("add").field("index", "test1").field("alias", "alias1").endObject().endObject(); builder.startObject().startObject("add").field("index", "test1").field("alias", "alias2").endObject().endObject(); @@ -295,32 +394,34 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { builder.startObject().startObject("add").field("index", "test2").field("alias", "alias3").endObject().endObject(); builder.startObject().startObject("add").field("index", "test4").field("alias", "alias3").endObject().endObject(); }); - - assertResultsForQuery("SYS COLUMNS", new String[][] { - {"alias1","id" ,"KEYWORD"}, - {"alias1","name" ,"KEYWORD"}, - {"alias1","number","LONG"}, - {"alias2","id" ,"KEYWORD"}, - {"alias2","number","LONG"}, - {"alias3","id" ,"KEYWORD"}, - {"test1" ,"id" ,"KEYWORD"}, - {"test1" ,"name" ,"KEYWORD"}, - {"test1" ,"number","LONG"}, - {"test2" ,"id" ,"KEYWORD"}, - {"test2" ,"name" ,"TEXT"}, - {"test3" ,"id" ,"KEYWORD"}, - {"test3" ,"name" ,"KEYWORD"}, - {"test3" ,"number","LONG"}, - {"test4" ,"id" ,"KEYWORD"}, - {"test4" ,"name" ,"TEXT"} - }); + + assertResultsForQuery( + "SYS COLUMNS", + new String[][] { + { "alias1", "id", "KEYWORD" }, + { "alias1", "name", "KEYWORD" }, + { "alias1", "number", "LONG" }, + { "alias2", "id", "KEYWORD" }, + { "alias2", "number", "LONG" }, + { "alias3", "id", "KEYWORD" }, + { "test1", "id", "KEYWORD" }, + { "test1", "name", "KEYWORD" }, + { "test1", "number", "LONG" }, + { "test2", "id", "KEYWORD" }, + { "test2", "name", "TEXT" }, + { "test3", "id", "KEYWORD" }, + { "test3", "name", "KEYWORD" }, + { "test3", "number", "LONG" }, + { "test4", "id", "KEYWORD" }, + { "test4", "name", "TEXT" } } + ); } - + private static void createIndexWithMapping(String indexName, CheckedConsumer mapping) throws Exception { - ResultSetTestCase.createIndex(indexName); + createIndex(indexName); updateMapping(indexName, mapping); } - + private void doWithQuery(String query, CheckedConsumer consumer) throws SQLException { try (Connection connection = esJdbc()) { try (PreparedStatement statement = connection.prepareStatement(query)) { @@ -330,7 +431,7 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { } } } - + private static void createAliases(CheckedConsumer definitions) throws Exception { Request request = new Request("POST", "/_aliases"); XContentBuilder createAliases = JsonXContent.contentBuilder().startObject(); @@ -343,7 +444,7 @@ public class SysColumnsTestCase extends JdbcIntegrationTestCase { request.setJsonEntity(Strings.toString(createAliases)); client().performRequest(request); } - + private void assertResultsForQuery(String query, String[][] rows) throws Exception { doWithQuery(query, (results) -> { for (String[] row : rows) { diff --git a/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java new file mode 100644 index 00000000000..a2eb37eac60 --- /dev/null +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/package-info.java @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * Support for integration tests for the Elasticsearch SQL JDBC client + * and integration tests shared between multiple qa projects. + */ +package org.elasticsearch.xpack.sql.qa.jdbc; diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/BaseRestSqlTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/BaseRestSqlTestCase.java similarity index 98% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/BaseRestSqlTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/BaseRestSqlTestCase.java index 4e61f486783..eed45ef0996 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/BaseRestSqlTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/BaseRestSqlTestCase.java @@ -61,7 +61,7 @@ public abstract class BaseRestSqlTestCase extends ESRestTestCase { String modeString = m.toString(); request.append(field(MODE_NAME, modeString)); if (isQuery) { - Mode mode = (m instanceof Mode) ? (Mode)m : Mode.fromString(modeString); + Mode mode = (m instanceof Mode) ? (Mode) m : Mode.fromString(modeString); if (Mode.isDedicatedClient(mode)) { version(Version.CURRENT.toString()); } @@ -169,7 +169,7 @@ public abstract class BaseRestSqlTestCase extends ESRestTestCase { return value.doubleValue(); } } - + public static Map toMap(Response response, String mode) throws IOException { Mode m = Mode.fromString(mode); try (InputStream content = response.getEntity().getContent()) { diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java similarity index 75% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java index 1957e9222ee..4bb9b9da140 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java @@ -55,9 +55,10 @@ import static org.hamcrest.Matchers.containsString; * user rather than to the JDBC driver or CLI. */ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements ErrorsTestCase { - + public static String SQL_QUERY_REST_ENDPOINT = org.elasticsearch.xpack.sql.proto.Protocol.SQL_QUERY_REST_ENDPOINT; private static String SQL_TRANSLATE_REST_ENDPOINT = org.elasticsearch.xpack.sql.proto.Protocol.SQL_TRANSLATE_REST_ENDPOINT; + /** * Builds that map that is returned in the header for each column. */ @@ -72,13 +73,12 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } public void testBasicQuery() throws IOException { - index("{\"test\":\"test\"}", - "{\"test\":\"test\"}"); + index("{\"test\":\"test\"}", "{\"test\":\"test\"}"); Map expected = new HashMap<>(); String mode = randomMode(); boolean columnar = randomBoolean(); - + expected.put("columns", singletonList(columnInfo(mode, "test", "text", JDBCType.VARCHAR, Integer.MAX_VALUE))); if (columnar) { expected.put("values", singletonList(Arrays.asList("test", "test"))); @@ -99,12 +99,11 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } request.setJsonEntity(bulk.toString()); client().performRequest(request); - + boolean columnar = randomBoolean(); - String sqlRequest = query( - "SELECT text, number, SQRT(number) AS s, SCORE()" - + " FROM test" - + " ORDER BY number, SCORE()").mode(mode).fetchSize(2).columnar(columnarValue(columnar)).toString(); + String sqlRequest = query("SELECT text, number, SQRT(number) AS s, SCORE()" + " FROM test" + " ORDER BY number, SCORE()").mode( + mode + ).fetchSize(2).columnar(columnarValue(columnar)).toString(); Number value = xContentDependentFloatingNumberValue(mode, 1f); String cursor = null; @@ -114,29 +113,44 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err response = runSql(new StringEntity(sqlRequest, ContentType.APPLICATION_JSON), "", mode); } else { columnar = randomBoolean(); - response = runSql(new StringEntity(cursor(cursor).mode(mode).columnar(columnarValue(columnar)).toString(), - ContentType.APPLICATION_JSON), StringUtils.EMPTY, mode); + response = runSql( + new StringEntity(cursor(cursor).mode(mode).columnar(columnarValue(columnar)).toString(), ContentType.APPLICATION_JSON), + StringUtils.EMPTY, + mode + ); } Map expected = new HashMap<>(); if (i == 0) { - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo(mode, "text", "text", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo(mode, "number", "long", JDBCType.BIGINT, 20), columnInfo(mode, "s", "double", JDBCType.DOUBLE, 25), - columnInfo(mode, "SCORE()", "float", JDBCType.REAL, 15))); + columnInfo(mode, "SCORE()", "float", JDBCType.REAL, 15) + ) + ); } - + if (columnar) { - expected.put("values", Arrays.asList( + expected.put( + "values", + Arrays.asList( Arrays.asList("text" + i, "text" + (i + 1)), Arrays.asList(i, i + 1), Arrays.asList(Math.sqrt(i), Math.sqrt(i + 1)), - Arrays.asList(value, value))); + Arrays.asList(value, value) + ) + ); } else { - expected.put("rows", Arrays.asList( + expected.put( + "rows", + Arrays.asList( Arrays.asList("text" + i, i, Math.sqrt(i), value), - Arrays.asList("text" + (i + 1), i + 1, Math.sqrt(i + 1), value))); + Arrays.asList("text" + (i + 1), i + 1, Math.sqrt(i + 1), value) + ) + ); } cursor = (String) response.remove("cursor"); assertResponse(expected, response); @@ -149,8 +163,14 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } else { expected.put("rows", emptyList()); } - assertResponse(expected, runSql(new StringEntity(cursor(cursor).mode(mode).columnar(columnarValue(columnar)).toString(), - ContentType.APPLICATION_JSON), StringUtils.EMPTY, mode)); + assertResponse( + expected, + runSql( + new StringEntity(cursor(cursor).mode(mode).columnar(columnarValue(columnar)).toString(), ContentType.APPLICATION_JSON), + StringUtils.EMPTY, + mode + ) + ); } public void testNextPageWithDatetimeAndTimezoneParam() throws IOException { @@ -182,8 +202,10 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err ZoneId zoneId = randomZone(); String mode = randomMode(); - String sqlRequest = query("SELECT DATE_PART('TZOFFSET', date) AS tz FROM test_date_timezone ORDER BY date") - .timeZone(zoneId.getId()).mode(mode).fetchSize(2).toString(); + String sqlRequest = query("SELECT DATE_PART('TZOFFSET', date) AS tz FROM test_date_timezone ORDER BY date").timeZone(zoneId.getId()) + .mode(mode) + .fetchSize(2) + .toString(); String cursor = null; for (int i = 0; i <= datetimes.length; i += 2) { @@ -194,14 +216,20 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err expected.put("columns", singletonList(columnInfo(mode, "tz", "integer", JDBCType.INTEGER, 11))); response = runSql(new StringEntity(sqlRequest, ContentType.APPLICATION_JSON), "", mode); } else { - response = runSql(new StringEntity(cursor(cursor).mode(mode).toString(), ContentType.APPLICATION_JSON), StringUtils.EMPTY, - mode); + response = runSql( + new StringEntity(cursor(cursor).mode(mode).toString(), ContentType.APPLICATION_JSON), + StringUtils.EMPTY, + mode + ); } List values = new ArrayList<>(2); for (int j = 0; j < (i < datetimes.length - 1 ? 2 : 1); j++) { - values.add(singletonList(ZonedDateTime.ofInstant(Instant.ofEpochMilli(datetimes[i + j]), zoneId) - .getOffset().getTotalSeconds() / 60)); + values.add( + singletonList( + ZonedDateTime.ofInstant(Instant.ofEpochMilli(datetimes[i + j]), zoneId).getOffset().getTotalSeconds() / 60 + ) + ); } expected.put("rows", values); cursor = (String) response.remove("cursor"); @@ -210,16 +238,17 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } Map expected = new HashMap<>(); expected.put("rows", emptyList()); - assertResponse(expected, runSql(new StringEntity(cursor(cursor).mode(mode).toString(), - ContentType.APPLICATION_JSON), StringUtils.EMPTY, mode)); + assertResponse( + expected, + runSql(new StringEntity(cursor(cursor).mode(mode).toString(), ContentType.APPLICATION_JSON), StringUtils.EMPTY, mode) + ); } @AwaitsFix(bugUrl = "Unclear status, https://github.com/elastic/x-pack-elasticsearch/issues/2074") public void testTimeZone() throws IOException { String mode = randomMode(); boolean columnar = randomBoolean(); - index("{\"test\":\"2017-07-27 00:00:00\"}", - "{\"test\":\"2017-07-27 01:00:00\"}"); + index("{\"test\":\"2017-07-27 00:00:00\"}", "{\"test\":\"2017-07-27 01:00:00\"}"); Map expected = new HashMap<>(); expected.put("columns", singletonMap("test", singletonMap("type", "text"))); @@ -247,58 +276,70 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err Map expected = new HashMap<>(); boolean columnar = randomBoolean(); - expected.put("columns", Arrays.asList( - columnInfo(mode, "name", "text", JDBCType.VARCHAR, Integer.MAX_VALUE), - columnInfo(mode, "score", "long", JDBCType.BIGINT, 20), - columnInfo(mode, "SCORE()", "float", JDBCType.REAL, 15))); + expected.put( + "columns", + Arrays.asList( + columnInfo(mode, "name", "text", JDBCType.VARCHAR, Integer.MAX_VALUE), + columnInfo(mode, "score", "long", JDBCType.BIGINT, 20), + columnInfo(mode, "SCORE()", "float", JDBCType.REAL, 15) + ) + ); Number value = xContentDependentFloatingNumberValue(mode, 1f); if (columnar) { expected.put("values", Arrays.asList(singletonList("test"), singletonList(10), singletonList(value))); } else { expected.put("rows", singletonList(Arrays.asList("test", 10, value))); } - + assertResponse(expected, runSql(mode, "SELECT *, SCORE() FROM test ORDER BY SCORE()", columnar)); assertResponse(expected, runSql(mode, "SELECT name, \\\"score\\\", SCORE() FROM test ORDER BY SCORE()", columnar)); } public void testSelectWithJoinFails() throws Exception { // Normal join not supported - expectBadRequest(() -> runSql(randomMode(), "SELECT * FROM test JOIN other"), - containsString("line 1:21: Queries with JOIN are not yet supported")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT * FROM test JOIN other"), + containsString("line 1:21: Queries with JOIN are not yet supported") + ); // Neither is a self join - expectBadRequest(() -> runSql(randomMode(), "SELECT * FROM test JOIN test"), - containsString("line 1:21: Queries with JOIN are not yet supported")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT * FROM test JOIN test"), + containsString("line 1:21: Queries with JOIN are not yet supported") + ); // Nor fancy stuff like CTEs - expectBadRequest(() -> runSql(randomMode(), - " WITH evil" - + " AS (SELECT *" - + " FROM foo)" - + "SELECT *" - + " FROM test" - + " JOIN evil"), - containsString("line 1:67: Queries with JOIN are not yet supported")); + expectBadRequest( + () -> runSql( + randomMode(), + " WITH evil" + " AS (SELECT *" + " FROM foo)" + "SELECT *" + " FROM test" + " JOIN evil" + ), + containsString("line 1:67: Queries with JOIN are not yet supported") + ); } public void testSelectDistinctFails() throws Exception { index("{\"name\":\"test\"}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT DISTINCT name FROM test"), - containsString("line 1:8: SELECT DISTINCT is not yet supported")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT DISTINCT name FROM test"), + containsString("line 1:8: SELECT DISTINCT is not yet supported") + ); } public void testSelectGroupByAllFails() throws Exception { index("{\"foo\":1}", "{\"foo\":2}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT foo FROM test GROUP BY ALL foo"), - containsString("line 1:32: GROUP BY ALL is not supported")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT foo FROM test GROUP BY ALL foo"), + containsString("line 1:32: GROUP BY ALL is not supported") + ); } public void testSelectWhereExistsFails() throws Exception { index("{\"foo\":1}", "{\"foo\":2}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT foo FROM test WHERE EXISTS (SELECT * FROM test t WHERE t.foo = test.foo)", - randomBoolean()), containsString("line 1:28: EXISTS is not yet supported")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT foo FROM test WHERE EXISTS (SELECT * FROM test t WHERE t.foo = test.foo)", randomBoolean()), + containsString("line 1:28: EXISTS is not yet supported") + ); } - @Override public void testSelectInvalidSql() { String mode = randomFrom("jdbc", "plain"); @@ -346,87 +387,95 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err @Override public void testSelectMissingFunction() throws Exception { index("{\"foo\":1}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT missing(foo) FROM test"), - containsString("1:8: Unknown function [missing]")); + expectBadRequest(() -> runSql(randomMode(), "SELECT missing(foo) FROM test"), containsString("1:8: Unknown function [missing]")); } @Override public void testSelectProjectScoreInAggContext() throws Exception { index("{\"foo\":1}"); - expectBadRequest(() -> runSql(randomMode(), - " SELECT foo, SCORE(), COUNT(*)" - + " FROM test" - + " GROUP BY foo"), - containsString("Cannot use non-grouped column [SCORE()], expected [foo]")); + expectBadRequest( + () -> runSql(randomMode(), " SELECT foo, SCORE(), COUNT(*)" + " FROM test" + " GROUP BY foo"), + containsString("Cannot use non-grouped column [SCORE()], expected [foo]") + ); } @Override public void testSelectOrderByScoreInAggContext() throws Exception { index("{\"foo\":1}"); - expectBadRequest(() -> runSql(randomMode(), - " SELECT foo, COUNT(*)" - + " FROM test" - + " GROUP BY foo" - + " ORDER BY SCORE()"), - containsString("Cannot order by non-grouped column [SCORE()], expected [foo]")); + expectBadRequest( + () -> runSql(randomMode(), " SELECT foo, COUNT(*)" + " FROM test" + " GROUP BY foo" + " ORDER BY SCORE()"), + containsString("Cannot order by non-grouped column [SCORE()], expected [foo]") + ); } @Override public void testSelectGroupByScore() throws Exception { index("{\"foo\":1}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT COUNT(*) FROM test GROUP BY SCORE()"), - containsString("Cannot use [SCORE()] for grouping")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT COUNT(*) FROM test GROUP BY SCORE()"), + containsString("Cannot use [SCORE()] for grouping") + ); } @Override public void testSelectScoreSubField() throws Exception { index("{\"foo\":1}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT SCORE().bar FROM test"), - containsString("line 1:15: extraneous input '.' expecting {, ','")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT SCORE().bar FROM test"), + containsString("line 1:15: extraneous input '.' expecting {, ','") + ); } @Override public void testSelectScoreInScalar() throws Exception { index("{\"foo\":1}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT SIN(SCORE()) FROM test"), - containsString("line 1:12: [SCORE()] cannot be an argument to a function")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT SIN(SCORE()) FROM test"), + containsString("line 1:12: [SCORE()] cannot be an argument to a function") + ); } @Override public void testHardLimitForSortOnAggregate() throws Exception { index("{\"a\": 1, \"b\": 2}"); - expectBadRequest(() -> runSql(randomMode(), "SELECT max(a) max FROM test GROUP BY b ORDER BY max LIMIT 12000"), - containsString("The maximum LIMIT for aggregate sorting is [10000], received [12000]")); + expectBadRequest( + () -> runSql(randomMode(), "SELECT max(a) max FROM test GROUP BY b ORDER BY max LIMIT 12000"), + containsString("The maximum LIMIT for aggregate sorting is [10000], received [12000]") + ); } public void testUseColumnarForUnsupportedFormats() throws Exception { String format = randomFrom("txt", "csv", "tsv"); index("{\"foo\":1}"); - + Request request = new Request("POST", SQL_QUERY_REST_ENDPOINT); request.addParameter("error_trace", "true"); request.addParameter("pretty", "true"); request.addParameter("format", format); - request.setEntity(new StringEntity(query("SELECT * FROM test") - .mode(randomValueOtherThan(Mode.JDBC.toString(), BaseRestSqlTestCase::randomMode)).columnar(true).toString(), - ContentType.APPLICATION_JSON)); + request.setEntity( + new StringEntity( + query("SELECT * FROM test").mode(randomValueOtherThan(Mode.JDBC.toString(), BaseRestSqlTestCase::randomMode)) + .columnar(true) + .toString(), + ContentType.APPLICATION_JSON + ) + ); expectBadRequest(() -> { - client().performRequest(request); - return Collections.emptyMap(); - }, containsString("Invalid use of [columnar] argument: cannot be used in combination with txt, csv or tsv formats")); + client().performRequest(request); + return Collections.emptyMap(); + }, containsString("Invalid use of [columnar] argument: cannot be used in combination with txt, csv or tsv formats")); } - + public void testUseColumnarForTranslateRequest() throws IOException { index("{\"test\":\"test\"}", "{\"test\":\"test\"}"); String mode = randomMode(); Request request = new Request("POST", SQL_TRANSLATE_REST_ENDPOINT); - request.setEntity(new StringEntity(query("SELECT * FROM test").mode(mode).columnar(true).toString(), - ContentType.APPLICATION_JSON)); + request.setEntity(new StringEntity(query("SELECT * FROM test").mode(mode).columnar(true).toString(), ContentType.APPLICATION_JSON)); expectBadRequest(() -> { - client().performRequest(request); - return Collections.emptyMap(); - }, containsString("unknown field [columnar]")); + client().performRequest(request); + return Collections.emptyMap(); + }, containsString("unknown field [columnar]")); } public static void expectBadRequest(CheckedSupplier, Exception> code, Matcher errorMessageMatcher) { @@ -437,12 +486,11 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err if (400 != e.getResponse().getStatusLine().getStatusCode()) { String body; try { - body = Streams.copyToString(new InputStreamReader( - e.getResponse().getEntity().getContent(), StandardCharsets.UTF_8)); + body = Streams.copyToString(new InputStreamReader(e.getResponse().getEntity().getContent(), StandardCharsets.UTF_8)); } catch (IOException bre) { throw new RuntimeException("error reading body after remote sent bad status", bre); } - fail("expected [400] response but get [" + e.getResponse().getStatusLine().getStatusCode() + "] with body:\n" + body); + fail("expected [400] response but get [" + e.getResponse().getStatusLine().getStatusCode() + "] with body:\n" + body); } assertThat(e.getMessage(), errorMessageMatcher); } catch (Exception e) { @@ -453,17 +501,20 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err private Map runSql(String mode, String sql) throws IOException { return runSql(mode, sql, StringUtils.EMPTY, randomBoolean()); } - + private Map runSql(String mode, String sql, boolean columnar) throws IOException { return runSql(mode, sql, StringUtils.EMPTY, columnar); } private Map runSql(String mode, String sql, String suffix, boolean columnar) throws IOException { // put an explicit "columnar": false parameter or omit it altogether, it should make no difference - return runSql(new StringEntity(query(sql).mode(mode).columnar(columnarValue(columnar)).toString(), - ContentType.APPLICATION_JSON), suffix, mode); + return runSql( + new StringEntity(query(sql).mode(mode).columnar(columnarValue(columnar)).toString(), ContentType.APPLICATION_JSON), + suffix, + mode + ); } - + protected Map runTranslateSql(String sql) throws IOException { return runSql(new StringEntity(sql, ContentType.APPLICATION_JSON), "/translate/", Mode.PLAIN.toString()); } @@ -494,41 +545,41 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err boolean columnar = randomBoolean(); String expected = ""; if (columnar) { - expected = "{\n" + - " \"columns\" : [\n" + - " {\n" + - " \"name\" : \"test1\",\n" + - " \"type\" : \"text\"\n" + - " }\n" + - " ],\n" + - " \"values\" : [\n" + - " [\n" + - " \"test1\",\n" + - " \"test2\"\n" + - " ]\n" + - " ]\n" + - "}\n"; + expected = "{\n" + + " \"columns\" : [\n" + + " {\n" + + " \"name\" : \"test1\",\n" + + " \"type\" : \"text\"\n" + + " }\n" + + " ],\n" + + " \"values\" : [\n" + + " [\n" + + " \"test1\",\n" + + " \"test2\"\n" + + " ]\n" + + " ]\n" + + "}\n"; } else { - expected = "{\n" + - " \"columns\" : [\n" + - " {\n" + - " \"name\" : \"test1\",\n" + - " \"type\" : \"text\"\n" + - " }\n" + - " ],\n" + - " \"rows\" : [\n" + - " [\n" + - " \"test1\"\n" + - " ],\n" + - " [\n" + - " \"test2\"\n" + - " ]\n" + - " ]\n" + - "}\n"; + expected = "{\n" + + " \"columns\" : [\n" + + " {\n" + + " \"name\" : \"test1\",\n" + + " \"type\" : \"text\"\n" + + " }\n" + + " ],\n" + + " \"rows\" : [\n" + + " [\n" + + " \"test1\"\n" + + " ],\n" + + " [\n" + + " \"test2\"\n" + + " ]\n" + + " ]\n" + + "}\n"; } executeAndAssertPrettyPrinting(expected, "true", columnar); } - + public void testPrettyPrintingDisabled() throws IOException { boolean columnar = randomBoolean(); String expected = ""; @@ -539,11 +590,9 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } executeAndAssertPrettyPrinting(expected, randomFrom("false", null), columnar); } - - private void executeAndAssertPrettyPrinting(String expectedJson, String prettyParameter, boolean columnar) - throws IOException { - index("{\"test1\":\"test1\"}", - "{\"test1\":\"test2\"}"); + + private void executeAndAssertPrettyPrinting(String expectedJson, String prettyParameter, boolean columnar) throws IOException { + index("{\"test1\":\"test1\"}", "{\"test1\":\"test2\"}"); Request request = new Request("POST", SQL_QUERY_REST_ENDPOINT); if (prettyParameter != null) { @@ -559,9 +608,12 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err options.addHeader("Accept", randomFrom("*/*", "application/json")); request.setOptions(options); } - request.setEntity(new StringEntity( + request.setEntity( + new StringEntity( query("SELECT * FROM test").mode(Mode.PLAIN).columnar(columnarValue(columnar)).toString(), - ContentType.APPLICATION_JSON)); + ContentType.APPLICATION_JSON + ) + ); Response response = client().performRequest(request); try (InputStream content = response.getEntity().getContent()) { @@ -590,44 +642,64 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err public void testBasicQueryWithFilter() throws IOException { String mode = randomMode(); - index("{\"test\":\"foo\"}", - "{\"test\":\"bar\"}"); + index("{\"test\":\"foo\"}", "{\"test\":\"bar\"}"); Map expected = new HashMap<>(); expected.put("columns", singletonList(columnInfo(mode, "test", "text", JDBCType.VARCHAR, Integer.MAX_VALUE))); expected.put("rows", singletonList(singletonList("foo"))); - assertResponse(expected, runSql( - new StringEntity(query("SELECT * FROM test").mode(mode).filter("{\"match\": {\"test\": \"foo\"}}").toString(), - ContentType.APPLICATION_JSON), StringUtils.EMPTY, mode)); + assertResponse( + expected, + runSql( + new StringEntity( + query("SELECT * FROM test").mode(mode).filter("{\"match\": {\"test\": \"foo\"}}").toString(), + ContentType.APPLICATION_JSON + ), + StringUtils.EMPTY, + mode + ) + ); } public void testBasicQueryWithParameters() throws IOException { String mode = randomMode(); boolean columnar = randomBoolean(); - index("{\"test\":\"foo\"}", - "{\"test\":\"bar\"}"); + index("{\"test\":\"foo\"}", "{\"test\":\"bar\"}"); Map expected = new HashMap<>(); - expected.put("columns", Arrays.asList( + expected.put( + "columns", + Arrays.asList( columnInfo(mode, "test", "text", JDBCType.VARCHAR, Integer.MAX_VALUE), columnInfo(mode, "param", "integer", JDBCType.INTEGER, 11) - )); + ) + ); if (columnar) { expected.put("values", Arrays.asList(singletonList("foo"), singletonList(10))); } else { expected.put("rows", Arrays.asList(Arrays.asList("foo", 10))); } - - String params = mode.equals("jdbc") ? "{\"type\": \"integer\", \"value\": 10}, {\"type\": \"keyword\", \"value\": \"foo\"}" : - "10, \"foo\""; - assertResponse(expected, runSql( - new StringEntity(query("SELECT test, ? param FROM test WHERE test = ?").mode(mode).columnar(columnarValue(columnar)) - .params("[" + params + "]").toString(), ContentType.APPLICATION_JSON), StringUtils.EMPTY, mode)); + + String params = mode.equals("jdbc") + ? "{\"type\": \"integer\", \"value\": 10}, {\"type\": \"keyword\", \"value\": \"foo\"}" + : "10, \"foo\""; + assertResponse( + expected, + runSql( + new StringEntity( + query("SELECT test, ? param FROM test WHERE test = ?").mode(mode) + .columnar(columnarValue(columnar)) + .params("[" + params + "]") + .toString(), + ContentType.APPLICATION_JSON + ), + StringUtils.EMPTY, + mode + ) + ); } public void testBasicTranslateQueryWithFilter() throws IOException { - index("{\"test\":\"foo\"}", - "{\"test\":\"bar\"}"); + index("{\"test\":\"foo\"}", "{\"test\":\"bar\"}"); Map response = runTranslateSql(query("SELECT * FROM test").filter("{\"match\": {\"test\": \"foo\"}}").toString()); @@ -665,11 +737,11 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } public void testTranslateQueryWithGroupByAndHaving() throws IOException { - index("{\"salary\":100}", - "{\"age\":20}"); + index("{\"salary\":100}", "{\"age\":20}"); Map response = runTranslateSql( - query("SELECT avg(salary) FROM test GROUP BY abs(age) HAVING avg(salary) > 50 LIMIT 10").toString()); + query("SELECT avg(salary) FROM test GROUP BY abs(age) HAVING avg(salary) > 50 LIMIT 10").toString() + ); assertEquals(response.get("size"), 0); assertEquals(false, response.get("_source")); @@ -694,8 +766,7 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err assertEquals(1, sources.size()); @SuppressWarnings("unchecked") - Map sourcesListMap = - (Map) ((Map) sources.get(0)).values().iterator().next(); + Map sourcesListMap = (Map) ((Map) sources.get(0)).values().iterator().next(); assertEquals(1, sourcesListMap.size()); @SuppressWarnings("unchecked") @@ -757,8 +828,7 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err @SuppressWarnings("unchecked") Map filterScript = (Map) bucketSelector.get("script"); assertEquals(3, filterScript.size()); - assertEquals("InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.gt(params.a0,params.v0))", - filterScript.get("source")); + assertEquals("InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.gt(params.a0,params.v0))", filterScript.get("source")); assertEquals("painless", filterScript.get("lang")); @SuppressWarnings("unchecked") Map filterScriptParams = (Map) filterScript.get("params"); @@ -767,14 +837,9 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } public void testBasicQueryText() throws IOException { - index("{\"test\":\"test\"}", - "{\"test\":\"test\"}"); + index("{\"test\":\"test\"}", "{\"test\":\"test\"}"); - String expected = - " test \n" + - "---------------\n" + - "test \n" + - "test \n"; + String expected = " test \n" + "---------------\n" + "test \n" + "test \n"; Tuple response = runSqlAsText("SELECT * FROM test", "text/plain"); assertEquals(expected, response.v1()); } @@ -790,15 +855,13 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } public void testDefaultQueryInCSV() throws IOException { - index("{\"name\":" + toJson("first") + ", \"number\" : 1 }", - "{\"name\":" + toJson("second\t") + ", \"number\": 2 }", - "{\"name\":" + toJson("\"third,\"") + ", \"number\": 3 }"); + index( + "{\"name\":" + toJson("first") + ", \"number\" : 1 }", + "{\"name\":" + toJson("second\t") + ", \"number\": 2 }", + "{\"name\":" + toJson("\"third,\"") + ", \"number\": 3 }" + ); - String expected = - "name,number\r\n" + - "first,1\r\n" + - "second\t,2\r\n" + - "\"\"\"third,\"\"\",3\r\n"; + String expected = "name,number\r\n" + "first,1\r\n" + "second\t,2\r\n" + "\"\"\"third,\"\"\",3\r\n"; String query = "SELECT * FROM test ORDER BY number"; Tuple response = runSqlAsText(query, "text/csv"); @@ -809,34 +872,31 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } public void testQueryWithoutHeaderInCSV() throws IOException { - index("{\"name\":" + toJson("first") + ", \"number\" : 1 }", - "{\"name\":" + toJson("second\t") + ", \"number\": 2 }", - "{\"name\":" + toJson("\"third,\"") + ", \"number\": 3 }"); + index( + "{\"name\":" + toJson("first") + ", \"number\" : 1 }", + "{\"name\":" + toJson("second\t") + ", \"number\": 2 }", + "{\"name\":" + toJson("\"third,\"") + ", \"number\": 3 }" + ); - String expected = - "first,1\r\n" + - "second\t,2\r\n" + - "\"\"\"third,\"\"\",3\r\n"; + String expected = "first,1\r\n" + "second\t,2\r\n" + "\"\"\"third,\"\"\",3\r\n"; String query = "SELECT * FROM test ORDER BY number"; Tuple response = runSqlAsText(query, "text/csv; header=absent"); assertEquals(expected, response.v1()); } - + public void testNextPageCSV() throws IOException { executeQueryWithNextPage("text/csv; header=present", "text,number,sum\r\n", "%s,%d,%d\r\n"); } public void testQueryInTSV() throws IOException { - index("{\"name\":" + toJson("first") + ", \"number\" : 1 }", - "{\"name\":" + toJson("second\t") + ", \"number\": 2 }", - "{\"name\":" + toJson("\"third,\"") + ", \"number\": 3 }"); + index( + "{\"name\":" + toJson("first") + ", \"number\" : 1 }", + "{\"name\":" + toJson("second\t") + ", \"number\": 2 }", + "{\"name\":" + toJson("\"third,\"") + ", \"number\": 3 }" + ); - String expected = - "name\tnumber\n" + - "first\t1\n" + - "second\\t\t2\n" + - "\"third,\"\t3\n"; + String expected = "name\tnumber\n" + "first\t1\n" + "second\\t\t2\n" + "\"third,\"\t3\n"; String query = "SELECT * FROM test ORDER BY number"; Tuple response = runSqlAsText(query, "text/tab-separated-values"); @@ -844,11 +904,11 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err response = runSqlAsTextFormat(query, "tsv"); assertEquals(expected, response.v1()); } - + public void testNextPageTSV() throws IOException { executeQueryWithNextPage("text/tab-separated-values", "text\tnumber\tsum\n", "%s\t%d\t%d\n"); } - + private void executeQueryWithNextPage(String format, String expectedHeader, String expectedLineFormat) throws IOException { int size = 20; String[] docs = new String[size]; @@ -865,8 +925,11 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err if (i == 0) { response = runSqlAsText(StringUtils.EMPTY, new StringEntity(request, ContentType.APPLICATION_JSON), format); } else { - response = runSqlAsText(StringUtils.EMPTY, new StringEntity(cursor(cursor).toString(), - ContentType.APPLICATION_JSON), format); + response = runSqlAsText( + StringUtils.EMPTY, + new StringEntity(cursor(cursor).toString(), ContentType.APPLICATION_JSON), + format + ); } StringBuilder expected = new StringBuilder(); @@ -884,11 +947,16 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err } Map expected = new HashMap<>(); expected.put("rows", emptyList()); - assertResponse(expected, runSql(new StringEntity(cursor(cursor).toString(), ContentType.APPLICATION_JSON), - StringUtils.EMPTY, Mode.PLAIN.toString())); + assertResponse( + expected, + runSql(new StringEntity(cursor(cursor).toString(), ContentType.APPLICATION_JSON), StringUtils.EMPTY, Mode.PLAIN.toString()) + ); - Map response = runSql(new StringEntity(cursor(cursor).toString(), ContentType.APPLICATION_JSON), - "/close", Mode.PLAIN.toString()); + Map response = runSql( + new StringEntity(cursor(cursor).toString(), ContentType.APPLICATION_JSON), + "/close", + Mode.PLAIN.toString() + ); assertEquals(true, response.get("succeeded")); assertEquals(0, getNumberOfSearchContexts("test")); @@ -911,8 +979,8 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err request.setOptions(options); Response response = client().performRequest(request); return new Tuple<>( - Streams.copyToString(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8)), - response.getHeader("Cursor") + Streams.copyToString(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8)), + response.getHeader("Cursor") ); } @@ -928,8 +996,8 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err Response response = client().performRequest(request); return new Tuple<>( - Streams.copyToString(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8)), - response.getHeader("Cursor") + Streams.copyToString(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8)), + response.getHeader("Cursor") ); } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlUsageTestCase.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlUsageTestCase.java similarity index 86% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlUsageTestCase.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlUsageTestCase.java index 47c79454510..ab1eab194f0 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlUsageTestCase.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlUsageTestCase.java @@ -33,24 +33,30 @@ import static org.elasticsearch.xpack.sql.qa.rest.RestSqlTestCase.query; public abstract class RestSqlUsageTestCase extends ESRestTestCase { private List testData = Arrays.asList( - new IndexDocument("used", "Don Quixote", 1072), - new IndexDocument("used", "Vacuum Diagrams", 335), - new IndexDocument("new", "Darwin's Radio", 270), - new IndexDocument("used", "The Martian", 387), - new IndexDocument("new", "Moving Mars", 495) + new IndexDocument("used", "Don Quixote", 1072), + new IndexDocument("used", "Vacuum Diagrams", 335), + new IndexDocument("new", "Darwin's Radio", 270), + new IndexDocument("used", "The Martian", 387), + new IndexDocument("new", "Moving Mars", 495) ); - + private enum ClientType { - CANVAS, CLI, JDBC, ODBC, ODBC32, ODBC64, REST; + CANVAS, + CLI, + JDBC, + ODBC, + ODBC32, + ODBC64, + REST; @Override public String toString() { return this.name().toLowerCase(Locale.ROOT); } - + } - private Map baseMetrics = new HashMap(); + private Map baseMetrics = new HashMap(); private Integer baseClientTypeTotalQueries = 0; private Integer baseClientTypeFailedQueries = 0; private Integer baseAllTotalQueries = 0; @@ -62,59 +68,59 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { /** * This method gets the metrics' values before the test runs, in case these values * were changed by other tests running in the same REST test cluster. The test itself - * will count the new metrics' values starting from the base values initialized here. + * will count the new metrics' values starting from the base values initialized here. */ @SuppressWarnings({ "unchecked", "rawtypes" }) @Before private void getBaseMetrics() throws UnsupportedOperationException, IOException { Map baseStats = getStats(); List>> nodesListStats = (List) baseStats.get("stats"); - + // used for "client_id" request parameter value, but also for getting the stats from ES clientType = randomFrom(ClientType.values()).toString(); ignoreClientType = randomBoolean(); - + // "client_id" parameter will not be sent in the requests // and "clientType" will only be used for getting the stats back from ES if (ignoreClientType) { clientType = ClientType.REST.toString(); } - + for (Map perNodeStats : nodesListStats) { Map featuresMetrics = (Map) ((Map) perNodeStats.get("stats")).get("features"); Map queriesMetrics = (Map) ((Map) perNodeStats.get("stats")).get("queries"); for (FeatureMetric metric : FeatureMetric.values()) { baseMetrics.put(metric.toString(), (Integer) featuresMetrics.get(metric.toString())); } - + // initialize the "base" metric values with whatever values are already recorded on ES - baseClientTypeTotalQueries = ((Map) queriesMetrics.get(clientType)).get("total"); - baseClientTypeFailedQueries = ((Map) queriesMetrics.get(clientType)).get("failed"); - baseAllTotalQueries = ((Map) queriesMetrics.get("_all")).get("total"); - baseAllFailedQueries = ((Map) queriesMetrics.get("_all")).get("failed"); - baseTranslateRequests = ((Map) queriesMetrics.get("translate")).get("count"); + baseClientTypeTotalQueries = ((Map) queriesMetrics.get(clientType)).get("total"); + baseClientTypeFailedQueries = ((Map) queriesMetrics.get(clientType)).get("failed"); + baseAllTotalQueries = ((Map) queriesMetrics.get("_all")).get("total"); + baseAllFailedQueries = ((Map) queriesMetrics.get("_all")).get("failed"); + baseTranslateRequests = ((Map) queriesMetrics.get("translate")).get("count"); } } - + public void testSqlRestUsage() throws IOException { index(testData); - + // // random WHERE and ORDER BY queries // int randomWhereExecutions = randomIntBetween(1, 15); int clientTypeTotalQueries = baseClientTypeTotalQueries + randomWhereExecutions; int allTotalQueries = baseAllTotalQueries + randomWhereExecutions; - + for (int i = 0; i < randomWhereExecutions; i++) { runSql("SELECT name FROM library WHERE page_count > 100 ORDER BY page_count"); } - + Map responseAsMap = getStats(); assertFeatureMetric(baseMetrics.get("where") + randomWhereExecutions, responseAsMap, "where"); assertFeatureMetric(baseMetrics.get("orderby") + randomWhereExecutions, responseAsMap, "orderby"); assertClientTypeAndAllQueryMetrics(clientTypeTotalQueries, allTotalQueries, responseAsMap); - + // // random HAVING and GROUP BY queries // @@ -128,7 +134,7 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { assertFeatureMetric(baseMetrics.get("having") + randomHavingExecutions, responseAsMap, "having"); assertFeatureMetric(baseMetrics.get("groupby") + randomHavingExecutions, responseAsMap, "groupby"); assertClientTypeAndAllQueryMetrics(clientTypeTotalQueries, allTotalQueries, responseAsMap); - + // // random LIMIT queries // @@ -141,7 +147,7 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { responseAsMap = getStats(); assertFeatureMetric(baseMetrics.get("limit") + randomLimitExecutions, responseAsMap, "limit"); assertClientTypeAndAllQueryMetrics(clientTypeTotalQueries, allTotalQueries, responseAsMap); - + // // random LOCALly executed queries // @@ -154,7 +160,7 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { responseAsMap = getStats(); assertFeatureMetric(baseMetrics.get("local") + randomLocalExecutions, responseAsMap, "local"); assertClientTypeAndAllQueryMetrics(clientTypeTotalQueries, allTotalQueries, responseAsMap); - + // // random COMMANDs // @@ -162,14 +168,23 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { clientTypeTotalQueries += randomCommandExecutions; allTotalQueries += randomCommandExecutions; for (int i = 0; i < randomCommandExecutions; i++) { - runSql(randomFrom("SHOW FUNCTIONS", "SHOW COLUMNS FROM library", "SHOW SCHEMAS", - "SHOW TABLES", "SYS TABLES", "SYS COLUMNS LIKE '%name'", - "SYS TABLES TYPE '%'", "SYS TYPES")); + runSql( + randomFrom( + "SHOW FUNCTIONS", + "SHOW COLUMNS FROM library", + "SHOW SCHEMAS", + "SHOW TABLES", + "SYS TABLES", + "SYS COLUMNS LIKE '%name'", + "SYS TABLES TYPE '%'", + "SYS TYPES" + ) + ); } responseAsMap = getStats(); assertFeatureMetric(baseMetrics.get("command") + randomCommandExecutions, responseAsMap, "command"); assertClientTypeAndAllQueryMetrics(clientTypeTotalQueries, allTotalQueries, responseAsMap); - + // // random TRANSLATE requests // @@ -179,7 +194,7 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { } responseAsMap = getStats(); assertTranslateQueryMetric(baseTranslateRequests + randomTranslateExecutions, responseAsMap); - + // // random failed queries // @@ -192,11 +207,15 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { // not interested in the exception type, but in the fact that the metrics are incremented // when an exception is thrown expectThrows(Exception.class, () -> { - runSql(randomFrom("SELECT missing_field FROM library", - "SELECT * FROM missing_index", - "SELECTT wrong_command", - "SELECT name + page_count AS not_allowed FROM library", - "SELECT incomplete_query FROM")); + runSql( + randomFrom( + "SELECT missing_field FROM library", + "SELECT * FROM missing_index", + "SELECTT wrong_command", + "SELECT name + page_count AS not_allowed FROM library", + "SELECT incomplete_query FROM" + ) + ); }); } responseAsMap = getStats(); @@ -205,17 +224,20 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { } private void assertClientTypeAndAllQueryMetrics(int clientTypeTotalQueries, int allTotalQueries, Map responseAsMap) - throws IOException { + throws IOException { assertClientTypeQueryMetric(clientTypeTotalQueries, responseAsMap, "total"); assertAllQueryMetric(allTotalQueries, responseAsMap, "total"); } - - private void assertClientTypeAndAllFailedQueryMetrics(int clientTypeFailedQueries, int allFailedQueries, - Map responseAsMap) throws IOException { + + private void assertClientTypeAndAllFailedQueryMetrics( + int clientTypeFailedQueries, + int allFailedQueries, + Map responseAsMap + ) throws IOException { assertClientTypeQueryMetric(clientTypeFailedQueries, responseAsMap, "failed"); assertAllQueryMetric(allFailedQueries, responseAsMap, "failed"); } - + private void index(List docs) throws IOException { Request request = new Request("POST", "/library/_bulk"); request.addParameter("refresh", "true"); @@ -227,17 +249,17 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { request.setJsonEntity(bulk.toString()); client().performRequest(request); } - + private Map getStats() throws UnsupportedOperationException, IOException { Request request = new Request("GET", SQL_STATS_REST_ENDPOINT); Map responseAsMap; try (InputStream content = client().performRequest(request).getEntity().getContent()) { responseAsMap = XContentHelper.convertToMap(JsonXContent.jsonXContent, content, false); } - + return responseAsMap; } - + private void runTranslate(String sql) throws IOException { Request request = new Request("POST", SQL_TRANSLATE_REST_ENDPOINT); if (randomBoolean()) { @@ -293,11 +315,15 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { options.addHeader("Accept", randomFrom("*/*", "application/json")); request.setOptions(options); } - request.setEntity(new StringEntity(query(sql).mode(mode).clientId(ignoreClientType ? StringUtils.EMPTY : restClient).toString(), - ContentType.APPLICATION_JSON)); + request.setEntity( + new StringEntity( + query(sql).mode(mode).clientId(ignoreClientType ? StringUtils.EMPTY : restClient).toString(), + ContentType.APPLICATION_JSON + ) + ); client().performRequest(request); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) private void assertFeatureMetric(int expected, Map responseAsMap, String feature) throws IOException { List> nodesListStats = (List>) responseAsMap.get("stats"); @@ -320,20 +346,20 @@ public abstract class RestSqlUsageTestCase extends ESRestTestCase { } assertEquals(expected, actualMetricValue); } - + private void assertClientTypeQueryMetric(int expected, Map responseAsMap, String metric) throws IOException { assertQueryMetric(expected, responseAsMap, clientType, metric); } - + private void assertAllQueryMetric(int expected, Map responseAsMap, String metric) throws IOException { assertQueryMetric(expected, responseAsMap, "_all", metric); } - + private class IndexDocument { private String condition; private String name; private int pageCount; - + IndexDocument(String condition, String name, int pageCount) { this.condition = condition; this.name = name; diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/package-info.java b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/package-info.java similarity index 83% rename from x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/package-info.java rename to x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/package-info.java index a07a23c7b04..b1a2456f7a2 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/package-info.java +++ b/x-pack/plugin/sql/qa/server/src/main/java/org/elasticsearch/xpack/sql/qa/rest/package-info.java @@ -5,6 +5,6 @@ */ /** - * Integration tests shared between multiple qa projects. + * Integration tests shared between multiple qa projects. */ package org.elasticsearch.xpack.sql.qa.rest; diff --git a/x-pack/plugin/sql/qa/src/main/resources/agg-ordering.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/agg-ordering.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/agg-ordering.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/agg-ordering.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/agg-ordering.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/agg-ordering.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/agg-ordering.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/agg-ordering.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/agg.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/agg.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/agg.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/agg.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/agg.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/agg.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/agg.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/agg.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/alias.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/alias.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/alias.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/alias.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/arithmetic.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/arithmetic.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/arithmetic.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/arithmetic.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/arithmetic.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/arithmetic.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/arithmetic.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/arithmetic.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/case-functions.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/case-functions.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/case-functions.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/case-functions.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/columns.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/columns.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/columns.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/columns.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/command.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/command.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/command.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/conditionals.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/conditionals.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/conditionals.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/conditionals.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/constant-keyword.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/constant-keyword.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/constant-keyword.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/constant-keyword.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/date.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/date.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/date.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/date.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/datetime-interval.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/datetime-interval.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/datetime-interval.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/datetime-interval.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/datetime.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/datetime.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/datetime.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/datetime.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/datetime.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/datetime.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/datetime.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/datetime.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/debug/debug.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/debug/debug.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/debug/debug.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/debug/debug.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/debug/debug.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/debug/debug.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/debug/debug.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/debug/debug.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/dep_emp.csv b/x-pack/plugin/sql/qa/server/src/main/resources/dep_emp.csv similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/dep_emp.csv rename to x-pack/plugin/sql/qa/server/src/main/resources/dep_emp.csv diff --git a/x-pack/plugin/sql/qa/src/main/resources/departments.csv b/x-pack/plugin/sql/qa/server/src/main/resources/departments.csv similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/departments.csv rename to x-pack/plugin/sql/qa/server/src/main/resources/departments.csv diff --git a/x-pack/plugin/sql/qa/src/main/resources/docs/docs.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/docs/docs.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/docs/docs.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/docs/docs.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/docs/geo.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/docs/geo.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/docs/geo.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/docs/geo.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/employees.csv b/x-pack/plugin/sql/qa/server/src/main/resources/employees.csv similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/employees.csv rename to x-pack/plugin/sql/qa/server/src/main/resources/employees.csv diff --git a/x-pack/plugin/sql/qa/src/main/resources/examples/example.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/examples/example.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/examples/example.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/examples/example.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/examples/example.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/examples/example.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/examples/example.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/examples/example.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/field-alias.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/field-alias.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/field-alias.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/field-alias.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/filter.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/filter.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/filter.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/filter.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/filter.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/filter.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/filter.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/filter.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/fulltext.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/fulltext.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/fulltext.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/fulltext.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/functions.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/functions.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/functions.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/functions.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geo.csv b/x-pack/plugin/sql/qa/server/src/main/resources/geo/geo.csv similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/geo/geo.csv rename to x-pack/plugin/sql/qa/server/src/main/resources/geo/geo.csv diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql-bulk.json b/x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql-bulk.json similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/geo/geosql-bulk.json rename to x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql-bulk.json diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.json b/x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql.json similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/geo/geosql.json rename to x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql.json diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/geo/geosql.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/geo/geosql.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/setup_test_geo.sql b/x-pack/plugin/sql/qa/server/src/main/resources/geo/setup_test_geo.sql similarity index 97% rename from x-pack/plugin/sql/qa/src/main/resources/geo/setup_test_geo.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/geo/setup_test_geo.sql index c736b0b5f4f..17e2b9646ef 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/setup_test_geo.sql +++ b/x-pack/plugin/sql/qa/server/src/main/resources/geo/setup_test_geo.sql @@ -1,10 +1,10 @@ -DROP TABLE IF EXISTS "geo"; -CREATE TABLE "geo" ( - "city" VARCHAR(50), - "region" VARCHAR(50), - "region_point" VARCHAR(50), - "location" POINT, - "geoshape" GEOMETRY, - "shape" GEOMETRY -) - AS SELECT * FROM CSVREAD('classpath:/geo/geo.csv'); +DROP TABLE IF EXISTS "geo"; +CREATE TABLE "geo" ( + "city" VARCHAR(50), + "region" VARCHAR(50), + "region_point" VARCHAR(50), + "location" POINT, + "geoshape" GEOMETRY, + "shape" GEOMETRY +) + AS SELECT * FROM CSVREAD('classpath:/geo/geo.csv'); diff --git a/x-pack/plugin/sql/qa/src/main/resources/ip.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/ip.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/ip.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/ip.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/library.csv b/x-pack/plugin/sql/qa/server/src/main/resources/library.csv similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/library.csv rename to x-pack/plugin/sql/qa/server/src/main/resources/library.csv diff --git a/x-pack/plugin/sql/qa/src/main/resources/logs.csv b/x-pack/plugin/sql/qa/server/src/main/resources/logs.csv similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/logs.csv rename to x-pack/plugin/sql/qa/server/src/main/resources/logs.csv diff --git a/x-pack/plugin/sql/qa/src/main/resources/math.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/math.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/math.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/math.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/math.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/math.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/math.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/math.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/nested.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/nested.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/nested.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/nested.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/null.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/null.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/null.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/null.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/null.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/null.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/null.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/null.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/ogc/OGC-NOTICE.txt b/x-pack/plugin/sql/qa/server/src/main/resources/ogc/OGC-NOTICE.txt similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/ogc/OGC-NOTICE.txt rename to x-pack/plugin/sql/qa/server/src/main/resources/ogc/OGC-NOTICE.txt diff --git a/x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/ogc/ogc.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/ogc/ogc.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.json b/x-pack/plugin/sql/qa/server/src/main/resources/ogc/ogc.json similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.json rename to x-pack/plugin/sql/qa/server/src/main/resources/ogc/ogc.json diff --git a/x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/ogc/ogc.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/ogc/ogc.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/ogc/sqltsch.sql b/x-pack/plugin/sql/qa/server/src/main/resources/ogc/sqltsch.sql similarity index 96% rename from x-pack/plugin/sql/qa/src/main/resources/ogc/sqltsch.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/ogc/sqltsch.sql index 6d1322ecd36..3e9fd8576e4 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/ogc/sqltsch.sql +++ b/x-pack/plugin/sql/qa/server/src/main/resources/ogc/sqltsch.sql @@ -1,672 +1,672 @@ --- FILE: sqltsch.sql 10/01/98 --- --- 1 2 3 4 5 6 7 8 ---345678901234567890123456789012345678901234567890123456789012345678901234567890 ---////////////////////////////////////////////////////////////////////////////// --- --- Copyright 1998, Open GIS Consortium, Inc. --- --- The material in this document details an Open GIS Consortium Test Suite in --- accordance with a license that your organization has signed. Please refer --- to http://www.opengeospatial.org/testing/ to obtain a copy of the general license --- (it is part of the Conformance Testing Agreement). --- ---////////////////////////////////////////////////////////////////////////////// --- --- OpenGIS Simple Features for SQL (Types and Functions) Test Suite Software --- --- This file "sqltsch.sql" is part 1 of a two part standardized test --- suite in SQL script form. The other file that is required for this test --- suite, "sqltque.sql", one additional script is provided ("sqltcle.sql") that --- performs cleanup operations between test runs, and other documents that --- describe the OGC Conformance Test Program are available via the WWW at --- http://www.opengeospatial.org/testing/index.htm --- --- NOTE CONCERNING INFORMATION ON CONFORMANCE TESTING AND THIS TEST SUITE --- ---------------------------------------------------------------------- --- --- Organizations wishing to submit product for conformance testing should --- access the above WWW site to discover the proper procedure for obtaining --- a license to use the OpenGIS(R) certification mark associated with this --- test suite. --- --- --- NOTE CONCERNING TEST SUITE ADAPTATION --- ------------------------------------- --- --- OGC recognizes that many products will have to adapt this test suite to --- make it work properly. OGC has documented the allowable adaptations within --- this test suite where possible. Other information about adaptations may be --- discovered in the Test Suite Guidelines document for this test suite. --- --- PLEASE NOTE THE OGC REQUIRES THAT ADAPTATIONS ARE FULLY DOCUMENTED USING --- LIBERAL COMMENT BLOCKS CONFORMING TO THE FOLLOWING FORMAT: --- --- -- !#@ ADAPTATION BEGIN --- explanatory text goes here --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- original sql goes here --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- --- adated sql goes here --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- ---////////////////////////////////////////////////////////////////////////////// --- --- BEGIN TEST SUITE CODE --- ---////////////////////////////////////////////////////////////////////////////// --- --- Create the neccessary feature and geometry tables(views) and metadata tables --- (views) to load and query the "Blue Lake" test data for OpenGIS Simple --- Features for SQL (Types and Functions) test. --- --- Required feature tables (views) are: --- Lakes --- Road Segments --- Divided Routes --- Buildings --- Forests --- Bridges --- Named Places --- Streams --- Ponds --- Map Neatlines --- --- Please refer to the Test Suite Guidelines for this test suite for further --- information concerning this test data. --- ---////////////////////////////////////////////////////////////////////////////// --- --- --- ---////////////////////////////////////////////////////////////////////////////// --- --- CREATE SPATIAL_REF_SYS METADATA TABLE --- ---////////////////////////////////////////////////////////////////////////////// --- --- --- *** ADAPTATION ALERT **** --- Implementations do not need to execute this statement if they already --- create the spatial_ref_sys table or view via another mechanism. --- The size of the srtext VARCHAR exceeds that allowed on some systems. --- --- CREATE TABLE spatial_ref_sys ( --- srid INTEGER NOT NULL PRIMARY KEY, --- auth_name VARCHAR(256), --- auth_srid INTEGER, --- -- srtext VARCHAR(2048) --- srtext VARCHAR(2000) --- ); --- -- --- INSERT INTO spatial_ref_sys VALUES(101, 'POSC', 32214, --- 'PROJCS["UTM_ZONE_14N", GEOGCS["World Geodetic System 72", --- DATUM["WGS_72", SPHEROID["NWL_10D", 6378135, 298.26]], --- PRIMEM["Greenwich", 0], UNIT["Meter", 1.0]], --- PROJECTION["Transverse_Mercator"], --- PARAMETER["False_Easting", 500000.0], --- PARAMETER["False_Northing", 0.0], --- PARAMETER["Central_Meridian", -99.0], --- PARAMETER["Scale_Factor", 0.9996], --- PARAMETER["Latitude_of_origin", 0.0], --- UNIT["Meter", 1.0]]' --- ); --- --- --- ---////////////////////////////////////////////////////////////////////////////// --- --- CREATE FEATURE SCHEMA --- --- *** ADAPTATION ALERT *** --- The following schema is created using CREATE TABLE statements. --- Furthermore, it DOES NOT create the GEOMETRY_COLUMNS metadata table. --- Implementer's should replace the CREATE TABLES below with the mechanism --- that it uses to create feature tables and the GEOMETRY_COLUMNS table/view --- ---////////////////////////////////////////////////////////////////////////////// --- --------------------------------------------------------------------------------- --- --- Create feature tables --- --------------------------------------------------------------------------------- --- --- Lakes --- --- --- --- -CREATE TABLE lakes ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - shore POLYGON -); --- --- Road Segments --- --- --- --- -CREATE TABLE road_segments ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - aliases VARCHAR(64), - num_lanes INTEGER, - centerline LINESTRING -); --- --- Divided Routes --- --- --- --- -CREATE TABLE divided_routes ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - num_lanes INTEGER, - centerlines MULTILINESTRING -); --- --- Forests --- --- --- --- -CREATE TABLE forests ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - boundary MULTIPOLYGON -); --- --- Bridges --- --- --- --- -CREATE TABLE bridges ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - position POINT -); --- --- Streams --- --- --- --- -CREATE TABLE streams ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - centerline LINESTRING -); --- --- Buildings --- ---*** ADAPTATION ALERT *** --- A view could be used to provide the below semantics without multiple geometry --- columns in a table. In other words, create two tables. One table would --- contain the POINT position and the other would create the POLYGON footprint. --- Then create a view with the semantics of the buildings table below. --- --- --- -CREATE TABLE buildings ( - fid INTEGER NOT NULL PRIMARY KEY, - address VARCHAR(64), - position POINT, - footprint POLYGON -); --- --- Ponds --- --- --- --- --- -- !#@ ADAPTATION BEGIN --- Fixes typo in the MULTIPOYLGON type --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- CREATE TABLE ponds ( --- fid INTEGER NOT NULL PRIMARY KEY, --- name VARCHAR(64), --- type VARCHAR(64), --- shores MULTIPOYLGON --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -CREATE TABLE ponds ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - type VARCHAR(64), - shores MULTIPOLYGON -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END - --- --- Named Places --- --- --- --- -CREATE TABLE named_places ( - fid INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(64), - boundary POLYGON -); --- --- Map Neatline --- --- --- --- -CREATE TABLE map_neatlines ( - fid INTEGER NOT NULL PRIMARY KEY, - neatline POLYGON -); --- --- --- ---////////////////////////////////////////////////////////////////////////////// --- --- POPULATE GEOMETRY AND FEATURE TABLES --- --- *** ADAPTATION ALERT *** --- This script DOES NOT make any inserts into a GEOMTERY_COLUMNS table/view. --- Implementers should insert whatever makes this happen in their implementation --- below. Furthermore, the inserts below may be replaced by whatever mechanism --- may be provided by implementers to insert rows in feature tables such that --- metadata (and other mechanisms) are updated properly. --- ---////////////////////////////////////////////////////////////////////////////// --- ---============================================================================== --- Lakes --- --- We have one lake, Blue Lake. It is a polygon with a hole. Its geometry is --- described in WKT format as: --- 'POLYGON( (52 18, 66 23, 73 9, 48 6, 52 18), --- (59 18, 67 18, 67 13, 59 13, 59 18) )' ---============================================================================== --- --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO lakes VALUES (101, 'BLUE LAKE', --- PolygonFromText('POLYGON((52 18,66 23,73 9,48 6,52 18),(59 18,67 18,67 13,59 13,59 18))', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO lakes VALUES (101, 'BLUE LAKE', - ST_PolyFromText('POLYGON((52 18,66 23,73 9,48 6,52 18),(59 18,67 18,67 13,59 13,59 18))', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- ---================== --- Road segments --- --- We have five road segments. Their geometries are all linestrings. --- The geometries are described in WKT format as: --- name 'Route 5', fid 102 --- 'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' --- name 'Route 5', fid 103 --- 'LINESTRING( 44 31, 56 34, 70 38 )' --- name 'Route 5', fid 104 --- 'LINESTRING( 70 38, 72 48 )' --- name 'Main Street', fid 105 --- 'LINESTRING( 70 38, 84 42 )' --- name 'Dirt Road by Green Forest', fid 106 --- 'LINESTRING( 28 26, 28 0 )' --- ---================== --- --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2, --- LineStringFromText('LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101) --- ); --- INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4, --- LineStringFromText('LINESTRING( 44 31, 56 34, 70 38 )' ,101) --- ); --- INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2, --- LineStringFromText('LINESTRING( 70 38, 72 48 )' ,101) --- ); --- INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4, --- LineStringFromText('LINESTRING( 70 38, 84 42 )' ,101) --- ); --- INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL, 1, --- LineStringFromText('LINESTRING( 28 26, 28 0 )',101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2, - ST_LineFromText('LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101) -); -INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4, - ST_LineFromText('LINESTRING( 44 31, 56 34, 70 38 )' ,101) -); -INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2, - ST_LineFromText('LINESTRING( 70 38, 72 48 )' ,101) -); -INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4, - ST_LineFromText('LINESTRING( 70 38, 84 42 )' ,101) -); -INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL, 1, - ST_LineFromText('LINESTRING( 28 26, 28 0 )',101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END - --- ---================== --- DividedRoutes --- --- We have one divided route. Its geometry is a multilinestring. --- The geometry is described in WKT format as: --- 'MULTILINESTRING( (10 48, 10 21, 10 0), (16 0, 10 23, 16 48) )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO divided_routes VALUES(119, 'Route 75', 4, --- MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO divided_routes VALUES(119, 'Route 75', 4, - ST_MLineFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- ---================== --- Forests --- --- We have one forest. Its geometry is a multipolygon. --- The geometry is described in WKT format as: --- 'MULTIPOLYGON( ( (28 26, 28 0, 84 0, 84 42, 28 26), --- (52 18, 66 23, 73 9, 48 6, 52 18) ), --- ( (59 18, 67 18, 67 13, 59 13, 59 18) ) )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO forests VALUES(109, 'Green Forest', --- MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO forests VALUES(109, 'Green Forest', - ST_MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END - --- ---================== --- Bridges --- --- We have one bridge. Its geometry is a point. --- The geometry is described in WKT format as: --- 'POINT( 44 31 )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO bridges VALUES(110, 'Cam Bridge', --- PointFromText('POINT( 44 31 )', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO bridges VALUES(110, 'Cam Bridge', - ST_PointFromText('POINT( 44 31 )', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- ---================== --- Streams --- --- We have two streams. Their geometries are linestrings. --- The geometries are described in WKT format as: --- 'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )' --- 'LINESTRING( 76 0, 78 4, 73 9 )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO streams VALUES(111, 'Cam Stream', --- LineStringFromText('LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101) --- ); --- INSERT INTO streams VALUES(112, NULL, --- LineStringFromText('LINESTRING( 76 0, 78 4, 73 9 )', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO streams VALUES(111, 'Cam Stream', - ST_LineFromText('LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101) -); -INSERT INTO streams VALUES(112, NULL, - ST_LineFromText('LINESTRING( 76 0, 78 4, 73 9 )', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- ---================== --- Buildings --- --- We have two buildings. Their geometries are points and polygons. --- The geometries are described in WKT format as: --- address '123 Main Street' fid 113 --- 'POINT( 52 30 )' and --- 'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )' --- address '215 Main Street' fid 114 --- 'POINT( 64 33 )' and --- 'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO buildings VALUES(113, '123 Main Street', --- PointFromText('POINT( 52 30 )', 101), --- PolygonFromText('POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101) --- ); --- INSERT INTO buildings VALUES(114, '215 Main Street', --- PointFromText('POINT( 64 33 )', 101), --- PolygonFromText('POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO buildings VALUES(113, '123 Main Street', - ST_PointFromText('POINT( 52 30 )', 101), - ST_PolyFromText('POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101) -); -INSERT INTO buildings VALUES(114, '215 Main Street', - ST_PointFromText('POINT( 64 33 )', 101), - ST_PolyFromText('POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- ---================== --- Ponds --- --- We have one pond. Its geometry is a multipolygon. --- The geometry is described in WKT format as: --- 'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ), ( ( 26 44, 26 40, 28 42, 26 44) ) )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO ponds VALUES(120, NULL, 'Stock Pond', --- MultiPolygonFromText('MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ), ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO ponds VALUES(120, NULL, 'Stock Pond', - ST_MPolyFromText('MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ), ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END - --- ---================== --- Named Places --- --- We have two named places. Their geometries are polygons. --- The geometries are described in WKT format as: --- name 'Ashton' fid 117 --- 'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )' --- address 'Goose Island' fid 118 --- 'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO named_places VALUES(117, 'Ashton', --- PolygonFromText('POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101) --- ); --- INSERT INTO named_places VALUES(118, 'Goose Island', --- PolygonFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO named_places VALUES(117, 'Ashton', - ST_PolyFromText('POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101) -); -INSERT INTO named_places VALUES(118, 'Goose Island', - ST_PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- ---================== --- Map Neatlines --- --- We have one map neatline. Its geometry is a polygon. --- The geometry is described in WKT format as: --- 'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )' --- ---================== --- --- -- !#@ ADAPTATION BEGIN --- Adds ST_ prefix to routing names --- --------------------- --- -- BEGIN ORIGINAL SQL --- --------------------- --- INSERT INTO map_neatlines VALUES(115, --- PolygonFromText('POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101) --- ); --- --------------------- --- -- END ORIGINAL SQL --- --------------------- --- -- BEGIN ADAPTED SQL --- --------------------- -INSERT INTO map_neatlines VALUES(115, - ST_PolyFromText('POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101) -); --- --------------------- --- -- END ADAPTED SQL --- --------------------- --- -- !#@ ADAPTATION END --- --- --- +-- FILE: sqltsch.sql 10/01/98 +-- +-- 1 2 3 4 5 6 7 8 +--345678901234567890123456789012345678901234567890123456789012345678901234567890 +--////////////////////////////////////////////////////////////////////////////// +-- +-- Copyright 1998, Open GIS Consortium, Inc. +-- +-- The material in this document details an Open GIS Consortium Test Suite in +-- accordance with a license that your organization has signed. Please refer +-- to http://www.opengeospatial.org/testing/ to obtain a copy of the general license +-- (it is part of the Conformance Testing Agreement). +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- OpenGIS Simple Features for SQL (Types and Functions) Test Suite Software +-- +-- This file "sqltsch.sql" is part 1 of a two part standardized test +-- suite in SQL script form. The other file that is required for this test +-- suite, "sqltque.sql", one additional script is provided ("sqltcle.sql") that +-- performs cleanup operations between test runs, and other documents that +-- describe the OGC Conformance Test Program are available via the WWW at +-- http://www.opengeospatial.org/testing/index.htm +-- +-- NOTE CONCERNING INFORMATION ON CONFORMANCE TESTING AND THIS TEST SUITE +-- ---------------------------------------------------------------------- +-- +-- Organizations wishing to submit product for conformance testing should +-- access the above WWW site to discover the proper procedure for obtaining +-- a license to use the OpenGIS(R) certification mark associated with this +-- test suite. +-- +-- +-- NOTE CONCERNING TEST SUITE ADAPTATION +-- ------------------------------------- +-- +-- OGC recognizes that many products will have to adapt this test suite to +-- make it work properly. OGC has documented the allowable adaptations within +-- this test suite where possible. Other information about adaptations may be +-- discovered in the Test Suite Guidelines document for this test suite. +-- +-- PLEASE NOTE THE OGC REQUIRES THAT ADAPTATIONS ARE FULLY DOCUMENTED USING +-- LIBERAL COMMENT BLOCKS CONFORMING TO THE FOLLOWING FORMAT: +-- +-- -- !#@ ADAPTATION BEGIN +-- explanatory text goes here +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- original sql goes here +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +-- adated sql goes here +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- BEGIN TEST SUITE CODE +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- Create the neccessary feature and geometry tables(views) and metadata tables +-- (views) to load and query the "Blue Lake" test data for OpenGIS Simple +-- Features for SQL (Types and Functions) test. +-- +-- Required feature tables (views) are: +-- Lakes +-- Road Segments +-- Divided Routes +-- Buildings +-- Forests +-- Bridges +-- Named Places +-- Streams +-- Ponds +-- Map Neatlines +-- +-- Please refer to the Test Suite Guidelines for this test suite for further +-- information concerning this test data. +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- CREATE SPATIAL_REF_SYS METADATA TABLE +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- +-- *** ADAPTATION ALERT **** +-- Implementations do not need to execute this statement if they already +-- create the spatial_ref_sys table or view via another mechanism. +-- The size of the srtext VARCHAR exceeds that allowed on some systems. +-- +-- CREATE TABLE spatial_ref_sys ( +-- srid INTEGER NOT NULL PRIMARY KEY, +-- auth_name VARCHAR(256), +-- auth_srid INTEGER, +-- -- srtext VARCHAR(2048) +-- srtext VARCHAR(2000) +-- ); +-- -- +-- INSERT INTO spatial_ref_sys VALUES(101, 'POSC', 32214, +-- 'PROJCS["UTM_ZONE_14N", GEOGCS["World Geodetic System 72", +-- DATUM["WGS_72", SPHEROID["NWL_10D", 6378135, 298.26]], +-- PRIMEM["Greenwich", 0], UNIT["Meter", 1.0]], +-- PROJECTION["Transverse_Mercator"], +-- PARAMETER["False_Easting", 500000.0], +-- PARAMETER["False_Northing", 0.0], +-- PARAMETER["Central_Meridian", -99.0], +-- PARAMETER["Scale_Factor", 0.9996], +-- PARAMETER["Latitude_of_origin", 0.0], +-- UNIT["Meter", 1.0]]' +-- ); +-- +-- +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- CREATE FEATURE SCHEMA +-- +-- *** ADAPTATION ALERT *** +-- The following schema is created using CREATE TABLE statements. +-- Furthermore, it DOES NOT create the GEOMETRY_COLUMNS metadata table. +-- Implementer's should replace the CREATE TABLES below with the mechanism +-- that it uses to create feature tables and the GEOMETRY_COLUMNS table/view +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-------------------------------------------------------------------------------- +-- +-- Create feature tables +-- +-------------------------------------------------------------------------------- +-- +-- Lakes +-- +-- +-- +-- +CREATE TABLE lakes ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + shore POLYGON +); +-- +-- Road Segments +-- +-- +-- +-- +CREATE TABLE road_segments ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + aliases VARCHAR(64), + num_lanes INTEGER, + centerline LINESTRING +); +-- +-- Divided Routes +-- +-- +-- +-- +CREATE TABLE divided_routes ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + num_lanes INTEGER, + centerlines MULTILINESTRING +); +-- +-- Forests +-- +-- +-- +-- +CREATE TABLE forests ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + boundary MULTIPOLYGON +); +-- +-- Bridges +-- +-- +-- +-- +CREATE TABLE bridges ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + position POINT +); +-- +-- Streams +-- +-- +-- +-- +CREATE TABLE streams ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + centerline LINESTRING +); +-- +-- Buildings +-- +--*** ADAPTATION ALERT *** +-- A view could be used to provide the below semantics without multiple geometry +-- columns in a table. In other words, create two tables. One table would +-- contain the POINT position and the other would create the POLYGON footprint. +-- Then create a view with the semantics of the buildings table below. +-- +-- +-- +CREATE TABLE buildings ( + fid INTEGER NOT NULL PRIMARY KEY, + address VARCHAR(64), + position POINT, + footprint POLYGON +); +-- +-- Ponds +-- +-- +-- +-- +-- -- !#@ ADAPTATION BEGIN +-- Fixes typo in the MULTIPOYLGON type +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- CREATE TABLE ponds ( +-- fid INTEGER NOT NULL PRIMARY KEY, +-- name VARCHAR(64), +-- type VARCHAR(64), +-- shores MULTIPOYLGON +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +CREATE TABLE ponds ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + type VARCHAR(64), + shores MULTIPOLYGON +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END + +-- +-- Named Places +-- +-- +-- +-- +CREATE TABLE named_places ( + fid INTEGER NOT NULL PRIMARY KEY, + name VARCHAR(64), + boundary POLYGON +); +-- +-- Map Neatline +-- +-- +-- +-- +CREATE TABLE map_neatlines ( + fid INTEGER NOT NULL PRIMARY KEY, + neatline POLYGON +); +-- +-- +-- +--////////////////////////////////////////////////////////////////////////////// +-- +-- POPULATE GEOMETRY AND FEATURE TABLES +-- +-- *** ADAPTATION ALERT *** +-- This script DOES NOT make any inserts into a GEOMTERY_COLUMNS table/view. +-- Implementers should insert whatever makes this happen in their implementation +-- below. Furthermore, the inserts below may be replaced by whatever mechanism +-- may be provided by implementers to insert rows in feature tables such that +-- metadata (and other mechanisms) are updated properly. +-- +--////////////////////////////////////////////////////////////////////////////// +-- +--============================================================================== +-- Lakes +-- +-- We have one lake, Blue Lake. It is a polygon with a hole. Its geometry is +-- described in WKT format as: +-- 'POLYGON( (52 18, 66 23, 73 9, 48 6, 52 18), +-- (59 18, 67 18, 67 13, 59 13, 59 18) )' +--============================================================================== +-- +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO lakes VALUES (101, 'BLUE LAKE', +-- PolygonFromText('POLYGON((52 18,66 23,73 9,48 6,52 18),(59 18,67 18,67 13,59 13,59 18))', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO lakes VALUES (101, 'BLUE LAKE', + ST_PolyFromText('POLYGON((52 18,66 23,73 9,48 6,52 18),(59 18,67 18,67 13,59 13,59 18))', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +--================== +-- Road segments +-- +-- We have five road segments. Their geometries are all linestrings. +-- The geometries are described in WKT format as: +-- name 'Route 5', fid 102 +-- 'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' +-- name 'Route 5', fid 103 +-- 'LINESTRING( 44 31, 56 34, 70 38 )' +-- name 'Route 5', fid 104 +-- 'LINESTRING( 70 38, 72 48 )' +-- name 'Main Street', fid 105 +-- 'LINESTRING( 70 38, 84 42 )' +-- name 'Dirt Road by Green Forest', fid 106 +-- 'LINESTRING( 28 26, 28 0 )' +-- +--================== +-- +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2, +-- LineStringFromText('LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101) +-- ); +-- INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4, +-- LineStringFromText('LINESTRING( 44 31, 56 34, 70 38 )' ,101) +-- ); +-- INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2, +-- LineStringFromText('LINESTRING( 70 38, 72 48 )' ,101) +-- ); +-- INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4, +-- LineStringFromText('LINESTRING( 70 38, 84 42 )' ,101) +-- ); +-- INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL, 1, +-- LineStringFromText('LINESTRING( 28 26, 28 0 )',101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2, + ST_LineFromText('LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101) +); +INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4, + ST_LineFromText('LINESTRING( 44 31, 56 34, 70 38 )' ,101) +); +INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2, + ST_LineFromText('LINESTRING( 70 38, 72 48 )' ,101) +); +INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4, + ST_LineFromText('LINESTRING( 70 38, 84 42 )' ,101) +); +INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL, 1, + ST_LineFromText('LINESTRING( 28 26, 28 0 )',101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END + +-- +--================== +-- DividedRoutes +-- +-- We have one divided route. Its geometry is a multilinestring. +-- The geometry is described in WKT format as: +-- 'MULTILINESTRING( (10 48, 10 21, 10 0), (16 0, 10 23, 16 48) )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO divided_routes VALUES(119, 'Route 75', 4, +-- MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO divided_routes VALUES(119, 'Route 75', 4, + ST_MLineFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +--================== +-- Forests +-- +-- We have one forest. Its geometry is a multipolygon. +-- The geometry is described in WKT format as: +-- 'MULTIPOLYGON( ( (28 26, 28 0, 84 0, 84 42, 28 26), +-- (52 18, 66 23, 73 9, 48 6, 52 18) ), +-- ( (59 18, 67 18, 67 13, 59 13, 59 18) ) )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO forests VALUES(109, 'Green Forest', +-- MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO forests VALUES(109, 'Green Forest', + ST_MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END + +-- +--================== +-- Bridges +-- +-- We have one bridge. Its geometry is a point. +-- The geometry is described in WKT format as: +-- 'POINT( 44 31 )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO bridges VALUES(110, 'Cam Bridge', +-- PointFromText('POINT( 44 31 )', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO bridges VALUES(110, 'Cam Bridge', + ST_PointFromText('POINT( 44 31 )', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +--================== +-- Streams +-- +-- We have two streams. Their geometries are linestrings. +-- The geometries are described in WKT format as: +-- 'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )' +-- 'LINESTRING( 76 0, 78 4, 73 9 )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO streams VALUES(111, 'Cam Stream', +-- LineStringFromText('LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101) +-- ); +-- INSERT INTO streams VALUES(112, NULL, +-- LineStringFromText('LINESTRING( 76 0, 78 4, 73 9 )', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO streams VALUES(111, 'Cam Stream', + ST_LineFromText('LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101) +); +INSERT INTO streams VALUES(112, NULL, + ST_LineFromText('LINESTRING( 76 0, 78 4, 73 9 )', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +--================== +-- Buildings +-- +-- We have two buildings. Their geometries are points and polygons. +-- The geometries are described in WKT format as: +-- address '123 Main Street' fid 113 +-- 'POINT( 52 30 )' and +-- 'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )' +-- address '215 Main Street' fid 114 +-- 'POINT( 64 33 )' and +-- 'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO buildings VALUES(113, '123 Main Street', +-- PointFromText('POINT( 52 30 )', 101), +-- PolygonFromText('POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101) +-- ); +-- INSERT INTO buildings VALUES(114, '215 Main Street', +-- PointFromText('POINT( 64 33 )', 101), +-- PolygonFromText('POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO buildings VALUES(113, '123 Main Street', + ST_PointFromText('POINT( 52 30 )', 101), + ST_PolyFromText('POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101) +); +INSERT INTO buildings VALUES(114, '215 Main Street', + ST_PointFromText('POINT( 64 33 )', 101), + ST_PolyFromText('POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +--================== +-- Ponds +-- +-- We have one pond. Its geometry is a multipolygon. +-- The geometry is described in WKT format as: +-- 'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ), ( ( 26 44, 26 40, 28 42, 26 44) ) )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO ponds VALUES(120, NULL, 'Stock Pond', +-- MultiPolygonFromText('MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ), ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO ponds VALUES(120, NULL, 'Stock Pond', + ST_MPolyFromText('MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ), ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END + +-- +--================== +-- Named Places +-- +-- We have two named places. Their geometries are polygons. +-- The geometries are described in WKT format as: +-- name 'Ashton' fid 117 +-- 'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )' +-- address 'Goose Island' fid 118 +-- 'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO named_places VALUES(117, 'Ashton', +-- PolygonFromText('POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101) +-- ); +-- INSERT INTO named_places VALUES(118, 'Goose Island', +-- PolygonFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO named_places VALUES(117, 'Ashton', + ST_PolyFromText('POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101) +); +INSERT INTO named_places VALUES(118, 'Goose Island', + ST_PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +--================== +-- Map Neatlines +-- +-- We have one map neatline. Its geometry is a polygon. +-- The geometry is described in WKT format as: +-- 'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )' +-- +--================== +-- +-- -- !#@ ADAPTATION BEGIN +-- Adds ST_ prefix to routing names +-- --------------------- +-- -- BEGIN ORIGINAL SQL +-- --------------------- +-- INSERT INTO map_neatlines VALUES(115, +-- PolygonFromText('POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101) +-- ); +-- --------------------- +-- -- END ORIGINAL SQL +-- --------------------- +-- -- BEGIN ADAPTED SQL +-- --------------------- +INSERT INTO map_neatlines VALUES(115, + ST_PolyFromText('POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101) +); +-- --------------------- +-- -- END ADAPTED SQL +-- --------------------- +-- -- !#@ ADAPTATION END +-- +-- +-- -- end sqltsch.sql \ No newline at end of file diff --git a/x-pack/plugin/sql/qa/src/main/resources/pivot.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/pivot.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/pivot.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/pivot.csv-spec diff --git a/x-pack/plugin/sql/qa/server/src/main/resources/plugin-security.policy b/x-pack/plugin/sql/qa/server/src/main/resources/plugin-security.policy new file mode 100644 index 00000000000..bb58eb4270d --- /dev/null +++ b/x-pack/plugin/sql/qa/server/src/main/resources/plugin-security.policy @@ -0,0 +1,4 @@ +grant { + // Policy is required for tests to connect to testing Elasticsearch instances. + permission java.net.SocketPermission "*", "connect,resolve"; +}; diff --git a/x-pack/plugin/sql/qa/src/main/resources/select.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/select.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/select.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/select.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/select.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/select.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/select.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/select.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_columns.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_columns.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_columns.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_columns.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_columns_empty.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_columns_empty.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_columns_empty.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_columns_empty.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_procedure_columns.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_procedure_columns.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_procedure_columns.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_procedure_columns.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_procedures.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_procedures.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_procedures.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_procedures.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_table_types.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_table_types.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_table_types.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_table_types.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_tables.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_tables.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_tables.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_tables.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_tables_empty.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_tables_empty.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_tables_empty.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_tables_empty.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_types_of_table.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_types_of_table.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_metadata_get_types_of_table.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_metadata_get_types_of_table.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_mock_show_tables.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_show_tables.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_mock_show_tables.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_mock_show_tables.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/setup_test_emp.sql b/x-pack/plugin/sql/qa/server/src/main/resources/setup_test_emp.sql similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/setup_test_emp.sql rename to x-pack/plugin/sql/qa/server/src/main/resources/setup_test_emp.sql diff --git a/x-pack/plugin/sql/qa/src/main/resources/single-node-only/command-sys-geo.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/single-node-only/command-sys-geo.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/single-node-only/command-sys-geo.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/single-node-only/command-sys-geo.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/single-node-only/command-sys.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/single-node-only/command-sys.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/single-node-only/command-sys.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/single-node-only/command-sys.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/slow/frozen.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/slow/frozen.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/slow/frozen.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/slow/frozen.csv-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/slow/readme.txt b/x-pack/plugin/sql/qa/server/src/main/resources/slow/readme.txt similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/slow/readme.txt rename to x-pack/plugin/sql/qa/server/src/main/resources/slow/readme.txt diff --git a/x-pack/plugin/sql/qa/src/main/resources/string-functions.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/string-functions.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/string-functions.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/string-functions.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/subselect.sql-spec b/x-pack/plugin/sql/qa/server/src/main/resources/subselect.sql-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/subselect.sql-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/subselect.sql-spec diff --git a/x-pack/plugin/sql/qa/src/main/resources/time.csv-spec b/x-pack/plugin/sql/qa/server/src/main/resources/time.csv-spec similarity index 100% rename from x-pack/plugin/sql/qa/src/main/resources/time.csv-spec rename to x-pack/plugin/sql/qa/server/src/main/resources/time.csv-spec diff --git a/x-pack/plugin/sql/qa/single-node/build.gradle b/x-pack/plugin/sql/qa/single-node/build.gradle deleted file mode 100644 index 137ffed68ad..00000000000 --- a/x-pack/plugin/sql/qa/single-node/build.gradle +++ /dev/null @@ -1,4 +0,0 @@ -testClusters.integTest { - setting 'xpack.security.enabled', 'false' - setting 'xpack.license.self_generated.type', 'trial' -} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcErrorsIT.java b/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcErrorsIT.java deleted file mode 100644 index ba9ef20c34a..00000000000 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcErrorsIT.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.qa.single_node; - -import org.elasticsearch.xpack.sql.qa.jdbc.ErrorsTestCase; - -public class JdbcErrorsIT extends ErrorsTestCase { -} diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcResultSetIT.java b/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcResultSetIT.java deleted file mode 100644 index 658911fb8d4..00000000000 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/JdbcResultSetIT.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -package org.elasticsearch.xpack.sql.qa.single_node; - -import org.elasticsearch.xpack.sql.qa.jdbc.ResultSetTestCase; - -/* - * Integration testing class for "no security" (cluster running without the Security plugin, - * or the Security is disbled) scenario. Runs all tests in the base class. - */ -public class JdbcResultSetIT extends ResultSetTestCase { -}