Files
seaweedfs/test/s3/lifecycle
Chris Lu a4479a927e test(s3/lifecycle): integration coverage for versioning + filters
First integration-test bundle building on the existing single-test
backdating harness. Each scenario follows the same shape: create
bucket, set lifecycle, PUT object, backdate mtime via filer
UpdateEntry, run the shell command for one shard sweep, assert
S3-side state.

Five new tests:

- TestLifecycleVersionedBucketCreatesDeleteMarker: Expiration on a
  versioned bucket must produce a delete marker (latest after worker
  runs is a marker) AND keep the original version directly addressable
  by versionId. ListObjectVersions confirms IsLatest=true on the
  marker.

- TestLifecycleNoncurrentVersionExpiration: NoncurrentVersionExpiration
  fires only on demoted versions. PUT v1, PUT v2 (so v1 → noncurrent),
  backdate v1, run worker. v1 must be gone, v2 still current.

- TestLifecycleExpiredDeleteMarkerCleanup: combined rule (noncurrent +
  expired-delete-marker) cleans up a sole-survivor marker. PUT v1,
  DELETE (creates marker), backdate both, run worker. Every version
  AND marker must be gone for the key.

- TestLifecycleDisabledRuleSkipsObject: rule with Status=Disabled
  must not produce dispatches even on a backdated match. Negative
  test for the engine's enabled-status gate.

- TestLifecycleTagFilter: rule with And{Prefix, Tag} only matches
  objects carrying the tag. Two backdated objects (one tagged, one
  not) — only the tagged one is removed.

Helpers extracted to keep each test focused: putVersioningEnabled,
putNoncurrentExpirationLifecycle, putExpiredDeleteMarkerLifecycle,
backdateVersionedMtime (ages a specific .versions/v_<id> entry),
runLifecycleShard (one-shot shell invocation with FATAL guard).
2026-05-09 22:36:28 -07:00
..

S3 Lifecycle Integration Tests

End-to-end test of the event-driven S3 lifecycle worker, exercised through the s3.lifecycle.run-shard shell command.

Why backdate mtimes?

The S3 API rejects Expiration.Days < 1, so a literal "wait one day" integration test isn't workable. Each test sets up a 1-day expiration rule, puts the target object, then rewrites its filer entry's Mtime to ~30 days ago via filer_pb.UpdateEntry. From the engine's perspective the object is past its expiration window the moment the shell command starts.

Running

# build the binary, start a local mini cluster, run tests, stop it
make test-with-server

# or, if a cluster is already running on the default ports
make test

The test runs the shell command once with -shards 0-15 (one filer subscription covering all 16 shards) rather than computing the target object's shard up front. This keeps the test independent of the ShardID(bucket, key) hash function — only that some shard reaches the deletion within the polling window.

Environment

variable default description
WEED_BINARY required path to weed_binary
S3_ENDPOINT http://localhost:8333 S3 API URL
S3_GRPC_ENDPOINT localhost:18333 S3 gRPC for lifecycle dispatch
MASTER_ENDPOINT http://localhost:9333 master HTTP
FILER_GRPC_ADDRESS localhost:18888 filer gRPC for UpdateEntry