From e1ce1a34b0a63803ad909a4935e7073ebc9407a4 Mon Sep 17 00:00:00 2001 From: James Phillips Date: Sat, 14 Nov 2015 21:59:23 -0800 Subject: [PATCH] Moves conversion of nil slices up to HTTP layer for prepared queries. --- command/agent/prepared_query_endpoint.go | 10 +++ command/agent/prepared_query_endpoint_test.go | 68 +++++++++++++++++++ consul/state/prepared_query.go | 2 +- consul/state/prepared_query_test.go | 4 +- 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/command/agent/prepared_query_endpoint.go b/command/agent/prepared_query_endpoint.go index 4c549c6b0f..2f4b78e49b 100644 --- a/command/agent/prepared_query_endpoint.go +++ b/command/agent/prepared_query_endpoint.go @@ -54,6 +54,11 @@ func (s *HTTPServer) PreparedQueryGeneral(resp http.ResponseWriter, req *http.Re if err := s.agent.RPC(endpoint+".List", &args, &reply); err != nil { return nil, err } + + // Use empty list instead of nil. + if reply.Queries == nil { + reply.Queries = make(structs.PreparedQueries, 0) + } return reply.Queries, nil default: @@ -111,6 +116,11 @@ func (s *HTTPServer) PreparedQuerySpecific(resp http.ResponseWriter, req *http.R } return nil, err } + + // Use empty list instead of nil. + if reply.Nodes == nil { + reply.Nodes = make(structs.CheckServiceNodes, 0) + } return reply, nil } else { args := structs.PreparedQuerySpecificRequest{ diff --git a/command/agent/prepared_query_endpoint_test.go b/command/agent/prepared_query_endpoint_test.go index 41b905249a..ac095320c1 100644 --- a/command/agent/prepared_query_endpoint_test.go +++ b/command/agent/prepared_query_endpoint_test.go @@ -144,6 +144,40 @@ func TestPreparedQuery_Create(t *testing.T) { } func TestPreparedQuery_List(t *testing.T) { + httpTest(t, func(srv *HTTPServer) { + m := MockPreparedQuery{} + if err := srv.agent.InjectEndpoint("PreparedQuery", &m); err != nil { + t.Fatalf("err: %v", err) + } + + m.listFn = func(args *structs.DCSpecificRequest, reply *structs.IndexedPreparedQueries) error { + // Return an empty response. + return nil + } + + body := bytes.NewBuffer(nil) + req, err := http.NewRequest("GET", "/v1/query", body) + if err != nil { + t.Fatalf("err: %v", err) + } + + resp := httptest.NewRecorder() + obj, err := srv.PreparedQueryGeneral(resp, req) + if err != nil { + t.Fatalf("err: %v", err) + } + if resp.Code != 200 { + t.Fatalf("bad code: %d", resp.Code) + } + r, ok := obj.(structs.PreparedQueries) + if !ok { + t.Fatalf("unexpected: %T", obj) + } + if r == nil || len(r) != 0 { + t.Fatalf("bad: %v", r) + } + }) + httpTest(t, func(srv *HTTPServer) { m := MockPreparedQuery{} if err := srv.agent.InjectEndpoint("PreparedQuery", &m); err != nil { @@ -194,6 +228,40 @@ func TestPreparedQuery_List(t *testing.T) { } func TestPreparedQuery_Execute(t *testing.T) { + httpTest(t, func(srv *HTTPServer) { + m := MockPreparedQuery{} + if err := srv.agent.InjectEndpoint("PreparedQuery", &m); err != nil { + t.Fatalf("err: %v", err) + } + + m.executeFn = func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { + // Just return an empty response. + return nil + } + + body := bytes.NewBuffer(nil) + req, err := http.NewRequest("GET", "/v1/query/my-id/execute", body) + if err != nil { + t.Fatalf("err: %v", err) + } + + resp := httptest.NewRecorder() + obj, err := srv.PreparedQuerySpecific(resp, req) + if err != nil { + t.Fatalf("err: %v", err) + } + if resp.Code != 200 { + t.Fatalf("bad code: %d", resp.Code) + } + r, ok := obj.(structs.PreparedQueryExecuteResponse) + if !ok { + t.Fatalf("unexpected: %T", obj) + } + if r.Nodes == nil || len(r.Nodes) != 0 { + t.Fatalf("bad: %v", r) + } + }) + httpTest(t, func(srv *HTTPServer) { m := MockPreparedQuery{} if err := srv.agent.InjectEndpoint("PreparedQuery", &m); err != nil { diff --git a/consul/state/prepared_query.go b/consul/state/prepared_query.go index 1570d20d6c..b404977e3c 100644 --- a/consul/state/prepared_query.go +++ b/consul/state/prepared_query.go @@ -243,7 +243,7 @@ func (s *StateStore) PreparedQueryList() (uint64, structs.PreparedQueries, error } // Go over all of the queries and build the response. - result := make(structs.PreparedQueries, 0) + var result structs.PreparedQueries for query := queries.Next(); query != nil; query = queries.Next() { result = append(result, query.(*structs.PreparedQuery)) } diff --git a/consul/state/prepared_query_test.go b/consul/state/prepared_query_test.go index bb057ec972..7f7dd0b7af 100644 --- a/consul/state/prepared_query_test.go +++ b/consul/state/prepared_query_test.go @@ -379,7 +379,7 @@ func TestStateStore_PreparedQueryLookup(t *testing.T) { func TestStateStore_PreparedQueryList(t *testing.T) { s := testStateStore(t) - // Make sure an empty (non-nil) slice is returned if there are no queries. + // Make sure nothing is returned for an empty query idx, actual, err := s.PreparedQueryList() if err != nil { t.Fatalf("err: %s", err) @@ -387,7 +387,7 @@ func TestStateStore_PreparedQueryList(t *testing.T) { if idx != 0 { t.Fatalf("bad index: %d", idx) } - if actual == nil || len(actual) != 0 { + if len(actual) != 0 { t.Fatalf("bad: %v", actual) }