Skip to content

test(opensearch3): expand HttpClient action coverage and fix 3 latent bugs#34

Merged
marevol merged 1 commit into
mainfrom
test/opensearch3-client-coverage
Jul 9, 2026
Merged

test(opensearch3): expand HttpClient action coverage and fix 3 latent bugs#34
marevol merged 1 commit into
mainfrom
test/opensearch3-client-coverage

Conversation

@marevol

@marevol marevol commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Overview

OpenSearch3ClientTest was already the most complete of the five backend integration suites, so this PR closes the remaining gap against the registered-action API surface: several Http*Actions wired in HttpClient had no coverage anywhere. Adding end-to-end tests for them (against a real OpenSearch 3.7 Testcontainer) surfaced three latent, previously-untested production bugs, which are fixed here.

New / enhanced tests (OpenSearch3ClientTest)

  • Task management / diagnostics smoke tests: test_list_tasks, test_get_task, test_cancel_tasks, test_nodes_usage, test_remote_info, test_upgrade_status.
  • Snapshot & repository lifecycle: test_crud_snapshot_repository (put → verify → get → delete) and test_snapshot_lifecycle (create → status → get → restore → delete, asserting the restored doc is searchable). startServer() now sets path.repo so an fs repository can be registered; teardown uses two independent delete blocks so one cleanup failure cannot leak the other resource.
  • Engine detection: test_engine_info asserts the live client detects OPENSEARCH3.
  • Depth improvements: test_pit_lifecycle now runs a PIT-backed search and asserts it reads the captured documents; test_stats now asserts the serialized NodesStatsResponse XContent is non-empty; test_upgrade_status asserts real (non-zero) byte totals.

Bug fixes surfaced by the new coverage

1. HttpPutRepositoryAction sent no request body.
PUT /_snapshot/{name} was issued without a body, so the server rejected it with 400 parse_exception: request body is required — the action never worked. It now serializes the repository type/settings via request.toXContent(...), mirroring HttpCreateSnapshotAction. Adds HttpPutRepositoryActionTest.

2. HttpUpgradeStatusAction always returned empty data.
fromXContent looked for a top-level _shards object that the _upgrade response never emits and always serialized zero ShardUpgradeStatus entries, so getIndices() was always empty and all byte/shard counts were 0. It also wrote the BroadcastResponse header with writeInt where the wire format reads writeVInt (only "worked" because every value was zero). It now parses the per-index aggregate byte counts (size_in_bytes / size_to_upgrade_in_bytes / size_to_upgrade_ancient_in_bytes) and reconstructs the response so getTotalBytes() and the per-index sizes are correct. Because the _upgrade API exposes no per-shard routing (detailed=true is rejected on 3.7), the reconstruction synthesizes one shard per index; the shard routing is therefore artificial and only the byte totals are meaningful — this is documented in the code. Adds HttpUpgradeStatusActionTest.

3. HttpSearchAction hung on point-in-time searches.
It emitted ccs_minimize_roundtrips and the index options (ignore_unavailable / allow_no_indices / expand_wildcards) unconditionally. OpenSearch rejects both together with a point-in-time search (400 "... cannot be used with point in time"), and over this HTTP client a 400 on a request that carries a body manifests as an indefinite hang. It now omits both when the request carries a PIT (a PIT already binds its own indices). Non-PIT searches are byte-identical, so all other engines are unaffected. Extends HttpSearchActionTest.

Testing

  • OpenSearch3ClientTest: 88/88 green (Docker, OpenSearch 3.7.0).
  • Offline unit suite (all engines' request-building + node/engine tests): 340/340 green.
  • mvn formatter:format license:format applied.

Notes / out of scope

  • The sibling HttpUpgradeAction (the POST /_upgrade action, no integration coverage here) has the same writeInt-vs-writeVInt header issue; left untouched to keep this change scoped.
  • The PIT-search fix guards the two parameter groups OpenSearch actually rejects with a PIT; other search parameters are unchanged.

… bugs

Add integration tests to OpenSearch3ClientTest for previously untested
registered actions (list/get/cancel tasks, nodes usage, remote info,
upgrade status, snapshot/repository lifecycle, engine detection), plus
depth improvements (PIT-backed search, stats XContent assertion).
Exercising these actions end-to-end surfaced three latent bugs, now fixed:

- HttpPutRepositoryAction never sent the request body, so PUT
  /_snapshot/{name} failed with 400 "request body is required". It now
  serializes the repository type/settings via request.toXContent, matching
  HttpCreateSnapshotAction. Adds HttpPutRepositoryActionTest.

- HttpUpgradeStatusAction.fromXContent looked for a _shards section the
  _upgrade response never emits and always wrote zero shards, so the
  response was always empty; it also wrote the broadcast header with
  writeInt where the wire format reads writeVInt. It now parses the
  per-index aggregate byte counts and reconstructs the response so
  getTotalBytes and the per-index sizes are correct (per-shard routing is
  synthetic because the API exposes none). Adds HttpUpgradeStatusActionTest.

- HttpSearchAction emitted ccs_minimize_roundtrips and index options
  unconditionally, which OpenSearch rejects together with a point-in-time
  search (400), manifesting as an indefinite hang over HTTP. It now omits
  both when the request carries a PIT. Extends HttpSearchActionTest.

Verified: OpenSearch3ClientTest 88/88 green (Docker) and the offline unit
suite 340/340 green.
@marevol marevol merged commit 131d8cc into main Jul 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant