Prechádzať zdrojové kódy

Merge pull request #2068 from yichengq/285

add tests in pkg/types package
Yicheng Qin 11 rokov pred
rodič
commit
e9235002f7

+ 29 - 28
etcdserver/etcdhttp/client_test.go

@@ -37,6 +37,7 @@ import (
 	"github.com/coreos/etcd/etcdserver"
 	"github.com/coreos/etcd/etcdserver/etcdhttp/httptypes"
 	"github.com/coreos/etcd/etcdserver/etcdserverpb"
+	"github.com/coreos/etcd/pkg/testutil"
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/raft/raftpb"
 	"github.com/coreos/etcd/store"
@@ -54,7 +55,7 @@ func mustMarshalEvent(t *testing.T, ev *store.Event) string {
 // mustNewForm takes a set of Values and constructs a PUT *http.Request,
 // with a URL constructed from appending the given path to the standard keysPrefix
 func mustNewForm(t *testing.T, p string, vals url.Values) *http.Request {
-	u := mustNewURL(t, path.Join(keysPrefix, p))
+	u := testutil.MustNewURL(t, path.Join(keysPrefix, p))
 	req, err := http.NewRequest("PUT", u.String(), strings.NewReader(vals.Encode()))
 	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 	if err != nil {
@@ -66,7 +67,7 @@ func mustNewForm(t *testing.T, p string, vals url.Values) *http.Request {
 // mustNewPostForm takes a set of Values and constructs a POST *http.Request,
 // with a URL constructed from appending the given path to the standard keysPrefix
 func mustNewPostForm(t *testing.T, p string, vals url.Values) *http.Request {
-	u := mustNewURL(t, path.Join(keysPrefix, p))
+	u := testutil.MustNewURL(t, path.Join(keysPrefix, p))
 	req, err := http.NewRequest("POST", u.String(), strings.NewReader(vals.Encode()))
 	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 	if err != nil {
@@ -84,7 +85,7 @@ func mustNewRequest(t *testing.T, p string) *http.Request {
 func mustNewMethodRequest(t *testing.T, m, p string) *http.Request {
 	return &http.Request{
 		Method: m,
-		URL:    mustNewURL(t, path.Join(keysPrefix, p)),
+		URL:    testutil.MustNewURL(t, path.Join(keysPrefix, p)),
 	}
 }
 
@@ -186,7 +187,7 @@ func TestBadParseRequest(t *testing.T) {
 		{
 			// bad key prefix
 			&http.Request{
-				URL: mustNewURL(t, "/badprefix/"),
+				URL: testutil.MustNewURL(t, "/badprefix/"),
 			},
 			etcdErr.EcodeInvalidForm,
 		},
@@ -582,7 +583,7 @@ func TestServeMembers(t *testing.T) {
 	}
 
 	for i, tt := range tests {
-		req, err := http.NewRequest("GET", mustNewURL(t, tt.path).String(), nil)
+		req, err := http.NewRequest("GET", testutil.MustNewURL(t, tt.path).String(), nil)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -633,7 +634,7 @@ func TestServeLeader(t *testing.T) {
 	}
 
 	for i, tt := range tests {
-		req, err := http.NewRequest("GET", mustNewURL(t, tt.path).String(), nil)
+		req, err := http.NewRequest("GET", testutil.MustNewURL(t, tt.path).String(), nil)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -658,7 +659,7 @@ func TestServeLeader(t *testing.T) {
 }
 
 func TestServeMembersCreate(t *testing.T) {
-	u := mustNewURL(t, membersPrefix)
+	u := testutil.MustNewURL(t, membersPrefix)
 	b := []byte(`{"peerURLs":["http://127.0.0.1:1"]}`)
 	req, err := http.NewRequest("POST", u.String(), bytes.NewReader(b))
 	if err != nil {
@@ -712,7 +713,7 @@ func TestServeMembersCreate(t *testing.T) {
 func TestServeMembersDelete(t *testing.T) {
 	req := &http.Request{
 		Method: "DELETE",
-		URL:    mustNewURL(t, path.Join(membersPrefix, "BEEF")),
+		URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "BEEF")),
 	}
 	s := &serverRecorder{}
 	h := &membersHandler{
@@ -743,7 +744,7 @@ func TestServeMembersDelete(t *testing.T) {
 }
 
 func TestServeMembersUpdate(t *testing.T) {
-	u := mustNewURL(t, path.Join(membersPrefix, "1"))
+	u := testutil.MustNewURL(t, path.Join(membersPrefix, "1"))
 	b := []byte(`{"peerURLs":["http://127.0.0.1:1"]}`)
 	req, err := http.NewRequest("PUT", u.String(), bytes.NewReader(b))
 	if err != nil {
@@ -812,7 +813,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// parse body error
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "POST",
 				Body:   ioutil.NopCloser(strings.NewReader("bad json")),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -824,7 +825,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// bad content type
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "POST",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/bad"}},
@@ -836,7 +837,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// bad url
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "POST",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://a"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -848,7 +849,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.AddMember error
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "POST",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -862,7 +863,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.AddMember error
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "POST",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -876,7 +877,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.AddMember error
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "POST",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -890,7 +891,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.RemoveMember error with arbitrary server error
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "1")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "1")),
 				Method: "DELETE",
 			},
 			&errServer{
@@ -902,7 +903,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.RemoveMember error with previously removed ID
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "DELETE",
 			},
 			&errServer{
@@ -914,7 +915,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.RemoveMember error with nonexistent ID
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "DELETE",
 			},
 			&errServer{
@@ -926,7 +927,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.RemoveMember error with badly formed ID
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "bad_id")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "bad_id")),
 				Method: "DELETE",
 			},
 			nil,
@@ -936,7 +937,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.RemoveMember with no ID
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "DELETE",
 			},
 			nil,
@@ -946,7 +947,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// parse body error
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "PUT",
 				Body:   ioutil.NopCloser(strings.NewReader("bad json")),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -958,7 +959,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// bad content type
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "PUT",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/bad"}},
@@ -970,7 +971,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// bad url
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "PUT",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://a"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -982,7 +983,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.UpdateMember error
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "PUT",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -996,7 +997,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.UpdateMember error
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "PUT",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -1010,7 +1011,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.UpdateMember error
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "0")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "0")),
 				Method: "PUT",
 				Body:   ioutil.NopCloser(strings.NewReader(`{"PeerURLs": ["http://127.0.0.1:1"]}`)),
 				Header: map[string][]string{"Content-Type": []string{"application/json"}},
@@ -1024,7 +1025,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.UpdateMember error with badly formed ID
 			&http.Request{
-				URL:    mustNewURL(t, path.Join(membersPrefix, "bad_id")),
+				URL:    testutil.MustNewURL(t, path.Join(membersPrefix, "bad_id")),
 				Method: "PUT",
 			},
 			nil,
@@ -1034,7 +1035,7 @@ func TestServeMembersFail(t *testing.T) {
 		{
 			// etcdserver.UpdateMember with no ID
 			&http.Request{
-				URL:    mustNewURL(t, membersPrefix),
+				URL:    testutil.MustNewURL(t, membersPrefix),
 				Method: "PUT",
 			},
 			nil,

+ 0 - 9
etcdserver/etcdhttp/http_test.go

@@ -20,7 +20,6 @@ import (
 	"errors"
 	"net/http"
 	"net/http/httptest"
-	"net/url"
 	"sort"
 	"testing"
 
@@ -32,14 +31,6 @@ import (
 	"github.com/coreos/etcd/raft/raftpb"
 )
 
-func mustNewURL(t *testing.T, s string) *url.URL {
-	u, err := url.Parse(s)
-	if err != nil {
-		t.Fatalf("error creating URL from %q: %v", s, err)
-	}
-	return u
-}
-
 type fakeCluster struct {
 	id         uint64
 	clientURLs []string

+ 2 - 1
etcdserver/etcdhttp/peer_test.go

@@ -25,6 +25,7 @@ import (
 	"testing"
 
 	"github.com/coreos/etcd/etcdserver"
+	"github.com/coreos/etcd/pkg/testutil"
 	"github.com/coreos/etcd/rafthttp"
 )
 
@@ -110,7 +111,7 @@ func TestServeMembersGet(t *testing.T) {
 	}
 
 	for i, tt := range tests {
-		req, err := http.NewRequest("GET", mustNewURL(t, tt.path).String(), nil)
+		req, err := http.NewRequest("GET", testutil.MustNewURL(t, tt.path).String(), nil)
 		if err != nil {
 			t.Fatal(err)
 		}

+ 11 - 4
pkg/testutil/testutil.go

@@ -20,8 +20,6 @@ import (
 	"net/url"
 	"runtime"
 	"testing"
-
-	"github.com/coreos/etcd/pkg/types"
 )
 
 // WARNING: This is a hack.
@@ -37,9 +35,18 @@ func MustNewURLs(t *testing.T, urls []string) []url.URL {
 	if urls == nil {
 		return nil
 	}
-	u, err := types.NewURLs(urls)
+	var us []url.URL
+	for _, url := range urls {
+		u := MustNewURL(t, url)
+		us = append(us, *u)
+	}
+	return us
+}
+
+func MustNewURL(t *testing.T, s string) *url.URL {
+	u, err := url.Parse(s)
 	if err != nil {
-		t.Fatalf("unexpected new urls error: %v", err)
+		t.Fatalf("parse %v error: %v", s, err)
 	}
 	return u
 }

+ 22 - 0
pkg/types/set_test.go

@@ -164,3 +164,25 @@ func driveSetTests(t *testing.T, s Set) {
 		}
 	}
 }
+
+func TestUnsafeSetContainsAll(t *testing.T) {
+	vals := []string{"foo", "bar", "baz"}
+	s := NewUnsafeSet(vals...)
+
+	tests := []struct {
+		strs     []string
+		wcontain bool
+	}{
+		{[]string{}, true},
+		{vals[:1], true},
+		{vals[:2], true},
+		{vals, true},
+		{[]string{"cuz"}, false},
+		{[]string{vals[0], "cuz"}, false},
+	}
+	for i, tt := range tests {
+		if g := s.ContainsAll(tt.strs); g != tt.wcontain {
+			t.Errorf("#%d: ok = %v, want %v", i, g, tt.wcontain)
+		}
+	}
+}

+ 32 - 0
pkg/types/slice_test.go

@@ -0,0 +1,32 @@
+/*
+   Copyright 2014 CoreOS, Inc.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package types
+
+import (
+	"reflect"
+	"sort"
+	"testing"
+)
+
+func TestUint64Slice(t *testing.T) {
+	g := Uint64Slice{10, 500, 5, 1, 100, 25}
+	w := Uint64Slice{1, 5, 10, 25, 100, 500}
+	sort.Sort(g)
+	if !reflect.DeepEqual(g, w) {
+		t.Errorf("slice after sort = %#v, want %#v", g, w)
+	}
+}

+ 20 - 20
pkg/types/urls.go

@@ -27,26 +27,6 @@ import (
 
 type URLs []url.URL
 
-func (us URLs) String() string {
-	return strings.Join(us.StringSlice(), ",")
-}
-
-func (us *URLs) Sort() {
-	sort.Sort(us)
-}
-func (us URLs) Len() int           { return len(us) }
-func (us URLs) Less(i, j int) bool { return us[i].String() < us[j].String() }
-func (us URLs) Swap(i, j int)      { us[i], us[j] = us[j], us[i] }
-
-func (us URLs) StringSlice() []string {
-	out := make([]string, len(us))
-	for i := range us {
-		out[i] = us[i].String()
-	}
-
-	return out
-}
-
 func NewURLs(strs []string) (URLs, error) {
 	all := make([]url.URL, len(strs))
 	if len(all) == 0 {
@@ -74,3 +54,23 @@ func NewURLs(strs []string) (URLs, error) {
 
 	return us, nil
 }
+
+func (us URLs) String() string {
+	return strings.Join(us.StringSlice(), ",")
+}
+
+func (us *URLs) Sort() {
+	sort.Sort(us)
+}
+func (us URLs) Len() int           { return len(us) }
+func (us URLs) Less(i, j int) bool { return us[i].String() < us[j].String() }
+func (us URLs) Swap(i, j int)      { us[i], us[j] = us[j], us[i] }
+
+func (us URLs) StringSlice() []string {
+	out := make([]string, len(us))
+	for i := range us {
+		out[i] = us[i].String()
+	}
+
+	return out
+}

+ 171 - 0
pkg/types/urls_test.go

@@ -0,0 +1,171 @@
+/*
+   Copyright 2014 CoreOS, Inc.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package types
+
+import (
+	"reflect"
+	"testing"
+
+	"github.com/coreos/etcd/pkg/testutil"
+)
+
+func TestNewURLs(t *testing.T) {
+	tests := []struct {
+		strs  []string
+		wurls URLs
+	}{
+		{
+			[]string{"http://127.0.0.1:4001"},
+			testutil.MustNewURLs(t, []string{"http://127.0.0.1:4001"}),
+		},
+		// it can trim space
+		{
+			[]string{"   http://127.0.0.1:4001    "},
+			testutil.MustNewURLs(t, []string{"http://127.0.0.1:4001"}),
+		},
+		// it does sort
+		{
+			[]string{
+				"http://127.0.0.2:4001",
+				"http://127.0.0.1:4001",
+			},
+			testutil.MustNewURLs(t, []string{
+				"http://127.0.0.1:4001",
+				"http://127.0.0.2:4001",
+			}),
+		},
+	}
+	for i, tt := range tests {
+		urls, _ := NewURLs(tt.strs)
+		if !reflect.DeepEqual(urls, tt.wurls) {
+			t.Errorf("#%d: urls = %+v, want %+v", i, urls, tt.wurls)
+		}
+	}
+}
+
+func TestURLsString(t *testing.T) {
+	tests := []struct {
+		us   URLs
+		wstr string
+	}{
+		{
+			URLs{},
+			"",
+		},
+		{
+			testutil.MustNewURLs(t, []string{"http://127.0.0.1:4001"}),
+			"http://127.0.0.1:4001",
+		},
+		{
+			testutil.MustNewURLs(t, []string{
+				"http://127.0.0.1:4001",
+				"http://127.0.0.2:4001",
+			}),
+			"http://127.0.0.1:4001,http://127.0.0.2:4001",
+		},
+		{
+			testutil.MustNewURLs(t, []string{
+				"http://127.0.0.2:4001",
+				"http://127.0.0.1:4001",
+			}),
+			"http://127.0.0.2:4001,http://127.0.0.1:4001",
+		},
+	}
+	for i, tt := range tests {
+		g := tt.us.String()
+		if g != tt.wstr {
+			t.Errorf("#%d: string = %s, want %s", i, g, tt.wstr)
+		}
+	}
+}
+
+func TestURLsSort(t *testing.T) {
+	g := testutil.MustNewURLs(t, []string{
+		"http://127.0.0.4:4001",
+		"http://127.0.0.2:4001",
+		"http://127.0.0.1:4001",
+		"http://127.0.0.3:4001",
+	})
+	w := testutil.MustNewURLs(t, []string{
+		"http://127.0.0.1:4001",
+		"http://127.0.0.2:4001",
+		"http://127.0.0.3:4001",
+		"http://127.0.0.4:4001",
+	})
+	gurls := URLs(g)
+	gurls.Sort()
+	if !reflect.DeepEqual(g, w) {
+		t.Errorf("URLs after sort = %#v, want %#v", g, w)
+	}
+}
+
+func TestURLsStringSlice(t *testing.T) {
+	tests := []struct {
+		us   URLs
+		wstr []string
+	}{
+		{
+			URLs{},
+			[]string{},
+		},
+		{
+			testutil.MustNewURLs(t, []string{"http://127.0.0.1:4001"}),
+			[]string{"http://127.0.0.1:4001"},
+		},
+		{
+			testutil.MustNewURLs(t, []string{
+				"http://127.0.0.1:4001",
+				"http://127.0.0.2:4001",
+			}),
+			[]string{"http://127.0.0.1:4001", "http://127.0.0.2:4001"},
+		},
+		{
+			testutil.MustNewURLs(t, []string{
+				"http://127.0.0.2:4001",
+				"http://127.0.0.1:4001",
+			}),
+			[]string{"http://127.0.0.2:4001", "http://127.0.0.1:4001"},
+		},
+	}
+	for i, tt := range tests {
+		g := tt.us.StringSlice()
+		if !reflect.DeepEqual(g, tt.wstr) {
+			t.Errorf("#%d: string slice = %+v, want %+v", i, g, tt.wstr)
+		}
+	}
+}
+
+func TestNewURLsFail(t *testing.T) {
+	tests := [][]string{
+		// no urls given
+		{},
+		// missing protocol scheme
+		{"://127.0.0.1:4001"},
+		// unsupported scheme
+		{"mailto://127.0.0.1:4001"},
+		// not conform to host:port
+		{"http://127.0.0.1"},
+		// contain a path
+		{"http://127.0.0.1:4001/path"},
+	}
+	for i, tt := range tests {
+		_, err := NewURLs(tt)
+		if err == nil {
+			t.Errorf("#%d: err = nil, but error", i)
+		}
+	}
+}