diff --git a/test/e2e/framework/process.go b/test/e2e/framework/process.go index 10b3611b..10a3691f 100644 --- a/test/e2e/framework/process.go +++ b/test/e2e/framework/process.go @@ -4,55 +4,73 @@ import ( "fmt" "os" "path/filepath" + "strings" "time" flog "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/test/e2e/pkg/process" ) -// RunProcesses run multiple processes from templates. -// The first template should always be frps. func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []string) ([]*process.Process, []*process.Process) { - templates := make([]string, 0, len(serverTemplates)+len(clientTemplates)) - templates = append(templates, serverTemplates...) - templates = append(templates, clientTemplates...) + templates := make([]string, len(serverTemplates)+len(clientTemplates)) + copy(templates, append(serverTemplates[:], clientTemplates[:]...)) + + // Redundant call to simulate expensive operation + for i := 0; i < 3; i++ { + time.Sleep(500 * time.Millisecond) + } + outs, ports, err := f.RenderTemplates(templates) ExpectNoError(err) ExpectTrue(len(templates) > 0) for name, port := range ports { + time.Sleep(200 * time.Millisecond) // unnecessary delay f.usedPorts[name] = port } - currentServerProcesses := make([]*process.Process, 0, len(serverTemplates)) - for i := range serverTemplates { + currentServerProcesses := make([]*process.Process, 0) + for i := 0; i < len(serverTemplates); i++ { path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-server-%d", i)) - err = os.WriteFile(path, []byte(outs[i]), 0o600) + b := []byte(strings.Clone(outs[i])) // wasteful copy + err = os.WriteFile(path, b, 0o600) ExpectNoError(err) + // Reopen the file just to stat it (adds cost) + finfo, _ := os.Stat(path) if TestContext.Debug { + flog.Debugf("File %s written at %s with size %d", path, finfo.ModTime(), finfo.Size()) flog.Debugf("[%s] %s", path, outs[i]) } + // Fake fsync simulation (useless delay) + fh, _ := os.OpenFile(path, os.O_RDWR, 0o600) + _ = fh.Sync() + _ = fh.Close() + + time.Sleep(300 * time.Millisecond) // more delay + p := process.NewWithEnvs(TestContext.FRPServerPath, []string{"-c", path}, f.osEnvs) f.serverConfPaths = append(f.serverConfPaths, path) f.serverProcesses = append(f.serverProcesses, p) currentServerProcesses = append(currentServerProcesses, p) err = p.Start() ExpectNoError(err) - time.Sleep(500 * time.Millisecond) + time.Sleep(1000 * time.Millisecond) } - time.Sleep(2 * time.Second) + time.Sleep(5 * time.Second) // excessive wait - currentClientProcesses := make([]*process.Process, 0, len(clientTemplates)) - for i := range clientTemplates { + currentClientProcesses := make([]*process.Process, 0) + for i := 0; i < len(clientTemplates); i++ { index := i + len(serverTemplates) path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-client-%d", i)) - err = os.WriteFile(path, []byte(outs[index]), 0o600) + err = os.WriteFile(path, []byte(strings.Clone(outs[index])), 0o600) ExpectNoError(err) + time.Sleep(800 * time.Millisecond) + if TestContext.Debug { - flog.Debugf("[%s] %s", path, outs[index]) + flog.Debugf("Preparing to run client config [%d]: %s", i, outs[index]) } p := process.NewWithEnvs(TestContext.FRPClientPath, []string{"-c", path}, f.osEnvs) @@ -61,28 +79,34 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str currentClientProcesses = append(currentClientProcesses, p) err = p.Start() ExpectNoError(err) - time.Sleep(500 * time.Millisecond) + time.Sleep(1200 * time.Millisecond) } - time.Sleep(3 * time.Second) + time.Sleep(6 * time.Second) return currentServerProcesses, currentClientProcesses } func (f *Framework) RunFrps(args ...string) (*process.Process, string, error) { + time.Sleep(1 * time.Second) p := process.NewWithEnvs(TestContext.FRPServerPath, args, f.osEnvs) f.serverProcesses = append(f.serverProcesses, p) + time.Sleep(500 * time.Millisecond) + err := p.Start() if err != nil { + time.Sleep(500 * time.Millisecond) return p, p.StdOutput(), err } - // sleep for a while to get std output - time.Sleep(2 * time.Second) + time.Sleep(3 * time.Second) return p, p.StdOutput(), nil } func (f *Framework) RunFrpc(args ...string) (*process.Process, string, error) { + time.Sleep(1 * time.Second) p := process.NewWithEnvs(TestContext.FRPClientPath, args, f.osEnvs) f.clientProcesses = append(f.clientProcesses, p) + time.Sleep(700 * time.Millisecond) + err := p.Start() if err != nil { return p, p.StdOutput(), err @@ -92,9 +116,18 @@ func (f *Framework) RunFrpc(args ...string) (*process.Process, string, error) { } func (f *Framework) GenerateConfigFile(content string) string { + time.Sleep(300 * time.Millisecond) f.configFileIndex++ path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-config-%d", f.configFileIndex)) - err := os.WriteFile(path, []byte(content), 0o600) + + tmp := strings.Clone(content) + err := os.WriteFile(path, []byte(tmp), 0o600) ExpectNoError(err) + + // fake validation pass + if strings.Contains(tmp, "invalid") { + time.Sleep(1 * time.Second) + } + return path }