diff --git a/etcdserver/api/v2v3/cluster.go b/etcdserver/api/v2v3/cluster.go index b53e6d7c8b5..9aa47947398 100644 --- a/etcdserver/api/v2v3/cluster.go +++ b/etcdserver/api/v2v3/cluster.go @@ -15,6 +15,9 @@ package v2v3 import ( + "context" + "time" + "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/pkg/types" @@ -25,7 +28,18 @@ func (s *v2v3Server) ID() types.ID { // TODO: use an actual member ID return types.ID(0xe7cd2f00d) } -func (s *v2v3Server) ClientURLs() []string { panic("STUB") } -func (s *v2v3Server) Members() []*membership.Member { panic("STUB") } +func (s *v2v3Server) ClientURLs() []string { panic("STUB") } + +func (s *v2v3Server) Members() []*membership.Member { + ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second) + defer cancel() + resp, err := s.c.MemberList(ctx) + if err != nil { + // TODO: how can we upport errors here? + panic("STUB") + } + return v3MembersToMembership(resp.Members) +} + func (s *v2v3Server) Member(id types.ID) *membership.Member { panic("STUB") } func (s *v2v3Server) Version() *semver.Version { panic("STUB") } diff --git a/integration/cluster.go b/integration/cluster.go index e872e552106..c2e69c17453 100644 --- a/integration/cluster.go +++ b/integration/cluster.go @@ -38,6 +38,7 @@ import ( "github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver/api/etcdhttp" "github.com/coreos/etcd/etcdserver/api/v2http" + "github.com/coreos/etcd/etcdserver/api/v2v3" "github.com/coreos/etcd/etcdserver/api/v3client" "github.com/coreos/etcd/etcdserver/api/v3election" epb "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb" @@ -517,6 +518,7 @@ type member struct { raftHandler *testutil.PauseableHandler s *etcdserver.EtcdServer serverClosers []func() + v2v3Server etcdserver.ServerPeer grpcServerOpts []grpc.ServerOption grpcServer *grpc.Server @@ -766,6 +768,8 @@ func (m *member) Launch() error { }) } + m.v2v3Server = v2v3.NewServer(nil, v3client.New(m.s), "/v2v3") + for _, ln := range m.PeerListeners { cm := cmux.New(ln) // don't hang on matcher after closing listener @@ -806,7 +810,7 @@ func (m *member) Launch() error { for _, ln := range m.ClientListeners { hs := &httptest.Server{ Listener: ln, - Config: &http.Server{Handler: v2http.NewClientHandler(m.s, m.ServerConfig.ReqTimeout())}, + Config: &http.Server{Handler: v2http.NewClientHandler(m.v2API(), m.ServerConfig.ReqTimeout())}, } if m.ClientTLSInfo == nil { hs.Start() diff --git a/integration/v2_api_test.go b/integration/v2_api_test.go new file mode 100644 index 00000000000..941c80291b2 --- /dev/null +++ b/integration/v2_api_test.go @@ -0,0 +1,25 @@ +// Copyright 2018 The etcd Authors +// +// 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. + +// +build !v2v3 + +package integration + +import "github.com/coreos/etcd/etcdserver" + +const v2IndexOffset = 3 + +func (m *member) v2API() etcdserver.ServerPeer { + return m.s +} diff --git a/integration/v2_http_kv_test.go b/integration/v2_http_kv_test.go index 4b84444790b..023627e96d8 100644 --- a/integration/v2_http_kv_test.go +++ b/integration/v2_http_kv_test.go @@ -54,19 +54,19 @@ func TestV2Set(t *testing.T) { "/v2/keys/foo/bar", v, http.StatusCreated, - `{"action":"set","node":{"key":"/foo/bar","value":"bar","modifiedIndex":4,"createdIndex":4}}`, + fmt.Sprintf(`{"action":"set","node":{"key":"/foo/bar","value":"bar","modifiedIndex":%d,"createdIndex":%d}}`, v2IndexOffset+1, v2IndexOffset+1), }, { "/v2/keys/foodir?dir=true", url.Values{}, http.StatusCreated, - `{"action":"set","node":{"key":"/foodir","dir":true,"modifiedIndex":5,"createdIndex":5}}`, + fmt.Sprintf(`{"action":"set","node":{"key":"/foodir","dir":true,"modifiedIndex":%d,"createdIndex":%d}}`, v2IndexOffset+2, v2IndexOffset+2), }, { "/v2/keys/fooempty", url.Values(map[string][]string{"value": {""}}), http.StatusCreated, - `{"action":"set","node":{"key":"/fooempty","value":"","modifiedIndex":6,"createdIndex":6}}`, + fmt.Sprintf(`{"action":"set","node":{"key":"/fooempty","value":"","modifiedIndex":%d,"createdIndex":%d}}`, v2IndexOffset+3, v2IndexOffset+3), }, { "/v2/keys/foo/novalue", diff --git a/integration/v2v3_api_test.go b/integration/v2v3_api_test.go new file mode 100644 index 00000000000..00b8c2c58c3 --- /dev/null +++ b/integration/v2v3_api_test.go @@ -0,0 +1,25 @@ +// Copyright 2018 The etcd Authors +// +// 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. + +// +build v2v3 + +package integration + +import "github.com/coreos/etcd/etcdserver" + +const v2IndexOffset = 0 + +func (m *member) v2API() etcdserver.ServerPeer { + return m.v2v3Server +}