From 49a77b3f938f7b034bea3dddda3257b0f39ae86b Mon Sep 17 00:00:00 2001 From: Sergey Chernov Date: Fri, 11 Sep 2026 23:14:34 -0700 Subject: [PATCH 1/4] Added integration-testing.md initial version --- docs/integration-index.md | 2 +- docs/integration-testing.md | 47 +++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 docs/integration-testing.md diff --git a/docs/integration-index.md b/docs/integration-index.md index fb262ac99..047476b53 100644 --- a/docs/integration-index.md +++ b/docs/integration-index.md @@ -1,4 +1,4 @@ -# ClickHouse Java Integration +# ClickHouse Java Client Integration Guide ## Abstract diff --git a/docs/integration-testing.md b/docs/integration-testing.md new file mode 100644 index 000000000..b77326a70 --- /dev/null +++ b/docs/integration-testing.md @@ -0,0 +1,47 @@ +# ClickHouse Java Client & JDBC Driver Integration Testing + +## Abstract + +Every integration case has specific requirements. For example, BI tools should verify connectivity, data type mapping, handling timestamps. This guide documents different scenarios we have learned from numerous integrations. + + + +# General Recommendations + +Tests has a gread values as contract verification tool when build properly. If there are tests for other integrations we recommend porting them to verify ClickHouse integration. + +Design your tests with posibility to run them on staging system and sometimes on production. For example, testing secure connection is important for communication with ClickHouse Cloud. It also helpes to onboard new customers when they want to integrate their ClickHouse instance. + +# Integration Tests + +Integration tests are useful on all stages of work: +- initial development help teams to have exacts scenarios to verify. +- verify production system is working correctly. +- during library upgrades to understand amount of changes. + + +## Configuration + +We test different configurations in our libraries but tests set values dirrectly. Application configuration passes a few more step before getting into library so verifying it is accepted by client is important. We recommend join configuration tests with core features. Additionaly it is good to have simple client or driver initialization tests with all important configuration parameters set. Client has `com.clickhouse.client.api.Client#getConfiguration()` to retrieve all settings after creation. ClickHouse JDBC Connection provides access to client via `com.clickhouse.jdbc.ConnectionImpl#getClient`. + + +Things to look for: +- configuration value encoding +- value ranges + +## Operations + +Majority of the tests should cover operation part: +- connection +- health checking +- read/write operations +- error handling +- failure handling and recovery. + + +## Behavior + + +# Performance Tests + +## Load Testing From f562a6d38da8c2fb8310ed9d1976634955917d1b Mon Sep 17 00:00:00 2001 From: Sergey Chernov Date: Tue, 15 Sep 2026 14:42:56 -0700 Subject: [PATCH 2/4] Completed initial version of integration-test.md --- docs/integration-testing.md | 117 ++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 24 deletions(-) diff --git a/docs/integration-testing.md b/docs/integration-testing.md index b77326a70..e9474be83 100644 --- a/docs/integration-testing.md +++ b/docs/integration-testing.md @@ -2,46 +2,115 @@ ## Abstract -Every integration case has specific requirements. For example, BI tools should verify connectivity, data type mapping, handling timestamps. This guide documents different scenarios we have learned from numerous integrations. +Integration testing essential in building integrations. Scope of it defines quality of service for end users. Each business case has own test goals along with +core ones. This guide will share our vision and some good practices we see worth using. +Goal integration testing is to verify: +- Systems can communicate +- Systems can handle failures +Tests have great value as a contract verification tool when built properly. If there are tests for other integrations, we recommend porting them to verify ClickHouse integration. -# General Recommendations +# General Recommendations -Tests has a gread values as contract verification tool when build properly. If there are tests for other integrations we recommend porting them to verify ClickHouse integration. +## Environment -Design your tests with posibility to run them on staging system and sometimes on production. For example, testing secure connection is important for communication with ClickHouse Cloud. It also helpes to onboard new customers when they want to integrate their ClickHouse instance. +Tests can be run in different environments: local, staging, production. Running tests locally is mainly for development and are essential. ClickHouse can be easily run as Docker container (see below). Tests running on staging environment is more important because they verify real systems integration. ClickHouse Cloud is cost effective so +running a test instance almost free compare to cost of missed issue. Staging environment is good for load testing because it gives real picture of how well systems +work. Local environment hardly can replicate cloud networking (what it crucial part): WiFi connecting developer's laptop is very unstable on physical level. Tests in production is also needed at least for two reasons: certify integration and find issues (failed tests points to a problem). -# Integration Tests -Integration tests are useful on all stages of work: -- initial development help teams to have exacts scenarios to verify. -- verify production system is working correctly. -- during library upgrades to understand amount of changes. +**Example: Running ClickHouse in Docker** +Start a local ClickHouse instance for testing: -## Configuration +```sh +docker run --rm -d -p 8123:8123 --name ch clickhouse/clickhouse-server +``` -We test different configurations in our libraries but tests set values dirrectly. Application configuration passes a few more step before getting into library so verifying it is accepted by client is important. We recommend join configuration tests with core features. Additionaly it is good to have simple client or driver initialization tests with all important configuration parameters set. Client has `com.clickhouse.client.api.Client#getConfiguration()` to retrieve all settings after creation. ClickHouse JDBC Connection provides access to client via `com.clickhouse.jdbc.ConnectionImpl#getClient`. +Stop it when done: +```sh +docker stop ch +``` -Things to look for: -- configuration value encoding -- value ranges +**ClickHouse Version** -## Operations +Make sure to test with different ClickHouse version expecially if your application connects to different on-prem installation. Test with LTS versions first. We recommend test +with most recent LTS versions that reached their end-of-life. It is very good practice to keep DB version inventory up-to-date to understand where to focus in testing. -Majority of the tests should cover operation part: -- connection -- health checking -- read/write operations -- error handling -- failure handling and recovery. +**Protocol** +Test with different protocols if applicable. Most important to verify secure connections even locally. For example, old JRE version may have expired CA certificate +and even valid SSL certificate will be seen as invalid because signed with new version of CA certificate unknow to JRE. -## Behavior +**Host** +Design test to be runnable against remote and local environment. ClickHouse can be run within [testcotnainer](https://testcontainers.com/) but external host configuration still useful to run same tests against staging or more complex local setup. -# Performance Tests +## Test Structure -## Load Testing +Tests tend to increase in number over time and initial structure will help to work with them in the future. For example, organizing tests in suits matching core workflow (like connection, read/write operations) helps to use some of them in smoke tests. More granular tests help to combine them into more complex end-to-end scenarios. It may be useful +for troubleshooting. + +**Tests after Issues** + +It is bad practice to make tests just to verify some issue - always bound tests to a feature or a function. This help to verify test correctnes in the future. + +# Tests by Scope + +Test scope can be different depending on your strategy. Further we will talk about areas we see as important for test coverage and about some their specifics. . + +## Configuration + +We test different configurations in our libraries, but tests set values directly. Application configuration passes through additional steps before reaching the library, so verifying that it is correctly accepted by the client is important. We recommend combining configuration tests with core feature tests. Additionally, it is good to have simple client or driver initialization tests with all important configuration parameters set. Client has `com.clickhouse.client.api.Client#getConfiguration()` to retrieve all settings after creation. ClickHouse JDBC Connection provides access to the client via `com.clickhouse.jdbc.ConnectionImpl#getClient`. + +Test scopes - what to verify: +- Default configuration - proper work for your case. +- Value boundaries - does client allow set extreme value that you have in your design. +- Invalid values - does application stop them before passing to the client, does client handle them in way you expect. +- ClickHouse settings - are they correctly passed from user to database. +- Timeouts - do they have effect and passed in correct units (most common mistake). + +## Operations + +This section covers testing operations part of your workload. Even we have own tests connecting to ClickHouse Cloud it is still important to test it within +your application. There are many different parameters and conditions where integration breaks. + +### Connecting + +Test scopes - what to verify: +- Client need time to establish connection. Some applications has requirement to do it within certain timeout and set `connection_request_timeout`. It is important to test with multiple runs that timeout is long enough - do not fail periodically because connection took a few milliseconds longer. +- Client has internal connection pool and returns connection only when response objects is closed. Verify that it happens by setting limited number of connections via `max_open_connections` and repeating request more than that times. JDBC keeps internal connection per result set. When data is inserted - connection is closed internally after request is complete. +- Always do concurrent tests when client used in multi-threaded application. Most common use is backend application processing user request. Default value of `max_open_connections` may be too low for such application. + +### Fetching Data + +These tests relate to any data query operations. It is very useful to have collection of some real production queries to verify complex cases like one using CTE's. + +Test scopes - what to verify: +- Data types - correct conversion between DB and application data types. Here is important to check well know values and take some random (save random seed somewhere) +- Data formats - format support and correct work. Formats like CSV may have difference in behavior like handling `null`. +- Failures - verify retries and timeouts along with correct handling of Client exceptions. + +### Loading Data + +These tests relate to any data insert operations. + +Test scopes - what to verify: +- Data types - see "Fetching Data" +- Data formats - see "Fetching Data" +- Failure - verify correct handling of failure and correct handling of Client exceptions. +- Deduplication token - verify that correct deduplication token is set in `InsertSettings` and data is deduplicated correctly. + + +# Load Testing + +This kind of tests are design to understand when system breaks. It used to understand capacity, find bottlenecks, etc. Run load tests on a signle application instance to make load analysis easier. Load should grow gradually till system breaks. This will tell you: + +- What are the limits. +- Are there problems with your projected load. +- How application performance degrade with load. +- Estimate needed resources. + +Load tests can be done by increasing data volume or (if applicable) growth of concurent requests. Test with multiple load of big datasets in same instance if applicable. From 190679b0ffbc58339d704a842a24ff3db09fbfec Mon Sep 17 00:00:00 2001 From: Sergey Chernov Date: Fri, 18 Sep 2026 13:42:42 -0700 Subject: [PATCH 3/4] Cleaned up integration-testing.md to be more specific what tests are about and when envs to use --- docs/integration-testing.md | 66 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/docs/integration-testing.md b/docs/integration-testing.md index e9474be83..f089c9e49 100644 --- a/docs/integration-testing.md +++ b/docs/integration-testing.md @@ -11,28 +11,29 @@ Goal integration testing is to verify: Tests have great value as a contract verification tool when built properly. If there are tests for other integrations, we recommend porting them to verify ClickHouse integration. -# General Recommendations +## General Recommendations -## Environment +### Test Environment -Tests can be run in different environments: local, staging, production. Running tests locally is mainly for development and are essential. ClickHouse can be easily run as Docker container (see below). Tests running on staging environment is more important because they verify real systems integration. ClickHouse Cloud is cost effective so -running a test instance almost free compare to cost of missed issue. Staging environment is good for load testing because it gives real picture of how well systems -work. Local environment hardly can replicate cloud networking (what it crucial part): WiFi connecting developer's laptop is very unstable on physical level. Tests in production is also needed at least for two reasons: certify integration and find issues (failed tests points to a problem). +Environment where tests run defines what can be tested, what factors affecting test results. Environment should serve test purpose, it should be sufficient for +the test scope. Integration tests is our main focus because they verify intercommunication of two systems. This type of tests can be run on different stages of development and +in different environments. Following this an important requirement for tests comes - ability to run same tests with local and remote system in similar way. -**Example: Running ClickHouse in Docker** +Using Testcontainers is very convinient in local or CI test environment and it is very good start. Most features can be verified in this way. But integration is not limited +to local machine or CI usually thus tests should be able to run against real DB instances. It could be your customer's on-prem installation or ClickHouse Cloud instance. +Running tests against environment that is close to production is required step for solid integration because production system has much more moving parts than local host. +Here is a short list of obvious differences: +- Computation power +- Network connectivity +- Software versions -Start a local ClickHouse instance for testing: +Tests that can be executed against different target systems may help while troubleshooting. For example, running group of selected integration tests againts production system +may narrow search area. Tests can be a good step in verifying production systems, too. -```sh -docker run --rm -d -p 8123:8123 --name ch clickhouse/clickhouse-server -``` - -Stop it when done: - -```sh -docker stop ch -``` +Another requirement for good integration tests is to run against ClickHouse cluster. Distributed setup works differently in many ways. Your application may have +cluster aware logic. ClickHouse has many distributed table engines that work differently than traditional ones. ClickHouse is eventually consistent and this +property is well observed on cluster. **ClickHouse Version** @@ -48,20 +49,21 @@ and even valid SSL certificate will be seen as invalid because signed with new v Design test to be runnable against remote and local environment. ClickHouse can be run within [testcotnainer](https://testcontainers.com/) but external host configuration still useful to run same tests against staging or more complex local setup. -## Test Structure +### Test Structure Tests tend to increase in number over time and initial structure will help to work with them in the future. For example, organizing tests in suits matching core workflow (like connection, read/write operations) helps to use some of them in smoke tests. More granular tests help to combine them into more complex end-to-end scenarios. It may be useful for troubleshooting. -**Tests after Issues** +**Test Functionality** -It is bad practice to make tests just to verify some issue - always bound tests to a feature or a function. This help to verify test correctnes in the future. +Write tests for functinality. Tests work as contract in this case. For each new issue investigate what is worng: requirements changed, behavior changed, missed case. +Single issue only a signal that something is not integrated (not always broken). Making tests only for a single issue usually is not enough to resolve a problem. -# Tests by Scope +## Tests by Scope Test scope can be different depending on your strategy. Further we will talk about areas we see as important for test coverage and about some their specifics. . -## Configuration +### Configuration We test different configurations in our libraries, but tests set values directly. Application configuration passes through additional steps before reaching the library, so verifying that it is correctly accepted by the client is important. We recommend combining configuration tests with core feature tests. Additionally, it is good to have simple client or driver initialization tests with all important configuration parameters set. Client has `com.clickhouse.client.api.Client#getConfiguration()` to retrieve all settings after creation. ClickHouse JDBC Connection provides access to the client via `com.clickhouse.jdbc.ConnectionImpl#getClient`. @@ -71,20 +73,23 @@ Test scopes - what to verify: - Invalid values - does application stop them before passing to the client, does client handle them in way you expect. - ClickHouse settings - are they correctly passed from user to database. - Timeouts - do they have effect and passed in correct units (most common mistake). +- Different types of authentication - important for SSL authentication to verify certificats are accepted. -## Operations +### Operations This section covers testing operations part of your workload. Even we have own tests connecting to ClickHouse Cloud it is still important to test it within your application. There are many different parameters and conditions where integration breaks. -### Connecting + +#### Connecting Test scopes - what to verify: - Client need time to establish connection. Some applications has requirement to do it within certain timeout and set `connection_request_timeout`. It is important to test with multiple runs that timeout is long enough - do not fail periodically because connection took a few milliseconds longer. - Client has internal connection pool and returns connection only when response objects is closed. Verify that it happens by setting limited number of connections via `max_open_connections` and repeating request more than that times. JDBC keeps internal connection per result set. When data is inserted - connection is closed internally after request is complete. - Always do concurrent tests when client used in multi-threaded application. Most common use is backend application processing user request. Default value of `max_open_connections` may be too low for such application. +- Connecting to ClickHouse Cloud - instances can be in idle state. If it is expected - verify that application can handle it. -### Fetching Data +#### Fetching Data These tests relate to any data query operations. It is very useful to have collection of some real production queries to verify complex cases like one using CTE's. @@ -93,7 +98,7 @@ Test scopes - what to verify: - Data formats - format support and correct work. Formats like CSV may have difference in behavior like handling `null`. - Failures - verify retries and timeouts along with correct handling of Client exceptions. -### Loading Data +#### Loading Data These tests relate to any data insert operations. @@ -103,8 +108,7 @@ Test scopes - what to verify: - Failure - verify correct handling of failure and correct handling of Client exceptions. - Deduplication token - verify that correct deduplication token is set in `InsertSettings` and data is deduplicated correctly. - -# Load Testing +## Load Testing This kind of tests are design to understand when system breaks. It used to understand capacity, find bottlenecks, etc. Run load tests on a signle application instance to make load analysis easier. Load should grow gradually till system breaks. This will tell you: @@ -113,4 +117,10 @@ This kind of tests are design to understand when system breaks. It used to under - How application performance degrade with load. - Estimate needed resources. -Load tests can be done by increasing data volume or (if applicable) growth of concurent requests. Test with multiple load of big datasets in same instance if applicable. +Load tests are targeted on understanding whole application throughput. It is important to saturate application with load while tests. Here are a few examples: +- Application serves different kinds of requests (query different aggregated stats) - load tests should call them simulteniously +- Application has periodic tasks (sync from another db, cleanup) - load tests should verify scenario when all it happens. + +As one might see load tests in these examples targeted to exhaust resources. This kind of tests are important to verify that solution fits your system and design. +Loading big datasets need memory what is not compressable resource what means that memory can hold only certain amout of data. With Java this problem also complicated by +GC runs because when big chunk of heep with millions of objects should be GC'ed then it will require more CPU time, longer GC pause and pilling up other requests. \ No newline at end of file From 705b4f85ccb86f82a3833c99936a34909a9993f3 Mon Sep 17 00:00:00 2001 From: Sergey Chernov Date: Fri, 18 Sep 2026 14:03:42 -0700 Subject: [PATCH 4/4] Added references to integration-testing.md in client and jdbc parts --- docs/integration-client.md | 14 ++++++++++++-- docs/integration-jdbc.md | 17 ++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/integration-client.md b/docs/integration-client.md index 79ff66bc2..edc3a85a2 100644 --- a/docs/integration-client.md +++ b/docs/integration-client.md @@ -358,6 +358,8 @@ The mechanism follows from how the server and any fronting infrastructure are co Runtime rotation via `updateUserAndPassword` / `updateBearerToken` updates the credentials of the **already-selected** mechanism; it throws `ClientMisconfigurationException` rather than switching to a different mechanism. +See [integration-testing.md — Configuration](integration-testing.md#configuration) for what to verify when testing authentication end-to-end (boundary/invalid values, certificate acceptance). + --- ## Step 3 — Transport & connectivity (TLS, proxies, timeouts) @@ -374,7 +376,7 @@ Runtime rotation via `updateUserAndPassword` / `updateBearerToken` updates the c | Trust store (JKS/PKCS12) | `setSSLTrustStore(...)`, `setSSLTrustStorePassword(...)` | | HTTP proxy | `setProxy(ProxyType.HTTP, host, port)`, `setProxyCredentials(user, password)` | -See [SSLExamples](../examples/client-v2/src/main/java/com/clickhouse/examples/client_v2/SSLExamples.java) for a runnable walkthrough and [authentication.md](authentication.md) for full details. +See [SSLExamples](../examples/client-v2/src/main/java/com/clickhouse/examples/client_v2/SSLExamples.java) for a runnable walkthrough and [authentication.md](authentication.md) for full details. See also [integration-testing.md — Test Environment](integration-testing.md#test-environment) for testing across protocols, hosts, and ClickHouse versions. ### Init configuration — timeouts @@ -412,6 +414,8 @@ Key use cases include: > **Timeouts too aggressive** for heavy analytical queries cause spurious failures — align `socket_timeout` with expected query duration or use per-operation network timeouts. > > **Proxy credentials omitted** on authenticated proxies produce opaque connection failures. + +See [integration-testing.md — Connecting](integration-testing.md#connecting) for connection-timeout and concurrency test scenarios to cover. --- ## Step 4 — Connections Configuration @@ -420,7 +424,7 @@ In the Java Client a "connection" is an **HTTP connection borrowed from the inte ### Connection limit (`max_open_connections`) -The pool size depends on your workload — specifically on its **concurrency**, not on how much data it moves. What matters is **how many operations run at the same time**, not the number of rows or bytes any single operation transfers. A pool of 20 connections serves at most 20 simultaneous operations regardless of whether each returns one row or a million. This is the single setting you actually tune. The table below will help to estimate rough number. Having slightly bigger number than actualy needed is not a problem because unused connections will be garbage collected. It is recommended to perform a load testing with one application instance to detect if estimated number works. +The pool size depends on your workload — specifically on its **concurrency**, not on how much data it moves. What matters is **how many operations run at the same time**, not the number of rows or bytes any single operation transfers. A pool of 20 connections serves at most 20 simultaneous operations regardless of whether each returns one row or a million. This is the single setting you actually tune. The table below will help to estimate rough number. Having slightly bigger number than actualy needed is not a problem because unused connections will be garbage collected. It is recommended to perform a load testing with one application instance to detect if estimated number works — see [integration-testing.md — Load Testing](integration-testing.md#load-testing) for how to design that test. Connection limit may acts as a backpreasure for incomming requests if they get blocked by DB access. When request backlog grows it may also slowdowns whole application so it is very important to find a balance between concurrent operations and their execution time. Be aware that in most applications allocated memory is freed only at the end of request. @@ -480,6 +484,8 @@ public Client.Builder createBaseClient() { > **Stale connection errors (`NoHttpResponseException`):** Occurs when idle pooled connections are closed by server/proxy timeouts. Resolve by configuring `setKeepAliveTimeout` to be less than the server keep-alive duration. > > **CONSTRAINT:** Always `close()` the client at shutdown to avoid leaking the pool and its threads. + +See [integration-testing.md — Connecting](integration-testing.md#connecting) for tests that verify pool sizing (`max_open_connections`) and connection release under load. --- ## Step 5 — Data formats, readers & writers @@ -703,6 +709,8 @@ See the [Error model](#error-model) for the exception hierarchy and how to unwra | Server aborted an excessively heavy query | `ServerException` code `159` (`TIMEOUT_EXCEEDED`) | The query exceeded `max_execution_time`. Raise the limit or optimize the query; do not retry unconditionally. | | Transport connect/read timeout | `DataTransferException` / timeout | Often transient. A read is idempotent, so re-running the whole query is safe. | | Connection dropped **mid-stream** (after you began iterating) | `DataTransferException` while reading | You cannot resume from the middle — some rows were already consumed. Close the `QueryResponse` and re-run the entire query. Make consumers tolerant of re-reading from the start. | + +See [integration-testing.md — Fetching Data](integration-testing.md#fetching-data) for read-path test scenarios to cover (data types, formats, failure handling). --- ## Step 7 — Write operations & tuning @@ -858,6 +866,7 @@ public void insertWithDeduplication(Client client, InputStream dataStream, Strin - Assign a **stable** token per logical batch (file name, Kafka offset, job ID). - Use it for retry-safe pipelines and at-least-once sources (Kafka, SQS, file reprocessing). - Requires a `MergeTree` engine with deduplication configured. See [`InsertTests.testInsertSettingsDeduplicationToken`](../client-v2/src/test/java/com/clickhouse/client/insert/InsertTests.java). +- See [integration-testing.md — Loading Data](integration-testing.md#loading-data) for how to verify the deduplication token is set correctly and honored. ### Errors & how to handle them @@ -1110,3 +1119,4 @@ public void executeQueryWithErrorHandling(Client client, String sql) throws Exce - [integration-ops.md](integration-ops.md) — operations and observability guide - [authentication.md](authentication.md) — full authentication and TLS reference (referenced from Steps 2–3) - [features.md](features.md) — compatibility contract (referenced from Step 5) +- [integration-testing.md](integration-testing.md) — integration testing recommendations and practices diff --git a/docs/integration-jdbc.md b/docs/integration-jdbc.md index 4557d503c..d23b1ebcb 100644 --- a/docs/integration-jdbc.md +++ b/docs/integration-jdbc.md @@ -259,6 +259,8 @@ LIMIT 100; - **`Connection.close()`** closes the underlying `Client` and its HTTP pool — expected when returning to a pool. + +See [integration-testing.md — Connecting](integration-testing.md#connecting) for tests that verify pool sizing (`max_open_connections`) and connection release under load. --- ## Step 2 — Authentication @@ -344,6 +346,8 @@ public Connection createCustomHeadersConnection() throws SQLException { - **Credentials embedded in the JDBC URL** leak into logs and connection-pool config dumps — use `Properties`. + +See [integration-testing.md — Configuration](integration-testing.md#configuration) for what to verify when testing authentication end-to-end (boundary/invalid values, certificate acceptance). --- ## Step 3 — Transport & connectivity (TLS, proxies, timeouts) @@ -360,7 +364,7 @@ public Connection createCustomHeadersConnection() throws SQLException { | Trust store | `trust_store`, `key_store_password`, `key_store_type` | | HTTP proxy | `proxy_type=http`, `proxy_host`, `proxy_port`, `proxy_user`, `proxy_password` | -See [examples/jdbc SSLExamples](../examples/jdbc/src/main/java/com/clickhouse/examples/jdbc/SSLExamples.java) and [authentication.md](authentication.md). +See [examples/jdbc SSLExamples](../examples/jdbc/src/main/java/com/clickhouse/examples/jdbc/SSLExamples.java) and [authentication.md](authentication.md). See also [integration-testing.md — Test Environment](integration-testing.md#test-environment) for testing across protocols, hosts, and ClickHouse versions. ### Init configuration — server vs client settings @@ -398,6 +402,8 @@ public boolean checkConnectionHealth(Connection conn, int timeoutSeconds) throws - **Proxy credentials omitted** on authenticated proxies produce opaque connection failures. + +See [integration-testing.md — Connecting](integration-testing.md#connecting) for connection-timeout and concurrency test scenarios to cover. --- ## Step 4 — Formats under the hood @@ -511,6 +517,8 @@ This hybrid approach allows you to use standard JDBC for simple CRUD and metadat - **Text INSERT overhead** — default SQL-based inserts are slower than binary streaming. Use the [Java Client](integration-client.md) for maximum throughput. + +See [integration-testing.md — Fetching Data](integration-testing.md#fetching-data) and [Loading Data](integration-testing.md#loading-data) for data-format test scenarios to cover. --- ## Step 5 — Read operations & tuning @@ -593,6 +601,8 @@ public void readSpecialTypes(ResultSet rs) throws SQLException { - **Some frameworks materialize all rows** even though the driver streams — watch memory. + +See [integration-testing.md — Fetching Data](integration-testing.md#fetching-data) for read-path test scenarios to cover (data types, formats, failure handling). --- ## Step 6 — Write operations & tuning @@ -674,7 +684,7 @@ public void insertWithPerStatementDedup(Connection conn, String token) throws SQ **2. Switch to the Java Client** for per-insert token control via `InsertSettings.setDeduplicationToken(...)`. -See [integration-client.md — deduplication token](integration-client.md#idempotency--deduplication-token) for semantics and requirements. +See [integration-client.md — deduplication token](integration-client.md#idempotency--deduplication-token) for semantics and requirements, and [integration-testing.md — Loading Data](integration-testing.md#loading-data) for how to verify the token is set correctly and honored. ### Best practices @@ -891,4 +901,5 @@ For a complete sample demonstrating JDBC driver setup and telemetry in a Spring - [integration-ops.md](integration-ops.md) — operations and observability guide - [authentication.md](authentication.md) — full authentication and TLS reference - [features.md](features.md) — compatibility contract -- [type_mapping.md](../type_mapping.md) — JDBC type mapping recommendations \ No newline at end of file +- [type_mapping.md](../type_mapping.md) — JDBC type mapping recommendations +- [integration-testing.md](integration-testing.md) — integration testing recommendations and practices \ No newline at end of file