Skip to content

Commit 00bf632

Browse files
kubestellar-hive[bot]Copilot
andauthored
[ci-maintainer] fix: resolve persistent go vet and test build failures across pkg/agent, pkg/settings, and pkg/api/transport (#18233)
- Remove var fakeExecCommandContext from provider_helpers.go (production file had test infrastructure causing redeclaration with server_gitops_test.go) - Fix Ciphertext field type: []byte -> string in manager_validation_test.go - Replace KubectlProxy struct literals (unexported fields) with kube.NewTestKubectlProxy() in server_test.go, server_sse_test.go, server_http_resources_stream_test.go - Add updater import to server_http_test.go; use updater.NewUpdateChecker() and checker.Status().Channel instead of accessing unexported fields - Add SetLookPathForTest/SetStatFileForTest/SetStandardToolCandidatesForTest to pkg/agent/kube/testing.go; update server_ops_clusters_test.go and server_ops_insights_test.go to use kube.* prefixes - Fix server_test.go: NewLocalClusterManager -> kube.NewLocalClusterManager - Move hub_close_test.go and websocket_test.go from pkg/api/handlers to pkg/api/transport (type aliases don't allow unexported field access) Signed-off-by: Copilot <copilot@example.com> Co-authored-by: Copilot <copilot@example.com>
1 parent be92081 commit 00bf632

11 files changed

Lines changed: 74 additions & 79 deletions

pkg/agent/kube/testing.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package kube
22

33
import (
4+
"os"
45
"strings"
56

67
"github.com/kubestellar/console/pkg/k8s"
@@ -22,3 +23,26 @@ func NewTestKubectlProxy(config *api.Config) *KubectlProxy {
2223
func AppendFormattedWarningEvents(sb *strings.Builder, events []k8s.Event) {
2324
appendFormattedWarningEvents(sb, events)
2425
}
26+
27+
// SetLookPathForTest replaces the lookPath function and returns a cleanup func.
28+
// Use in tests outside the kube package to control tool detection.
29+
func SetLookPathForTest(fn func(string) (string, error)) func() {
30+
old := lookPath
31+
lookPath = fn
32+
return func() { lookPath = old }
33+
}
34+
35+
// SetStatFileForTest replaces the statFile function and returns a cleanup func.
36+
func SetStatFileForTest(fn func(string) (os.FileInfo, error)) func() {
37+
old := statFile
38+
statFile = fn
39+
return func() { statFile = old }
40+
}
41+
42+
// SetStandardToolCandidatesForTest replaces standardToolCandidates and returns a cleanup func.
43+
func SetStandardToolCandidatesForTest(fn func(string) []string) func() {
44+
old := standardToolCandidates
45+
standardToolCandidates = fn
46+
return func() { standardToolCandidates = old }
47+
}
48+

pkg/agent/provider_helpers.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ var execCommand = exec.Command
3131
// execCommandContext allows mocking exec.CommandContext for testing
3232
var execCommandContext = exec.CommandContext
3333

34-
// fakeExecCommandContext is a test helper for mocking exec.CommandContext
35-
var fakeExecCommandContext func(context.Context, string, ...string) *exec.Cmd
36-
3734
// aiProviderHTTPClient is reused across AI provider API calls to enable
3835
// connection pooling and reduce per-request allocation overhead.
3936
var aiProviderHTTPClient = newRestrictedAIProviderHTTPClient(aiProviderHTTPTimeout)

pkg/agent/server_http_resources_stream_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,7 @@ func newTestKubectlProxy(clusterNames ...string) *kube.KubectlProxy {
303303
if len(clusterNames) > 0 {
304304
cfg.CurrentContext = clusterNames[0]
305305
}
306-
return &kube.KubectlProxy{
307-
kubeconfig: "/dev/null",
308-
config: cfg,
309-
}
306+
return kube.NewTestKubectlProxy(cfg)
310307
}
311308

312309
// mustTestK8sClient creates a MultiClusterClient for testing (no actual cluster).

pkg/agent/server_http_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88
"testing"
99

10+
"github.com/kubestellar/console/pkg/agent/updater"
1011
"github.com/kubestellar/console/pkg/k8s"
1112
"github.com/kubestellar/console/pkg/settings"
1213
appsv1 "k8s.io/api/apps/v1"
@@ -251,7 +252,7 @@ func TestHandleAutoUpdateConfig_SaveAllError_Returns500(t *testing.T) {
251252
mgr.SetSettingsPath("/dev/null/no-such-dir/settings.json")
252253
defer mgr.SetSettingsPath(original)
253254

254-
checker := &UpdateChecker{channel: "stable"}
255+
checker := updater.NewUpdateChecker(updater.UpdateCheckerConfig{})
255256
server := &Server{
256257
allowedOrigins: []string{"*"},
257258
agentToken: "",
@@ -268,9 +269,7 @@ func TestHandleAutoUpdateConfig_SaveAllError_Returns500(t *testing.T) {
268269
if w.Code != http.StatusInternalServerError {
269270
t.Errorf("expected 500, got %d", w.Code)
270271
}
271-
checker.mu.Lock()
272-
ch := checker.channel
273-
checker.mu.Unlock()
272+
ch := checker.Status().Channel
274273
if ch != "stable" {
275274
t.Errorf("updateChecker.Configure must not be called on SaveAll failure, but channel changed to %q", ch)
276275
}

pkg/agent/server_ops_clusters_test.go

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"os/exec"
1010
"testing"
1111
"time"
12+
13+
"github.com/kubestellar/console/pkg/agent/kube"
1214
)
1315

1416
func TestServer_HandleCloudCLIStatus(t *testing.T) {
@@ -39,20 +41,16 @@ func TestServer_HandleCloudCLIStatus(t *testing.T) {
3941
}
4042

4143
func TestServer_HandleLocalClusterTools(t *testing.T) {
42-
// Mock lookPath to simulate tool detection without invoking real executables.
43-
oldLookPath := lookPath
44-
oldStandardToolCandidates := standardToolCandidates
45-
defer func() {
46-
lookPath = oldLookPath
47-
standardToolCandidates = oldStandardToolCandidates
48-
}()
49-
standardToolCandidates = func(string) []string { return nil }
50-
lookPath = func(file string) (string, error) {
44+
// Mock kube package vars to simulate tool detection without real executables.
45+
restoreLookPath := kube.SetLookPathForTest(func(file string) (string, error) {
5146
if file == "kind" {
5247
return "/usr/local/bin/kind", nil
5348
}
5449
return "", &execError{file}
55-
}
50+
})
51+
defer restoreLookPath()
52+
restoreCandidates := kube.SetStandardToolCandidatesForTest(func(string) []string { return nil })
53+
defer restoreCandidates()
5654

5755
// Mock execCommand so DetectTools does not invoke real binaries (e.g.
5856
// "kind version"). The stub command exits 0 with empty output, which is
@@ -65,7 +63,7 @@ func TestServer_HandleLocalClusterTools(t *testing.T) {
6563

6664
s := &Server{
6765
allowedOrigins: []string{"*"},
68-
localClusters: NewLocalClusterManager(nil),
66+
localClusters: kube.NewLocalClusterManager(nil),
6967
}
7068

7169
req := httptest.NewRequest("GET", "/local-cluster-tools", nil)
@@ -78,7 +76,7 @@ func TestServer_HandleLocalClusterTools(t *testing.T) {
7876
}
7977

8078
var resp struct {
81-
Tools []LocalClusterTool `json:"tools"`
79+
Tools []kube.LocalClusterTool `json:"tools"`
8280
}
8381
if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
8482
t.Fatalf("Failed to decode response: %v", err)
@@ -109,31 +107,25 @@ func (f fakeExecutableInfoOps) IsDir() bool { return false }
109107
func (f fakeExecutableInfoOps) Sys() interface{} { return nil }
110108

111109
func TestServer_HandleLocalClusterTools_RequestedToolsFallback(t *testing.T) {
112-
oldLookPath := lookPath
113-
oldStatFile := statFile
114-
oldStandardToolCandidates := standardToolCandidates
115-
defer func() {
116-
lookPath = oldLookPath
117-
statFile = oldStatFile
118-
standardToolCandidates = oldStandardToolCandidates
119-
}()
120-
121-
lookPath = func(file string) (string, error) {
110+
restoreLookPath := kube.SetLookPathForTest(func(file string) (string, error) {
122111
return "", &execError{file}
123-
}
124-
standardToolCandidates = func(name string) []string {
125-
return []string{"/usr/local/bin/" + name}
126-
}
127-
statFile = func(name string) (os.FileInfo, error) {
112+
})
113+
defer restoreLookPath()
114+
restoreStat := kube.SetStatFileForTest(func(name string) (os.FileInfo, error) {
128115
if name == "/usr/local/bin/helm" {
129116
return fakeExecutableInfoOps{name: "helm"}, nil
130117
}
131118
return nil, errors.New("not found")
132-
}
119+
})
120+
defer restoreStat()
121+
restoreCandidates := kube.SetStandardToolCandidatesForTest(func(name string) []string {
122+
return []string{"/usr/local/bin/" + name}
123+
})
124+
defer restoreCandidates()
133125

134126
s := &Server{
135127
allowedOrigins: []string{"*"},
136-
localClusters: NewLocalClusterManager(nil),
128+
localClusters: kube.NewLocalClusterManager(nil),
137129
}
138130

139131
req := httptest.NewRequest("GET", "/local-cluster-tools?tool=helm", nil)
@@ -149,7 +141,7 @@ func TestServer_HandleLocalClusterTools_RequestedToolsFallback(t *testing.T) {
149141
}
150142

151143
var resp struct {
152-
Tools []LocalClusterTool `json:"tools"`
144+
Tools []kube.LocalClusterTool `json:"tools"`
153145
}
154146
if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
155147
t.Fatalf("Failed to decode response: %v", err)
@@ -172,7 +164,7 @@ func TestServer_HandleLocalClusters_List(t *testing.T) {
172164

173165
s := &Server{
174166
allowedOrigins: []string{"*"},
175-
localClusters: NewLocalClusterManager(nil),
167+
localClusters: kube.NewLocalClusterManager(nil),
176168
}
177169

178170
req := httptest.NewRequest("GET", "/local-clusters", nil)

pkg/agent/server_ops_insights_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package agent
22

33
import (
4+
"github.com/kubestellar/console/pkg/agent/kube"
45
"bytes"
56
"encoding/json"
67
"net/http"
@@ -85,7 +86,7 @@ func TestServer_HandleVClusterCheck(t *testing.T) {
8586

8687
s := &Server{
8788
allowedOrigins: []string{"*"},
88-
localClusters: &LocalClusterManager{},
89+
localClusters: &kube.LocalClusterManager{},
8990
}
9091

9192
req := httptest.NewRequest("GET", "/vcluster/check", nil)

pkg/agent/server_sse_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,7 @@ func newTestServerForSSE(t *testing.T, contexts map[string]*api.Context) (*Serve
3939
cfg.AuthInfos[name] = &api.AuthInfo{}
4040
}
4141

42-
proxy := &kube.KubectlProxy{
43-
kubeconfig: "/dev/null",
44-
config: cfg,
45-
}
42+
proxy := kube.NewTestKubectlProxy(cfg)
4643

4744
srv := &Server{
4845
k8sClient: k8sMock,
@@ -562,7 +559,7 @@ func TestHandleJobsStreamSSE_Unauthorized(t *testing.T) {
562559

563560
func TestHandleJobsStreamSSE_NilK8sClient(t *testing.T) {
564561
srv := &Server{
565-
kubectl: &kube.KubectlProxy{kubeconfig: "/dev/null", config: &api.Config{}},
562+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
566563
k8sClient: nil,
567564
allowedOrigins: []string{"*"},
568565
agentToken: "",

pkg/agent/server_test.go

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestServer_HandleHealth_CORS(t *testing.T) {
6060
server := &Server{
6161
allowedOrigins: []string{"http://allowed.com"},
6262
registry: &Registry{providers: make(map[string]AIProvider)},
63-
kubectl: &kube.KubectlProxy{config: &api.Config{}},
63+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
6464
}
6565

6666
// Case 1: Allowed Origin
@@ -90,7 +90,7 @@ func TestServer_HandleStatus(t *testing.T) {
9090
},
9191
}
9292
server := &Server{
93-
kubectl: &kube.KubectlProxy{config: config},
93+
kubectl: kube.NewTestKubectlProxy(config),
9494
allowedOrigins: []string{"http://allowed.com"},
9595
agentToken: "test-token",
9696
tokenExplicit: true,
@@ -225,7 +225,7 @@ func TestServer_HandleClustersHTTP(t *testing.T) {
225225
"c1": {Server: "https://c1.com"},
226226
},
227227
}
228-
mockProxy := &kube.KubectlProxy{config: config}
228+
mockProxy := kube.NewTestKubectlProxy(config)
229229
server := &Server{
230230
kubectl: mockProxy,
231231
allowedOrigins: []string{"*"},
@@ -271,10 +271,7 @@ func TestServer_HandleRenameContextHTTP(t *testing.T) {
271271
execCommandContext = fakeExecCommandContext
272272

273273
// Setup proxy
274-
proxy := &kube.KubectlProxy{
275-
kubeconfig: "/tmp/config",
276-
config: &api.Config{},
277-
}
274+
proxy := kube.NewTestKubectlProxy(&api.Config{})
278275

279276
server := &Server{
280277
kubectl: proxy,
@@ -323,10 +320,7 @@ func TestServer_ResourceHandlers(t *testing.T) {
323320
config := &api.Config{
324321
CurrentContext: "ctx-1",
325322
}
326-
proxy := &kube.KubectlProxy{
327-
config: config,
328-
kubeconfig: "/tmp/config",
329-
}
323+
proxy := kube.NewTestKubectlProxy(config)
330324

331325
// Create mock k8s client
332326
k8sClient, _ := k8s.NewMultiClusterClient("")
@@ -973,7 +967,7 @@ func TestMatchOrigin(t *testing.T) {
973967

974968
func TestServer_HandleClustersHTTP_Unauthorized(t *testing.T) {
975969
server := &Server{
976-
kubectl: &kube.KubectlProxy{config: &api.Config{}},
970+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
977971
agentToken: "secret", // require token
978972
allowedOrigins: []string{"*"},
979973
}
@@ -992,7 +986,7 @@ func TestServer_HandleClustersHTTP_Unauthorized(t *testing.T) {
992986

993987
func TestServer_HandleClustersHTTP_OPTIONS(t *testing.T) {
994988
server := &Server{
995-
kubectl: &kube.KubectlProxy{config: &api.Config{}},
989+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
996990
allowedOrigins: []string{"http://allowed.com"},
997991
}
998992

@@ -1434,7 +1428,7 @@ func (fakeFileInfo) Sys() interface{} { return nil }
14341428

14351429
func TestServer_HandleRenameContextHTTP_Unauthorized(t *testing.T) {
14361430
server := &Server{
1437-
kubectl: &kube.KubectlProxy{config: &api.Config{}},
1431+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
14381432
agentToken: "secret",
14391433
allowedOrigins: []string{"*"},
14401434
}
@@ -1452,7 +1446,7 @@ func TestServer_HandleRenameContextHTTP_Unauthorized(t *testing.T) {
14521446

14531447
func TestServer_HandleRenameContextHTTP_WrongMethod(t *testing.T) {
14541448
server := &Server{
1455-
kubectl: &kube.KubectlProxy{config: &api.Config{}},
1449+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
14561450
allowedOrigins: []string{"*"},
14571451
}
14581452

@@ -1472,10 +1466,7 @@ func TestServer_HandleRenameContextHTTP_MissingNames(t *testing.T) {
14721466
execCommandContext = fakeExecCommandContext
14731467

14741468
server := &Server{
1475-
kubectl: &kube.KubectlProxy{
1476-
config: &api.Config{},
1477-
kubeconfig: "/tmp/config",
1478-
},
1469+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
14791470
allowedOrigins: []string{"*"},
14801471
}
14811472

@@ -1499,10 +1490,7 @@ func TestServer_HandleRenameContextHTTP_FlagInjection(t *testing.T) {
14991490
execCommandContext = fakeExecCommandContext
15001491

15011492
server := &Server{
1502-
kubectl: &kube.KubectlProxy{
1503-
config: &api.Config{},
1504-
kubeconfig: "/tmp/config",
1505-
},
1493+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
15061494
allowedOrigins: []string{"*"},
15071495
}
15081496

@@ -2130,7 +2118,7 @@ func TestServer_ValidateAPIKeyValue_EmptyKey(t *testing.T) {
21302118

21312119
func TestServer_HandleHealth_OPTIONS(t *testing.T) {
21322120
server := &Server{
2133-
kubectl: &kube.KubectlProxy{config: &api.Config{}},
2121+
kubectl: kube.NewTestKubectlProxy(&api.Config{}),
21342122
registry: &Registry{providers: make(map[string]AIProvider)},
21352123
allowedOrigins: []string{"http://localhost"},
21362124
}
@@ -3417,7 +3405,7 @@ func TestCheckPingHealth_AllScenarios(t *testing.T) {
34173405

34183406
func TestServer_HandleLocalClusterTools_GET(t *testing.T) {
34193407
server := &Server{
3420-
localClusters: NewLocalClusterManager(nil),
3408+
localClusters: kube.NewLocalClusterManager(nil),
34213409
allowedOrigins: []string{"*"},
34223410
}
34233411

@@ -3433,7 +3421,7 @@ func TestServer_HandleLocalClusterTools_GET(t *testing.T) {
34333421

34343422
func TestServer_HandleLocalClusters_GET(t *testing.T) {
34353423
server := &Server{
3436-
localClusters: NewLocalClusterManager(nil),
3424+
localClusters: kube.NewLocalClusterManager(nil),
34373425
allowedOrigins: []string{"*"},
34383426
}
34393427

@@ -3449,7 +3437,7 @@ func TestServer_HandleLocalClusters_GET(t *testing.T) {
34493437

34503438
func TestServer_HandleLocalClusters_WrongMethod(t *testing.T) {
34513439
server := &Server{
3452-
localClusters: NewLocalClusterManager(nil),
3440+
localClusters: kube.NewLocalClusterManager(nil),
34533441
allowedOrigins: []string{"*"},
34543442
}
34553443

@@ -3464,7 +3452,7 @@ func TestServer_HandleLocalClusters_WrongMethod(t *testing.T) {
34643452

34653453
func TestServer_HandleLocalClusterTools_WrongMethod(t *testing.T) {
34663454
server := &Server{
3467-
localClusters: NewLocalClusterManager(nil),
3455+
localClusters: kube.NewLocalClusterManager(nil),
34683456
allowedOrigins: []string{"*"},
34693457
}
34703458

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package handlers
1+
package transport
22

33
import (
44
"sync"

0 commit comments

Comments
 (0)