Repository: kubernetes-sigs/apiserver-network-proxy
Pull request #745 (2025-05-28 19:16:30)

Cherry-pick 0.30: Bump golangci/golangci-lint-action from 6 to 8
All lint-actions after 6 require you to use lint version 2+. Pulled the 2.1 version of golangci-lint
Ran 'golangci-lint migrate'
Fixed concerns raised by linter.
Increase lint timeout to 2 minutes.
Move to go lint 2.1.6
Fixed case complaint on 'as'.

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/apiserver-network-proxy/pull/745#" title="Author self-approved">cheftako</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fapiserver-network-proxy).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/apiserver-network-proxy/blob/release-0.30/OWNERS)~~ [cheftako]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
k8s-ci-robot: @cheftako: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-apiserver-network-proxy-make-lint-0-30 | 00fca178b68dcdc979edd574d9b32b3f35d44b8a | [link](https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_apiserver-network-proxy/745/pull-apiserver-network-proxy-make-lint-0-30/1927806214243094528) | true | `/test pull-apiserver-network-proxy-make-lint-0-30`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=apiserver-network-proxy&pr=745). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Acheftako). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/apiserver-network-proxy/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml
new file mode 100644
index 00000000..d9309825
--- /dev/null
+++ b/.github/workflows/golangci-lint.yaml
@@ -0,0 +1,29 @@
+name: golangci-lint
+on:
+  push:
+    branches:
+      - master
+      - release-0.31
+  pull_request:
+
+permissions:
+  contents: read
+
+env:
+  GO_VERSION: v1.22
+  GOLANGCI_LINT_VERSION: v2.1.6
+
+jobs:
+  golangci:
+    name: lint
+    runs-on: ubuntu-22.04
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-go@v5
+        with:
+          go-version: ${{ env.GO_VERSION }}
+      - name: golangci-lint
+        uses: golangci/golangci-lint-action@v8
+        with:
+          version: ${{ env.GOLANGCI_LINT_VERSION }}
+          args: --verbose --timeout=2m
diff --git a/.golangci.yaml b/.golangci.yaml
index d5f061c1..9f07886d 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -1,22 +1,37 @@
-run:
-  timeout: 3m
-  skip-dirs:
-    - vendor
+version: "2"
 linters:
-  disable-all: true
+  default: none
   enable:
-  - gofmt
-  - revive
-  - gosec
-  - govet
-  - unused
+    - gosec
+    - govet
+    - revive
+    - unused
+  exclusions:
+    generated: lax
+    presets:
+      - comments
+      - common-false-positives
+      - legacy
+      - std-error-handling
+    rules:
+      - linters:
+          - gosec
+        path: _test\.go
+      - linters:
+          - gosec
+        path: ^tests/
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
 issues:
   fix: true
-  exclude-rules:
-    # Don't run security checks on test files
-    - path: _test\.go
-      linters:
-        - gosec
-    - path: ^tests/
-      linters:
-        - gosec
+formatters:
+  enable:
+    - gofmt
+  exclusions:
+    generated: lax
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
diff --git a/Makefile b/Makefile
index 370eaaeb..6bf2f9fe 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ endif
 GOOS ?= $(shell go env GOOS)
 GOARCH ?= $(shell go env GOARCH)
 INSTALL_LOCATION:=$(shell go env GOPATH)/bin
-GOLANGCI_LINT_VERSION ?= 1.54.0
+GOLANGCI_LINT_VERSION ?= 2.1.6
 GOSEC_VERSION ?= 2.13.1
 
 REGISTRY ?= gcr.io/$(shell gcloud config get-value project)
diff --git a/artifacts/images/agent-build.Dockerfile b/artifacts/images/agent-build.Dockerfile
index 08fd3dbc..02af7d00 100644
--- a/artifacts/images/agent-build.Dockerfile
+++ b/artifacts/images/agent-build.Dockerfile
@@ -5,7 +5,7 @@ ARG GO_TOOLCHAIN
 ARG GO_VERSION
 ARG BASEIMAGE
 
-FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} as builder
+FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} AS builder
 
 # Copy in the go src
 WORKDIR /go/src/sigs.k8s.io/apiserver-network-proxy
