open-consul/agent/acl_endpoint_test.go
Frank Schroeder 62c77d70f0 build: make tests independent of build tags
When the metadata server is scanning the agents for potential servers
it is parsing the version number which the agent provided when it
joined. This version number has to conform to a certain format, i.e.
'n.n.n'. Without this version number properly set some tests fail with
error messages that disguise the root cause.

The default version number is currently set to 'unknown' in
version/version.go which does not parse and triggers the tests to fail.
The work around is to use a build tag 'consul' which will use the
version number set in version_base.go instead which has the correct
format and is set to the current release version.

In addition, some parts of the code also require the version number to
be of a certain value. Setting it to '0.0.0' for example makes some
tests pass and others fail since they don't pass the semantic check.

When using go build/install/test one has to remember to use '-tags
consul' or tests will fail with non-obvious error messages.

Using build tags makes the build process more complex and error prone
since it prevents the use of the plain go toolchain and - at least in
its current form - introduces subtle build and test issues. We should
try to eliminate build tags for anything else but platform specific
code.

This patch removes all references to specific version numbers in the
code and tests and sets the default version to '9.9.9' which is
syntactically correct and passes the semantic check. This solves the
issue of running go build/install/test without tags for the OSS build.
2017-08-30 13:40:18 +02:00

295 lines
6.4 KiB
Go

