diff --git a/embed/etcd.go b/embed/etcd.go index 4d23a04009c..7ebbcf201cb 100644 --- a/embed/etcd.go +++ b/embed/etcd.go @@ -70,13 +70,21 @@ func StartEtcd(inCfg *Config) (e *Etcd, err error) { if err = inCfg.Validate(); err != nil { return nil, err } + serving := false e = &Etcd{cfg: *inCfg, stopc: make(chan struct{})} cfg := &e.cfg defer func() { - if e != nil && err != nil { - e.Close() - e = nil + if e == nil || err == nil { + return + } + if !serving { + // errored before starting gRPC server for serveCtx.grpcServerC + for _, sctx := range e.sctxs { + close(sctx.grpcServerC) + } } + e.Close() + e = nil }() if e.Peers, err = startPeerListeners(cfg); err != nil { @@ -137,6 +145,7 @@ func StartEtcd(inCfg *Config) (e *Etcd, err error) { if err = e.serve(); err != nil { return } + serving = true return } diff --git a/embed/serve_test.go b/embed/serve_test.go new file mode 100644 index 00000000000..d46631fcfde --- /dev/null +++ b/embed/serve_test.go @@ -0,0 +1,38 @@ +// Copyright 2017 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. + +package embed + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/coreos/etcd/auth" +) + +// TestStartEtcdWrongToken ensures that StartEtcd with wrong configs returns with error. +func TestStartEtcdWrongToken(t *testing.T) { + tdir, err := ioutil.TempDir(os.TempDir(), "token-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tdir) + cfg := NewConfig() + cfg.Dir = tdir + cfg.AuthToken = "wrong-token" + if _, err = StartEtcd(cfg); err != auth.ErrInvalidAuthOpts { + t.Fatalf("expected %v, got %v", auth.ErrInvalidAuthOpts, err) + } +}