// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package state import ( "reflect" "testing" "time" "github.com/hashicorp/consul/agent/structs" "github.com/stretchr/testify/require" ) func TestStateStore_Autopilot(t *testing.T) { s := testStateStore(t) expected := &structs.AutopilotConfig{ CleanupDeadServers: true, LastContactThreshold: 5 * time.Second, MaxTrailingLogs: 500, ServerStabilizationTime: 100 * time.Second, RedundancyZoneTag: "az", DisableUpgradeMigration: true, UpgradeVersionTag: "build", } if err := s.AutopilotSetConfig(0, expected); err != nil { t.Fatal(err) } idx, config, err := s.AutopilotConfig() if err != nil { t.Fatal(err) } if idx != 0 { t.Fatalf("bad: %d", idx) } if !reflect.DeepEqual(expected, config) { t.Fatalf("bad: %#v, %#v", expected, config) } } func TestStateStore_AutopilotCAS(t *testing.T) { s := testStateStore(t) expected := &structs.AutopilotConfig{ CleanupDeadServers: true, } if err := s.AutopilotSetConfig(0, expected); err != nil { t.Fatal(err) } if err := s.AutopilotSetConfig(1, expected); err != nil { t.Fatal(err) } // Do a CAS with an index lower than the entry ok, err := s.AutopilotCASConfig(2, 0, &structs.AutopilotConfig{ CleanupDeadServers: false, }) if ok || err != nil { t.Fatalf("expected (false, nil), got: (%v, %#v)", ok, err) } // Check that the index is untouched and the entry // has not been updated. idx, config, err := s.AutopilotConfig() if err != nil { t.Fatal(err) } if idx != 1 { t.Fatalf("bad: %d", idx) } if !config.CleanupDeadServers { t.Fatalf("bad: %#v", config) } // Do another CAS, this time with the correct index ok, err = s.AutopilotCASConfig(2, 1, &structs.AutopilotConfig{ CleanupDeadServers: false, }) if !ok || err != nil { t.Fatalf("expected (true, nil), got: (%v, %#v)", ok, err) } // Make sure the config was updated idx, config, err = s.AutopilotConfig() if err != nil { t.Fatal(err) } if idx != 2 { t.Fatalf("bad: %d", idx) } if config.CleanupDeadServers { t.Fatalf("bad: %#v", config) } } func TestStateStore_Autopilot_Snapshot_Restore(t *testing.T) { s := testStateStore(t) before := &structs.AutopilotConfig{ CleanupDeadServers: true, } if err := s.AutopilotSetConfig(99, before); err != nil { t.Fatal(err) } snap := s.Snapshot() defer snap.Close() after := &structs.AutopilotConfig{ CleanupDeadServers: false, } if err := s.AutopilotSetConfig(100, after); err != nil { t.Fatal(err) } snapped, err := snap.Autopilot() if err != nil { t.Fatalf("err: %s", err) } require.Equal(t, snapped, before, "autopilot snapshot") s2 := testStateStore(t) restore := s2.Restore() if err := restore.Autopilot(snapped); err != nil { t.Fatalf("err: %s", err) } restore.Commit() idx, res, err := s2.AutopilotConfig() if err != nil { t.Fatalf("err: %s", err) } if idx != 99 { t.Fatalf("bad index: %d", idx) } require.Equal(t, res, before, "autopilot config") }