diff --git a/internal/portforward/service/helpers.go b/internal/portforward/service/helpers.go index db2eb9f4..ad222434 100644 --- a/internal/portforward/service/helpers.go +++ b/internal/portforward/service/helpers.go @@ -2,6 +2,10 @@ package service import ( "fmt" + "maps" + "slices" + "sort" + "strconv" "strings" ) @@ -20,3 +24,28 @@ func portsToString(ports []uint16) (s string) { " and " + portStrings[len(portStrings)-1] } } + +func portPairsToString(internalToExternalPort map[uint16]uint16) (s string) { + switch len(internalToExternalPort) { + case 0: + return "no port forwarded" + case 1: + internal := slices.Collect(maps.Keys(internalToExternalPort))[0] + return "port forwarded is " + portPairToString(internal, internalToExternalPort[internal]) + default: + portStrings := make([]string, 0, len(internalToExternalPort)) + for internal, external := range internalToExternalPort { + portStrings = append(portStrings, portPairToString(internal, external)) + } + sort.StringSlice(portStrings).Sort() + return "ports forwarded are " + strings.Join(portStrings[:len(portStrings)-1], ", ") + + " and " + portStrings[len(portStrings)-1] + } +} + +func portPairToString(internal, external uint16) string { + if internal == external { + return strconv.FormatUint(uint64(external), 10) + } + return fmt.Sprintf("%d (internal port %d)", external, internal) +} diff --git a/internal/portforward/service/helpers_test.go b/internal/portforward/service/helpers_test.go index da28c246..b7c09289 100644 --- a/internal/portforward/service/helpers_test.go +++ b/internal/portforward/service/helpers_test.go @@ -40,3 +40,42 @@ func Test_portsToString(t *testing.T) { }) } } + +func Test_externalInternalPortsToString(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + internalToExternalPort map[uint16]uint16 + s string + }{ + "no_port": { + s: "no port forwarded", + }, + "one_port": { + internalToExternalPort: map[uint16]uint16{123: 123}, + s: "port forwarded is 123", + }, + "two_ports": { + internalToExternalPort: map[uint16]uint16{123: 123, 456: 456}, + s: "ports forwarded are 123 and 456", + }, + "two_ports_different_internal_external": { + internalToExternalPort: map[uint16]uint16{123: 124, 456: 457}, + s: "ports forwarded are 124 (internal port 123) and 457 (internal port 456)", + }, + "three_ports": { + internalToExternalPort: map[uint16]uint16{123: 123, 456: 456, 789: 789}, + s: "ports forwarded are 123, 456 and 789", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + s := portPairsToString(testCase.internalToExternalPort) + + assert.Equal(t, testCase.s, s) + }) + } +} diff --git a/internal/portforward/service/start.go b/internal/portforward/service/start.go index bef256ee..a5932a8b 100644 --- a/internal/portforward/service/start.go +++ b/internal/portforward/service/start.go @@ -89,6 +89,9 @@ func (s *Service) Start(ctx context.Context) (runError <-chan error, err error) } func (s *Service) onNewPorts(ctx context.Context, internalToExternalPorts map[uint16]uint16) (err error) { + s.logger.Info(portPairsToString(internalToExternalPorts)) + + externalPorts := slices.Collect(maps.Values(internalToExternalPorts)) autoRedirectionNeeded := false externalToInternalPorts := make(map[uint16]uint16, len(internalToExternalPorts)) for internal, external := range internalToExternalPorts { @@ -97,12 +100,7 @@ func (s *Service) onNewPorts(ctx context.Context, internalToExternalPorts map[ui autoRedirectionNeeded = true } } - - externalPorts := slices.Collect(maps.Keys(externalToInternalPorts)) slices.Sort(externalPorts) - - s.logger.Info(portsToString(externalPorts)) - userRedirectionEnabled := !slices.Equal(s.settings.ListeningPorts, []uint16{0}) for i, port := range externalPorts { internalPort := externalToInternalPorts[port]