mirror of
https://github.com/status-im/consul.git
synced 2025-01-09 13:26:07 +00:00
Test every endpoint for OPTIONS/MethodNotFound
This commit is contained in:
parent
c5f0bb3711
commit
f770f360e9
@ -3,94 +3,96 @@ package agent
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/logger"
|
||||
)
|
||||
|
||||
func TestHTTPAPI_MethodNotAllowed_OSS(t *testing.T) {
|
||||
tests := []struct {
|
||||
var expectedEndpoints = []struct {
|
||||
methods, uri string
|
||||
}{
|
||||
{"PUT", "/v1/acl/bootstrap"},
|
||||
{"PUT", "/v1/acl/create"},
|
||||
{"PUT", "/v1/acl/update"},
|
||||
{"PUT", "/v1/acl/destroy/"},
|
||||
{"GET", "/v1/acl/info/"},
|
||||
{"PUT", "/v1/acl/clone/"},
|
||||
{"GET", "/v1/acl/list"},
|
||||
{"GET", "/v1/acl/replication"},
|
||||
{"PUT", "/v1/agent/token/"},
|
||||
{"GET", "/v1/agent/self"},
|
||||
{"GET", "/v1/agent/members"},
|
||||
{"PUT", "/v1/agent/check/deregister/"},
|
||||
{"PUT", "/v1/agent/check/fail/"},
|
||||
{"PUT", "/v1/agent/check/pass/"},
|
||||
{"PUT", "/v1/agent/check/register"},
|
||||
{"PUT", "/v1/agent/check/update/"},
|
||||
{"PUT", "/v1/agent/check/warn/"},
|
||||
{"GET", "/v1/agent/checks"},
|
||||
{"PUT", "/v1/agent/force-leave/"},
|
||||
{"PUT", "/v1/agent/join/"},
|
||||
{"PUT", "/v1/agent/leave"},
|
||||
{"PUT", "/v1/agent/maintenance"},
|
||||
{"GET", "/v1/agent/metrics"},
|
||||
}{
|
||||
{"OPTIONS,PUT", "/v1/acl/bootstrap"},
|
||||
{"OPTIONS,PUT", "/v1/acl/create"},
|
||||
{"OPTIONS,PUT", "/v1/acl/update"},
|
||||
{"OPTIONS,PUT", "/v1/acl/destroy/"},
|
||||
{"OPTIONS,GET", "/v1/acl/info/"},
|
||||
{"OPTIONS,PUT", "/v1/acl/clone/"},
|
||||
{"OPTIONS,GET", "/v1/acl/list"},
|
||||
{"OPTIONS,GET", "/v1/acl/replication"},
|
||||
{"OPTIONS,PUT", "/v1/agent/token/"},
|
||||
{"OPTIONS,GET", "/v1/agent/self"},
|
||||
{"OPTIONS,GET", "/v1/agent/members"},
|
||||
{"OPTIONS,PUT", "/v1/agent/check/deregister/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/check/fail/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/check/pass/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/check/register"},
|
||||
{"OPTIONS,PUT", "/v1/agent/check/update/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/check/warn/"},
|
||||
{"OPTIONS,GET", "/v1/agent/checks"},
|
||||
{"OPTIONS,PUT", "/v1/agent/force-leave/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/join/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/leave"},
|
||||
{"OPTIONS,PUT", "/v1/agent/maintenance"},
|
||||
{"OPTIONS,GET", "/v1/agent/metrics"},
|
||||
// {"GET", "/v1/agent/monitor"}, // requires LogWriter. Hangs if LogWriter is provided
|
||||
{"PUT", "/v1/agent/reload"},
|
||||
{"PUT", "/v1/agent/service/deregister/"},
|
||||
{"PUT", "/v1/agent/service/maintenance/"},
|
||||
{"PUT", "/v1/agent/service/register"},
|
||||
{"GET", "/v1/agent/services"},
|
||||
{"GET", "/v1/catalog/datacenters"},
|
||||
{"PUT", "/v1/catalog/deregister"},
|
||||
{"GET", "/v1/catalog/node/"},
|
||||
{"GET", "/v1/catalog/nodes"},
|
||||
{"PUT", "/v1/catalog/register"},
|
||||
{"GET", "/v1/catalog/service/"},
|
||||
{"GET", "/v1/catalog/services"},
|
||||
{"GET", "/v1/coordinate/datacenters"},
|
||||
{"GET", "/v1/coordinate/nodes"},
|
||||
{"GET", "/v1/coordinate/node/"},
|
||||
{"PUT", "/v1/event/fire/"},
|
||||
{"GET", "/v1/event/list"},
|
||||
{"GET", "/v1/health/checks/"},
|
||||
{"GET", "/v1/health/node/"},
|
||||
{"GET", "/v1/health/service/"},
|
||||
{"GET", "/v1/health/state/"},
|
||||
{"GET", "/v1/internal/ui/node/"},
|
||||
{"GET", "/v1/internal/ui/nodes"},
|
||||
{"GET", "/v1/internal/ui/services"},
|
||||
{"GET PUT DELETE", "/v1/kv/"},
|
||||
{"GET PUT", "/v1/operator/autopilot/configuration"},
|
||||
{"GET", "/v1/operator/autopilot/health"},
|
||||
{"GET POST PUT DELETE", "/v1/operator/keyring"},
|
||||
{"GET", "/v1/operator/raft/configuration"},
|
||||
{"DELETE", "/v1/operator/raft/peer"},
|
||||
{"GET POST", "/v1/query"},
|
||||
{"GET PUT DELETE", "/v1/query/"},
|
||||
{"GET", "/v1/query/xxx/execute"},
|
||||
{"GET", "/v1/query/xxx/explain"},
|
||||
{"PUT", "/v1/session/create"},
|
||||
{"PUT", "/v1/session/destroy/"},
|
||||
{"GET", "/v1/session/info/"},
|
||||
{"GET", "/v1/session/list"},
|
||||
{"GET", "/v1/session/node/"},
|
||||
{"PUT", "/v1/session/renew/"},
|
||||
{"GET PUT", "/v1/snapshot"},
|
||||
{"GET", "/v1/status/leader"},
|
||||
{"OPTIONS,PUT", "/v1/agent/reload"},
|
||||
{"OPTIONS,PUT", "/v1/agent/service/deregister/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/service/maintenance/"},
|
||||
{"OPTIONS,PUT", "/v1/agent/service/register"},
|
||||
{"OPTIONS,GET", "/v1/agent/services"},
|
||||
{"OPTIONS,GET", "/v1/catalog/datacenters"},
|
||||
{"OPTIONS,PUT", "/v1/catalog/deregister"},
|
||||
{"OPTIONS,GET", "/v1/catalog/node/"},
|
||||
{"OPTIONS,GET", "/v1/catalog/nodes"},
|
||||
{"OPTIONS,PUT", "/v1/catalog/register"},
|
||||
{"OPTIONS,GET", "/v1/catalog/service/"},
|
||||
{"OPTIONS,GET", "/v1/catalog/services"},
|
||||
{"OPTIONS,GET", "/v1/coordinate/datacenters"},
|
||||
{"OPTIONS,GET", "/v1/coordinate/nodes"},
|
||||
{"OPTIONS,GET", "/v1/coordinate/node/"},
|
||||
{"OPTIONS,PUT", "/v1/event/fire/"},
|
||||
{"OPTIONS,GET", "/v1/event/list"},
|
||||
{"OPTIONS,GET", "/v1/health/checks/"},
|
||||
{"OPTIONS,GET", "/v1/health/node/"},
|
||||
{"OPTIONS,GET", "/v1/health/service/"},
|
||||
{"OPTIONS,GET", "/v1/health/state/"},
|
||||
{"OPTIONS,GET", "/v1/internal/ui/node/"},
|
||||
{"OPTIONS,GET", "/v1/internal/ui/nodes"},
|
||||
{"OPTIONS,GET", "/v1/internal/ui/services"},
|
||||
{"OPTIONS,GET,PUT,DELETE", "/v1/kv/"},
|
||||
{"OPTIONS,GET,PUT", "/v1/operator/autopilot/configuration"},
|
||||
{"OPTIONS,GET", "/v1/operator/autopilot/health"},
|
||||
{"OPTIONS,GET,POST,PUT,DELETE", "/v1/operator/keyring"},
|
||||
{"OPTIONS,GET", "/v1/operator/raft/configuration"},
|
||||
{"OPTIONS,DELETE", "/v1/operator/raft/peer"},
|
||||
{"OPTIONS,GET,POST", "/v1/query"},
|
||||
{"OPTIONS,GET,PUT,DELETE", "/v1/query/"},
|
||||
{"OPTIONS,GET", "/v1/query/xxx/execute"},
|
||||
{"OPTIONS,GET", "/v1/query/xxx/explain"},
|
||||
{"OPTIONS,PUT", "/v1/session/create"},
|
||||
{"OPTIONS,PUT", "/v1/session/destroy/"},
|
||||
{"OPTIONS,GET", "/v1/session/info/"},
|
||||
{"OPTIONS,GET", "/v1/session/list"},
|
||||
{"OPTIONS,GET", "/v1/session/node/"},
|
||||
{"OPTIONS,PUT", "/v1/session/renew/"},
|
||||
{"OPTIONS,GET,PUT", "/v1/snapshot"},
|
||||
{"OPTIONS,GET", "/v1/status/leader"},
|
||||
// {"GET", "/v1/status/peers"},// hangs
|
||||
{"PUT", "/v1/txn"},
|
||||
}
|
||||
{"OPTIONS,PUT", "/v1/txn"},
|
||||
}
|
||||
|
||||
func TestHTTPAPI_MethodNotAllowed_OSS(t *testing.T) {
|
||||
|
||||
a := NewTestAgent(t.Name(), `acl_datacenter = "dc1"`)
|
||||
a.Agent.LogWriter = logger.NewLogWriter(512)
|
||||
defer a.Shutdown()
|
||||
|
||||
all := []string{"GET", "PUT", "POST", "DELETE", "HEAD"}
|
||||
all := []string{"GET", "PUT", "POST", "DELETE", "HEAD", "OPTIONS"}
|
||||
client := http.Client{}
|
||||
|
||||
for _, tt := range tests {
|
||||
for _, tt := range expectedEndpoints {
|
||||
for _, m := range all {
|
||||
t.Run(m+" "+tt.uri, func(t *testing.T) {
|
||||
uri := fmt.Sprintf("http://%s%s", a.HTTPAddr(), tt.uri)
|
||||
@ -111,3 +113,29 @@ func TestHTTPAPI_MethodNotAllowed_OSS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPAPI_OptionMethod_OSS(t *testing.T) {
|
||||
a := NewTestAgent(t.Name(), `acl_datacenter = "dc1"`)
|
||||
a.Agent.LogWriter = logger.NewLogWriter(512)
|
||||
defer a.Shutdown()
|
||||
|
||||
for _, tt := range expectedEndpoints {
|
||||
t.Run("OPTIONS "+tt.uri, func(t *testing.T) {
|
||||
uri := fmt.Sprintf("http://%s%s", a.HTTPAddr(), tt.uri)
|
||||
req, _ := http.NewRequest("OPTIONS", uri, nil)
|
||||
resp := httptest.NewRecorder()
|
||||
a.srv.Handler.ServeHTTP(resp, req)
|
||||
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatalf("options request: got status code %d want %d", resp.Code, http.StatusOK)
|
||||
}
|
||||
|
||||
optionsStr := resp.Header().Get("Allow")
|
||||
if optionsStr == "" {
|
||||
t.Fatalf("options request: got empty 'Allow' header")
|
||||
} else if optionsStr != tt.methods {
|
||||
t.Fatalf("options request: got 'Allow' header value of %s want %s", optionsStr, tt.methods)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -714,42 +714,6 @@ func TestEnableWebUI(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHttpOptions(t *testing.T) {
|
||||
|
||||
req, _ := http.NewRequest("OPTIONS", "/v1/query", nil)
|
||||
resp := httptest.NewRecorder()
|
||||
a := NewTestAgent(t.Name(), "")
|
||||
a.srv.Handler.ServeHTTP(resp, req)
|
||||
|
||||
// Check the result
|
||||
if resp.Code != 200 {
|
||||
t.Fatalf("should handle options method")
|
||||
}
|
||||
optionsStr := resp.Header().Get("Allow")
|
||||
if optionsStr == "" {
|
||||
t.Fatalf("options method should set 'Allow' header")
|
||||
} else if optionsStr != "OPTIONS,GET,POST" {
|
||||
t.Fatalf("options method should set 'Allow' header correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethodNotAllowed(t *testing.T) {
|
||||
req, _ := http.NewRequest("PATH", "/v1/kv/", nil)
|
||||
resp := httptest.NewRecorder()
|
||||
a := NewTestAgent(t.Name(), "")
|
||||
a.srv.Handler.ServeHTTP(resp, req)
|
||||
|
||||
if resp.Code != 405 {
|
||||
t.Fatalf("should reject an unsupported method with 405")
|
||||
}
|
||||
optionsStr := resp.Header().Get("Allow")
|
||||
if optionsStr == "" {
|
||||
t.Fatalf("405 error should set 'Allow' header")
|
||||
} else if optionsStr != "OPTIONS,GET,PUT,DELETE" {
|
||||
t.Fatalf("options method should set 'Allow' header correctly")
|
||||
}
|
||||
}
|
||||
|
||||
// assertIndex tests that X-Consul-Index is set and non-zero
|
||||
func assertIndex(t *testing.T, resp *httptest.ResponseRecorder) {
|
||||
header := resp.Header().Get("X-Consul-Index")
|
||||
|
Loading…
x
Reference in New Issue
Block a user