diff --git a/etcdserver/etcdhttp/client.go b/etcdserver/etcdhttp/client.go index addd6b349..1c676c031 100644 --- a/etcdserver/etcdhttp/client.go +++ b/etcdserver/etcdhttp/client.go @@ -35,6 +35,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/strutil" "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/store" "github.com/coreos/etcd/version" @@ -534,7 +535,7 @@ func newMemberCollection(ms []*etcdserver.Member) httptypes.MemberCollection { for i, m := range ms { tm := httptypes.Member{ - ID: etcdserver.IDAsHex(m.ID), + ID: strutil.IDAsHex(m.ID), Name: m.Name, PeerURLs: make([]string, len(m.PeerURLs)), ClientURLs: make([]string, len(m.ClientURLs)), diff --git a/etcdserver/member.go b/etcdserver/member.go index cb0edab6d..dcaced977 100644 --- a/etcdserver/member.go +++ b/etcdserver/member.go @@ -26,6 +26,7 @@ import ( "sort" "time" + "github.com/coreos/etcd/pkg/strutil" "github.com/coreos/etcd/pkg/types" ) @@ -81,11 +82,11 @@ func (m *Member) PickPeerURL() string { } func memberStoreKey(id uint64) string { - return path.Join(storeMembersPrefix, IDAsHex(id)) + return path.Join(storeMembersPrefix, strutil.IDAsHex(id)) } func mustParseMemberIDFromKey(key string) uint64 { - id, err := IDFromHex(path.Base(key)) + id, err := strutil.IDFromHex(path.Base(key)) if err != nil { log.Panicf("unexpected parse member id error: %v", err) } @@ -93,7 +94,7 @@ func mustParseMemberIDFromKey(key string) uint64 { } func removedMemberStoreKey(id uint64) string { - return path.Join(storeRemovedMembersPrefix, IDAsHex(id)) + return path.Join(storeRemovedMembersPrefix, strutil.IDAsHex(id)) } type SortableMemberSliceByPeerURLs []*Member diff --git a/etcdserver/sender.go b/etcdserver/sender.go index 60aad66a5..9d5cf02d7 100644 --- a/etcdserver/sender.go +++ b/etcdserver/sender.go @@ -25,6 +25,7 @@ import ( "time" "github.com/coreos/etcd/etcdserver/stats" + "github.com/coreos/etcd/pkg/strutil" "github.com/coreos/etcd/raft/raftpb" ) @@ -72,7 +73,7 @@ func send(c *http.Client, cl *Cluster, m raftpb.Message, ss *stats.ServerStats, if m.Type == raftpb.MsgApp { ss.SendAppendReq(len(data)) } - to := IDAsHex(m.To) + to := strutil.IDAsHex(m.To) fs := ls.Follower(to) start := time.Now() diff --git a/etcdserver/server.go b/etcdserver/server.go index 35006452f..f140fd202 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -36,6 +36,7 @@ import ( pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/etcdserver/stats" "github.com/coreos/etcd/pkg/pbutil" + "github.com/coreos/etcd/pkg/strutil" "github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/snap" @@ -239,9 +240,9 @@ func NewServer(cfg *ServerConfig) *EtcdServer { sstats := &stats.ServerStats{ Name: cfg.Name, - ID: IDAsHex(id), + ID: strutil.IDAsHex(id), } - lstats := stats.NewLeaderStats(IDAsHex(id)) + lstats := stats.NewLeaderStats(strutil.IDAsHex(id)) s := &EtcdServer{ store: st, @@ -423,7 +424,7 @@ func (s *EtcdServer) StoreStats() []byte { } func (s *EtcdServer) UpdateRecvApp(from uint64, length int64) { - s.stats.RecvAppendReq(IDAsHex(from), int(length)) + s.stats.RecvAppendReq(strutil.IDAsHex(from), int(length)) } func (s *EtcdServer) AddMember(ctx context.Context, memb Member) error { @@ -780,11 +781,3 @@ func containsUint64(a []uint64, x uint64) bool { } return false } - -func IDAsHex(id uint64) string { - return strconv.FormatUint(id, 16) -} - -func IDFromHex(s string) (uint64, error) { - return strconv.ParseUint(s, 16, 64) -} diff --git a/etcdserver/server_test.go b/etcdserver/server_test.go index ca9cdb0f0..6693d4f4e 100644 --- a/etcdserver/server_test.go +++ b/etcdserver/server_test.go @@ -1390,68 +1390,3 @@ func mustMakePeerSlice(t *testing.T, ids ...uint64) []raft.Peer { } return peers } - -func TestIDAsHex(t *testing.T) { - tests := []struct { - input uint64 - want string - }{ - { - input: uint64(12), - want: "c", - }, - { - input: uint64(4918257920282737594), - want: "444129853c343bba", - }, - } - - for i, tt := range tests { - got := IDAsHex(tt.input) - if tt.want != got { - t.Errorf("#%d: IDAsHex failure: want=%v, got=%v", i, tt.want, got) - } - } -} - -func TestIDFromHex(t *testing.T) { - tests := []struct { - input string - want uint64 - }{ - { - input: "17", - want: uint64(23), - }, - { - input: "612840dae127353", - want: uint64(437557308098245459), - }, - } - - for i, tt := range tests { - got, err := IDFromHex(tt.input) - if err != nil { - t.Errorf("#%d: IDFromHex failure: err=%v", i, err) - continue - } - if tt.want != got { - t.Errorf("#%d: IDFromHex failure: want=%v, got=%v", i, tt.want, got) - } - } -} - -func TestIDFromHexFail(t *testing.T) { - tests := []string{ - "", - "XXX", - "612840dae127353612840dae127353", - } - - for i, tt := range tests { - _, err := IDFromHex(tt) - if err == nil { - t.Fatalf("#%d: IDFromHex expected error, but err=nil", i) - } - } -} diff --git a/pkg/strutil/hex.go b/pkg/strutil/hex.go new file mode 100644 index 000000000..acfc197e8 --- /dev/null +++ b/pkg/strutil/hex.go @@ -0,0 +1,29 @@ +/* + 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 strutil + +import ( + "strconv" +) + +func IDAsHex(id uint64) string { + return strconv.FormatUint(id, 16) +} + +func IDFromHex(s string) (uint64, error) { + return strconv.ParseUint(s, 16, 64) +} diff --git a/pkg/strutil/hex_test.go b/pkg/strutil/hex_test.go new file mode 100644 index 000000000..1ee69df44 --- /dev/null +++ b/pkg/strutil/hex_test.go @@ -0,0 +1,86 @@ +/* + 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 strutil + +import ( + "testing" +) + +func TestIDAsHex(t *testing.T) { + tests := []struct { + input uint64 + want string + }{ + { + input: uint64(12), + want: "c", + }, + { + input: uint64(4918257920282737594), + want: "444129853c343bba", + }, + } + + for i, tt := range tests { + got := IDAsHex(tt.input) + if tt.want != got { + t.Errorf("#%d: IDAsHex failure: want=%v, got=%v", i, tt.want, got) + } + } +} + +func TestIDFromHex(t *testing.T) { + tests := []struct { + input string + want uint64 + }{ + { + input: "17", + want: uint64(23), + }, + { + input: "612840dae127353", + want: uint64(437557308098245459), + }, + } + + for i, tt := range tests { + got, err := IDFromHex(tt.input) + if err != nil { + t.Errorf("#%d: IDFromHex failure: err=%v", i, err) + continue + } + if tt.want != got { + t.Errorf("#%d: IDFromHex failure: want=%v, got=%v", i, tt.want, got) + } + } +} + +func TestIDFromHexFail(t *testing.T) { + tests := []string{ + "", + "XXX", + "612840dae127353612840dae127353", + } + + for i, tt := range tests { + _, err := IDFromHex(tt) + if err == nil { + t.Fatalf("#%d: IDFromHex expected error, but err=nil", i) + } + } +} diff --git a/test b/test index 6433eca30..88faac8ff 100755 --- a/test +++ b/test @@ -15,7 +15,7 @@ COVER=${COVER:-"-cover"} source ./build # Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt. -TESTABLE_AND_FORMATTABLE="client discovery etcdctl/command etcdserver etcdserver/etcdhttp etcdserver/etcdhttp/httptypes etcdserver/etcdserverpb integration pkg/flags pkg/transport proxy raft snap store wait wal" +TESTABLE_AND_FORMATTABLE="client discovery etcdctl/command etcdserver etcdserver/etcdhttp etcdserver/etcdhttp/httptypes etcdserver/etcdserverpb integration pkg/flags pkg/strutil pkg/transport proxy raft snap store wait wal" TESTABLE="$TESTABLE_AND_FORMATTABLE ./" FORMATTABLE="$TESTABLE_AND_FORMATTABLE *.go etcdctl/"