diff --git a/artifacts/images/server-build.Dockerfile b/artifacts/images/server-build.Dockerfile
index d2065786..72d1fa29 100644
--- a/artifacts/images/server-build.Dockerfile
+++ b/artifacts/images/server-build.Dockerfile
@@ -5,7 +5,7 @@ ARG GO_TOOLCHAIN
 ARG GO_VERSION
 ARG BASEIMAGE
 
-FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} as builder
+FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} AS builder
 
 # Copy in the go src
 WORKDIR /go/src/sigs.k8s.io/apiserver-network-proxy
diff --git a/cmd/agent/app/server.go b/cmd/agent/app/server.go
index 8cc3cfd0..a346a7a0 100644
--- a/cmd/agent/app/server.go
+++ b/cmd/agent/app/server.go
@@ -48,7 +48,7 @@ func NewAgentCommand(a *Agent, o *options.GrpcProxyAgentOptions) *cobra.Command
 	cmd := &cobra.Command{
 		Use:  "agent",
 		Long: `A gRPC agent, Connects to the proxy and then allows traffic to be forwarded to it.`,
-		RunE: func(cmd *cobra.Command, args []string) error {
+		RunE: func(_ *cobra.Command, _ []string) error {
 			stopCh := make(chan struct{})
 			return a.Run(o, stopCh)
 		},
@@ -113,7 +113,7 @@ func (a *Agent) runProxyConnection(o *options.GrpcProxyAgentOptions, stopCh <-ch
 }
 
 func (a *Agent) runHealthServer(o *options.GrpcProxyAgentOptions, cs agent.ReadinessManager) error {
-	livenessHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	livenessHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
 		fmt.Fprintf(w, "ok")
 	})
 
diff --git a/cmd/server/app/options/options.go b/cmd/server/app/options/options.go
index f887653c..c35a27c3 100644
--- a/cmd/server/app/options/options.go
+++ b/cmd/server/app/options/options.go
@@ -74,7 +74,7 @@ type ProxyRunOptions struct {
 	// ID of this proxy server.
 	ServerID string
 	// Number of proxy server instances, should be 1 unless it is a HA proxy server.
-	ServerCount uint
+	ServerCount int
 	// Agent pod's namespace for token-based agent authentication
 	AgentNamespace string
 	// Agent pod's service account for token-based agent authentication
@@ -128,7 +128,7 @@ func (o *ProxyRunOptions) Flags() *pflag.FlagSet {
 	flags.BoolVar(&o.EnableProfiling, "enable-profiling", o.EnableProfiling, "enable pprof at host:admin-port/debug/pprof")
 	flags.BoolVar(&o.EnableContentionProfiling, "enable-contention-profiling", o.EnableContentionProfiling, "enable contention profiling at host:admin-port/debug/pprof/block. \"--enable-profiling\" must also be set.")
 	flags.StringVar(&o.ServerID, "server-id", o.ServerID, "The unique ID of this server. Can also be set by the 'PROXY_SERVER_ID' environment variable.")
-	flags.UintVar(&o.ServerCount, "server-count", o.ServerCount, "The number of proxy server instances, should be 1 unless it is an HA server.")
+	flags.IntVar(&o.ServerCount, "server-count", o.ServerCount, "The number of proxy server instances, should be 1 unless it is an HA server.")
 	flags.StringVar(&o.AgentNamespace, "agent-namespace", o.AgentNamespace, "Expected agent's namespace during agent authentication (used with agent-service-account, authentication-audience, kubeconfig).")
 	flags.StringVar(&o.AgentServiceAccount, "agent-service-account", o.AgentServiceAccount, "Expected agent's service account during agent authentication (used with agent-namespace, authentication-audience, kubeconfig).")
 	flags.StringVar(&o.KubeconfigPath, "kubeconfig", o.KubeconfigPath, "absolute path to the kubeconfig file (used with agent-namespace, agent-service-account, authentication-audience).")
diff --git a/cmd/server/app/server.go b/cmd/server/app/server.go
index 4f2ce21b..fe5291ad 100644
--- a/cmd/server/app/server.go
+++ b/cmd/server/app/server.go
@@ -58,7 +58,7 @@ func NewProxyCommand(p *Proxy, o *options.ProxyRunOptions) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:  "proxy",
 		Long: `A gRPC proxy server, receives requests from the API server and forwards to the agent.`,
-		RunE: func(cmd *cobra.Command, args []string) error {
+		RunE: func(_ *cobra.Command, _ []string) error {
 			stopCh := SetupSignalHandler()
 			return p.Run(o, stopCh)
 		},
@@ -132,7 +132,7 @@ func (p *Proxy) Run(o *options.ProxyRunOptions, stopCh <-chan struct{}) error {
 	if err != nil {
 		return err
 	}
-	p.server = server.NewProxyServer(o.ServerID, ps, int(o.ServerCount), authOpt)
+	p.server = server.NewProxyServer(o.ServerID, ps, o.ServerCount, authOpt)
 
 	frontendStop, err := p.runFrontendServer(ctx, o, p.server)
 	if err != nil {
@@ -325,7 +325,7 @@ func (p *Proxy) runMTLSFrontendServer(ctx context.Context, o *options.ProxyRunOp
 		}
 		labels := runpprof.Labels(
 			"core", "mtlsGrpcFrontend",
-			"port", strconv.FormatUint(uint64(o.ServerPort), 10),
+			"port", strconv.Itoa(o.ServerPort),
 		)
 		go runpprof.Do(context.Background(), labels, func(context.Context) { grpcServer.Serve(lis) })
 		stop = grpcServer.GracefulStop
@@ -348,7 +348,7 @@ func (p *Proxy) runMTLSFrontendServer(ctx context.Context, o *options.ProxyRunOp
 		}
 		labels := runpprof.Labels(
 			"core", "mtlsHttpFrontend",
-			"port", strconv.FormatUint(uint64(o.ServerPort), 10),
+			"port", strconv.Itoa(o.ServerPort),
 		)
 		go runpprof.Do(context.Background(), labels, func(context.Context) {
 			err := server.ListenAndServeTLS("", "") // empty files defaults to tlsConfig
@@ -385,7 +385,7 @@ func (p *Proxy) runAgentServer(o *options.ProxyRunOptions, server *server.ProxyS
 	}
 	labels := runpprof.Labels(
 		"core", "agentListener",
-		"port", strconv.FormatUint(uint64(o.AgentPort), 10),
+		"port", strconv.Itoa(o.AgentPort),
 	)
 	go runpprof.Do(context.Background(), labels, func(context.Context) { grpcServer.Serve(lis) })
 	p.agentServer = grpcServer
@@ -415,7 +415,7 @@ func (p *Proxy) runAdminServer(o *options.ProxyRunOptions, _ *server.ProxyServer
 
 	labels := runpprof.Labels(
 		"core", "adminListener",
-		"port", strconv.FormatUint(uint64(o.AdminPort), 10),
+		"port", strconv.Itoa(o.AdminPort),
 	)
 	go runpprof.Do(context.Background(), labels, func(context.Context) {
 		err := p.adminServer.ListenAndServe()
@@ -429,10 +429,10 @@ func (p *Proxy) runAdminServer(o *options.ProxyRunOptions, _ *server.ProxyServer
 }
 
 func (p *Proxy) runHealthServer(o *options.ProxyRunOptions, server *server.ProxyServer) error {
-	livenessHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	livenessHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
 		fmt.Fprintf(w, "ok")
 	})
-	readinessHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	readinessHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
 		ready, msg := server.Readiness.Ready()
 		if ready {
 			w.WriteHeader(200)
@@ -457,7 +457,7 @@ func (p *Proxy) runHealthServer(o *options.ProxyRunOptions, server *server.Proxy
 
 	labels := runpprof.Labels(
 		"core", "healthListener",
-		"port", strconv.FormatUint(uint64(o.HealthPort), 10),
+		"port", strconv.Itoa(o.HealthPort),
 	)
 	go runpprof.Do(context.Background(), labels, func(context.Context) {
 		err := p.healthServer.ListenAndServe()
diff --git a/pkg/agent/client.go b/pkg/agent/client.go
index 16b1df24..5735c7a6 100644
--- a/pkg/agent/client.go
+++ b/pkg/agent/client.go
@@ -536,14 +536,13 @@ func (a *Client) remoteToProxy(connID int64, eConn *endpointConn) {
 				klog.ErrorS(err, "connection read failure", "connectionID", connID)
 			}
 			return
-		} else {
-			resp.Payload = &client.Packet_Data{Data: &client.Data{
-				Data:      buf[:n],
-				ConnectID: connID,
-			}}
-			if err := a.Send(resp); err != nil {
-				klog.ErrorS(err, "could not send DATA", "connectionID", connID)
-			}
+		}
+		resp.Payload = &client.Packet_Data{Data: &client.Data{
+			Data:      buf[:n],
+			ConnectID: connID,
+		}}
+		if err := a.Send(resp); err != nil {
+			klog.ErrorS(err, "could not send DATA", "connectionID", connID)
 		}
 	}
 }
diff --git a/pkg/server/server.go b/pkg/server/server.go
index d65d5c4b..f4e34a8f 100644
--- a/pkg/server/server.go
+++ b/pkg/server/server.go
@@ -135,9 +135,8 @@ func (c *ProxyClientConnection) send(pkt *client.Packet) error {
 				return c.CloseHTTP()
 			}
 			return nil
-		} else {
-			return fmt.Errorf("attempt to send via unrecognized connection type %v", pkt.Type)
 		}
+		return fmt.Errorf("attempt to send via unrecognized connection type %v", pkt.Type)
 	}
 	return fmt.Errorf("attempt to send via unrecognized connection mode %q", c.Mode)
 }


Test patch:
diff --git a/artifacts/images/test-client-build.Dockerfile b/artifacts/images/test-client-build.Dockerfile
index 3d936bd3..e4af8007 100644
--- a/artifacts/images/test-client-build.Dockerfile
+++ b/artifacts/images/test-client-build.Dockerfile
@@ -5,7 +5,7 @@ ARG GO_TOOLCHAIN
 ARG GO_VERSION
 ARG BASEIMAGE
 
-FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} as builder
+FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} AS builder
 
 # Copy in the go src
 WORKDIR /go/src/sigs.k8s.io/apiserver-network-proxy
diff --git a/artifacts/images/test-server-build.Dockerfile b/artifacts/images/test-server-build.Dockerfile
index 139eaa58..65e83851 100644
--- a/artifacts/images/test-server-build.Dockerfile
+++ b/artifacts/images/test-server-build.Dockerfile
@@ -5,7 +5,7 @@ ARG GO_TOOLCHAIN
 ARG GO_VERSION
 ARG BASEIMAGE
 
-FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} as builder
+FROM --platform=linux/${BUILDARCH} ${GO_TOOLCHAIN}:${GO_VERSION} AS builder
 
 # Copy in the go src
 WORKDIR /go/src/sigs.k8s.io/apiserver-network-proxy
diff --git a/cmd/server/app/options/options_test.go b/cmd/server/app/options/options_test.go
index f7e4d63e..b5b0216e 100644
--- a/cmd/server/app/options/options_test.go
+++ b/cmd/server/app/options/options_test.go
@@ -52,7 +52,7 @@ func TestDefaultServerOptions(t *testing.T) {
 	assertDefaultValue(t, "FrontendKeepaliveTime", defaultServerOptions.FrontendKeepaliveTime, 1*time.Hour)
 	assertDefaultValue(t, "EnableProfiling", defaultServerOptions.EnableProfiling, false)
 	assertDefaultValue(t, "EnableContentionProfiling", defaultServerOptions.EnableContentionProfiling, false)
-	assertDefaultValue(t, "ServerCount", defaultServerOptions.ServerCount, uint(1))
+	assertDefaultValue(t, "ServerCount", defaultServerOptions.ServerCount, 1)
 	assertDefaultValue(t, "AgentNamespace", defaultServerOptions.AgentNamespace, "")
 	assertDefaultValue(t, "AgentServiceAccount", defaultServerOptions.AgentServiceAccount, "")
 	assertDefaultValue(t, "KubeconfigPath", defaultServerOptions.KubeconfigPath, "")
diff --git a/cmd/test-client/main.go b/cmd/test-client/main.go
index e90e1dc6..10f5d382 100644
--- a/cmd/test-client/main.go
+++ b/cmd/test-client/main.go
@@ -216,7 +216,7 @@ func newGrpcProxyClientCommand(c *Client, o *GrpcProxyClientOptions) *cobra.Comm
 	cmd := &cobra.Command{
 		Use:  "proxy-client",
 		Long: `A gRPC proxy Client, primarily used to test the Kubernetes gRPC Proxy Server.`,
-		RunE: func(cmd *cobra.Command, args []string) error {
+		RunE: func(cmd *cobra.Command, _ []string) error {
 			cmd.SilenceUsage = true
 			return c.run(o)
 		},
@@ -479,7 +479,7 @@ func (c *Client) getUDSDialer(o *GrpcProxyClientOptions) (func(ctx context.Conte
 		return nil, fmt.Errorf("failed to process mode %s", o.mode)
 	}
 
-	return func(ctx context.Context, network, addr string) (net.Conn, error) {
+	return func(_ context.Context, _, _ string) (net.Conn, error) {
 		return proxyConn, nil
 	}, nil
 }
@@ -556,7 +556,7 @@ func (c *Client) getMTLSDialer(o *GrpcProxyClientOptions) (func(ctx context.Cont
 		return nil, fmt.Errorf("failed to process mode %s", o.mode)
 	}
 
-	return func(ctx context.Context, network, addr string) (net.Conn, error) {
+	return func(_ context.Context, _, _ string) (net.Conn, error) {
 		return proxyConn, nil
 	}, nil
 }
diff --git a/cmd/test-server/main.go b/cmd/test-server/main.go
index 13bc238d..203c8209 100644
--- a/cmd/test-server/main.go
+++ b/cmd/test-server/main.go
@@ -89,7 +89,7 @@ func newTestServerCommand(p *TestServer, o *TestServerRunOptions) *cobra.Command
 	cmd := &cobra.Command{
 		Use:  "test http server",
 		Long: `A test http server, url determines behavior for certain tests.`,
-		RunE: func(cmd *cobra.Command, args []string) error {
+		RunE: func(_ *cobra.Command, _ []string) error {
 			return p.run(o)
 		},
 	}
diff --git a/pkg/agent/client_test.go b/pkg/agent/client_test.go
index 87b61b1b..dd5d1571 100644
--- a/pkg/agent/client_test.go
+++ b/pkg/agent/client_test.go
@@ -54,7 +54,7 @@ func TestServeData_HTTP(t *testing.T) {
 
 	// Start test http server as remote service
 	expectedBody := "Hello, client"
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
 		fmt.Fprint(w, expectedBody)
 	}))
 	defer ts.Close()
@@ -152,7 +152,7 @@ func TestClose_Client(t *testing.T) {
 	defer close(stopCh)
 
 	// Start test http server as remote service
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
 		fmt.Fprint(w, "hello, world")
 	}))
 	defer ts.Close()
diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go
index d12e0e01..117b0b63 100644
--- a/pkg/server/server_test.go
+++ b/pkg/server/server_test.go
@@ -135,7 +135,7 @@ func TestAgentTokenAuthenticationErrorsToken(t *testing.T) {
 		t.Run(tc.desc, func(t *testing.T) {
 			kcs := k8sfake.NewSimpleClientset()
 
-			kcs.AuthenticationV1().(*fakeauthenticationv1.FakeAuthenticationV1).Fake.PrependReactor("create", "tokenreviews", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
+			kcs.AuthenticationV1().(*fakeauthenticationv1.FakeAuthenticationV1).Fake.PrependReactor("create", "tokenreviews", func(_ k8stesting.Action) (handled bool, ret runtime.Object, err error) {
 				tr := &authv1.TokenReview{
 					Status: authv1.TokenReviewStatus{
 						Authenticated: tc.authenticated,
@@ -553,7 +553,7 @@ func TestServerProxyRecvChanFull(t *testing.T) {
 }
 
 func TestServerProxyNoDial(t *testing.T) {
-	baseServerProxyTestWithBackend(t, func(frontendConn, agentConn *agentmock.MockAgentService_ConnectServer) {
+	baseServerProxyTestWithBackend(t, func(frontendConn, _ *agentmock.MockAgentService_ConnectServer) {
 		const connectID = 123456
 		data := &client.Packet{
 			Type: client.PacketType_DATA,
diff --git a/tests/agent_disconnect_test.go b/tests/agent_disconnect_test.go
index f829a0ad..3c586131 100644
--- a/tests/agent_disconnect_test.go
+++ b/tests/agent_disconnect_test.go
@@ -216,7 +216,7 @@ func createHTTPConnectClient(_ context.Context, proxyAddr, addr string) (*http.C
 		return nil, fmt.Errorf("unexpected extra buffer")
 	}
 
-	dialer := func(network, addr string) (net.Conn, error) {
+	dialer := func(_, _ string) (net.Conn, error) {
 		return conn, nil
 	}
 
diff --git a/tests/custom_alpn_test.go b/tests/custom_alpn_test.go
index 1d63deb1..71102b21 100644
--- a/tests/custom_alpn_test.go
+++ b/tests/custom_alpn_test.go
@@ -40,7 +40,7 @@ func TestCustomALPN(t *testing.T) {
 	svr := httptest.NewUnstartedServer(http.DefaultServeMux)
 	svr.TLS = &tls.Config{NextProtos: []string{proto}, MinVersion: tls.VersionTLS13}
 	svr.Config.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){
-		proto: func(svr *http.Server, conn *tls.Conn, handle http.Handler) {
+		proto: func(_ *http.Server, _ *tls.Conn, _ http.Handler) {
 			atomic.AddInt32(&protoUsed, 1)
 		},
 	}
diff --git a/tests/framework/proxy_server.go b/tests/framework/proxy_server.go
index 4ad740b6..4af10bf7 100644
--- a/tests/framework/proxy_server.go
+++ b/tests/framework/proxy_server.go
@@ -139,7 +139,7 @@ func serverOptions(t testing.TB, opts ProxyServerOpts) (*serveropts.ProxyRunOpti
 	t.Helper()
 	o := serveropts.NewProxyRunOptions()
 
-	o.ServerCount = uint(opts.ServerCount)
+	o.ServerCount = opts.ServerCount
 	o.Mode = opts.Mode
 
 	uid := uuid.New().String()
diff --git a/tests/proxy_test.go b/tests/proxy_test.go
index f3876d1e..21993707 100644
--- a/tests/proxy_test.go
+++ b/tests/proxy_test.go
@@ -105,11 +105,13 @@ type delayedServer struct {
 	maxWait time.Duration
 }
 
-// randomDuration returns a random duration in the [min, max) interval
-func randomDuration(min, max time.Duration) time.Duration {
-	d := min
-	if max != min {
-		d += time.Duration(rand.Int63n(int64(max - min)))
+// randomDuration returns a random duration in the [lower, upper) interval
+// Cannot use min/max because linter gives the following error.
+// "redefines-builtin-id: redefinition of the built-in function min (revive)"
+func randomDuration(lower, upper time.Duration) time.Duration {
+	d := lower
+	if upper != lower {
+		d += time.Duration(rand.Int63n(int64(upper - lower)))
 	}
 	return d
 }
@@ -372,7 +374,7 @@ func TestProxyDial_RequestCancelled_Concurrent_GRPC(t *testing.T) {
 	waitForConnectedServerCount(t, 1, a)
 
 	wg := sync.WaitGroup{}
-	dialFn := func(id int, cancelDelay time.Duration) {
+	dialFn := func(_ int, cancelDelay time.Duration) {
 		defer wg.Done()
 
 		// run test client
@@ -629,7 +631,7 @@ func TestBasicProxy_HTTPCONN(t *testing.T) {
 		t.Error("unexpected extra buffer")
 	}
 
-	dialer := func(network, addr string) (net.Conn, error) {
+	dialer := func(_, _ string) (net.Conn, error) {
 		return conn, nil
 	}
 
@@ -693,7 +695,7 @@ func TestFailedDNSLookupProxy_HTTPCONN(t *testing.T) {
 	if br.Buffered() > 0 {
 		t.Error("unexpected extra buffer")
 	}
-	dialer := func(network, addr string) (net.Conn, error) {
+	dialer := func(_, _ string) (net.Conn, error) {
 		return conn, nil
 	}
 
@@ -767,7 +769,7 @@ func TestFailedDial_HTTPCONN(t *testing.T) {
 		t.Fatalf("expect 200; got %d", res.StatusCode)
 	}
 
-	dialer := func(network, addr string) (net.Conn, error) {
+	dialer := func(_, _ string) (net.Conn, error) {
 		return conn, nil
 	}