From 62856a1f9f9e7cfd20c35ef42a891824fb60c9b4 Mon Sep 17 00:00:00 2001 From: intojhanurag Date: Thu, 11 Dec 2025 20:14:45 +0000 Subject: [PATCH 1/7] Do refactoring and add tests --- pkg/functions/runner.go | 38 ++++++++++----------- pkg/functions/runner_test.go | 65 ++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 20 deletions(-) diff --git a/pkg/functions/runner.go b/pkg/functions/runner.go index 27c4ce3895..7289d29e8a 100644 --- a/pkg/functions/runner.go +++ b/pkg/functions/runner.go @@ -11,6 +11,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "time" ) @@ -26,6 +27,19 @@ type defaultRunner struct { err io.Writer } +func ParseAddressFlag(val string) (string, string) { + if h, p, err := net.SplitHostPort(val); err == nil { + return h, p + } + + if val == "" { + val = "localhost" + } + + // TODO: optionally validate hostname or IP + return val, "8080" +} + func newDefaultRunner(client *Client, out, err io.Writer) *defaultRunner { return &defaultRunner{ client: client, @@ -41,17 +55,9 @@ func (r *defaultRunner) Run(ctx context.Context, f Function, address string, sta ) // Parse address if provided, otherwise use defaults - host := defaultRunHost - port := defaultRunPort - explicitPort := address != "" - - if address != "" { - var err error - host, port, err = net.SplitHostPort(address) - if err != nil { - return nil, fmt.Errorf("invalid address format '%s': %w", address, err) - } - } + host, port := ParseAddressFlag(address) + explicitPort := address != "" && strings.Contains(address, ":") + port, err = choosePort(host, port, explicitPort) if err != nil { @@ -95,15 +101,7 @@ func getRunFunc(ctx context.Context, job *Job) (runFn func() error, err error) { runFn = func() error { return runGo(ctx, job) } case "python": runFn = func() error { return runPython(ctx, job) } - case "springboot": - err = ErrRunnerNotImplemented{runtime} - case "node": - err = ErrRunnerNotImplemented{runtime} - case "typescript": - err = ErrRunnerNotImplemented{runtime} - case "rust": - err = ErrRunnerNotImplemented{runtime} - case "quarkus": + case "springboot", "node", "typescript", "rust", "quarkus": err = ErrRunnerNotImplemented{runtime} default: err = ErrRuntimeNotRecognized{runtime} diff --git a/pkg/functions/runner_test.go b/pkg/functions/runner_test.go index 6b64816800..5f428fe293 100644 --- a/pkg/functions/runner_test.go +++ b/pkg/functions/runner_test.go @@ -39,3 +39,68 @@ func TestGetRunFuncErrors(t *testing.T) { }) } } + +func TestParseAddressFlag(t *testing.T) { + tests := []struct { + name string + val string + host string + port string + }{ + { + name: "empty value", + val: "", + host: "localhost", + port: "8080", + }, + { + name: "host-only as hostname", + val: "localhost", + host: "localhost", + port: "8080", + }, + { + name: "host-only as ipv4", + val: "127.0.0.2", + host: "127.0.0.2", + port: "8080", + }, + { + name: "host-only as ipv6", + val: "::1", + host: "::1", + port: "8080", + }, + { + name: "hostport as hostname", + val: "localhost:5000", + host: "localhost", + port: "5000", + }, + { + name: "hostport as ipv4", + val: "127.0.0.2:5000", + host: "127.0.0.2", + port: "5000", + }, + { + name: "hostport as ipv6", + val: "[::1]:5000", + host: "::1", + port: "5000", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + h, p := ParseAddressFlag(tt.val) + if h != tt.host { + t.Errorf("ParseAddressFlag() got host = %v, want host %v", h, tt.host) + } + if p != tt.port { + t.Errorf("ParseAddressFlag() got port = %v, want port %v", p, tt.port) + } + }) + } +} + From 579d23ee2587971aebe94631249457e8007faaf3 Mon Sep 17 00:00:00 2001 From: intojhanurag Date: Thu, 11 Dec 2025 20:22:17 +0000 Subject: [PATCH 2/7] linting issue --- pkg/functions/runner.go | 1 - pkg/functions/runner_test.go | 1 - 2 files changed, 2 deletions(-) diff --git a/pkg/functions/runner.go b/pkg/functions/runner.go index 7289d29e8a..9e2aa0a5d4 100644 --- a/pkg/functions/runner.go +++ b/pkg/functions/runner.go @@ -58,7 +58,6 @@ func (r *defaultRunner) Run(ctx context.Context, f Function, address string, sta host, port := ParseAddressFlag(address) explicitPort := address != "" && strings.Contains(address, ":") - port, err = choosePort(host, port, explicitPort) if err != nil { return nil, fmt.Errorf("cannot choose port: %w", err) diff --git a/pkg/functions/runner_test.go b/pkg/functions/runner_test.go index 5f428fe293..cc07c82abc 100644 --- a/pkg/functions/runner_test.go +++ b/pkg/functions/runner_test.go @@ -103,4 +103,3 @@ func TestParseAddressFlag(t *testing.T) { }) } } - From 992d07385bf2110ce330a54a388171f8299cfc6d Mon Sep 17 00:00:00 2001 From: intojhanurag Date: Thu, 11 Dec 2025 20:26:32 +0000 Subject: [PATCH 3/7] remove comment --- pkg/functions/runner.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/functions/runner.go b/pkg/functions/runner.go index 9e2aa0a5d4..a1b4dc8143 100644 --- a/pkg/functions/runner.go +++ b/pkg/functions/runner.go @@ -35,8 +35,6 @@ func ParseAddressFlag(val string) (string, string) { if val == "" { val = "localhost" } - - // TODO: optionally validate hostname or IP return val, "8080" } From 43741302e9e8a838d097ac56bab6ef0826eeaf9e Mon Sep 17 00:00:00 2001 From: intojhanurag Date: Fri, 12 Dec 2025 16:27:04 +0000 Subject: [PATCH 4/7] code rafactoring and naming conventions --- pkg/functions/runner.go | 10 +++--- pkg/functions/runner_test.go | 60 ++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/pkg/functions/runner.go b/pkg/functions/runner.go index a1b4dc8143..133340f895 100644 --- a/pkg/functions/runner.go +++ b/pkg/functions/runner.go @@ -16,7 +16,7 @@ import ( ) const ( - defaultRunHost = "127.0.0.1" // TODO allow to be altered via a runOpt + defaultRunHost = "127.0.0.1" defaultRunPort = "8080" readinessEndpoint = "/health/readiness" ) @@ -27,15 +27,15 @@ type defaultRunner struct { err io.Writer } -func ParseAddressFlag(val string) (string, string) { +func ParseAddress(val string) (string, string) { if h, p, err := net.SplitHostPort(val); err == nil { return h, p } if val == "" { - val = "localhost" + return defaultRunHost, defaultRunPort } - return val, "8080" + return val, defaultRunPort } func newDefaultRunner(client *Client, out, err io.Writer) *defaultRunner { @@ -53,7 +53,7 @@ func (r *defaultRunner) Run(ctx context.Context, f Function, address string, sta ) // Parse address if provided, otherwise use defaults - host, port := ParseAddressFlag(address) + host, port := ParseAddress(address) explicitPort := address != "" && strings.Contains(address, ":") port, err = choosePort(host, port, explicitPort) diff --git a/pkg/functions/runner_test.go b/pkg/functions/runner_test.go index cc07c82abc..e37c591949 100644 --- a/pkg/functions/runner_test.go +++ b/pkg/functions/runner_test.go @@ -40,65 +40,65 @@ func TestGetRunFuncErrors(t *testing.T) { } } -func TestParseAddressFlag(t *testing.T) { +func TestParseAddress(t *testing.T) { tests := []struct { name string - val string - host string - port string + input string + expectedHost string + expectedPort string }{ { name: "empty value", - val: "", - host: "localhost", - port: "8080", + input: "", + expectedHost: "127.0.0.1", + expectedPort: "8080", }, { name: "host-only as hostname", - val: "localhost", - host: "localhost", - port: "8080", + input: "localhost", + expectedHost: "localhost", + expectedPort: "8080", }, { name: "host-only as ipv4", - val: "127.0.0.2", - host: "127.0.0.2", - port: "8080", + input: "127.0.0.2", + expectedHost: "127.0.0.2", + expectedPort: "8080", }, { name: "host-only as ipv6", - val: "::1", - host: "::1", - port: "8080", + input: "::1", + expectedHost: "::1", + expectedPort: "8080", }, { name: "hostport as hostname", - val: "localhost:5000", - host: "localhost", - port: "5000", + input: "localhost:5000", + expectedHost: "localhost", + expectedPort: "5000", }, { name: "hostport as ipv4", - val: "127.0.0.2:5000", - host: "127.0.0.2", - port: "5000", + input: "127.0.0.2:5000", + expectedHost: "127.0.0.2", + expectedPort: "5000", }, { name: "hostport as ipv6", - val: "[::1]:5000", - host: "::1", - port: "5000", + input: "[::1]:5000", + expectedHost: "::1", + expectedPort: "5000", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h, p := ParseAddressFlag(tt.val) - if h != tt.host { - t.Errorf("ParseAddressFlag() got host = %v, want host %v", h, tt.host) + h, p := ParseAddress(tt.input) + if h != tt.expectedHost { + t.Errorf("ParseAddress() got host = %v, want host %v", h, tt.expectedHost) } - if p != tt.port { - t.Errorf("ParseAddressFlag() got port = %v, want port %v", p, tt.port) + if p != tt.expectedPort { + t.Errorf("ParseAddress() got port = %v, want port %v", p, tt.expectedPort) } }) } From 3dd618b963a723ca37dc22997a6130245129333a Mon Sep 17 00:00:00 2001 From: intojhanurag Date: Fri, 12 Dec 2025 16:28:34 +0000 Subject: [PATCH 5/7] linting issue --- pkg/functions/runner.go | 2 +- pkg/functions/runner_test.go | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pkg/functions/runner.go b/pkg/functions/runner.go index 133340f895..8ad97f4fb3 100644 --- a/pkg/functions/runner.go +++ b/pkg/functions/runner.go @@ -33,7 +33,7 @@ func ParseAddress(val string) (string, string) { } if val == "" { - return defaultRunHost, defaultRunPort + return defaultRunHost, defaultRunPort } return val, defaultRunPort } diff --git a/pkg/functions/runner_test.go b/pkg/functions/runner_test.go index e37c591949..199d16fa68 100644 --- a/pkg/functions/runner_test.go +++ b/pkg/functions/runner_test.go @@ -42,50 +42,50 @@ func TestGetRunFuncErrors(t *testing.T) { func TestParseAddress(t *testing.T) { tests := []struct { - name string - input string + name string + input string expectedHost string expectedPort string }{ { - name: "empty value", - input: "", + name: "empty value", + input: "", expectedHost: "127.0.0.1", expectedPort: "8080", }, { - name: "host-only as hostname", - input: "localhost", + name: "host-only as hostname", + input: "localhost", expectedHost: "localhost", expectedPort: "8080", }, { - name: "host-only as ipv4", - input: "127.0.0.2", + name: "host-only as ipv4", + input: "127.0.0.2", expectedHost: "127.0.0.2", expectedPort: "8080", }, { - name: "host-only as ipv6", - input: "::1", + name: "host-only as ipv6", + input: "::1", expectedHost: "::1", expectedPort: "8080", }, { - name: "hostport as hostname", - input: "localhost:5000", + name: "hostport as hostname", + input: "localhost:5000", expectedHost: "localhost", expectedPort: "5000", }, { - name: "hostport as ipv4", - input: "127.0.0.2:5000", + name: "hostport as ipv4", + input: "127.0.0.2:5000", expectedHost: "127.0.0.2", expectedPort: "5000", }, { - name: "hostport as ipv6", - input: "[::1]:5000", + name: "hostport as ipv6", + input: "[::1]:5000", expectedHost: "::1", expectedPort: "5000", }, From ce7ebd67900a684980634c130d69cefbca3a85eb Mon Sep 17 00:00:00 2001 From: intojhanurag Date: Sat, 13 Dec 2025 17:16:20 +0000 Subject: [PATCH 6/7] Added edgecases --- pkg/functions/runner.go | 25 ++++++++------ pkg/functions/runner_test.go | 64 +++++++++++++++++++++++++----------- 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/pkg/functions/runner.go b/pkg/functions/runner.go index 8ad97f4fb3..e1aea96472 100644 --- a/pkg/functions/runner.go +++ b/pkg/functions/runner.go @@ -11,7 +11,6 @@ import ( "os" "os/exec" "path/filepath" - "strings" "time" ) @@ -27,15 +26,22 @@ type defaultRunner struct { err io.Writer } -func ParseAddress(val string) (string, string) { - if h, p, err := net.SplitHostPort(val); err == nil { - return h, p - } - +func ParseAddress(val string) (host, port string, explicitPort bool) { if val == "" { - return defaultRunHost, defaultRunPort + return defaultRunHost, defaultRunPort, false + } + + if h, p, err := net.SplitHostPort(val); err == nil { + if h == "" { + h = defaultRunHost + } + if p == "" { + return h, defaultRunPort, false + } + return h, p, true } - return val, defaultRunPort + + return val, defaultRunPort, false } func newDefaultRunner(client *Client, out, err io.Writer) *defaultRunner { @@ -53,8 +59,7 @@ func (r *defaultRunner) Run(ctx context.Context, f Function, address string, sta ) // Parse address if provided, otherwise use defaults - host, port := ParseAddress(address) - explicitPort := address != "" && strings.Contains(address, ":") + host, port, explicitPort := ParseAddress(address) port, err = choosePort(host, port, explicitPort) if err != nil { diff --git a/pkg/functions/runner_test.go b/pkg/functions/runner_test.go index 199d16fa68..5dfa32f825 100644 --- a/pkg/functions/runner_test.go +++ b/pkg/functions/runner_test.go @@ -42,64 +42,90 @@ func TestGetRunFuncErrors(t *testing.T) { func TestParseAddress(t *testing.T) { tests := []struct { - name string - input string - expectedHost string - expectedPort string + name string + input string + expectedHost string + expectedPort string + explicitPort bool }{ { name: "empty value", input: "", - expectedHost: "127.0.0.1", - expectedPort: "8080", + expectedHost: defaultRunHost, + expectedPort: defaultRunPort, + explicitPort: false, }, { - name: "host-only as hostname", + name: "host-only hostname", input: "localhost", expectedHost: "localhost", - expectedPort: "8080", + expectedPort: defaultRunPort, + explicitPort: false, }, { - name: "host-only as ipv4", + name: "host-only ipv4", input: "127.0.0.2", expectedHost: "127.0.0.2", - expectedPort: "8080", + expectedPort: defaultRunPort, + explicitPort: false, }, { - name: "host-only as ipv6", + name: "host-only ipv6", input: "::1", expectedHost: "::1", - expectedPort: "8080", + expectedPort: defaultRunPort, + explicitPort: false, }, { - name: "hostport as hostname", + name: "hostname with explicit port", input: "localhost:5000", expectedHost: "localhost", expectedPort: "5000", + explicitPort: true, }, { - name: "hostport as ipv4", + name: "ipv4 with explicit port", input: "127.0.0.2:5000", expectedHost: "127.0.0.2", expectedPort: "5000", + explicitPort: true, }, { - name: "hostport as ipv6", + name: "ipv6 with explicit port", input: "[::1]:5000", expectedHost: "::1", expectedPort: "5000", + explicitPort: true, + }, + { + name: "ipv4 with empty port", + input: "127.0.0.1:", + expectedHost: "127.0.0.1", + expectedPort: defaultRunPort, + explicitPort: false, + }, + { + name: "empty host with explicit port", + input: ":5000", + expectedHost: defaultRunHost, + expectedPort: "5000", + explicitPort: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h, p := ParseAddress(tt.input) + h, p, explicit := ParseAddress(tt.input) + if h != tt.expectedHost { - t.Errorf("ParseAddress() got host = %v, want host %v", h, tt.expectedHost) + t.Errorf("host = %v, want %v", h, tt.expectedHost) } if p != tt.expectedPort { - t.Errorf("ParseAddress() got port = %v, want port %v", p, tt.expectedPort) + t.Errorf("port = %v, want %v", p, tt.expectedPort) + } + if explicit != tt.explicitPort { + t.Errorf("explicitPort = %v, want %v", explicit, tt.explicitPort) } }) } -} +} \ No newline at end of file From f0f35b7ec65ab5aca6a14e45a1c4707531848cd6 Mon Sep 17 00:00:00 2001 From: intojhanurag Date: Sat, 13 Dec 2025 17:19:02 +0000 Subject: [PATCH 7/7] linting issue --- pkg/functions/runner.go | 4 ++-- pkg/functions/runner_test.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/functions/runner.go b/pkg/functions/runner.go index e1aea96472..d0eabcc02a 100644 --- a/pkg/functions/runner.go +++ b/pkg/functions/runner.go @@ -30,7 +30,7 @@ func ParseAddress(val string) (host, port string, explicitPort bool) { if val == "" { return defaultRunHost, defaultRunPort, false } - + if h, p, err := net.SplitHostPort(val); err == nil { if h == "" { h = defaultRunHost @@ -40,7 +40,7 @@ func ParseAddress(val string) (host, port string, explicitPort bool) { } return h, p, true } - + return val, defaultRunPort, false } diff --git a/pkg/functions/runner_test.go b/pkg/functions/runner_test.go index 5dfa32f825..6eb8885476 100644 --- a/pkg/functions/runner_test.go +++ b/pkg/functions/runner_test.go @@ -42,11 +42,11 @@ func TestGetRunFuncErrors(t *testing.T) { func TestParseAddress(t *testing.T) { tests := []struct { - name string - input string - expectedHost string - expectedPort string - explicitPort bool + name string + input string + expectedHost string + expectedPort string + explicitPort bool }{ { name: "empty value", @@ -128,4 +128,4 @@ func TestParseAddress(t *testing.T) { } }) } -} \ No newline at end of file +}