Files
seaweedfs/test/erasure_coding
Chris Lu 8ac5133abe admin: default to port 12535, keep 23646 as a best-effort compat listener (#11816)
* admin: default to port 12535, keep 23646 as a best-effort compat listener

The default admin HTTP port 23646 derives a worker gRPC port of 33646
(port + GrpcPortOffset), inside the Linux default ephemeral range
(32768+). One of our own startup dials can claim 33646 before the admin
binds it, killing startup. This is the same failure #10209 fixed for
the test port allocator, still reachable via the mini default (#10838)
and via standalone `weed admin` defaults.

Move the default admin port to 12535 (gRPC 22535) everywhere, keeping
the http+10000 convention so worker -admin derivation, the Rust worker
and host:http.grpc addressing keep working:

- weed admin -port, weed mini -admin.port
- weed worker -admin, the plugin worker fallback, Rust worker and
  weed-lance-worker defaults
- help text, README, helm values, docker compose, tests

So old workers, bookmarks and scripts keep working, admin also serves
the same handler and the worker gRPC server on the previous default
(-port.legacy / -admin.port.legacy, default 23646, 0 disables). The
legacy gRPC port binds best-effort: it lives in the ephemeral range, so
a failed bind only warns instead of reintroducing the startup failure.
weed mini reserves it early like the primary port and keeps it out of
its own port relocation. grpc.Server tracks every listener handed to
Serve, so the compat listener stops with the primary.

Also warn when an explicitly configured admin port puts the derived
gRPC port at or above the ephemeral floor, the other fix suggested in
the issue.

Supersedes the pinned-grpc approach in #11814: pinning -admin.port.grpc
off the +10000 convention breaks external workers that derive the admin
gRPC port from the HTTP address. ClickHouse/ClickHouse#115512 pins
-admin.port on their side; this makes that pin unnecessary.

Fixes #10838

* admin: let services win the legacy ports, close compat listener on failure

Review findings on the compat listeners:

- Do not put the legacy ports in mini's reservedPorts: an explicit
  -s3.port=23646 or -master.port.grpc=33646 must be honored, not rejected
  or stolen by the early reservation. Mini now checks the finalized port
  set and skips only the conflicting compat listener, so HTTP and gRPC
  compat degrade independently and the service keeps its port.
- Also skip the legacy HTTP listener when a mini service owns the port:
  a wildcard-bound service can still leave loopback bindable, which would
  let the compat listener shadow it for loopback clients.
- Close legacyServer's raw listener in the deferred cleanup: Serve may
  not have registered it yet when startAdminServer returns early.
- Helm: add admin.legacyPort (default 23646) and expose the legacy
  http/grpc ports through the admin Service, container ports and
  NetworkPolicy so older workers resolved via the Service keep working.

* helm: only pass -port.legacy when it differs from the binary default

ct install deploys the released image with the new chart, and 4.48 does
not know -port.legacy, so the admin pod crash-loops. Omitting the flag at
the default value is behavior-identical on new binaries (their default
is also 23646) and keeps older releases installable; legacyPort: 0 or a
custom port still renders the flag.
2026-10-18 21:21:05 -07:00
..

Erasure Coding Integration Tests

This directory contains integration tests for the EC (Erasure Coding) encoding volume location timing bug fix.

The Bug

The bug caused double storage usage during EC encoding because:

  1. Silent failure: Functions returned nil instead of proper error messages
  2. Timing race condition: Volume locations were collected AFTER EC encoding when master metadata was already updated
  3. Missing cleanup: Original volumes weren't being deleted after EC encoding

This resulted in both original .dat files AND EC .ec00-.ec13 files coexisting, effectively doubling storage usage.

The Fix

The fix addresses all three issues:

  1. Fixed silent failures: Updated doDeleteVolumes() and doEcEncode() to return proper errors
  2. Fixed timing race condition: Created doDeleteVolumesWithLocations() that uses pre-collected volume locations
  3. Enhanced cleanup: Volume locations are now collected BEFORE EC encoding, preventing the race condition

Integration Tests

TestECEncodingVolumeLocationTimingBug

The main integration test that:

  • Simulates master timing race condition: Tests what happens when volume locations are read from master AFTER EC encoding has updated the metadata
  • Verifies fix effectiveness: Checks for the "Collecting volume locations...before EC encoding" message that proves the fix is working
  • Tests multi-server distribution: Runs EC encoding with 6 volume servers to test shard distribution
  • Validates cleanup: Ensures original volumes are properly cleaned up after EC encoding

TestECEncodingMasterTimingRaceCondition

A focused test that specifically targets the master metadata timing race condition:

  • Simulates the exact race condition: Tests volume location collection timing relative to master metadata updates
  • Detects timing fix: Verifies that volume locations are collected BEFORE EC encoding starts
  • Demonstrates bug impact: Shows what happens when volume locations are unavailable after master metadata update

TestECEncodingRegressionPrevention

Regression tests that ensure:

  • Function signatures: Fixed functions still exist and return proper errors
  • Timing patterns: Volume location collection happens in the correct order

Test Architecture

The tests use:

  • Real SeaweedFS cluster: 1 master server + 6 volume servers
  • Multi-server setup: Tests realistic EC shard distribution across multiple servers
  • Timing simulation: Goroutines and delays to simulate race conditions
  • Output validation: Checks for specific log messages that prove the fix is working

Why Integration Tests Were Necessary

Unit tests could not catch this bug because:

  1. Race condition: The bug only occurred in real-world timing scenarios
  2. Master-volume server interaction: Required actual master metadata updates
  3. File system operations: Needed real volume creation and EC shard generation
  4. Cleanup timing: Required testing the sequence of operations in correct order

The integration tests successfully catch the timing bug by:

  • Testing real command execution: Uses actual ec.encode shell command
  • Simulating race conditions: Creates timing scenarios that expose the bug
  • Validating output messages: Checks for the key "Collecting volume locations...before EC encoding" message
  • Monitoring cleanup behavior: Ensures original volumes are properly deleted

Running the Tests

# Run all integration tests
go test -v

# Run only the main timing test
go test -v -run TestECEncodingVolumeLocationTimingBug

# Run only the race condition test
go test -v -run TestECEncodingMasterTimingRaceCondition

# Skip integration tests (short mode)
go test -v -short

Manual Testing with Makefile

A Makefile is provided for manual EC testing.

Requirements: curl, jq (command-line JSON processor)

# Quick start: start cluster and populate data
make setup

# Open weed shell to run EC commands
make shell

# Individual targets
make start      # Start test cluster (master + 6 volume servers + filer)
make stop       # Stop test cluster
make populate   # Populate ~300MB of test data
make status     # Show cluster and EC shard status
make clean      # Stop cluster and remove all test data
make help       # Show all targets

EC Rebalance Limited Slots (Unit Test)

The "no free ec shard slots" issue is tested with a unit test that works directly on topology data structures without requiring a running cluster.

Location: weed/shell/ec_rebalance_slots_test.go

Tests included:

  • TestECRebalanceWithLimitedSlots: Tests a topology with 6 servers, 7 EC volumes (98 shards)
  • TestECRebalanceZeroFreeSlots: Reproduces the exact 0 free slots scenario

Known Issue: When volume servers are at capacity (volumeCount == maxVolumeCount), the rebalance step fails with "no free ec shard slots" instead of recognizing that moving shards frees slots on source servers.

Test Results

With the fix: Shows "Collecting volume locations for N volumes before EC encoding..." message Without the fix: No collection message, potential timing race condition

The tests demonstrate that the fix prevents the volume location timing bug that caused double storage usage in EC encoding operations.