mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-17 04:36:50 +00:00
* test(s3/lifecycle): bundle dispatcher + engine edge-case coverage Two-package bundle covering uncovered branches in production code that the existing happy-path tests don't reach. Dispatcher 58.1% → 60.2% and engine 81.0% → 81.7% (engine lift modest because most branches were already hit; the nil-rule defensive case is otherwise unreachable from a Compile flow). dispatcher (4 tests): - FilerPersister.Load with nil Store errors with a "nil Store" message rather than panicking at the Read call. - FilerPersister.Save with nil Store same. - FilerPersister.Load with a non-NotFound transport error wraps the shard ID into the message AND keeps the underlying error recoverable via errors.Is. - FilerPersister.Load with successful empty []byte returns an empty map, not a JSON-decode error — pinning that an existing-but-empty cursor file is treated as "no entries". - Tick initializes the retries map on first call without panic so a freshly-constructed Dispatcher works. - Tick with already-canceled ctx re-queues the popped Match, returns zero, and never invokes the LifecycleDelete client — the Match must not be lost across worker restart. engine (4 tests): - rulePredicateSensitive(nil) returns false rather than panicking on the FilterTags dereference. The non-nil paths run through Compile, but a defensive nil-rule arrival isn't reachable that way. - rule with no FilterTags / empty FilterTags map returns false (the check is len(FilterTags) > 0, so empty must classify as non-sensitive — pinning catches a flipped >= comparison). - rule with a populated FilterTags returns true. * fix(s3/lifecycle): Tick must requeue every drained Match on shutdown Per codex review on #9413: Tick called Schedule.Drain to pop ALL due matches at once, then iterated. If ctx canceled mid-loop, only the current Match was re-added — everything past that index was silently lost across the worker restart. With N due matches, up to N-1 were dropped. Fix: on cancellation, re-add due[i:] (current + remaining) before returning. Matches already dispatched (due[:i]) stay processed; the schedule is left exactly as it would be if Drain had returned only the dispatched prefix. Strengthen the existing test to enqueue three due matches and assert sched.Len()==3 after a pre-canceled Tick. Pre-fix the test would have seen Len()==1 because only the first popped Match was re-added.
46 lines
1.5 KiB
Go
46 lines
1.5 KiB
Go
package engine
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/s3api/s3lifecycle"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// rulePredicateSensitive's non-nil branches are exercised by the
|
|
// existing Compile tests; this test pins the defensive nil-rule
|
|
// branch directly. Compile shouldn't ever pass a nil rule, but a
|
|
// future caller that does shouldn't panic.
|
|
|
|
func TestRulePredicateSensitive_NilRuleReturnsFalse(t *testing.T) {
|
|
assert.False(t, rulePredicateSensitive(nil))
|
|
}
|
|
|
|
func TestRulePredicateSensitive_NoFilterTagsReturnsFalse(t *testing.T) {
|
|
// A rule without FilterTags is not predicate-sensitive; the
|
|
// router's MatchPredicateChange path skips actions whose rule
|
|
// returns false here.
|
|
rule := &s3lifecycle.Rule{ID: "r", Status: s3lifecycle.StatusEnabled, ExpirationDays: 7}
|
|
assert.False(t, rulePredicateSensitive(rule))
|
|
}
|
|
|
|
func TestRulePredicateSensitive_EmptyFilterTagsReturnsFalse(t *testing.T) {
|
|
// An empty (non-nil) FilterTags map must classify as non-sensitive
|
|
// — the function checks len, so empty == 0 == false.
|
|
rule := &s3lifecycle.Rule{
|
|
ID: "r",
|
|
Status: s3lifecycle.StatusEnabled,
|
|
FilterTags: map[string]string{},
|
|
}
|
|
assert.False(t, rulePredicateSensitive(rule))
|
|
}
|
|
|
|
func TestRulePredicateSensitive_PopulatedFilterTagsReturnsTrue(t *testing.T) {
|
|
rule := &s3lifecycle.Rule{
|
|
ID: "r",
|
|
Status: s3lifecycle.StatusEnabled,
|
|
FilterTags: map[string]string{"env": "prod"},
|
|
}
|
|
assert.True(t, rulePredicateSensitive(rule))
|
|
}
|