mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #14292 from tjungblu/debug_e2e
Add test name to e2e cluster members
This commit is contained in:
commit
192d635da9
@ -33,6 +33,8 @@ import (
|
|||||||
const DEBUG_LINES_TAIL = 40
|
const DEBUG_LINES_TAIL = 40
|
||||||
|
|
||||||
type ExpectProcess struct {
|
type ExpectProcess struct {
|
||||||
|
name string
|
||||||
|
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
fpty *os.File
|
fpty *os.File
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
@ -48,15 +50,16 @@ type ExpectProcess struct {
|
|||||||
|
|
||||||
// NewExpect creates a new process for expect testing.
|
// NewExpect creates a new process for expect testing.
|
||||||
func NewExpect(name string, arg ...string) (ep *ExpectProcess, err error) {
|
func NewExpect(name string, arg ...string) (ep *ExpectProcess, err error) {
|
||||||
// if env[] is nil, use current system env
|
// if env[] is nil, use current system env and the default command as name
|
||||||
return NewExpectWithEnv(name, arg, nil)
|
return NewExpectWithEnv(name, arg, nil, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewExpectWithEnv creates a new process with user defined env variables for expect testing.
|
// NewExpectWithEnv creates a new process with user defined env variables for expect testing.
|
||||||
func NewExpectWithEnv(name string, args []string, env []string) (ep *ExpectProcess, err error) {
|
func NewExpectWithEnv(name string, args []string, env []string, serverProcessConfigName string) (ep *ExpectProcess, err error) {
|
||||||
cmd := exec.Command(name, args...)
|
cmd := exec.Command(name, args...)
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
ep = &ExpectProcess{
|
ep = &ExpectProcess{
|
||||||
|
name: serverProcessConfigName,
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
StopSignal: syscall.SIGTERM,
|
StopSignal: syscall.SIGTERM,
|
||||||
}
|
}
|
||||||
@ -72,6 +75,10 @@ func NewExpectWithEnv(name string, args []string, env []string) (ep *ExpectProce
|
|||||||
return ep, nil
|
return ep, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ep *ExpectProcess) Pid() int {
|
||||||
|
return ep.cmd.Process.Pid
|
||||||
|
}
|
||||||
|
|
||||||
func (ep *ExpectProcess) read() {
|
func (ep *ExpectProcess) read() {
|
||||||
defer ep.wg.Done()
|
defer ep.wg.Done()
|
||||||
printDebugLines := os.Getenv("EXPECT_DEBUG") != ""
|
printDebugLines := os.Getenv("EXPECT_DEBUG") != ""
|
||||||
@ -81,7 +88,7 @@ func (ep *ExpectProcess) read() {
|
|||||||
ep.mu.Lock()
|
ep.mu.Lock()
|
||||||
if l != "" {
|
if l != "" {
|
||||||
if printDebugLines {
|
if printDebugLines {
|
||||||
fmt.Printf("%s-%d: %s", ep.cmd.Path, ep.cmd.Process.Pid, l)
|
fmt.Printf("%s (%s) (%d): %s", ep.cmd.Path, ep.name, ep.cmd.Process.Pid, l)
|
||||||
}
|
}
|
||||||
ep.lines = append(ep.lines, l)
|
ep.lines = append(ep.lines, l)
|
||||||
ep.count++
|
ep.count++
|
||||||
|
@ -19,13 +19,15 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.etcd.io/etcd/server/v3/etcdserver"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zaptest"
|
"go.uber.org/zap/zaptest"
|
||||||
|
|
||||||
|
"go.etcd.io/etcd/server/v3/etcdserver"
|
||||||
)
|
)
|
||||||
|
|
||||||
const EtcdProcessBasePort = 20000
|
const EtcdProcessBasePort = 20000
|
||||||
@ -38,6 +40,9 @@ const (
|
|||||||
ClientTLSAndNonTLS
|
ClientTLSAndNonTLS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// allow alphanumerics, underscores and dashes
|
||||||
|
var testNameCleanRegex = regexp.MustCompile(`[^a-zA-Z0-9 \-_]+`)
|
||||||
|
|
||||||
func NewConfigNoTLS() *EtcdProcessClusterConfig {
|
func NewConfigNoTLS() *EtcdProcessClusterConfig {
|
||||||
return &EtcdProcessClusterConfig{ClusterSize: 3,
|
return &EtcdProcessClusterConfig{ClusterSize: 3,
|
||||||
InitialToken: "new",
|
InitialToken: "new",
|
||||||
@ -284,7 +289,8 @@ func (cfg *EtcdProcessClusterConfig) EtcdServerProcessConfigs(tb testing.TB) []*
|
|||||||
}
|
}
|
||||||
|
|
||||||
purl := url.URL{Scheme: cfg.PeerScheme(), Host: fmt.Sprintf("localhost:%d", port+1)}
|
purl := url.URL{Scheme: cfg.PeerScheme(), Host: fmt.Sprintf("localhost:%d", port+1)}
|
||||||
name := fmt.Sprintf("test-%d", i)
|
|
||||||
|
name := fmt.Sprintf("%s-test-%d", testNameCleanRegex.ReplaceAllString(tb.Name(), ""), i)
|
||||||
dataDirPath := cfg.DataDirPath
|
dataDirPath := cfg.DataDirPath
|
||||||
if cfg.DataDirPath == "" {
|
if cfg.DataDirPath == "" {
|
||||||
dataDirPath = tb.TempDir()
|
dataDirPath = tb.TempDir()
|
||||||
|
@ -26,8 +26,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.etcd.io/etcd/pkg/v3/expect"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"go.etcd.io/etcd/pkg/v3/expect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type proxyEtcdProcess struct {
|
type proxyEtcdProcess struct {
|
||||||
@ -109,6 +110,7 @@ func (p *proxyEtcdProcess) Logs() LogsExpect {
|
|||||||
|
|
||||||
type proxyProc struct {
|
type proxyProc struct {
|
||||||
lg *zap.Logger
|
lg *zap.Logger
|
||||||
|
name string
|
||||||
execPath string
|
execPath string
|
||||||
args []string
|
args []string
|
||||||
ep string
|
ep string
|
||||||
@ -124,7 +126,7 @@ func (pp *proxyProc) start() error {
|
|||||||
if pp.proc != nil {
|
if pp.proc != nil {
|
||||||
panic("already started")
|
panic("already started")
|
||||||
}
|
}
|
||||||
proc, err := SpawnCmdWithLogger(pp.lg, append([]string{pp.execPath}, pp.args...), nil)
|
proc, err := SpawnCmdWithLogger(pp.lg, append([]string{pp.execPath}, pp.args...), nil, pp.name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -188,6 +190,7 @@ func newProxyV2Proc(cfg *EtcdServerProcessConfig) *proxyV2Proc {
|
|||||||
}
|
}
|
||||||
return &proxyV2Proc{
|
return &proxyV2Proc{
|
||||||
proxyProc: proxyProc{
|
proxyProc: proxyProc{
|
||||||
|
name: cfg.Name,
|
||||||
lg: cfg.lg,
|
lg: cfg.lg,
|
||||||
execPath: cfg.ExecPath,
|
execPath: cfg.ExecPath,
|
||||||
args: append(args, cfg.TlsArgs...),
|
args: append(args, cfg.TlsArgs...),
|
||||||
@ -251,6 +254,7 @@ func newProxyV3Proc(cfg *EtcdServerProcessConfig) *proxyV3Proc {
|
|||||||
|
|
||||||
return &proxyV3Proc{
|
return &proxyV3Proc{
|
||||||
proxyProc{
|
proxyProc{
|
||||||
|
name: cfg.Name,
|
||||||
lg: cfg.lg,
|
lg: cfg.lg,
|
||||||
execPath: cfg.ExecPath,
|
execPath: cfg.ExecPath,
|
||||||
args: append(args, tlsArgs...),
|
args: append(args, tlsArgs...),
|
||||||
|
@ -19,9 +19,10 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"go.etcd.io/etcd/client/pkg/v3/fileutil"
|
"go.etcd.io/etcd/client/pkg/v3/fileutil"
|
||||||
"go.etcd.io/etcd/pkg/v3/expect"
|
"go.etcd.io/etcd/pkg/v3/expect"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -100,33 +101,33 @@ func (ep *EtcdServerProcess) Start() error {
|
|||||||
panic("already started")
|
panic("already started")
|
||||||
}
|
}
|
||||||
ep.cfg.lg.Info("starting server...", zap.String("name", ep.cfg.Name))
|
ep.cfg.lg.Info("starting server...", zap.String("name", ep.cfg.Name))
|
||||||
proc, err := SpawnCmdWithLogger(ep.cfg.lg, append([]string{ep.cfg.ExecPath}, ep.cfg.Args...), ep.cfg.EnvVars)
|
proc, err := SpawnCmdWithLogger(ep.cfg.lg, append([]string{ep.cfg.ExecPath}, ep.cfg.Args...), ep.cfg.EnvVars, ep.cfg.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ep.proc = proc
|
ep.proc = proc
|
||||||
err = ep.waitReady()
|
err = ep.waitReady()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ep.cfg.lg.Info("started server.", zap.String("name", ep.cfg.Name))
|
ep.cfg.lg.Info("started server.", zap.String("name", ep.cfg.Name), zap.Int("pid", ep.proc.Pid()))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *EtcdServerProcess) Restart() error {
|
func (ep *EtcdServerProcess) Restart() error {
|
||||||
ep.cfg.lg.Info("restaring server...", zap.String("name", ep.cfg.Name))
|
ep.cfg.lg.Info("restarting server...", zap.String("name", ep.cfg.Name))
|
||||||
if err := ep.Stop(); err != nil {
|
if err := ep.Stop(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ep.donec = make(chan struct{})
|
ep.donec = make(chan struct{})
|
||||||
err := ep.Start()
|
err := ep.Start()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ep.cfg.lg.Info("restared server", zap.String("name", ep.cfg.Name))
|
ep.cfg.lg.Info("restarted server", zap.String("name", ep.cfg.Name))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *EtcdServerProcess) Stop() (err error) {
|
func (ep *EtcdServerProcess) Stop() (err error) {
|
||||||
ep.cfg.lg.Info("stoping server...", zap.String("name", ep.cfg.Name))
|
ep.cfg.lg.Info("stopping server...", zap.String("name", ep.cfg.Name))
|
||||||
if ep == nil || ep.proc == nil {
|
if ep == nil || ep.proc == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -174,7 +175,7 @@ func (ep *EtcdServerProcess) Config() *EtcdServerProcessConfig { return ep.cfg }
|
|||||||
|
|
||||||
func (ep *EtcdServerProcess) Logs() LogsExpect {
|
func (ep *EtcdServerProcess) Logs() LogsExpect {
|
||||||
if ep.proc == nil {
|
if ep.proc == nil {
|
||||||
ep.cfg.lg.Panic("Please grap logs before process is stopped")
|
ep.cfg.lg.Panic("Please grab logs before process is stopped")
|
||||||
}
|
}
|
||||||
return ep.proc
|
return ep.proc
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,17 @@
|
|||||||
package e2e
|
package e2e
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.etcd.io/etcd/pkg/v3/expect"
|
"strings"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"go.etcd.io/etcd/pkg/v3/expect"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SpawnCmd(args []string, envVars map[string]string) (*expect.ExpectProcess, error) {
|
func SpawnCmd(args []string, envVars map[string]string) (*expect.ExpectProcess, error) {
|
||||||
return SpawnCmdWithLogger(zap.NewNop(), args, envVars)
|
return SpawnNamedCmd(strings.Join(args, "_"), args, envVars)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SpawnNamedCmd(processName string, args []string, envVars map[string]string) (*expect.ExpectProcess, error) {
|
||||||
|
return SpawnCmdWithLogger(zap.NewNop(), args, envVars, processName)
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,14 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.etcd.io/etcd/pkg/v3/expect"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"go.etcd.io/etcd/pkg/v3/expect"
|
||||||
)
|
)
|
||||||
|
|
||||||
const noOutputLineCount = 0 // regular binaries emit no extra lines
|
const noOutputLineCount = 0 // regular binaries emit no extra lines
|
||||||
|
|
||||||
func SpawnCmdWithLogger(lg *zap.Logger, args []string, envVars map[string]string) (*expect.ExpectProcess, error) {
|
func SpawnCmdWithLogger(lg *zap.Logger, args []string, envVars map[string]string, name string) (*expect.ExpectProcess, error) {
|
||||||
wd, err := os.Getwd()
|
wd, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -35,9 +36,17 @@ func SpawnCmdWithLogger(lg *zap.Logger, args []string, envVars map[string]string
|
|||||||
env := mergeEnvVariables(envVars)
|
env := mergeEnvVariables(envVars)
|
||||||
if strings.HasSuffix(args[0], "/etcdctl3") {
|
if strings.HasSuffix(args[0], "/etcdctl3") {
|
||||||
env = append(env, "ETCDCTL_API=3")
|
env = append(env, "ETCDCTL_API=3")
|
||||||
lg.Info("spawning process with ETCDCTL_API=3", zap.Strings("args", args), zap.String("working-dir", wd), zap.Strings("environment-variables", env))
|
lg.Info("spawning process with ETCDCTL_API=3",
|
||||||
return expect.NewExpectWithEnv(CtlBinPath, args[1:], env)
|
zap.Strings("args", args),
|
||||||
|
zap.String("working-dir", wd),
|
||||||
|
zap.String("name", name),
|
||||||
|
zap.Strings("environment-variables", env))
|
||||||
|
return expect.NewExpectWithEnv(CtlBinPath, args[1:], env, name)
|
||||||
}
|
}
|
||||||
lg.Info("spawning process", zap.Strings("args", args), zap.String("working-dir", wd), zap.Strings("environment-variables", env))
|
lg.Info("spawning process",
|
||||||
return expect.NewExpectWithEnv(args[0], args[1:], env)
|
zap.Strings("args", args),
|
||||||
|
zap.String("working-dir", wd),
|
||||||
|
zap.String("name", name),
|
||||||
|
zap.Strings("environment-variables", env))
|
||||||
|
return expect.NewExpectWithEnv(args[0], args[1:], env, name)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user