From e457d52f5cd237c704248ac6f9a0418508e0769e Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 29 Oct 2014 15:56:19 -0700 Subject: [PATCH 1/5] client: log incorrect HTTP resp body as string --- client/keys_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/keys_test.go b/client/keys_test.go index 1ab0937a1..d2428c72d 100644 --- a/client/keys_test.go +++ b/client/keys_test.go @@ -224,7 +224,7 @@ func assertResponse(got http.Request, wantURL *url.URL, wantHeader http.Header, } } else { if wantBody == nil { - return fmt.Errorf("want.Body=%v got.Body=%v", wantBody, got.Body) + return fmt.Errorf("want.Body=%v got.Body=%s", wantBody, got.Body) } else { gotBytes, err := ioutil.ReadAll(got.Body) if err != nil { @@ -232,7 +232,7 @@ func assertResponse(got http.Request, wantURL *url.URL, wantHeader http.Header, } if !reflect.DeepEqual(wantBody, gotBytes) { - return fmt.Errorf("want.Body=%v got.Body=%v", wantBody, gotBytes) + return fmt.Errorf("want.Body=%s got.Body=%s", wantBody, gotBytes) } } } From 011a67c878376598ad4de1052b8c18aa8f9f356a Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 29 Oct 2014 16:01:05 -0700 Subject: [PATCH 2/5] httptypes: add MemberCreateRequest.MarshalJSON --- etcdserver/etcdhttp/httptypes/member.go | 14 ++++++++++++++ etcdserver/etcdhttp/httptypes/member_test.go | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/etcdserver/etcdhttp/httptypes/member.go b/etcdserver/etcdhttp/httptypes/member.go index 06fd0ccb8..6d8554ed0 100644 --- a/etcdserver/etcdhttp/httptypes/member.go +++ b/etcdserver/etcdhttp/httptypes/member.go @@ -33,6 +33,20 @@ type MemberCreateRequest struct { PeerURLs types.URLs } +func (m *MemberCreateRequest) MarshalJSON() ([]byte, error) { + s := struct { + PeerURLs []string `json:"peerURLs"` + }{ + PeerURLs: make([]string, len(m.PeerURLs)), + } + + for i, u := range m.PeerURLs { + s.PeerURLs[i] = u.String() + } + + return json.Marshal(&s) +} + func (m *MemberCreateRequest) UnmarshalJSON(data []byte) error { s := struct { PeerURLs []string `json:"peerURLs"` diff --git a/etcdserver/etcdhttp/httptypes/member_test.go b/etcdserver/etcdhttp/httptypes/member_test.go index 2b07c28b0..823f44630 100644 --- a/etcdserver/etcdhttp/httptypes/member_test.go +++ b/etcdserver/etcdhttp/httptypes/member_test.go @@ -199,3 +199,22 @@ func TestMemberCreateRequestUnmarshalFail(t *testing.T) { } } } + +func TestMemberCreateRequestMarshal(t *testing.T) { + req := MemberCreateRequest{ + PeerURLs: types.URLs([]url.URL{ + url.URL{Scheme: "http", Host: "127.0.0.1:8081"}, + url.URL{Scheme: "https", Host: "127.0.0.1:8080"}, + }), + } + want := []byte(`{"peerURLs":["http://127.0.0.1:8081","https://127.0.0.1:8080"]}`) + + got, err := json.Marshal(&req) + if err != nil { + t.Fatalf("Marshal returned unexpected err=%v", err) + } + + if !reflect.DeepEqual(want, got) { + t.Fatalf("Failed to marshal MemberCreateRequest: want=%s, got=%s", want, got) + } +} From 4e759b46ce96d09efcf8fa776b4f4aba36c250bd Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 29 Oct 2014 16:14:26 -0700 Subject: [PATCH 3/5] client: use httptypes.MemberCreateRequest in member add --- client/members.go | 12 +++++++++--- client/members_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/client/members.go b/client/members.go index 0b551878b..d178b9a76 100644 --- a/client/members.go +++ b/client/members.go @@ -26,6 +26,7 @@ import ( "time" "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" + "github.com/coreos/etcd/pkg/types" ) var ( @@ -82,7 +83,12 @@ func (m *httpMembersAPI) List() ([]httptypes.Member, error) { } func (m *httpMembersAPI) Add(peerURL string) (*httptypes.Member, error) { - req := &membersAPIActionAdd{peerURL: peerURL} + urls, err := types.NewURLs([]string{peerURL}) + if err != nil { + return nil, err + } + + req := &membersAPIActionAdd{peerURLs: urls} code, body, err := m.client.doWithTimeout(req) if err != nil { return nil, err @@ -128,11 +134,11 @@ func (d *membersAPIActionRemove) httpRequest(ep url.URL) *http.Request { } type membersAPIActionAdd struct { - peerURL string + peerURLs types.URLs } func (a *membersAPIActionAdd) httpRequest(ep url.URL) *http.Request { - m := httptypes.Member{PeerURLs: []string{a.peerURL}} + m := httptypes.MemberCreateRequest{PeerURLs: a.peerURLs} b, _ := json.Marshal(&m) req, _ := http.NewRequest("POST", ep.String(), bytes.NewReader(b)) req.Header.Set("Content-Type", "application/json") diff --git a/client/members_test.go b/client/members_test.go index b8cdd2bc4..e3333b07b 100644 --- a/client/members_test.go +++ b/client/members_test.go @@ -20,6 +20,8 @@ import ( "net/http" "net/url" "testing" + + "github.com/coreos/etcd/pkg/types" ) func TestMembersAPIListAction(t *testing.T) { @@ -37,3 +39,29 @@ func TestMembersAPIListAction(t *testing.T) { t.Errorf(err.Error()) } } + +func TestMembersAPIActionAdd(t *testing.T) { + ep := url.URL{Scheme: "http", Host: "example.com/v2/admin/members"} + act := &membersAPIActionAdd{ + peerURLs: types.URLs([]url.URL{ + url.URL{Scheme: "https", Host: "127.0.0.1:8081"}, + url.URL{Scheme: "http", Host: "127.0.0.1:8080"}, + }), + } + + wantURL := &url.URL{ + Scheme: "http", + Host: "example.com", + Path: "/v2/admin/members", + } + wantHeader := http.Header{ + "Content-Type": []string{"application/json"}, + } + wantBody := []byte(`{"peerURLs":["https://127.0.0.1:8081","http://127.0.0.1:8080"]}`) + + got := *act.httpRequest(ep) + err := assertResponse(got, wantURL, wantHeader, wantBody) + if err != nil { + t.Error(err.Error()) + } +} From 5264c05ddb79a6e06f893f7d617d7ae6d67b6a5f Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 29 Oct 2014 16:14:49 -0700 Subject: [PATCH 4/5] client: clean up style of TestMembersAPIActionList --- client/members_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/members_test.go b/client/members_test.go index e3333b07b..14589d77d 100644 --- a/client/members_test.go +++ b/client/members_test.go @@ -24,19 +24,20 @@ import ( "github.com/coreos/etcd/pkg/types" ) -func TestMembersAPIListAction(t *testing.T) { +func TestMembersAPIActionList(t *testing.T) { ep := url.URL{Scheme: "http", Host: "example.com/v2/members"} + act := &membersAPIActionList{} + wantURL := &url.URL{ Scheme: "http", Host: "example.com", Path: "/v2/members", } - act := &membersAPIActionList{} got := *act.httpRequest(ep) err := assertResponse(got, wantURL, http.Header{}, nil) if err != nil { - t.Errorf(err.Error()) + t.Error(err.Error()) } } From d756dd20790c9765bab5a51bf4cf02b32435ba3a Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 29 Oct 2014 16:13:20 -0700 Subject: [PATCH 5/5] client: test membersAPIActionRemove --- client/members_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/client/members_test.go b/client/members_test.go index 14589d77d..e003be2e5 100644 --- a/client/members_test.go +++ b/client/members_test.go @@ -66,3 +66,20 @@ func TestMembersAPIActionAdd(t *testing.T) { t.Error(err.Error()) } } + +func TestMembersAPIActionRemove(t *testing.T) { + ep := url.URL{Scheme: "http", Host: "example.com/v2/members"} + act := &membersAPIActionRemove{memberID: "XXX"} + + wantURL := &url.URL{ + Scheme: "http", + Host: "example.com", + Path: "/v2/members/XXX", + } + + got := *act.httpRequest(ep) + err := assertResponse(got, wantURL, http.Header{}, nil) + if err != nil { + t.Error(err.Error()) + } +}