浏览代码

e2e: test /metrics, /health endpoints

Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Gyu-Ho Lee 8 年之前
父节点
当前提交
411ab276b0
共有 5 个文件被更改,包括 88 次插入10 次删除
  1. 10 0
      e2e/cluster_proxy_test.go
  2. 12 1
      e2e/cluster_test.go
  3. 5 2
      e2e/etcd_process.go
  4. 47 0
      e2e/metrics_test.go
  5. 14 7
      e2e/v2_curl_test.go

+ 10 - 0
e2e/cluster_proxy_test.go

@@ -54,6 +54,9 @@ func (p *proxyEtcdProcess) Config() *etcdServerProcessConfig { return p.etcdProc
 
 
 func (p *proxyEtcdProcess) EndpointsV2() []string { return p.proxyV2.endpoints() }
 func (p *proxyEtcdProcess) EndpointsV2() []string { return p.proxyV2.endpoints() }
 func (p *proxyEtcdProcess) EndpointsV3() []string { return p.proxyV3.endpoints() }
 func (p *proxyEtcdProcess) EndpointsV3() []string { return p.proxyV3.endpoints() }
+func (p *proxyEtcdProcess) EndpointsMetrics() []string {
+	panic("not implemented; proxy doesn't provide health information")
+}
 
 
 func (p *proxyEtcdProcess) Start() error {
 func (p *proxyEtcdProcess) Start() error {
 	if err := p.etcdProc.Start(); err != nil {
 	if err := p.etcdProc.Start(); err != nil {
@@ -113,6 +116,7 @@ type proxyProc struct {
 	execPath string
 	execPath string
 	args     []string
 	args     []string
 	ep       string
 	ep       string
+	murl     string
 	donec    chan struct{}
 	donec    chan struct{}
 
 
 	proc *expect.ExpectProcess
 	proc *expect.ExpectProcess
@@ -232,6 +236,11 @@ func newProxyV3Proc(cfg *etcdServerProcessConfig) *proxyV3Proc {
 		// pass-through member RPCs
 		// pass-through member RPCs
 		"--advertise-client-url", "",
 		"--advertise-client-url", "",
 	}
 	}
+	murl := ""
+	if cfg.murl != "" {
+		murl = proxyListenURL(cfg, 4)
+		args = append(args, "--metrics-addr", murl)
+	}
 	tlsArgs := []string{}
 	tlsArgs := []string{}
 	for i := 0; i < len(cfg.tlsArgs); i++ {
 	for i := 0; i < len(cfg.tlsArgs); i++ {
 		switch cfg.tlsArgs[i] {
 		switch cfg.tlsArgs[i] {
@@ -258,6 +267,7 @@ func newProxyV3Proc(cfg *etcdServerProcessConfig) *proxyV3Proc {
 			execPath: cfg.execPath,
 			execPath: cfg.execPath,
 			args:     append(args, tlsArgs...),
 			args:     append(args, tlsArgs...),
 			ep:       listenAddr,
 			ep:       listenAddr,
+			murl:     murl,
 			donec:    make(chan struct{}),
 			donec:    make(chan struct{}),
 		},
 		},
 	}
 	}

+ 12 - 1
e2e/cluster_test.go

@@ -101,6 +101,8 @@ type etcdProcessClusterConfig struct {
 	baseScheme string
 	baseScheme string
 	basePort   int
 	basePort   int
 
 
+	metricsURLScheme string
+
 	snapCount int // default is 10000
 	snapCount int // default is 10000
 
 
 	clientTLS             clientConnType
 	clientTLS             clientConnType
@@ -175,7 +177,7 @@ func (cfg *etcdProcessClusterConfig) etcdServerProcessConfigs() []*etcdServerPro
 	for i := 0; i < cfg.clusterSize; i++ {
 	for i := 0; i < cfg.clusterSize; i++ {
 		var curls []string
 		var curls []string
 		var curl, curltls string
 		var curl, curltls string
-		port := cfg.basePort + 4*i
+		port := cfg.basePort + 5*i
 		curlHost := fmt.Sprintf("localhost:%d", port)
 		curlHost := fmt.Sprintf("localhost:%d", port)
 
 
 		switch cfg.clientTLS {
 		switch cfg.clientTLS {
@@ -221,6 +223,14 @@ func (cfg *etcdProcessClusterConfig) etcdServerProcessConfigs() []*etcdServerPro
 		if cfg.noStrictReconfig {
 		if cfg.noStrictReconfig {
 			args = append(args, "--strict-reconfig-check=false")
 			args = append(args, "--strict-reconfig-check=false")
 		}
 		}
+		var murl string
+		if cfg.metricsURLScheme != "" {
+			murl = (&url.URL{
+				Scheme: cfg.metricsURLScheme,
+				Host:   fmt.Sprintf("localhost:%d", port+2),
+			}).String()
+			args = append(args, "--listen-metrics-urls", murl)
+		}
 
 
 		args = append(args, cfg.tlsArgs()...)
 		args = append(args, cfg.tlsArgs()...)
 		etcdCfgs[i] = &etcdServerProcessConfig{
 		etcdCfgs[i] = &etcdServerProcessConfig{
@@ -232,6 +242,7 @@ func (cfg *etcdProcessClusterConfig) etcdServerProcessConfigs() []*etcdServerPro
 			name:         name,
 			name:         name,
 			purl:         purl,
 			purl:         purl,
 			acurl:        curl,
 			acurl:        curl,
+			murl:         murl,
 			initialToken: cfg.initialToken,
 			initialToken: cfg.initialToken,
 		}
 		}
 	}
 	}

+ 5 - 2
e2e/etcd_process.go

@@ -29,6 +29,7 @@ var etcdServerReadyLines = []string{"enabled capabilities for version", "publish
 type etcdProcess interface {
 type etcdProcess interface {
 	EndpointsV2() []string
 	EndpointsV2() []string
 	EndpointsV3() []string
 	EndpointsV3() []string
+	EndpointsMetrics() []string
 
 
 	Start() error
 	Start() error
 	Restart() error
 	Restart() error
@@ -57,6 +58,7 @@ type etcdServerProcessConfig struct {
 	purl url.URL
 	purl url.URL
 
 
 	acurl string
 	acurl string
+	murl  string
 
 
 	initialToken   string
 	initialToken   string
 	initialCluster string
 	initialCluster string
@@ -74,8 +76,9 @@ func newEtcdServerProcess(cfg *etcdServerProcessConfig) (*etcdServerProcess, err
 	return &etcdServerProcess{cfg: cfg, donec: make(chan struct{})}, nil
 	return &etcdServerProcess{cfg: cfg, donec: make(chan struct{})}, nil
 }
 }
 
 
-func (ep *etcdServerProcess) EndpointsV2() []string { return []string{ep.cfg.acurl} }
-func (ep *etcdServerProcess) EndpointsV3() []string { return ep.EndpointsV2() }
+func (ep *etcdServerProcess) EndpointsV2() []string      { return []string{ep.cfg.acurl} }
+func (ep *etcdServerProcess) EndpointsV3() []string      { return ep.EndpointsV2() }
+func (ep *etcdServerProcess) EndpointsMetrics() []string { return []string{ep.cfg.murl} }
 
 
 func (ep *etcdServerProcess) Start() error {
 func (ep *etcdServerProcess) Start() error {
 	if ep.proc != nil {
 	if ep.proc != nil {

+ 47 - 0
e2e/metrics_test.go

@@ -0,0 +1,47 @@
+// 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.
+
+// +build !cluster_proxy
+
+package e2e
+
+import (
+	"testing"
+)
+
+func TestV3MetricsSecure(t *testing.T) {
+	cfg := configTLS
+	cfg.clusterSize = 1
+	cfg.metricsURLScheme = "https"
+	testCtl(t, metricsTest)
+}
+
+func TestV3MetricsInsecure(t *testing.T) {
+	cfg := configTLS
+	cfg.clusterSize = 1
+	cfg.metricsURLScheme = "http"
+	testCtl(t, metricsTest)
+}
+
+func metricsTest(cx ctlCtx) {
+	if err := ctlV3Put(cx, "k", "v", ""); err != nil {
+		cx.t.Fatal(err)
+	}
+	if err := cURLGet(cx.epc, cURLReq{endpoint: "/metrics", expected: `etcd_debugging_mvcc_keys_total 1`, metricsURLScheme: cx.cfg.metricsURLScheme}); err != nil {
+		cx.t.Fatalf("failed get with curl (%v)", err)
+	}
+	if err := cURLGet(cx.epc, cURLReq{endpoint: "/health", expected: `{"health": "true"}`, metricsURLScheme: cx.cfg.metricsURLScheme}); err != nil {
+		cx.t.Fatalf("failed get with curl (%v)", err)
+	}
+}

+ 14 - 7
e2e/v2_curl_test.go

@@ -125,6 +125,8 @@ type cURLReq struct {
 	value    string
 	value    string
 	expected string
 	expected string
 	header   string
 	header   string
+
+	metricsURLScheme string
 }
 }
 
 
 // cURLPrefixArgs builds the beginning of a curl command for a given key
 // cURLPrefixArgs builds the beginning of a curl command for a given key
@@ -134,14 +136,19 @@ func cURLPrefixArgs(clus *etcdProcessCluster, method string, req cURLReq) []stri
 		cmdArgs = []string{"curl"}
 		cmdArgs = []string{"curl"}
 		acurl   = clus.procs[rand.Intn(clus.cfg.clusterSize)].Config().acurl
 		acurl   = clus.procs[rand.Intn(clus.cfg.clusterSize)].Config().acurl
 	)
 	)
-	if req.isTLS {
-		if clus.cfg.clientTLS != clientTLSAndNonTLS {
-			panic("should not use cURLPrefixArgsUseTLS when serving only TLS or non-TLS")
+	if req.metricsURLScheme != "https" {
+		if req.isTLS {
+			if clus.cfg.clientTLS != clientTLSAndNonTLS {
+				panic("should not use cURLPrefixArgsUseTLS when serving only TLS or non-TLS")
+			}
+			cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath)
+			acurl = toTLS(clus.procs[rand.Intn(clus.cfg.clusterSize)].Config().acurl)
+		} else if clus.cfg.clientTLS == clientTLS {
+			cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath)
 		}
 		}
-		cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath)
-		acurl = toTLS(clus.procs[rand.Intn(clus.cfg.clusterSize)].Config().acurl)
-	} else if clus.cfg.clientTLS == clientTLS {
-		cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath)
+	}
+	if req.metricsURLScheme != "" {
+		acurl = clus.procs[rand.Intn(clus.cfg.clusterSize)].EndpointsMetrics()[0]
 	}
 	}
 	ep := acurl + req.endpoint
 	ep := acurl + req.endpoint