This was generated by AI during triage.
Problem
The library's existing tests exercise endpoints and response fixtures, but requester tests mock HttpsURLConnection. They do not verify the complete path from KrakenAPI through request encoding, signing, real HTTPS transport, and response parsing. Tests running against project classes also cannot establish that the published JAR and POM work for downstream consumers or remain compatible with a previous release.
Add tests at those boundaries. Unit-test coverage is already being handled separately; this issue excludes the examples module.
1. Local HTTPS integration and protocol contract tests
Use JUnit Jupiter, AssertJ, and a local WireMock HTTPS server with a dynamically allocated port. Keep the facade, endpoints, serializers, credentials/signing, requester, and response parsing real. Use dummy credentials and deterministic nonces; these tests must not contact Kraken.
Use the existing package-private DefaultKrakenRestRequester.ConnectionFactory seam. Place the test harness in dev.andstuff.kraken.api.rest and inject a factory that opens a real HttpsURLConnection to the local server, replacing only the host and port while preserving the encoded path and query. Configure certificate trust on those test connections and retain hostname verification; avoid changing global TLS defaults.
Assert both the request received by the server and the result or exception returned to the caller. Cover each distinct protocol instead of duplicating every endpoint's unit tests:
| Request/response path |
Required checks |
| Public GET |
Method, encoded query, no authentication headers, typed result |
| Private form POST |
Form fields, nonce, content type, authentication headers, signature |
| Private JSON POST |
Arrays and nested objects, numeric nonce, exact signed and transmitted body bytes |
| Funding Beta |
GET/POST/PUT/DELETE, encoded path segments, bracketed query parameters, optional JSON body, API-Nonce, signature including the query, unwrapped response |
| Report download |
Actual ZIP response through CSV parsing into ledger records |
| Public extension APIs |
Representative enum-based, raw-path, and custom-endpoint calls through the facade |
Verify signatures against fixed independently generated vectors or an independent verifier operating on captured request bytes. Do not calculate expected signatures with the production signing method. Include Unicode and reserved characters where the relevant fields permit them.
Reuse documented response fixtures already in the repository and retain their upstream source/version provenance. Expected responses must not be generated by serializing the library's own records. Pinned fixtures establish compatibility with that contract snapshot; they do not prove the current provider still conforms to it.
2. Transport failures and robustness
Reuse the HTTPS harness to cover Kraken error envelopes, Funding Beta HTTP errors, empty error bodies, HTTP 429/500 responses, malformed JSON, truncated ZIP responses, missing content types, and application/json; charset=utf-8.
Use WireMock fault simulation for disconnects and delayed responses. Assert the caller-visible exception, preservation of useful error information, and request counts after failures, especially for order and withdrawal operations where an unintended resubmission matters.
Specify intended behavior before encoding it as an acceptance test. Two current implementation details deserve particular attention:
- Legacy response parsing requires an exact content-type match, whereas Funding Beta accepts a JSON content type with parameters.
- The default requester configures no connection or read timeouts. Define the intended timeout contract before testing bounded completion. Timeouts injected only by the test factory protect the harness but do not establish bounded behavior for the default client.
Give fault tests bounded execution and deterministic cleanup so a regression cannot hang CI.
3. Concurrency integration tests
Share one KrakenAPI across concurrent requests to the local server. Use barriers or latches rather than sleeps, initially use separate parameter objects and an atomic nonce generator, and verify that every captured request retains its own payload, nonce, signature, and corresponding response.
The facade documents that it can be shared when its requester and nonce generator can be shared. The default EpochBasedNonceGenerator uses System.currentTimeMillis(), which does not guarantee unique nonces for rapid calls. PrivateEndpoint.encodedParamsWith() also mutates the supplied parameters. Establish the supported concurrency contract and include shared-parameter reuse only if it is supported. Do not assume nonce generation order guarantees network arrival order.
4. Published-artifact and backward compatibility
Configure japicmp to compare the candidate library JAR with an explicitly pinned released version, checking public source and binary compatibility across methods, constructors, records, builders, and extension interfaces. Deliberate breaking changes require an explicit compatibility-policy or baseline update rather than blanket suppression.
Add a minimal downstream consumer project under library/src/it, executed with Maven Invoker. Install the candidate library and its required parent POM into an isolated test repository. The consumer must resolve the artifact and its declared transitive dependencies without using the workspace's target/classes, compile using only public APIs, and execute representative calls with a custom requester and custom endpoint.
Include a consumer implementing the legacy requester interface to protect the Funding Beta default-method compatibility behavior. Also run a small consumer compiled against the pinned previous release with the candidate JAR to exercise binary compatibility without recompiling that consumer.
5. Optional live Kraken smoke tests
Keep a small explicitly enabled suite for public endpoints such as server time, system status, and ticker. Assert structural invariants and successful decoding, not exact prices or a permanently online status. This suite can run manually or in a separate scheduled job to detect upstream drift.
Live tests must be excluded from ordinary PR checks. Any private smoke suite is a separate opt-in using read-only credentials. Trading and funding mutations remain confined to the local server.
Maven and CI implementation
- Keep existing unit tests named
*Test; name local integration tests *IT under library/src/test/java.
- Add Maven Failsafe with its
integration-test and verify goals in the library module.
- Exclude live tests by default using a distinct tag or naming convention and enable them through a dedicated profile.
- Run deterministic integration, protocol, concurrency, artifact, and compatibility checks in the library CI job. Change that job to reach
verify; package stops before Failsafe runs.
- Use Java 25 and select only the library plus its reactor prerequisites, excluding
examples.
Local command after configuration:
JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home ~/.local/bin/mvnd -B -pl library -am clean verify
CI can use mvn -B -pl library -am clean verify with its configured Java 25 installation.
Acceptance criteria
References
Problem
The library's existing tests exercise endpoints and response fixtures, but requester tests mock
HttpsURLConnection. They do not verify the complete path fromKrakenAPIthrough request encoding, signing, real HTTPS transport, and response parsing. Tests running against project classes also cannot establish that the published JAR and POM work for downstream consumers or remain compatible with a previous release.Add tests at those boundaries. Unit-test coverage is already being handled separately; this issue excludes the
examplesmodule.1. Local HTTPS integration and protocol contract tests
Use JUnit Jupiter, AssertJ, and a local WireMock HTTPS server with a dynamically allocated port. Keep the facade, endpoints, serializers, credentials/signing, requester, and response parsing real. Use dummy credentials and deterministic nonces; these tests must not contact Kraken.
Use the existing package-private
DefaultKrakenRestRequester.ConnectionFactoryseam. Place the test harness indev.andstuff.kraken.api.restand inject a factory that opens a realHttpsURLConnectionto the local server, replacing only the host and port while preserving the encoded path and query. Configure certificate trust on those test connections and retain hostname verification; avoid changing global TLS defaults.Assert both the request received by the server and the result or exception returned to the caller. Cover each distinct protocol instead of duplicating every endpoint's unit tests:
API-Nonce, signature including the query, unwrapped responseVerify signatures against fixed independently generated vectors or an independent verifier operating on captured request bytes. Do not calculate expected signatures with the production signing method. Include Unicode and reserved characters where the relevant fields permit them.
Reuse documented response fixtures already in the repository and retain their upstream source/version provenance. Expected responses must not be generated by serializing the library's own records. Pinned fixtures establish compatibility with that contract snapshot; they do not prove the current provider still conforms to it.
2. Transport failures and robustness
Reuse the HTTPS harness to cover Kraken error envelopes, Funding Beta HTTP errors, empty error bodies, HTTP 429/500 responses, malformed JSON, truncated ZIP responses, missing content types, and
application/json; charset=utf-8.Use WireMock fault simulation for disconnects and delayed responses. Assert the caller-visible exception, preservation of useful error information, and request counts after failures, especially for order and withdrawal operations where an unintended resubmission matters.
Specify intended behavior before encoding it as an acceptance test. Two current implementation details deserve particular attention:
Give fault tests bounded execution and deterministic cleanup so a regression cannot hang CI.
3. Concurrency integration tests
Share one
KrakenAPIacross concurrent requests to the local server. Use barriers or latches rather than sleeps, initially use separate parameter objects and an atomic nonce generator, and verify that every captured request retains its own payload, nonce, signature, and corresponding response.The facade documents that it can be shared when its requester and nonce generator can be shared. The default
EpochBasedNonceGeneratorusesSystem.currentTimeMillis(), which does not guarantee unique nonces for rapid calls.PrivateEndpoint.encodedParamsWith()also mutates the supplied parameters. Establish the supported concurrency contract and include shared-parameter reuse only if it is supported. Do not assume nonce generation order guarantees network arrival order.4. Published-artifact and backward compatibility
Configure japicmp to compare the candidate library JAR with an explicitly pinned released version, checking public source and binary compatibility across methods, constructors, records, builders, and extension interfaces. Deliberate breaking changes require an explicit compatibility-policy or baseline update rather than blanket suppression.
Add a minimal downstream consumer project under
library/src/it, executed with Maven Invoker. Install the candidate library and its required parent POM into an isolated test repository. The consumer must resolve the artifact and its declared transitive dependencies without using the workspace'starget/classes, compile using only public APIs, and execute representative calls with a custom requester and custom endpoint.Include a consumer implementing the legacy requester interface to protect the Funding Beta default-method compatibility behavior. Also run a small consumer compiled against the pinned previous release with the candidate JAR to exercise binary compatibility without recompiling that consumer.
5. Optional live Kraken smoke tests
Keep a small explicitly enabled suite for public endpoints such as server time, system status, and ticker. Assert structural invariants and successful decoding, not exact prices or a permanently online status. This suite can run manually or in a separate scheduled job to detect upstream drift.
Live tests must be excluded from ordinary PR checks. Any private smoke suite is a separate opt-in using read-only credentials. Trading and funding mutations remain confined to the local server.
Maven and CI implementation
*Test; name local integration tests*ITunderlibrary/src/test/java.integration-testandverifygoals in the library module.verify;packagestops before Failsafe runs.examples.Local command after configuration:
JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home ~/.local/bin/mvnd -B -pl library -am clean verifyCI can use
mvn -B -pl library -am clean verifywith its configured Java 25 installation.Acceptance criteria
verify, runs the intended suites, and excludesexamplesand live Kraken access.References