diff --git a/test/e2e/examples.go b/test/e2e/examples.go index 135ce706..9f0bc335 100644 --- a/test/e2e/examples.go +++ b/test/e2e/examples.go @@ -26,7 +26,7 @@ var _ = ginkgo.Describe("[Feature: Example]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() }) diff --git a/test/e2e/framework/process.go b/test/e2e/framework/process.go index 702a9b87..6d21e3a2 100644 --- a/test/e2e/framework/process.go +++ b/test/e2e/framework/process.go @@ -3,67 +3,70 @@ package framework import ( "fmt" "maps" + "net" "os" "path/filepath" - "slices" + "strconv" "time" flog "github.com/fatedier/frp/pkg/util/log" + "github.com/fatedier/frp/test/e2e/framework/consts" "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 := slices.Concat(serverTemplates, clientTemplates) +// RunProcesses starts one frps and zero or more frpc processes from templates. +func (f *Framework) RunProcesses(serverTemplate string, clientTemplates []string) (*process.Process, []*process.Process) { + templates := append([]string{serverTemplate}, clientTemplates...) outs, ports, err := f.RenderTemplates(templates) ExpectNoError(err) - ExpectTrue(len(templates) > 0) maps.Copy(f.usedPorts, ports) - currentServerProcesses := make([]*process.Process, 0, len(serverTemplates)) - for i := range serverTemplates { - path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-server-%d", i)) - err = os.WriteFile(path, []byte(outs[i]), 0o600) - ExpectNoError(err) + // Start frps. + serverPath := filepath.Join(f.TempDirectory, "frp-e2e-server-0") + err = os.WriteFile(serverPath, []byte(outs[0]), 0o600) + ExpectNoError(err) - if TestContext.Debug { - flog.Debugf("[%s] %s", path, outs[i]) - } - - 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) + if TestContext.Debug { + flog.Debugf("[%s] %s", serverPath, outs[0]) } - time.Sleep(2 * time.Second) - currentClientProcesses := make([]*process.Process, 0, len(clientTemplates)) + serverProcess := process.NewWithEnvs(TestContext.FRPServerPath, []string{"-c", serverPath}, f.osEnvs) + f.serverConfPaths = append(f.serverConfPaths, serverPath) + f.serverProcesses = append(f.serverProcesses, serverProcess) + err = serverProcess.Start() + ExpectNoError(err) + + if port, ok := ports[consts.PortServerName]; ok { + ExpectNoError(WaitForTCPReady(net.JoinHostPort("127.0.0.1", strconv.Itoa(port)), 5*time.Second)) + } else { + time.Sleep(2 * time.Second) + } + + // Start frpc(s). + clientProcesses := make([]*process.Process, 0, len(clientTemplates)) for i := range clientTemplates { - 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(outs[1+i]), 0o600) ExpectNoError(err) if TestContext.Debug { - flog.Debugf("[%s] %s", path, outs[index]) + flog.Debugf("[%s] %s", path, outs[1+i]) } p := process.NewWithEnvs(TestContext.FRPClientPath, []string{"-c", path}, f.osEnvs) f.clientConfPaths = append(f.clientConfPaths, path) f.clientProcesses = append(f.clientProcesses, p) - currentClientProcesses = append(currentClientProcesses, p) + clientProcesses = append(clientProcesses, p) err = p.Start() ExpectNoError(err) - time.Sleep(500 * time.Millisecond) } - time.Sleep(3 * time.Second) + // frpc needs time to connect and register proxies with frps. + if len(clientProcesses) > 0 { + time.Sleep(1500 * time.Millisecond) + } - return currentServerProcesses, currentClientProcesses + return serverProcess, clientProcesses } func (f *Framework) RunFrps(args ...string) (*process.Process, string, error) { @@ -71,11 +74,10 @@ func (f *Framework) RunFrps(args ...string) (*process.Process, string, error) { f.serverProcesses = append(f.serverProcesses, p) err := p.Start() if err != nil { - return p, p.StdOutput(), err + return p, p.Output(), err } - // Give frps extra time to finish binding ports before proceeding. - time.Sleep(4 * time.Second) - return p, p.StdOutput(), nil + time.Sleep(2 * time.Second) + return p, p.Output(), nil } func (f *Framework) RunFrpc(args ...string) (*process.Process, string, error) { @@ -83,10 +85,10 @@ func (f *Framework) RunFrpc(args ...string) (*process.Process, string, error) { f.clientProcesses = append(f.clientProcesses, p) err := p.Start() if err != nil { - return p, p.StdOutput(), err + return p, p.Output(), err } - time.Sleep(2 * time.Second) - return p, p.StdOutput(), nil + time.Sleep(1500 * time.Millisecond) + return p, p.Output(), nil } func (f *Framework) GenerateConfigFile(content string) string { @@ -96,3 +98,25 @@ func (f *Framework) GenerateConfigFile(content string) string { ExpectNoError(err) return path } + +// WaitForTCPReady polls a TCP address until a connection succeeds or timeout. +func WaitForTCPReady(addr string, timeout time.Duration) error { + if timeout <= 0 { + return fmt.Errorf("invalid timeout for TCP readiness on %s: timeout must be positive", addr) + } + deadline := time.Now().Add(timeout) + var lastErr error + for time.Now().Before(deadline) { + conn, err := net.DialTimeout("tcp", addr, 100*time.Millisecond) + if err == nil { + conn.Close() + return nil + } + lastErr = err + time.Sleep(50 * time.Millisecond) + } + if lastErr == nil { + return fmt.Errorf("timeout waiting for TCP readiness on %s before any dial attempt", addr) + } + return fmt.Errorf("timeout waiting for TCP readiness on %s: %w", addr, lastErr) +} diff --git a/test/e2e/legacy/basic/basic.go b/test/e2e/legacy/basic/basic.go index d3cd61b1..0115c6cb 100644 --- a/test/e2e/legacy/basic/basic.go +++ b/test/e2e/legacy/basic/basic.go @@ -82,7 +82,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { clientConf.WriteString(getProxyConf(test.proxyName, test.portName, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) for _, test := range tests { framework.NewRequestExpect(f). @@ -152,7 +152,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { clientConf.WriteString(getProxyConf(test.proxyName, tests[i].customDomains, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) for _, test := range tests { for domain := range strings.SplitSeq(test.customDomains, ",") { @@ -235,7 +235,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { clientConf.WriteString(getProxyConf(test.proxyName, tests[i].customDomains, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) @@ -419,7 +419,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { } } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientServerConf.String(), clientVisitorConf.String(), clientUser2VisitorConf.String()}) + f.RunProcesses(serverConf, []string{clientServerConf.String(), clientVisitorConf.String(), clientUser2VisitorConf.String()}) for _, test := range tests { timeout := time.Second @@ -497,7 +497,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) // Request without HTTP connect should get error framework.NewRequestExpect(f). diff --git a/test/e2e/legacy/basic/client.go b/test/e2e/legacy/basic/client.go index daed8b22..d9b9b6da 100644 --- a/test/e2e/legacy/basic/client.go +++ b/test/e2e/legacy/basic/client.go @@ -48,7 +48,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() { framework.TCPEchoServerPort, p2Port, framework.TCPEchoServerPort, p3Port) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(p1Port).Ensure() framework.NewRequestExpect(f).Port(p2Port).Ensure() @@ -90,7 +90,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() { admin_pwd = admin `, dashboardPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).RequestModify(func(r *request.Request) { r.HTTP().HTTPPath("/healthz") @@ -116,7 +116,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() { remote_port = %d `, adminPort, framework.TCPEchoServerPort, testPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(testPort).Ensure() diff --git a/test/e2e/legacy/basic/client_server.go b/test/e2e/legacy/basic/client_server.go index d85b5acc..330b9cfc 100644 --- a/test/e2e/legacy/basic/client_server.go +++ b/test/e2e/legacy/basic/client_server.go @@ -76,7 +76,7 @@ func runClientServerTest(f *framework.Framework, configures *generalTestConfigur clientConfs = append(clientConfs, client2Conf) } - f.RunProcesses([]string{serverConf}, clientConfs) + f.RunProcesses(serverConf, clientConfs) if configures.testDelay > 0 { time.Sleep(configures.testDelay) diff --git a/test/e2e/legacy/basic/config.go b/test/e2e/legacy/basic/config.go index 6e9f3564..334cc062 100644 --- a/test/e2e/legacy/basic/config.go +++ b/test/e2e/legacy/basic/config.go @@ -33,7 +33,7 @@ var _ = ginkgo.Describe("[Feature: Config]", func() { `, "`", "`", framework.TCPEchoServerPort, portName) f.SetEnvs([]string{"FRP_TOKEN=123"}) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).PortName(portName).Ensure() }) diff --git a/test/e2e/legacy/basic/http.go b/test/e2e/legacy/basic/http.go index 77ba1052..f1807ecd 100644 --- a/test/e2e/legacy/basic/http.go +++ b/test/e2e/legacy/basic/http.go @@ -56,7 +56,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { locations = /bar `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) tests := []struct { path string @@ -111,7 +111,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { custom_domains = normal.example.com `, fooPort, barPort, otherPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // user1 framework.NewRequestExpect(f).Explain("user1").Port(vhostHTTPPort). @@ -152,7 +152,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { http_pwd = test `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // not set auth header framework.NewRequestExpect(f).Port(vhostHTTPPort). @@ -188,7 +188,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { custom_domains = *.example.com `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // not match host framework.NewRequestExpect(f).Port(vhostHTTPPort). @@ -238,7 +238,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { subdomain = bar `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // foo framework.NewRequestExpect(f).Explain("foo subdomain").Port(vhostHTTPPort). @@ -279,7 +279,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { header_X-From-Where = frp `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // not set auth header framework.NewRequestExpect(f).Port(vhostHTTPPort). @@ -312,7 +312,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { host_header_rewrite = rewrite.example.com `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { @@ -360,7 +360,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { custom_domains = 127.0.0.1 `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) u := url.URL{Scheme: "ws", Host: "127.0.0.1:" + strconv.Itoa(vhostHTTPPort)} c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) diff --git a/test/e2e/legacy/basic/server.go b/test/e2e/legacy/basic/server.go index 418910aa..a01f44aa 100644 --- a/test/e2e/legacy/basic/server.go +++ b/test/e2e/legacy/basic/server.go @@ -58,7 +58,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { remote_port = 11003 `, framework.UDPEchoServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // TCP // Allowed in range @@ -97,7 +97,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { local_port = {{ .%s }} `, adminPort, framework.TCPEchoServerPort, framework.UDPEchoServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) client := f.APIClientForFrpc(adminPort) @@ -138,7 +138,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { custom_domains = example.com `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).RequestModify(func(r *request.Request) { r.HTTP().HTTPHost("example.com") @@ -165,7 +165,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { custom_domains = example.com `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).RequestModify(func(r *request.Request) { r.HTTP().HTTPPath("/healthz") diff --git a/test/e2e/legacy/basic/tcpmux.go b/test/e2e/legacy/basic/tcpmux.go index 15477837..3872ea04 100644 --- a/test/e2e/legacy/basic/tcpmux.go +++ b/test/e2e/legacy/basic/tcpmux.go @@ -76,7 +76,7 @@ var _ = ginkgo.Describe("[Feature: TCPMUX httpconnect]", func() { custom_domains = normal.example.com `, fooPort, barPort, otherPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // user1 framework.NewRequestExpect(f).Explain("user1"). @@ -121,7 +121,7 @@ var _ = ginkgo.Describe("[Feature: TCPMUX httpconnect]", func() { http_pwd = test `, fooPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // not set auth header framework.NewRequestExpect(f).Explain("no auth"). @@ -204,7 +204,7 @@ var _ = ginkgo.Describe("[Feature: TCPMUX httpconnect]", func() { custom_domains = normal.example.com `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f). RequestModify(func(r *request.Request) { diff --git a/test/e2e/legacy/basic/xtcp.go b/test/e2e/legacy/basic/xtcp.go index 3c47f577..6e72f2e1 100644 --- a/test/e2e/legacy/basic/xtcp.go +++ b/test/e2e/legacy/basic/xtcp.go @@ -41,7 +41,7 @@ var _ = ginkgo.Describe("[Feature: XTCP]", func() { fallback_timeout_ms = 200 `, framework.TCPEchoServerPort, bindPortName) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f). RequestModify(func(r *request.Request) { r.Timeout(time.Second) diff --git a/test/e2e/legacy/features/bandwidth_limit.go b/test/e2e/legacy/features/bandwidth_limit.go index c94e473f..a54866b8 100644 --- a/test/e2e/legacy/features/bandwidth_limit.go +++ b/test/e2e/legacy/features/bandwidth_limit.go @@ -35,7 +35,7 @@ var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { bandwidth_limit = 10KB `, localPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) content := strings.Repeat("a", 50*1024) // 5KB start := time.Now() @@ -89,7 +89,7 @@ var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { remote_port = %d `, localPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) content := strings.Repeat("a", 50*1024) // 5KB start := time.Now() diff --git a/test/e2e/legacy/features/group.go b/test/e2e/legacy/features/group.go index 28e5eeed..57c143c5 100644 --- a/test/e2e/legacy/features/group.go +++ b/test/e2e/legacy/features/group.go @@ -88,7 +88,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { group_key = 123 `, fooPort, remotePort, barPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) fooCount := 0 barCount := 0 @@ -144,7 +144,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { health_check_interval_s = 1 `, fooPort, remotePort, barPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // check foo and bar is ok results := []string{} @@ -213,7 +213,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { health_check_url = /healthz `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // send first HTTP request var contents []string diff --git a/test/e2e/legacy/features/heartbeat.go b/test/e2e/legacy/features/heartbeat.go index 09bf0e6a..3c1758f2 100644 --- a/test/e2e/legacy/features/heartbeat.go +++ b/test/e2e/legacy/features/heartbeat.go @@ -38,7 +38,7 @@ var _ = ginkgo.Describe("[Feature: Heartbeat]", func() { `, serverPort, f.PortByName(framework.TCPEchoServerPort), remotePort) // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Protocol("tcp").Port(remotePort).Ensure() diff --git a/test/e2e/legacy/features/monitor.go b/test/e2e/legacy/features/monitor.go index 75aa183b..0b19a85e 100644 --- a/test/e2e/legacy/features/monitor.go +++ b/test/e2e/legacy/features/monitor.go @@ -33,7 +33,7 @@ var _ = ginkgo.Describe("[Feature: Monitor]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() time.Sleep(500 * time.Millisecond) diff --git a/test/e2e/legacy/features/real_ip.go b/test/e2e/legacy/features/real_ip.go index a79afb45..dae74e56 100644 --- a/test/e2e/legacy/features/real_ip.go +++ b/test/e2e/legacy/features/real_ip.go @@ -44,7 +44,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { custom_domains = normal.example.com `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { @@ -90,7 +90,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { proxy_protocol_version = v2 `, localPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure(func(resp *request.Response) bool { log.Tracef("proxy protocol get SourceAddr: %s", string(resp.Content)) @@ -136,7 +136,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { proxy_protocol_version = v2 `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort).RequestModify(func(r *request.Request) { r.HTTP().HTTPHost("normal.example.com") diff --git a/test/e2e/legacy/plugin/client.go b/test/e2e/legacy/plugin/client.go index c38cbaf7..ca294280 100644 --- a/test/e2e/legacy/plugin/client.go +++ b/test/e2e/legacy/plugin/client.go @@ -70,7 +70,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { clientConf.WriteString(getProxyConf(test.proxyName, test.portName, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) for _, test := range tests { framework.NewRequestExpect(f).Port(f.PortByName(test.portName)).Ensure() @@ -92,7 +92,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { plugin_http_passwd = 123 `, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // http proxy, no auth info framework.NewRequestExpect(f).PortName(framework.HTTPSimpleServerPort).RequestModify(func(r *request.Request) { @@ -124,7 +124,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { plugin_passwd = 123 `, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // http proxy, no auth info framework.NewRequestExpect(f).PortName(framework.TCPEchoServerPort).RequestModify(func(r *request.Request) { @@ -168,7 +168,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { plugin_http_passwd = 123 `, remotePort, f.TempDirectory, f.TempDirectory, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // from tcp proxy framework.NewRequestExpect(f).Request( @@ -202,7 +202,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { plugin_local_addr = 127.0.0.1:%d `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) @@ -246,7 +246,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { plugin_key_path = %s `, localPort, crtPath, keyPath) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) localServer := httpserver.New( httpserver.WithBindPort(localPort), @@ -290,7 +290,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { plugin_key_path = %s `, localPort, crtPath, keyPath) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) diff --git a/test/e2e/legacy/plugin/server.go b/test/e2e/legacy/plugin/server.go index 9120b7d7..b00b1bac 100644 --- a/test/e2e/legacy/plugin/server.go +++ b/test/e2e/legacy/plugin/server.go @@ -71,7 +71,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort2) - f.RunProcesses([]string{serverConf}, []string{clientConf, invalidTokenClientConf}) + f.RunProcesses(serverConf, []string{clientConf, invalidTokenClientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() framework.NewRequestExpect(f).Port(remotePort2).ExpectError(true).Ensure() @@ -119,7 +119,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() }) @@ -153,7 +153,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = 0 `, framework.TCPEchoServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() }) @@ -195,7 +195,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort) - _, clients := f.RunProcesses([]string{serverConf}, []string{clientConf}) + _, clients := f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -250,7 +250,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -297,7 +297,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -342,7 +342,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -389,7 +389,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remote_port = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() diff --git a/test/e2e/pkg/process/process.go b/test/e2e/pkg/process/process.go index e6721e1d..04796225 100644 --- a/test/e2e/pkg/process/process.go +++ b/test/e2e/pkg/process/process.go @@ -61,6 +61,10 @@ func (p *Process) StdOutput() string { return p.stdOutput.String() } +func (p *Process) Output() string { + return p.stdOutput.String() + p.errorOutput.String() +} + func (p *Process) SetBeforeStopHandler(fn func()) { p.beforeStopHandler = fn } diff --git a/test/e2e/v1/basic/annotations.go b/test/e2e/v1/basic/annotations.go index 4f4a8a91..78e94a16 100644 --- a/test/e2e/v1/basic/annotations.go +++ b/test/e2e/v1/basic/annotations.go @@ -35,7 +35,7 @@ var _ = ginkgo.Describe("[Feature: Annotations]", func() { "frp.e2e.test/bar" = "value2" `, framework.TCPEchoServerPort, p1Port) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(p1Port).Ensure() diff --git a/test/e2e/v1/basic/basic.go b/test/e2e/v1/basic/basic.go index b9f4eded..8994ba73 100644 --- a/test/e2e/v1/basic/basic.go +++ b/test/e2e/v1/basic/basic.go @@ -83,7 +83,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { clientConf.WriteString(getProxyConf(test.proxyName, test.portName, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) for _, test := range tests { framework.NewRequestExpect(f). @@ -154,7 +154,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { clientConf.WriteString(getProxyConf(test.proxyName, tests[i].customDomains, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) for _, test := range tests { for domain := range strings.SplitSeq(test.customDomains, ",") { @@ -240,7 +240,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { clientConf.WriteString(getProxyConf(test.proxyName, tests[i].customDomains, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) @@ -426,7 +426,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { } } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientServerConf.String(), clientVisitorConf.String(), clientUser2VisitorConf.String()}) + f.RunProcesses(serverConf, []string{clientServerConf.String(), clientVisitorConf.String(), clientUser2VisitorConf.String()}) for _, test := range tests { timeout := time.Second @@ -505,7 +505,7 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() { } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) // Request without HTTP connect should get error framework.NewRequestExpect(f). diff --git a/test/e2e/v1/basic/client.go b/test/e2e/v1/basic/client.go index fd269d75..ec2011ea 100644 --- a/test/e2e/v1/basic/client.go +++ b/test/e2e/v1/basic/client.go @@ -51,7 +51,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() { framework.TCPEchoServerPort, p2Port, framework.TCPEchoServerPort, p3Port) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(p1Port).Ensure() framework.NewRequestExpect(f).Port(p2Port).Ensure() @@ -93,7 +93,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() { webServer.password = "admin" `, dashboardPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).RequestModify(func(r *request.Request) { r.HTTP().HTTPPath("/healthz") @@ -120,7 +120,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() { remotePort = %d `, adminPort, framework.TCPEchoServerPort, testPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(testPort).Ensure() diff --git a/test/e2e/v1/basic/client_server.go b/test/e2e/v1/basic/client_server.go index 85dd1227..3a2fa28d 100644 --- a/test/e2e/v1/basic/client_server.go +++ b/test/e2e/v1/basic/client_server.go @@ -78,7 +78,7 @@ func runClientServerTest(f *framework.Framework, configures *generalTestConfigur clientConfs = append(clientConfs, client2Conf) } - f.RunProcesses([]string{serverConf}, clientConfs) + f.RunProcesses(serverConf, clientConfs) if configures.testDelay > 0 { time.Sleep(configures.testDelay) diff --git a/test/e2e/v1/basic/config.go b/test/e2e/v1/basic/config.go index 314e7fc4..e290109e 100644 --- a/test/e2e/v1/basic/config.go +++ b/test/e2e/v1/basic/config.go @@ -35,7 +35,7 @@ var _ = ginkgo.Describe("[Feature: Config]", func() { `, "`", "`", framework.TCPEchoServerPort, portName) f.SetEnvs([]string{"FRP_TOKEN=123"}) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).PortName(portName).Ensure() }) @@ -69,7 +69,7 @@ var _ = ginkgo.Describe("[Feature: Config]", func() { escapeTemplate("{{- end }}"), ) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) client := f.APIClientForFrpc(adminPort) checkProxyFn := func(name string, localPort, remotePort int) { @@ -149,7 +149,7 @@ proxies: remotePort: %d `, port.GenName("Server"), framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() }) @@ -161,7 +161,7 @@ proxies: "proxies": [{"name": "tcp", "type": "tcp", "localPort": {{ .%s }}, "remotePort": %d}]}`, port.GenName("Server"), framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() }) }) diff --git a/test/e2e/v1/basic/http.go b/test/e2e/v1/basic/http.go index c37e84e7..b594f1ea 100644 --- a/test/e2e/v1/basic/http.go +++ b/test/e2e/v1/basic/http.go @@ -59,7 +59,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { locations = ["/bar"] `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) tests := []struct { path string @@ -117,7 +117,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { customDomains = ["normal.example.com"] `, fooPort, barPort, otherPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // user1 framework.NewRequestExpect(f).Explain("user1").Port(vhostHTTPPort). @@ -159,7 +159,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { httpPassword = "test" `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // not set auth header framework.NewRequestExpect(f).Port(vhostHTTPPort). @@ -196,7 +196,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { customDomains = ["*.example.com"] `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // not match host framework.NewRequestExpect(f).Port(vhostHTTPPort). @@ -248,7 +248,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { subdomain = "bar" `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // foo framework.NewRequestExpect(f).Explain("foo subdomain").Port(vhostHTTPPort). @@ -290,7 +290,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { requestHeaders.set.x-from-where = "frp" `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { @@ -323,7 +323,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { responseHeaders.set.x-from-where = "frp" `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { @@ -357,7 +357,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { hostHeaderRewrite = "rewrite.example.com" `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { @@ -406,7 +406,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { customDomains = ["127.0.0.1"] `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) u := url.URL{Scheme: "ws", Host: "127.0.0.1:" + strconv.Itoa(vhostHTTPPort)} c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) @@ -447,7 +447,7 @@ var _ = ginkgo.Describe("[Feature: HTTP]", func() { customDomains = ["normal.example.com"] `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { diff --git a/test/e2e/v1/basic/server.go b/test/e2e/v1/basic/server.go index 274102a2..f2714abb 100644 --- a/test/e2e/v1/basic/server.go +++ b/test/e2e/v1/basic/server.go @@ -67,7 +67,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { remotePort = 11003 `, framework.UDPEchoServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // TCP // Allowed in range @@ -108,7 +108,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { localPort = {{ .%s }} `, adminPort, framework.TCPEchoServerPort, framework.UDPEchoServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) client := f.APIClientForFrpc(adminPort) @@ -150,7 +150,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { customDomains = ["example.com"] `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).RequestModify(func(r *request.Request) { r.HTTP().HTTPHost("example.com") @@ -178,7 +178,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() { customDomains = ["example.com"] `, framework.HTTPSimpleServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).RequestModify(func(r *request.Request) { r.HTTP().HTTPPath("/healthz") diff --git a/test/e2e/v1/basic/tcpmux.go b/test/e2e/v1/basic/tcpmux.go index 7ee58a79..9b839faa 100644 --- a/test/e2e/v1/basic/tcpmux.go +++ b/test/e2e/v1/basic/tcpmux.go @@ -79,7 +79,7 @@ var _ = ginkgo.Describe("[Feature: TCPMUX httpconnect]", func() { customDomains = ["normal.example.com"] `, fooPort, barPort, otherPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // user1 framework.NewRequestExpect(f).Explain("user1"). @@ -125,7 +125,7 @@ var _ = ginkgo.Describe("[Feature: TCPMUX httpconnect]", func() { httpPassword = "test" `, fooPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // not set auth header framework.NewRequestExpect(f).Explain("no auth"). @@ -209,7 +209,7 @@ var _ = ginkgo.Describe("[Feature: TCPMUX httpconnect]", func() { customDomains = ["normal.example.com"] `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f). RequestModify(func(r *request.Request) { diff --git a/test/e2e/v1/basic/token_source.go b/test/e2e/v1/basic/token_source.go index 4ed7051c..d12dd4de 100644 --- a/test/e2e/v1/basic/token_source.go +++ b/test/e2e/v1/basic/token_source.go @@ -16,8 +16,11 @@ package basic import ( "fmt" + "net" "os" "path/filepath" + "strconv" + "time" "github.com/onsi/ginkgo/v2" @@ -73,7 +76,7 @@ localPort = {{ .%s }} remotePort = {{ .%s }} `, tokenContent, framework.TCPEchoServerPort, portName) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).PortName(portName).Ensure() }) @@ -109,7 +112,7 @@ localPort = {{ .%s }} remotePort = {{ .%s }} `, tokenFile, framework.TCPEchoServerPort, portName) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).PortName(portName).Ensure() }) @@ -150,7 +153,7 @@ localPort = {{ .%s }} remotePort = {{ .%s }} `, clientTokenFile, framework.TCPEchoServerPort, portName) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).PortName(portName).Ensure() }) @@ -190,7 +193,7 @@ localPort = {{ .%s }} remotePort = {{ .%s }} `, clientTokenFile, framework.TCPEchoServerPort, portName) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // This should fail due to token mismatch - the client should not be able to connect // We expect the request to fail because the proxy tunnel is not established @@ -198,32 +201,27 @@ remotePort = {{ .%s }} }) ginkgo.It("should fail with non-existent token file", func() { - // This test verifies that server fails to start when tokenSource points to non-existent file - // We'll verify this by checking that the configuration loading itself fails - - // Create a config that references a non-existent file tmpDir := f.TempDirectory nonExistentFile := filepath.Join(tmpDir, "non_existent_token") - serverConf := consts.DefaultServerConfig - - // Server config with non-existent tokenSource file - serverConf += fmt.Sprintf(` + serverPort := f.AllocPort() + serverConf := fmt.Sprintf(` +bindAddr = "0.0.0.0" +bindPort = %d auth.tokenSource.type = "file" auth.tokenSource.file.path = "%s" -`, nonExistentFile) +`, serverPort, nonExistentFile) - // The test expectation is that this will fail during the RunProcesses call - // because the server cannot load the configuration due to missing token file - defer func() { - if r := recover(); r != nil { - // Expected: server should fail to start due to missing file - ginkgo.By(fmt.Sprintf("Server correctly failed to start: %v", r)) - } - }() + serverConfigPath := f.GenerateConfigFile(serverConf) - // This should cause a panic or error during server startup - f.RunProcesses([]string{serverConf}, []string{}) + _, _, _ = f.RunFrps("-c", serverConfigPath) + + // Server should have failed to start, so the port should not be listening. + conn, err := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(serverPort)), 1*time.Second) + if err == nil { + conn.Close() + } + framework.ExpectTrue(err != nil, "server should not be listening on port %d", serverPort) }) }) diff --git a/test/e2e/v1/basic/xtcp.go b/test/e2e/v1/basic/xtcp.go index a5aaf67b..57905f0d 100644 --- a/test/e2e/v1/basic/xtcp.go +++ b/test/e2e/v1/basic/xtcp.go @@ -42,7 +42,7 @@ var _ = ginkgo.Describe("[Feature: XTCP]", func() { fallbackTimeoutMs = 200 `, framework.TCPEchoServerPort, bindPortName) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f). RequestModify(func(r *request.Request) { r.Timeout(time.Second) diff --git a/test/e2e/v1/features/bandwidth_limit.go b/test/e2e/v1/features/bandwidth_limit.go index efcf38ed..11503adb 100644 --- a/test/e2e/v1/features/bandwidth_limit.go +++ b/test/e2e/v1/features/bandwidth_limit.go @@ -36,7 +36,7 @@ var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { transport.bandwidthLimit = "10KB" `, localPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) content := strings.Repeat("a", 50*1024) // 5KB start := time.Now() @@ -92,7 +92,7 @@ var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { remotePort = %d `, localPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) content := strings.Repeat("a", 50*1024) // 5KB start := time.Now() diff --git a/test/e2e/v1/features/group.go b/test/e2e/v1/features/group.go index 2a7891e7..610903d0 100644 --- a/test/e2e/v1/features/group.go +++ b/test/e2e/v1/features/group.go @@ -92,7 +92,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { loadBalancer.groupKey = "123" `, fooPort, remotePort, barPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) fooCount := 0 barCount := 0 @@ -157,7 +157,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { loadBalancer.groupKey = "123" `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) fooCount := 0 barCount := 0 @@ -222,7 +222,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { loadBalancer.groupKey = "123" `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) proxyURL := fmt.Sprintf("http://127.0.0.1:%d", vhostPort) fooCount := 0 @@ -286,7 +286,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { healthCheck.intervalSeconds = 1 `, fooPort, remotePort, barPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // check foo and bar is ok results := []string{} @@ -357,7 +357,7 @@ var _ = ginkgo.Describe("[Feature: Group]", func() { healthCheck.path = "/healthz" `, fooPort, barPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // send first HTTP request var contents []string diff --git a/test/e2e/v1/features/heartbeat.go b/test/e2e/v1/features/heartbeat.go index 4f5409fe..08a1b5d9 100644 --- a/test/e2e/v1/features/heartbeat.go +++ b/test/e2e/v1/features/heartbeat.go @@ -37,7 +37,7 @@ var _ = ginkgo.Describe("[Feature: Heartbeat]", func() { `, serverPort, f.PortByName(framework.TCPEchoServerPort), remotePort) // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Protocol("tcp").Port(remotePort).Ensure() diff --git a/test/e2e/v1/features/monitor.go b/test/e2e/v1/features/monitor.go index fe92203a..f70dce16 100644 --- a/test/e2e/v1/features/monitor.go +++ b/test/e2e/v1/features/monitor.go @@ -34,7 +34,7 @@ var _ = ginkgo.Describe("[Feature: Monitor]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() time.Sleep(500 * time.Millisecond) diff --git a/test/e2e/v1/features/real_ip.go b/test/e2e/v1/features/real_ip.go index a52cf0a2..6bebfc2b 100644 --- a/test/e2e/v1/features/real_ip.go +++ b/test/e2e/v1/features/real_ip.go @@ -48,7 +48,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { customDomains = ["normal.example.com"] `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { @@ -82,7 +82,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { customDomains = ["normal.example.com"] `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort). RequestModify(func(r *request.Request) { @@ -112,7 +112,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { localAddr = "127.0.0.1:%d" `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) @@ -154,7 +154,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { localAddr = "127.0.0.1:%d" `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) localServer := httpserver.New( httpserver.WithBindPort(localPort), @@ -212,7 +212,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { transport.proxyProtocolVersion = "v2" `, localPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure(func(resp *request.Response) bool { log.Tracef("proxy protocol get SourceAddr: %s", string(resp.Content)) @@ -262,7 +262,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { transport.proxyProtocolVersion = "v2" `, localPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Protocol("udp").Port(remotePort).Ensure(func(resp *request.Response) bool { log.Tracef("udp proxy protocol get SourceAddr: %s", string(resp.Content)) @@ -309,7 +309,7 @@ var _ = ginkgo.Describe("[Feature: Real IP]", func() { transport.proxyProtocolVersion = "v2" `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(vhostHTTPPort).RequestModify(func(r *request.Request) { r.HTTP().HTTPHost("normal.example.com") diff --git a/test/e2e/v1/features/ssh_tunnel.go b/test/e2e/v1/features/ssh_tunnel.go index 0b8725f6..c120eab0 100644 --- a/test/e2e/v1/features/ssh_tunnel.go +++ b/test/e2e/v1/features/ssh_tunnel.go @@ -3,6 +3,8 @@ package features import ( "crypto/tls" "fmt" + "net" + "strconv" "time" "github.com/onsi/ginkgo/v2" @@ -25,7 +27,8 @@ var _ = ginkgo.Describe("[Feature: SSH Tunnel]", func() { sshTunnelGateway.bindPort = %d `, sshPort) - f.RunProcesses([]string{serverConf}, nil) + f.RunProcesses(serverConf, nil) + framework.ExpectNoError(framework.WaitForTCPReady(net.JoinHostPort("127.0.0.1", strconv.Itoa(sshPort)), 5*time.Second)) localPort := f.PortByName(framework.TCPEchoServerPort) remotePort := f.AllocPort() @@ -49,7 +52,8 @@ var _ = ginkgo.Describe("[Feature: SSH Tunnel]", func() { sshTunnelGateway.bindPort = %d `, vhostPort, sshPort) - f.RunProcesses([]string{serverConf}, nil) + f.RunProcesses(serverConf, nil) + framework.ExpectNoError(framework.WaitForTCPReady(net.JoinHostPort("127.0.0.1", strconv.Itoa(sshPort)), 5*time.Second)) localPort := f.PortByName(framework.HTTPSimpleServerPort) tc := ssh.NewTunnelClient( @@ -76,7 +80,8 @@ var _ = ginkgo.Describe("[Feature: SSH Tunnel]", func() { sshTunnelGateway.bindPort = %d `, vhostPort, sshPort) - f.RunProcesses([]string{serverConf}, nil) + f.RunProcesses(serverConf, nil) + framework.ExpectNoError(framework.WaitForTCPReady(net.JoinHostPort("127.0.0.1", strconv.Itoa(sshPort)), 5*time.Second)) localPort := f.AllocPort() testDomain := "test.example.com" @@ -118,7 +123,8 @@ var _ = ginkgo.Describe("[Feature: SSH Tunnel]", func() { sshTunnelGateway.bindPort = %d `, tcpmuxPort, sshPort) - f.RunProcesses([]string{serverConf}, nil) + f.RunProcesses(serverConf, nil) + framework.ExpectNoError(framework.WaitForTCPReady(net.JoinHostPort("127.0.0.1", strconv.Itoa(sshPort)), 5*time.Second)) localPort := f.AllocPort() testDomain := "test.example.com" @@ -173,7 +179,8 @@ var _ = ginkgo.Describe("[Feature: SSH Tunnel]", func() { bindPort = %d `, bindPort) - f.RunProcesses([]string{serverConf}, []string{visitorConf}) + f.RunProcesses(serverConf, []string{visitorConf}) + framework.ExpectNoError(framework.WaitForTCPReady(net.JoinHostPort("127.0.0.1", strconv.Itoa(sshPort)), 5*time.Second)) localPort := f.PortByName(framework.TCPEchoServerPort) tc := ssh.NewTunnelClient( diff --git a/test/e2e/v1/features/store.go b/test/e2e/v1/features/store.go index 284c85f4..3fc6bb14 100644 --- a/test/e2e/v1/features/store.go +++ b/test/e2e/v1/features/store.go @@ -30,7 +30,7 @@ var _ = ginkgo.Describe("[Feature: Store]", func() { path = "%s/store.json" `, adminPort, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) time.Sleep(500 * time.Millisecond) proxyConfig := map[string]any{ @@ -71,7 +71,7 @@ var _ = ginkgo.Describe("[Feature: Store]", func() { path = "%s/store.json" `, adminPort, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) time.Sleep(500 * time.Millisecond) proxyConfig := map[string]any{ @@ -125,7 +125,7 @@ var _ = ginkgo.Describe("[Feature: Store]", func() { path = "%s/store.json" `, adminPort, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) time.Sleep(500 * time.Millisecond) proxyConfig := map[string]any{ @@ -173,7 +173,7 @@ var _ = ginkgo.Describe("[Feature: Store]", func() { path = "%s/store.json" `, adminPort, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) time.Sleep(500 * time.Millisecond) proxyConfig := map[string]any{ @@ -225,7 +225,7 @@ var _ = ginkgo.Describe("[Feature: Store]", func() { webServer.port = %d `, adminPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) time.Sleep(500 * time.Millisecond) framework.NewRequestExpect(f).RequestModify(func(r *request.Request) { @@ -247,7 +247,7 @@ var _ = ginkgo.Describe("[Feature: Store]", func() { path = "%s/store.json" `, adminPort, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) time.Sleep(500 * time.Millisecond) invalidBody, _ := json.Marshal(map[string]any{ @@ -280,7 +280,7 @@ var _ = ginkgo.Describe("[Feature: Store]", func() { path = "%s/store.json" `, adminPort, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) time.Sleep(500 * time.Millisecond) createBody, _ := json.Marshal(map[string]any{ diff --git a/test/e2e/v1/plugin/client.go b/test/e2e/v1/plugin/client.go index 4cb9d7d4..1ea25a6e 100644 --- a/test/e2e/v1/plugin/client.go +++ b/test/e2e/v1/plugin/client.go @@ -74,7 +74,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { clientConf.WriteString(getProxyConf(test.proxyName, test.portName, test.extraConfig) + "\n") } // run frps and frpc - f.RunProcesses([]string{serverConf}, []string{clientConf.String()}) + f.RunProcesses(serverConf, []string{clientConf.String()}) for _, test := range tests { framework.NewRequestExpect(f).Port(f.PortByName(test.portName)).Ensure() @@ -98,7 +98,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { httpPassword = "123" `, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // http proxy, no auth info framework.NewRequestExpect(f).PortName(framework.HTTPSimpleServerPort).RequestModify(func(r *request.Request) { @@ -132,7 +132,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { password = "123" `, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // http proxy, no auth info framework.NewRequestExpect(f).PortName(framework.TCPEchoServerPort).RequestModify(func(r *request.Request) { @@ -182,7 +182,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { httpPassword = "123" `, remotePort, f.TempDirectory, f.TempDirectory, f.TempDirectory) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) // from tcp proxy framework.NewRequestExpect(f).Request( @@ -218,7 +218,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { localAddr = "127.0.0.1:%d" `, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) @@ -264,7 +264,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { keyPath = "%s" `, localPort, crtPath, keyPath) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) localServer := httpserver.New( httpserver.WithBindPort(localPort), @@ -310,7 +310,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { keyPath = "%s" `, localPort, crtPath, keyPath) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) tlsConfig, err := transport.NewServerTLSConfig("", "", "") framework.ExpectNoError(err) @@ -350,7 +350,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { hostHeaderRewrite = "rewrite.test.com" `, remotePort, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) localServer := httpserver.New( httpserver.WithBindPort(localPort), @@ -385,7 +385,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { requestHeaders.set.x-from-where = "frp" `, remotePort, localPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) localServer := httpserver.New( httpserver.WithBindPort(localPort), @@ -431,7 +431,7 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { keyPath = "%s" `, localPort, crtPath, keyPath) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) localServer := httpserver.New( httpserver.WithBindPort(localPort), diff --git a/test/e2e/v1/plugin/server.go b/test/e2e/v1/plugin/server.go index 6637650d..fd684ef5 100644 --- a/test/e2e/v1/plugin/server.go +++ b/test/e2e/v1/plugin/server.go @@ -74,7 +74,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort2) - f.RunProcesses([]string{serverConf}, []string{clientConf, invalidTokenClientConf}) + f.RunProcesses(serverConf, []string{clientConf, invalidTokenClientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() framework.NewRequestExpect(f).Port(remotePort2).ExpectError(true).Ensure() @@ -124,7 +124,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() }) @@ -160,7 +160,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = 0 `, framework.TCPEchoServerPort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() }) @@ -204,7 +204,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - _, clients := f.RunProcesses([]string{serverConf}, []string{clientConf}) + _, clients := f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -261,7 +261,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -310,7 +310,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -357,7 +357,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure() @@ -406,7 +406,7 @@ var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { remotePort = %d `, framework.TCPEchoServerPort, remotePort) - f.RunProcesses([]string{serverConf}, []string{clientConf}) + f.RunProcesses(serverConf, []string{clientConf}) framework.NewRequestExpect(f).Port(remotePort).Ensure()