1package api 2 3import ( 4 "testing" 5 "time" 6 7 "github.com/hashicorp/consul/sdk/testutil" 8 "github.com/hashicorp/consul/sdk/testutil/retry" 9 "github.com/stretchr/testify/require" 10) 11 12func TestAPI_OperatorAutopilotGetSetConfiguration(t *testing.T) { 13 t.Parallel() 14 c, s := makeClient(t) 15 defer s.Stop() 16 s.WaitForSerfCheck(t) 17 18 operator := c.Operator() 19 config, err := operator.AutopilotGetConfiguration(nil) 20 if err != nil { 21 t.Fatalf("err: %v", err) 22 } 23 if !config.CleanupDeadServers { 24 t.Fatalf("bad: %v", config) 25 } 26 27 // Change a config setting 28 newConf := &AutopilotConfiguration{CleanupDeadServers: false} 29 if err := operator.AutopilotSetConfiguration(newConf, nil); err != nil { 30 t.Fatalf("err: %v", err) 31 } 32 33 config, err = operator.AutopilotGetConfiguration(nil) 34 if err != nil { 35 t.Fatalf("err: %v", err) 36 } 37 if config.CleanupDeadServers { 38 t.Fatalf("bad: %v", config) 39 } 40} 41 42func TestAPI_OperatorAutopilotCASConfiguration(t *testing.T) { 43 t.Parallel() 44 c, s := makeClient(t) 45 defer s.Stop() 46 47 retry.Run(t, func(r *retry.R) { 48 operator := c.Operator() 49 config, err := operator.AutopilotGetConfiguration(nil) 50 if err != nil { 51 r.Fatalf("err: %v", err) 52 } 53 if !config.CleanupDeadServers { 54 r.Fatalf("bad: %v", config) 55 } 56 57 // Pass an invalid ModifyIndex 58 { 59 newConf := &AutopilotConfiguration{ 60 CleanupDeadServers: false, 61 ModifyIndex: config.ModifyIndex - 1, 62 } 63 resp, err := operator.AutopilotCASConfiguration(newConf, nil) 64 if err != nil { 65 r.Fatalf("err: %v", err) 66 } 67 if resp { 68 r.Fatalf("bad: %v", resp) 69 } 70 } 71 72 // Pass a valid ModifyIndex 73 { 74 newConf := &AutopilotConfiguration{ 75 CleanupDeadServers: false, 76 ModifyIndex: config.ModifyIndex, 77 } 78 resp, err := operator.AutopilotCASConfiguration(newConf, nil) 79 if err != nil { 80 r.Fatalf("err: %v", err) 81 } 82 if !resp { 83 r.Fatalf("bad: %v", resp) 84 } 85 } 86 }) 87} 88 89func TestAPI_OperatorAutopilotServerHealth(t *testing.T) { 90 t.Parallel() 91 c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) { 92 c.RaftProtocol = 3 93 }) 94 defer s.Stop() 95 96 operator := c.Operator() 97 retry.Run(t, func(r *retry.R) { 98 out, err := operator.AutopilotServerHealth(nil) 99 if err != nil { 100 r.Fatalf("err: %v", err) 101 } 102 103 if len(out.Servers) != 1 || 104 !out.Servers[0].Healthy || 105 out.Servers[0].Name != s.Config.NodeName { 106 r.Fatalf("bad: %v", out) 107 } 108 }) 109} 110 111func TestAPI_OperatorAutopilotState(t *testing.T) { 112 c, s := makeClient(t) 113 defer s.Stop() 114 115 operator := c.Operator() 116 retry.Run(t, func(r *retry.R) { 117 out, err := operator.AutopilotState(nil) 118 if err != nil { 119 r.Fatalf("err: %v", err) 120 } 121 122 srv, ok := out.Servers[s.Config.NodeID] 123 if !ok || !srv.Healthy || srv.Name != s.Config.NodeName { 124 r.Fatalf("bad: %v", out) 125 } 126 }) 127} 128 129func TestAPI_OperatorAutopilotServerHealth_429(t *testing.T) { 130 mapi, client := setupMockAPI(t) 131 132 reply := OperatorHealthReply{ 133 Healthy: false, 134 FailureTolerance: 0, 135 Servers: []ServerHealth{ 136 { 137 ID: "d9fdded2-27ae-4db2-9232-9d8d0114ac98", 138 Name: "foo", 139 Address: "198.18.0.1:8300", 140 SerfStatus: "alive", 141 Version: "1.8.3", 142 Leader: true, 143 LastContact: NewReadableDuration(0), 144 LastTerm: 4, 145 LastIndex: 99, 146 Healthy: true, 147 Voter: true, 148 StableSince: time.Date(2020, 9, 2, 12, 0, 0, 0, time.UTC), 149 }, 150 { 151 ID: "1bcdda01-b896-41bc-a763-1a62b4260777", 152 Name: "bar", 153 Address: "198.18.0.2:8300", 154 SerfStatus: "alive", 155 Version: "1.8.3", 156 Leader: false, 157 LastContact: NewReadableDuration(10 * time.Millisecond), 158 LastTerm: 4, 159 LastIndex: 99, 160 Healthy: true, 161 Voter: true, 162 StableSince: time.Date(2020, 9, 2, 12, 0, 0, 0, time.UTC), 163 }, 164 { 165 ID: "661d1eac-81be-436b-bfe1-d51ffd665b9d", 166 Name: "baz", 167 Address: "198.18.0.3:8300", 168 SerfStatus: "failed", 169 Version: "1.8.3", 170 Leader: false, 171 LastContact: NewReadableDuration(10 * time.Millisecond), 172 LastTerm: 4, 173 LastIndex: 99, 174 Healthy: false, 175 Voter: true, 176 }, 177 }, 178 } 179 mapi.withReply("GET", "/v1/operator/autopilot/health", nil, 429, reply).Once() 180 181 out, err := client.Operator().AutopilotServerHealth(nil) 182 require.NoError(t, err) 183 require.Equal(t, &reply, out) 184} 185