package agent
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
)
func makeTestACL(t *testing.T, srv *HTTPServer) string {
body := bytes.NewBuffer(nil)
enc := json.NewEncoder(body)
raw := map[string]interface{}{
"Name": "User Token",
"Type": "client",
"Rules": "",
}
enc.Encode(raw)
req, _ := http.NewRequest("PUT", "/v1/acl/create?token=root", body)
resp := httptest.NewRecorder()
obj, err := srv.ACLCreate(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
aclResp := obj.(aclCreateResponse)
return aclResp.ID
}
func TestACL_Bootstrap(t *testing.T) {
t.Parallel()
cfg := TestACLConfig()
cfg.ACLMasterToken = ""
a := NewTestAgent(t.Name(), cfg)
defer a.Shutdown()
tests := []struct {
name string
method string
code int
token bool
}{
{"bad method", "GET", http.StatusMethodNotAllowed, false},
{"bootstrap", "PUT", http.StatusOK, true},
{"not again", "PUT", http.StatusForbidden, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, _ := http.NewRequest(tt.method, "/v1/acl/bootstrap", nil)
out, err := a.srv.ACLBootstrap(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
if got, want := resp.Code, tt.code; got != want {
t.Fatalf("got %d want %d", got, want)
}
if tt.token {
wrap, ok := out.(aclCreateResponse)
if !ok {
t.Fatalf("bad: %T", out)
}
if len(wrap.ID) != len("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") {
t.Fatalf("bad: %v", wrap)
}
} else {
if out != nil {
t.Fatalf("bad: %T", out)
}
}
})
}
}
func TestACL_Update(t *testing.T) {
t.Parallel()
a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown()
id := makeTestACL(t, a.srv)
body := bytes.NewBuffer(nil)
enc := json.NewEncoder(body)
raw := map[string]interface{}{
"ID": id,
"Name": "User Token 2",
"Type": "client",
"Rules": "",
}
enc.Encode(raw)
req, _ := http.NewRequest("PUT", "/v1/acl/update?token=root", body)
resp := httptest.NewRecorder()
obj, err := a.srv.ACLUpdate(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
aclResp := obj.(aclCreateResponse)
if aclResp.ID != id {
t.Fatalf("bad: %v", aclResp)
}
}
func TestACL_UpdateUpsert(t *testing.T) {
t.Parallel()
a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown()
body := bytes.NewBuffer(nil)
enc := json.NewEncoder(body)
raw := map[string]interface{}{
"ID": "my-old-id",
"Name": "User Token 2",
"Type": "client",
"Rules": "",
}
enc.Encode(raw)
req, _ := http.NewRequest("PUT", "/v1/acl/update?token=root", body)
resp := httptest.NewRecorder()
obj, err := a.srv.ACLUpdate(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
aclResp := obj.(aclCreateResponse)
if aclResp.ID != "my-old-id" {
t.Fatalf("bad: %v", aclResp)
}
}
func TestACL_Destroy(t *testing.T) {
t.Parallel()
a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown()
id := makeTestACL(t, a.srv)
req, _ := http.NewRequest("PUT", "/v1/acl/destroy/"+id+"?token=root", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.ACLDestroy(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp, ok := obj.(bool); !ok || !resp {
t.Fatalf("should work")
}
req, _ = http.NewRequest("GET", "/v1/acl/info/"+id, nil)
resp = httptest.NewRecorder()
obj, err = a.srv.ACLGet(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
respObj, ok := obj.(structs.ACLs)
if !ok {
t.Fatalf("should work")
}
if len(respObj) != 0 {
t.Fatalf("bad: %v", respObj)
}
}
func TestACL_Clone(t *testing.T) {
t.Parallel()
a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown()
id := makeTestACL(t, a.srv)
req, _ := http.NewRequest("PUT", "/v1/acl/clone/"+id, nil)
resp := httptest.NewRecorder()
_, err := a.srv.ACLClone(resp, req)
if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err)
}
req, _ = http.NewRequest("PUT", "/v1/acl/clone/"+id+"?token=root", nil)
resp = httptest.NewRecorder()
obj, err := a.srv.ACLClone(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
aclResp, ok := obj.(aclCreateResponse)
if !ok {
t.Fatalf("should work: %#v %#v", obj, resp)
}
if aclResp.ID == id {
t.Fatalf("bad id")
}
req, _ = http.NewRequest("GET", "/v1/acl/info/"+aclResp.ID, nil)
resp = httptest.NewRecorder()
obj, err = a.srv.ACLGet(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
respObj, ok := obj.(structs.ACLs)
if !ok {
t.Fatalf("should work")
}
if len(respObj) != 1 {
t.Fatalf("bad: %v", respObj)
}
}
func TestACL_Get(t *testing.T) {
t.Parallel()
t.Run("wrong id", func(t *testing.T) {
a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown()
req, _ := http.NewRequest("GET", "/v1/acl/info/nope", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.ACLGet(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
respObj, ok := obj.(structs.ACLs)
if !ok {
t.Fatalf("should work")
}
if respObj == nil || len(respObj) != 0 {
t.Fatalf("bad: %v", respObj)
}
})
t.Run("right id", func(t *testing.T) {
a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown()
id := makeTestACL(t, a.srv)
req, _ := http.NewRequest("GET", "/v1/acl/info/"+id, nil)
resp := httptest.NewRecorder()
obj, err := a.srv.ACLGet(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
respObj, ok := obj.(structs.ACLs)
if !ok {
t.Fatalf("should work")
}
if len(respObj) != 1 {
t.Fatalf("bad: %v", respObj)
}
})
}
func TestACL_List(t *testing.T) {
t.Parallel()
a := NewTestAgent(t.Name(), TestACLConfig())
defer a.Shutdown()
var ids []string
for i := 0; i < 10; i++ {
ids = append(ids, makeTestACL(t, a.srv))
}
req, _ := http.NewRequest("GET", "/v1/acl/list?token=root", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.ACLList(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
respObj, ok := obj.(structs.ACLs)
if !ok {
t.Fatalf("should work")
}
// 10 + anonymous + master
if len(respObj) != 12 {
t.Fatalf("bad: %v", respObj)
}
}
func TestACLReplicationStatus(t *testing.T) {
t.Parallel()
a := NewTestAgent(t.Name(), nil)
defer a.Shutdown()
req, _ := http.NewRequest("GET", "/v1/acl/replication", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.ACLReplicationStatus(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
_, ok := obj.(structs.ACLReplicationStatus)
if !ok {
t.Fatalf("should work")
}
}