From e6c8bf82e0b3977795dcd70f4d43913210319d2e Mon Sep 17 00:00:00 2001 From: Chao Chen Date: Thu, 8 Jun 2023 14:12:21 -0700 Subject: [PATCH] add uds test cases into e2e TestAuthority Signed-off-by: Chao Chen --- server/embed/etcd.go | 4 +-- tests/e2e/ctl_v3_grpc_test.go | 31 +++++++++++++++++++ tests/e2e/ctl_v3_test.go | 2 +- tests/e2e/etcd_release_upgrade_test.go | 4 +-- tests/e2e/utils.go | 1 + tests/framework/e2e/cluster.go | 43 ++++++++++++-------------- tests/framework/e2e/util.go | 18 ++++++++++- tests/framework/integration/cluster.go | 3 +- 8 files changed, 76 insertions(+), 30 deletions(-) diff --git a/server/embed/etcd.go b/server/embed/etcd.go index 7d30562bc..594e11ec3 100644 --- a/server/embed/etcd.go +++ b/server/embed/etcd.go @@ -630,10 +630,10 @@ func configureClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err erro for _, u := range append(cfg.ListenClientUrls, cfg.ListenClientHttpUrls...) { if u.Scheme == "http" || u.Scheme == "unix" { if !cfg.ClientTLSInfo.Empty() { - cfg.logger.Warn("scheme is HTTP while key and cert files are present; ignoring key and cert files", zap.String("client-url", u.String())) + cfg.logger.Warn("scheme is http or unix while key and cert files are present; ignoring key and cert files", zap.String("client-url", u.String())) } if cfg.ClientTLSInfo.ClientCertAuth { - cfg.logger.Warn("scheme is HTTP while --client-cert-auth is enabled; ignoring client cert auth for this URL", zap.String("client-url", u.String())) + cfg.logger.Warn("scheme is http or unix while --client-cert-auth is enabled; ignoring client cert auth for this URL", zap.String("client-url", u.String())) } } if (u.Scheme == "https" || u.Scheme == "unixs") && cfg.ClientTLSInfo.Empty() { diff --git a/tests/e2e/ctl_v3_grpc_test.go b/tests/e2e/ctl_v3_grpc_test.go index a26b5d2a9..7059017db 100644 --- a/tests/e2e/ctl_v3_grpc_test.go +++ b/tests/e2e/ctl_v3_grpc_test.go @@ -33,11 +33,39 @@ import ( func TestAuthority(t *testing.T) { tcs := []struct { name string + useUnix bool useTLS bool useInsecureTLS bool clientURLPattern string expectAuthorityPattern string }{ + { + name: "unix:path", + useUnix: true, + clientURLPattern: "unix:localhost:${MEMBER_PORT}", + expectAuthorityPattern: "localhost:${MEMBER_PORT}", + }, + { + name: "unix://absolute_path", + useUnix: true, + clientURLPattern: "unix://localhost:${MEMBER_PORT}", + expectAuthorityPattern: "localhost:${MEMBER_PORT}", + }, + // "unixs" is not standard schema supported by etcd + { + name: "unixs:absolute_path", + useUnix: true, + useTLS: true, + clientURLPattern: "unixs:localhost:${MEMBER_PORT}", + expectAuthorityPattern: "localhost:${MEMBER_PORT}", + }, + { + name: "unixs://absolute_path", + useUnix: true, + useTLS: true, + clientURLPattern: "unixs://localhost:${MEMBER_PORT}", + expectAuthorityPattern: "localhost:${MEMBER_PORT}", + }, { name: "http://domain[:port]", clientURLPattern: "http://localhost:${MEMBER_PORT}", @@ -90,6 +118,9 @@ func TestAuthority(t *testing.T) { cfg.Client.AutoTLS = tc.useInsecureTLS // Enable debug mode to get logs with http2 headers (including authority) cfg.EnvVars = map[string]string{"GODEBUG": "http2debug=2"} + if tc.useUnix { + cfg.BaseClientScheme = "unix" + } epc, err := e2e.NewEtcdProcessCluster(context.TODO(), t, e2e.WithConfig(cfg)) if err != nil { diff --git a/tests/e2e/ctl_v3_test.go b/tests/e2e/ctl_v3_test.go index a775ad3a7..405aa1506 100644 --- a/tests/e2e/ctl_v3_test.go +++ b/tests/e2e/ctl_v3_test.go @@ -54,7 +54,7 @@ func TestClusterVersion(t *testing.T) { e2e.BeforeTest(t) cfg := e2e.NewConfig( e2e.WithSnapshotCount(3), - e2e.WithBaseScheme("unix"), // to avoid port conflict) + e2e.WithBasePeerScheme("unix"), // to avoid port conflict) e2e.WithRollingStart(tt.rollingStart), ) diff --git a/tests/e2e/etcd_release_upgrade_test.go b/tests/e2e/etcd_release_upgrade_test.go index 3b91665e4..c51240c26 100644 --- a/tests/e2e/etcd_release_upgrade_test.go +++ b/tests/e2e/etcd_release_upgrade_test.go @@ -38,7 +38,7 @@ func TestReleaseUpgrade(t *testing.T) { epc, err := e2e.NewEtcdProcessCluster(context.TODO(), t, e2e.WithVersion(e2e.LastVersion), e2e.WithSnapshotCount(3), - e2e.WithBaseScheme("unix"), // to avoid port conflict + e2e.WithBasePeerScheme("unix"), // to avoid port conflict ) if err != nil { t.Fatalf("could not start etcd process cluster (%v)", err) @@ -120,7 +120,7 @@ func TestReleaseUpgradeWithRestart(t *testing.T) { epc, err := e2e.NewEtcdProcessCluster(context.TODO(), t, e2e.WithVersion(e2e.LastVersion), e2e.WithSnapshotCount(10), - e2e.WithBaseScheme("unix"), + e2e.WithBasePeerScheme("unix"), ) if err != nil { diff --git a/tests/e2e/utils.go b/tests/e2e/utils.go index 581ff8c27..b49239b73 100644 --- a/tests/e2e/utils.go +++ b/tests/e2e/utils.go @@ -59,6 +59,7 @@ func newClient(t *testing.T, entpoints []string, cfg e2e.ClientConfig) *clientv3 return c } +// tlsInfo follows the Client-to-server communication in https://etcd.io/docs/v3.6/op-guide/security/#basic-setup func tlsInfo(t testing.TB, cfg e2e.ClientConfig) (*transport.TLSInfo, error) { switch cfg.ConnectionType { case e2e.ClientNonTLS, e2e.ClientTLSAndNonTLS: diff --git a/tests/framework/e2e/cluster.go b/tests/framework/e2e/cluster.go index 0eafc4579..f6f962a5f 100644 --- a/tests/framework/e2e/cluster.go +++ b/tests/framework/e2e/cluster.go @@ -143,8 +143,11 @@ type EtcdProcessClusterConfig struct { ClusterSize int - BaseScheme string - BasePort int + // BasePeerScheme specifies scheme of --listen-peer-urls and --initial-advertise-peer-urls + BasePeerScheme string + BasePort int + // BaseClientScheme specifies scheme of --listen-client-urls, --listen-client-http-urls and --initial-advertise-client-urls + BaseClientScheme string MetricsURLScheme string @@ -239,14 +242,18 @@ func WithClusterSize(size int) EPClusterOption { return func(c *EtcdProcessClusterConfig) { c.ClusterSize = size } } -func WithBaseScheme(scheme string) EPClusterOption { - return func(c *EtcdProcessClusterConfig) { c.BaseScheme = scheme } +func WithBasePeerScheme(scheme string) EPClusterOption { + return func(c *EtcdProcessClusterConfig) { c.BasePeerScheme = scheme } } func WithBasePort(port int) EPClusterOption { return func(c *EtcdProcessClusterConfig) { c.BasePort = port } } +func WithBaseClientScheme(scheme string) EPClusterOption { + return func(c *EtcdProcessClusterConfig) { c.BaseClientScheme = scheme } +} + func WithClientConnType(clientConnType ClientConnType) EPClusterOption { return func(c *EtcdProcessClusterConfig) { c.Client.ConnectionType = clientConnType } } @@ -413,21 +420,11 @@ func StartEtcdProcessCluster(ctx context.Context, epc *EtcdProcessCluster, cfg * } func (cfg *EtcdProcessClusterConfig) ClientScheme() string { - if cfg.Client.ConnectionType == ClientTLS { - return "https" - } - return "http" + return setupScheme(cfg.BaseClientScheme, cfg.Client.ConnectionType == ClientTLS) } func (cfg *EtcdProcessClusterConfig) PeerScheme() string { - peerScheme := cfg.BaseScheme - if peerScheme == "" { - peerScheme = "http" - } - if cfg.IsPeerTLS { - peerScheme += "s" - } - return peerScheme + return setupScheme(cfg.BasePeerScheme, cfg.IsPeerTLS) } func (cfg *EtcdProcessClusterConfig) EtcdAllServerProcessConfigs(tb testing.TB) []*EtcdServerProcessConfig { @@ -470,10 +467,10 @@ func (cfg *EtcdProcessClusterConfig) EtcdServerProcessConfig(tb testing.TB, i in clientHttpPort := port + 4 if cfg.Client.ConnectionType == ClientTLSAndNonTLS { - curl = clientURL(clientPort, ClientNonTLS) - curls = []string{curl, clientURL(clientPort, ClientTLS)} + curl = clientURL(cfg.ClientScheme(), clientPort, ClientNonTLS) + curls = []string{curl, clientURL(cfg.ClientScheme(), clientPort, ClientTLS)} } else { - curl = clientURL(clientPort, cfg.Client.ConnectionType) + curl = clientURL(cfg.ClientScheme(), clientPort, cfg.Client.ConnectionType) curls = []string{curl} } @@ -518,7 +515,7 @@ func (cfg *EtcdProcessClusterConfig) EtcdServerProcessConfig(tb testing.TB, i in } var clientHttpUrl string if cfg.ClientHttpSeparate { - clientHttpUrl = clientURL(clientHttpPort, cfg.Client.ConnectionType) + clientHttpUrl = clientURL(cfg.ClientScheme(), clientHttpPort, cfg.Client.ConnectionType) args = append(args, "--listen-client-http-urls", clientHttpUrl) } @@ -648,13 +645,13 @@ func (cfg *EtcdProcessClusterConfig) EtcdServerProcessConfig(tb testing.TB, i in } } -func clientURL(port int, connType ClientConnType) string { +func clientURL(scheme string, port int, connType ClientConnType) string { curlHost := fmt.Sprintf("localhost:%d", port) switch connType { case ClientNonTLS: - return (&url.URL{Scheme: "http", Host: curlHost}).String() + return (&url.URL{Scheme: scheme, Host: curlHost}).String() case ClientTLS: - return (&url.URL{Scheme: "https", Host: curlHost}).String() + return (&url.URL{Scheme: ToTLS(scheme), Host: curlHost}).String() default: panic(fmt.Sprintf("Unsupported connection type %v", connType)) } diff --git a/tests/framework/e2e/util.go b/tests/framework/e2e/util.go index 94e1156a2..8e4604ad3 100644 --- a/tests/framework/e2e/util.go +++ b/tests/framework/e2e/util.go @@ -130,8 +130,24 @@ func CloseWithTimeout(p *expect.ExpectProcess, d time.Duration) error { return fmt.Errorf("took longer than %v to Close process %+v", d, p) } +func setupScheme(s string, isTLS bool) string { + if s == "" { + s = "http" + } + if isTLS { + s = ToTLS(s) + } + return s +} + func ToTLS(s string) string { - return strings.Replace(s, "http://", "https://", 1) + if strings.Contains(s, "http") && !strings.Contains(s, "https") { + return strings.Replace(s, "http", "https", 1) + } + if strings.Contains(s, "unix") && !strings.Contains(s, "unixs") { + return strings.Replace(s, "unix", "unixs", 1) + } + return s } func SkipInShortMode(t testing.TB) { diff --git a/tests/framework/integration/cluster.go b/tests/framework/integration/cluster.go index c02352804..446813844 100644 --- a/tests/framework/integration/cluster.go +++ b/tests/framework/integration/cluster.go @@ -191,6 +191,7 @@ func SchemeFromTLSInfo(tls *transport.TLSInfo) string { return URLSchemeTLS } +// fillClusterForMembers fills up Member.InitialPeerURLsMap from each member's [name, scheme and PeerListeners address] func (c *Cluster) fillClusterForMembers() error { if c.Cfg.DiscoveryURL != "" { // Cluster will be discovered @@ -239,7 +240,7 @@ func (c *Cluster) Launch(t testutil.TB) { } } -// ProtoMembers returns a list of all active members as client.Members +// ProtoMembers returns a list of all active members as etcdserverpb.Member func (c *Cluster) ProtoMembers() []*pb.Member { var ms []*pb.Member for _, m := range c.Members {