mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix flakes in portforward test.
Attempt to fix flaky port forward test using "netstat" in the container to check the a process is listening on the port before attempting to connect. Also, re-enable the test in a seperate job, but w/ a soft fail. This will be removed later in favor of adding port-forward to integration tests to remove the high overhead of starting a new job (scheduling, compiling runsc, downloading images, etc). PiperOrigin-RevId: 526135859
This commit is contained in:
committed by
gVisor bot
parent
79b38029d7
commit
2e45ce14a4
@@ -238,7 +238,6 @@ steps:
|
||||
<<: *kvm_agents
|
||||
cgroup: "v2"
|
||||
arch: "amd64"
|
||||
|
||||
# All system call tests.
|
||||
- <<: *common
|
||||
label: ":toolbox: System call tests (AMD64)"
|
||||
@@ -271,7 +270,7 @@ steps:
|
||||
# See above: not truly a source test.
|
||||
<<: *source_test
|
||||
label: ":docker: Docker tests (cgroupv2)"
|
||||
command: make portforward-tests docker-tests
|
||||
command: make docker-tests
|
||||
agents:
|
||||
<<: *ubuntu_agents
|
||||
arch: "amd64"
|
||||
@@ -284,6 +283,14 @@ steps:
|
||||
<<: *platform_specific_agents
|
||||
<<: *ubuntu_agents
|
||||
arch: "amd64"
|
||||
- <<: *common
|
||||
<<: *docker
|
||||
label: ":one-does-not-simply: Port-Forward tests"
|
||||
command: make portforward-tests
|
||||
agents:
|
||||
<<: *ubuntu_agents
|
||||
arch: "amd64"
|
||||
soft_fail: true
|
||||
- <<: *common
|
||||
<<: *docker
|
||||
label: ":safety_pin: Host network tests"
|
||||
|
||||
@@ -264,9 +264,9 @@ simple-tests: unit-tests # Compatibility target.
|
||||
|
||||
portforward-tests: load-basic_redis load-basic_nginx $(RUNTIME_BIN)
|
||||
@$(call install_runtime,$(RUNTIME),--network=sandbox)
|
||||
@$(call sudo,test/root:portforward_test,--runtime=$(RUNTIME) -test.v)
|
||||
@$(call sudo,test/root:portforward_test,--runtime=$(RUNTIME) -test.v $(ARGS))
|
||||
@$(call install_runtime,$(RUNTIME),--network=host)
|
||||
@$(call sudo,test/root:portforward_test,--runtime=$(RUNTIME) -test.v)
|
||||
@$(call sudo,test/root:portforward_test,--runtime=$(RUNTIME) -test.v $(ARGS))
|
||||
.PHONY: portforward-test
|
||||
|
||||
# Standard integration targets.
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
FROM redis:5.0.4
|
||||
|
||||
RUN apt-get update && apt-get install -y net-tools
|
||||
@@ -54,6 +54,10 @@ func TestPortForwardLocalMode(t *testing.T) {
|
||||
t.Fatalf("failed to create redis server: %v", err)
|
||||
}
|
||||
|
||||
if err := waitUntilServerIsUp(ctx, server, redisPort); err != nil {
|
||||
t.Fatalf("failed to wait for redis server to be up: %v", err)
|
||||
}
|
||||
|
||||
localPort, err := getUnusedPort()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to pick unused port: %v", err)
|
||||
@@ -120,30 +124,8 @@ func TestPortForwardStreamMode(t *testing.T) {
|
||||
t.Fatalf("failed to create nginx server: %v", err)
|
||||
}
|
||||
|
||||
// This is a bit crude, but we need to make sure the server is up without exposing a port to the
|
||||
// host. When the server container boots, the nginx process should run first. If we run nginx
|
||||
// again, it will fail to bind to port 80. Run exec calls until we get that failure.
|
||||
serverUpChan := make(chan struct{}, 1)
|
||||
var upOut string
|
||||
var upErr error
|
||||
reg := regexp.MustCompile(`0\.0\.0\.0:80[\s]*0\.0\.0\.0:\*[\s]*LISTEN`)
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
upOut, upErr = server.Exec(ctx, dockerutil.ExecOpts{}, []string{"netstat", "-l"}...)
|
||||
if reg.MatchString(upOut) {
|
||||
serverUpChan <- struct{}{}
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// If the server isn't up after 10 seconds, there is probably something wrong.
|
||||
select {
|
||||
case <-serverUpChan:
|
||||
break
|
||||
case <-time.After(time.Second * 30):
|
||||
t.Fatalf("could not verify server is up: err: %v out: %s", upErr, upOut)
|
||||
if err := waitUntilServerIsUp(ctx, server, nginxPort); err != nil {
|
||||
t.Fatalf("failed to wait for nginx server to be up: %v", err)
|
||||
}
|
||||
|
||||
socket, err := net.Listen("unix", sockAddr)
|
||||
@@ -192,6 +174,36 @@ func getUnusedPort() (int, error) {
|
||||
return l.Addr().(*net.TCPAddr).Port, nil
|
||||
}
|
||||
|
||||
func waitUntilServerIsUp(ctx context.Context, server *dockerutil.Container, port int) error {
|
||||
// This is a bit crude, but we need to make sure the server is up without exposing a port to the
|
||||
// host. When the server container boots, the nginx process should run first. If we run nginx
|
||||
// again, it will fail to bind to port 80. Run exec calls until we get that failure.
|
||||
serverUpChan := make(chan struct{})
|
||||
var upOut string
|
||||
var upErr error
|
||||
reg := regexp.MustCompile(fmt.Sprintf(`0\.0\.0\.0:%d[\s]*0\.0\.0\.0:\*[\s]*LISTEN`, port))
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
upOut, upErr = server.Exec(ctx, dockerutil.ExecOpts{}, []string{"netstat", "-l"}...)
|
||||
if reg.MatchString(upOut) {
|
||||
close(serverUpChan)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// If the server isn't up after 30 seconds, there is probably something wrong.
|
||||
select {
|
||||
case <-serverUpChan:
|
||||
break
|
||||
case <-time.After(time.Second * 30):
|
||||
return fmt.Errorf("could not verify server is up: err: %v out: %s", upErr, upOut)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type portForwardProcess struct {
|
||||
cmd *exec.Cmd
|
||||
buf bytes.Buffer
|
||||
|
||||
Reference in New Issue
Block a user