mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-31 17:30:42 +01:00
* test/s3vectors: data-plane lifecycle integration test TestVectorDataPlaneLifecycle spawns a real weed-vector against the lance listener, mirrors the pytest cluster's flags, waits for the gateway to discover the registered engine, and walks the full lifecycle: create bucket and index, put/get/list vectors, a filtered query that excludes the nearer non-matching vector, delete vectors, index, and bucket. The test skips when no engine binary resolves (VECTOR_BINARY, ./weed-vector, PATH). * test/s3vectors: fail fast when the engine dies before listening * test/s3vectors: harden engine launch and tighten lifecycle assertions * test/s3vectors: wait on the engine's exit once through a broadcast channel
87 lines
4.5 KiB
Markdown
87 lines
4.5 KiB
Markdown
# S3 Vectors integration tests — design
|
|
|
|
## Goal
|
|
|
|
Cover the vector-bucket API surface end-to-end against a real `weed` server —
|
|
the path no unit or handler-level test exercises: HTTP dispatch on
|
|
`X-Amz-Target` / per-path routing, authentication, catalog persistence,
|
|
policy enforcement, and (when a vector engine is reachable) the data plane.
|
|
|
|
## Layout
|
|
|
|
test/s3vectors/
|
|
DESIGN.md this file
|
|
s3vectors_integration_test.go environment + test cases
|
|
|
|
Conventions follow `test/s3tables/sts_integration`: a `TestEnvironment`
|
|
brings up `weed server` (master + filer + volume + s3) on testutil-allocated
|
|
ports against a temp data dir, the test drives the JSON API over real HTTP,
|
|
and `testing.Short()` skips the suite.
|
|
|
|
## What the test covers
|
|
|
|
### Tier 1 — no vector engine required (runs everywhere)
|
|
|
|
These ops resolve through the catalog and the vector policy layer without an
|
|
engine RPC, so they work against a plain `weed server`:
|
|
|
|
- `CreateVectorBucket` / `GetVectorBucket` / `ListVectorBuckets` /
|
|
`DeleteVectorBucket` — happy path, `encryptionConfiguration` round-trip
|
|
(`sseType` -> stored `sseAlgorithm` -> echoed back as `sseType`), format
|
|
filtering (an explicit non-Lance bucket is not a vector bucket).
|
|
- `PutVectorBucketPolicy` / `GetVectorBucketPolicy` / `DeleteVectorBucketPolicy`
|
|
— the caller's document round-trips verbatim; `s3vectors:` actions are
|
|
accepted, foreign-service actions/ARNs rejected; `NotAction`/`NotResource`
|
|
rejected.
|
|
- Policy **enforcement** through the gateway: a non-owner `PutVectors` /
|
|
`GetVectors` is denied without a grant, an `Allow` on
|
|
`arn:aws:s3vectors:...:bucket/B/*` grants, a `Deny` vetoes an `Allow` on the
|
|
same action, deletion restores owner-only access — the same lifecycle the
|
|
package-level conformance test covers, but through signed HTTP requests.
|
|
- Validation boundaries: `maxResults` caps, `topK` bounds, `dataType`
|
|
rejection, `dimension` range, empty/oversize PutVectors batches (these fail
|
|
before the engine is touched, so they work engine-less too).
|
|
|
|
### Tier 2 — vector engine required (skipped when absent)
|
|
|
|
`TestVectorDataPlaneLifecycle` spawns a real `weed-vector` against the
|
|
environment's lance listener (`-s3.port.lance`), mirroring the cluster the
|
|
pytest suite builds in `conftest.py`: `--namespace` points at the lance
|
|
HTTP port, `--masters` at `master.http.grpc`, and the storage options carry
|
|
the same test credentials the IAM config writes. The binary resolves as
|
|
`VECTOR_BINARY` env → `./weed-vector` (the Makefile's output) → PATH; the
|
|
test skips when none is found, and `waitForEngineDiscovery` polls a
|
|
data-plane op until the gateway routes to the registered engine instead of
|
|
503. The test then walks the full lifecycle: `CreateVectorBucket` →
|
|
`CreateIndex` → `PutVectors` → `GetVectors` → `ListVectors` → filtered
|
|
`QueryVectors` → `DeleteVectors` → `DeleteIndex` → `DeleteVectorBucket`.
|
|
|
|
## Harness
|
|
|
|
- `NewTestEnvironment` mirrors `sts_integration`: locate the `weed` binary
|
|
(built `weed/weed` first, then PATH), allocate ports with `testutil`
|
|
(`MustFreeMiniPorts`, since `weed server` derives each gRPC port as
|
|
HTTP+10000), spawn `weed server -dir=<tmp> -master.port -volume.port
|
|
-filer -s3.port` against a written `-s3.config` identity file, disable
|
|
the unused Iceberg/Lance listeners, wait for the S3 port to serve
|
|
`/status`, then run requests. The vectors router rides the S3 port
|
|
automatically once the gateway can reach a master — no extra flag.
|
|
- Requests are signed SigV4 with the `s3vectors` service name — the gateway
|
|
routes vectors traffic on the service name in the credential scope, so an
|
|
unsigned or `s3`-signed request never reaches the vectors router. A small
|
|
`vectorsClient` helper wraps POST + `X-Amz-Target`/`/op` + signing +
|
|
status-code assertions; identities vary per-request for policy tests.
|
|
- `Cleanup` kills the process group and removes the temp dir.
|
|
- `TestMain`-less design: each test builds its own environment so a hung
|
|
server can't take down the suite; `t.Parallel()` is deliberately avoided —
|
|
port allocation is cheap but vector-engine bring-up is not.
|
|
|
|
## Not covered here (by design)
|
|
|
|
- Auth failure modes (expired creds, bad signatures) — covered by the
|
|
`sts_integration` suite and the s3api auth tests; the vectors router shares
|
|
the same `iam.AuthenticateRequest` path.
|
|
- Lance/segment internals — the package's `listSegmentVectors` unit tests and
|
|
the engine's own suite cover them; the integration layer only asserts the
|
|
API contract.
|