Merge pull request #73676 from martin-helmich/bugfix/expose-forwarded-local-port

client-go: Dynamically assigned local port number not retrievable when port-forwarding
pull/564/head
Kubernetes Prow Robot 2019-02-26 20:55:12 -08:00 committed by GitHub
commit 38a325250f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 2 deletions

View File

@ -205,8 +205,9 @@ func (pf *PortForwarder) forward() error {
var err error
listenSuccess := false
for _, port := range pf.ports {
err = pf.listenOnPort(&port)
for i := range pf.ports {
port := &pf.ports[i]
err = pf.listenOnPort(port)
switch {
case err == nil:
listenSuccess = true

View File

@ -18,11 +18,13 @@ package portforward
import (
"net"
"net/http"
"os"
"reflect"
"sort"
"strings"
"testing"
"time"
"k8s.io/apimachinery/pkg/util/httpstream"
)
@ -39,6 +41,37 @@ func (d *fakeDialer) Dial(protocols ...string) (httpstream.Connection, string, e
return d.conn, d.negotiatedProtocol, d.err
}
type fakeConnection struct {
closed bool
closeChan chan bool
}
func newFakeConnection() httpstream.Connection {
return &fakeConnection{
closeChan: make(chan bool),
}
}
func (c *fakeConnection) CreateStream(headers http.Header) (httpstream.Stream, error) {
return nil, nil
}
func (c *fakeConnection) Close() error {
if !c.closed {
c.closed = true
close(c.closeChan)
}
return nil
}
func (c *fakeConnection) CloseChan() <-chan bool {
return c.closeChan
}
func (c *fakeConnection) SetIdleTimeout(timeout time.Duration) {
// no-op
}
func TestParsePortsAndNew(t *testing.T) {
tests := []struct {
input []string
@ -310,3 +343,46 @@ func TestGetListener(t *testing.T) {
}
}
func TestGetPortsReturnsDynamicallyAssignedLocalPort(t *testing.T) {
dialer := &fakeDialer{
conn: newFakeConnection(),
}
stopChan := make(chan struct{})
readyChan := make(chan struct{})
errChan := make(chan error)
defer func() {
close(stopChan)
forwardErr := <-errChan
if forwardErr != nil {
t.Fatalf("ForwardPorts returned error: %s", forwardErr)
}
}()
pf, err := New(dialer, []string{":5000"}, stopChan, readyChan, os.Stdout, os.Stderr)
if err != nil {
t.Fatalf("error while calling New: %s", err)
}
go func() {
errChan <- pf.ForwardPorts()
close(errChan)
}()
<-pf.Ready
ports, err := pf.GetPorts()
if len(ports) != 1 {
t.Fatalf("expected 1 port, got %d", len(ports))
}
port := ports[0]
if port.Local == 0 {
t.Fatalf("local port is 0, expected != 0")
}
}