Files
seaweedfs/weed/admin/maintenance/maintenance_policy_test.go
T

134 lines
4.7 KiB
Go

package maintenance
import (
"testing"
"github.com/seaweedfs/seaweedfs/weed/pb/worker_pb"
)
// stubConfigPersistence implements the LoadXTaskPolicy accessors that the task config loaders
// type-assert on. The real implementation is *dash.ConfigPersistence, which this package cannot
// import: weed/admin/dash already imports weed/admin/maintenance, so the dependency only runs one
// way and the persistence argument has to stay duck-typed.
type stubConfigPersistence struct {
vacuum *worker_pb.TaskPolicy
ec *worker_pb.TaskPolicy
balance *worker_pb.TaskPolicy
ecBalance *worker_pb.TaskPolicy
}
func (s *stubConfigPersistence) LoadVacuumTaskPolicy() (*worker_pb.TaskPolicy, error) {
return s.vacuum, nil
}
func (s *stubConfigPersistence) LoadErasureCodingTaskPolicy() (*worker_pb.TaskPolicy, error) {
return s.ec, nil
}
func (s *stubConfigPersistence) LoadBalanceTaskPolicy() (*worker_pb.TaskPolicy, error) {
return s.balance, nil
}
func (s *stubConfigPersistence) LoadEcBalanceTaskPolicy() (*worker_pb.TaskPolicy, error) {
return s.ecBalance, nil
}
func disabledStub() *stubConfigPersistence {
return &stubConfigPersistence{
vacuum: &worker_pb.TaskPolicy{
Enabled: false,
MaxConcurrent: 2,
RepeatIntervalSeconds: 2 * 3600,
TaskConfig: &worker_pb.TaskPolicy_VacuumConfig{
VacuumConfig: &worker_pb.VacuumTaskConfig{GarbageThreshold: 0.3, MinVolumeAgeHours: 24},
},
},
ec: &worker_pb.TaskPolicy{
Enabled: false,
MaxConcurrent: 1,
RepeatIntervalSeconds: 3600,
TaskConfig: &worker_pb.TaskPolicy_ErasureCodingConfig{
ErasureCodingConfig: &worker_pb.ErasureCodingTaskConfig{FullnessRatio: 0.95, QuietForSeconds: 3600, MinVolumeSizeMb: 30},
},
},
balance: &worker_pb.TaskPolicy{
Enabled: false,
MaxConcurrent: 1,
RepeatIntervalSeconds: 30 * 60,
TaskConfig: &worker_pb.TaskPolicy_BalanceConfig{
BalanceConfig: &worker_pb.BalanceTaskConfig{ImbalanceThreshold: 0.2, MinServerCount: 7},
},
},
ecBalance: &worker_pb.TaskPolicy{
Enabled: false,
MaxConcurrent: 1,
RepeatIntervalSeconds: 60 * 60,
TaskConfig: &worker_pb.TaskPolicy_EcBalanceConfig{
EcBalanceConfig: &worker_pb.EcBalanceTaskConfig{ImbalanceThreshold: 0.2, MinServerCount: 5},
},
},
}
}
// TestBuildPolicyFromTaskConfigsUsesPersistence covers a reported bug: the persistence argument used to be a
// literal nil, which no type assertion can satisfy, so a task disabled on disk came back enabled.
func TestBuildPolicyFromTaskConfigsUsesPersistence(t *testing.T) {
policy := BuildPolicyFromTaskConfigs(disabledStub())
for _, taskType := range []string{"vacuum", "erasure_coding", "balance", "ec_balance"} {
taskPolicy := policy.TaskPolicies[taskType]
if taskPolicy == nil {
t.Fatalf("no %s task policy built", taskType)
}
if taskPolicy.Enabled {
t.Errorf("%s enabled = true, want false from the persisted config", taskType)
}
}
if got := policy.TaskPolicies["balance"].GetBalanceConfig().GetMinServerCount(); got != 7 {
t.Errorf("balance min server count = %d, want persisted 7", got)
}
}
// TestBuildPolicyFromTaskConfigsWithoutPersistence keeps the documented fallback: with no config
// store there is nothing to read, so the compiled-in defaults apply.
func TestBuildPolicyFromTaskConfigsWithoutPersistence(t *testing.T) {
policy := BuildPolicyFromTaskConfigs(nil)
for _, taskType := range []string{"vacuum", "erasure_coding", "balance", "ec_balance"} {
taskPolicy := policy.TaskPolicies[taskType]
if taskPolicy == nil {
t.Fatalf("no %s task policy built", taskType)
}
if !taskPolicy.Enabled {
t.Errorf("%s enabled = false, want the compiled-in default true", taskType)
}
}
}
// TestNewMaintenanceManagerUsesPersistenceForPolicyFallback covers the path the admin server takes
// when no maintenance.pb has been written yet: the config carries no policy, so the manager builds
// one itself and must read the persisted task configs to do it.
func TestNewMaintenanceManagerUsesPersistenceForPolicyFallback(t *testing.T) {
config := DefaultMaintenanceConfig()
if config.Policy != nil {
t.Fatal("default config unexpectedly carries a policy, test no longer covers the fallback")
}
manager := NewMaintenanceManager(nil, config, disabledStub())
policy := manager.queue.policy
if policy == nil {
t.Fatal("queue policy is nil")
}
if IsTaskEnabled(policy, MaintenanceTaskType("balance")) {
t.Error("balance enabled = true, want false from the persisted config")
}
if IsTaskEnabled(policy, MaintenanceTaskType("vacuum")) {
t.Error("vacuum enabled = true, want false from the persisted config")
}
if manager.scanner.policy != policy {
t.Error("scanner and queue disagree on the policy")
}
}