From 8af889bc8f0bc8960695eb074a63d24d73f9e9b0 Mon Sep 17 00:00:00 2001 From: Marc Nuri Date: Thu, 18 Sep 2025 16:08:53 +0200 Subject: [PATCH] test(mcp): refactor helm toolset tests (#333) Refactor tests to new approach before adding more functionality. Signed-off-by: Marc Nuri --- internal/test/test.go | 13 ++ pkg/mcp/events_test.go | 2 +- pkg/mcp/helm_test.go | 421 +++++++++++++++++++------------------ pkg/mcp/namespaces_test.go | 2 +- pkg/mcp/toolsets_test.go | 24 +-- 5 files changed, 236 insertions(+), 226 deletions(-) diff --git a/internal/test/test.go b/internal/test/test.go index b11b957..0349142 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -1,8 +1,21 @@ package test +import ( + "os" + "path/filepath" + "runtime" +) + func Must[T any](v T, err error) T { if err != nil { panic(err) } return v } + +func ReadFile(path ...string) string { + _, file, _, _ := runtime.Caller(1) + filePath := filepath.Join(append([]string{filepath.Dir(file)}, path...)...) + fileBytes := Must(os.ReadFile(filePath)) + return string(fileBytes) +} diff --git a/pkg/mcp/events_test.go b/pkg/mcp/events_test.go index 8e0f4f4..cb3219d 100644 --- a/pkg/mcp/events_test.go +++ b/pkg/mcp/events_test.go @@ -104,7 +104,7 @@ func (s *EventsSuite) TestEventsList() { func (s *EventsSuite) TestEventsListDenied() { s.Require().NoError(toml.Unmarshal([]byte(` denied_resources = [ { version = "v1", kind = "Event" } ] - `), s.Cfg), "Expected to parse denied resources config") + `), s.Cfg), "Expected to parse denied resources config") s.InitMcpClient() s.Run("events_list (denied)", func() { toolResult, err := s.CallTool("events_list", map[string]interface{}{}) diff --git a/pkg/mcp/helm_test.go b/pkg/mcp/helm_test.go index b5c777a..5d52c79 100644 --- a/pkg/mcp/helm_test.go +++ b/pkg/mcp/helm_test.go @@ -8,255 +8,260 @@ import ( "strings" "testing" - "github.com/containers/kubernetes-mcp-server/internal/test" + "github.com/BurntSushi/toml" "github.com/mark3labs/mcp-go/mcp" + "github.com/stretchr/testify/suite" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "sigs.k8s.io/yaml" - - "github.com/containers/kubernetes-mcp-server/pkg/config" ) -func TestHelmInstall(t *testing.T) { - testCase(t, func(c *mcpContext) { - c.withEnvTest() +type HelmSuite struct { + BaseMcpSuite +} + +func (s *HelmSuite) SetupTest() { + s.BaseMcpSuite.SetupTest() + clearHelmReleases(s.T().Context(), kubernetes.NewForConfigOrDie(envTestRestConfig)) +} + +func (s *HelmSuite) TestHelmInstall() { + s.InitMcpClient() + s.Run("helm_install(chart=helm-chart-no-op)", func() { _, file, _, _ := runtime.Caller(0) chartPath := filepath.Join(filepath.Dir(file), "testdata", "helm-chart-no-op") - toolResult, err := c.callTool("helm_install", map[string]interface{}{ + toolResult, err := s.CallTool("helm_install", map[string]interface{}{ "chart": chartPath, }) - t.Run("helm_install with local chart and no release name, returns installed chart", func(t *testing.T) { - if err != nil { - t.Fatalf("call tool failed %v", err) - } - if toolResult.IsError { - t.Fatalf("call tool failed") - } + s.Run("no error", func() { + s.Nilf(err, "call tool failed %v", err) + s.Falsef(toolResult.IsError, "call tool failed") + }) + s.Run("returns installed chart", func() { var decoded []map[string]interface{} err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded) - if err != nil { - t.Fatalf("invalid tool result content %v", err) - } - if !strings.HasPrefix(decoded[0]["name"].(string), "helm-chart-no-op-") { - t.Fatalf("invalid helm install name, expected no-op-*, got %v", decoded[0]["name"]) - } - if decoded[0]["namespace"] != "default" { - t.Fatalf("invalid helm install namespace, expected default, got %v", decoded[0]["namespace"]) - } - if decoded[0]["chart"] != "no-op" { - t.Fatalf("invalid helm install name, expected release name, got empty") - } - if decoded[0]["chartVersion"] != "1.33.7" { - t.Fatalf("invalid helm install version, expected 1.33.7, got empty") - } - if decoded[0]["status"] != "deployed" { - t.Fatalf("invalid helm install status, expected deployed, got %v", decoded[0]["status"]) - } - if decoded[0]["revision"] != float64(1) { - t.Fatalf("invalid helm install revision, expected 1, got %v", decoded[0]["revision"]) - } + s.Run("has yaml content", func() { + s.Nilf(err, "invalid tool result content %v", err) + }) + s.Run("has 1 item", func() { + s.Lenf(decoded, 1, "invalid helm install count, expected 1, got %v", len(decoded)) + }) + s.Run("has valid name", func() { + s.Truef(strings.HasPrefix(decoded[0]["name"].(string), "helm-chart-no-op-"), "invalid helm install name, expected no-op-*, got %v", decoded[0]["name"]) + }) + s.Run("has valid namespace", func() { + s.Equalf("default", decoded[0]["namespace"], "invalid helm install namespace, expected default, got %v", decoded[0]["namespace"]) + }) + s.Run("has valid chart", func() { + s.Equalf("no-op", decoded[0]["chart"], "invalid helm install name, expected release name, got empty") + }) + s.Run("has valid chartVersion", func() { + s.Equalf("1.33.7", decoded[0]["chartVersion"], "invalid helm install version, expected 1.33.7, got empty") + }) + s.Run("has valid status", func() { + s.Equalf("deployed", decoded[0]["status"], "invalid helm install status, expected deployed, got %v", decoded[0]["status"]) + }) + s.Run("has valid revision", func() { + s.Equalf(float64(1), decoded[0]["revision"], "invalid helm install revision, expected 1, got %v", decoded[0]["revision"]) + }) }) }) } -func TestHelmInstallDenied(t *testing.T) { - deniedResourcesServer := test.Must(config.ReadToml([]byte(` +func (s *HelmSuite) TestHelmInstallDenied() { + s.Require().NoError(toml.Unmarshal([]byte(` denied_resources = [ { version = "v1", kind = "Secret" } ] - `))) - testCaseWithContext(t, &mcpContext{staticConfig: deniedResourcesServer}, func(c *mcpContext) { - c.withEnvTest() + `), s.Cfg), "Expected to parse denied resources config") + s.InitMcpClient() + s.Run("helm_install(chart=helm-chart-secret, denied)", func() { _, file, _, _ := runtime.Caller(0) chartPath := filepath.Join(filepath.Dir(file), "testdata", "helm-chart-secret") - helmInstall, _ := c.callTool("helm_install", map[string]interface{}{ + toolResult, err := s.CallTool("helm_install", map[string]interface{}{ "chart": chartPath, }) - t.Run("helm_install has error", func(t *testing.T) { - if !helmInstall.IsError { - t.Fatalf("call tool should fail") - } + s.Run("has error", func() { + s.Truef(toolResult.IsError, "call tool should fail") + s.Nilf(err, "call tool should not return error object") }) - t.Run("helm_install describes denial", func(t *testing.T) { - toolOutput := helmInstall.Content[0].(mcp.TextContent).Text + s.Run("describes denial", func() { + s.Truef(strings.HasPrefix(toolResult.Content[0].(mcp.TextContent).Text, "failed to install helm chart"), "expected descriptive error, got %v", toolResult.Content[0].(mcp.TextContent).Text) expectedMessage := ": resource not allowed: /v1, Kind=Secret" - if !strings.HasPrefix(toolOutput, "failed to install helm chart") || !strings.HasSuffix(toolOutput, expectedMessage) { - t.Fatalf("expected descriptive error '%s', got %v", expectedMessage, helmInstall.Content[0].(mcp.TextContent).Text) - } + s.Truef(strings.HasSuffix(toolResult.Content[0].(mcp.TextContent).Text, expectedMessage), "expected descriptive error '%s', got %v", expectedMessage, toolResult.Content[0].(mcp.TextContent).Text) }) }) } -func TestHelmList(t *testing.T) { - testCase(t, func(c *mcpContext) { - c.withEnvTest() - kc := c.newKubernetesClient() - clearHelmReleases(c.ctx, kc) - toolResult, err := c.callTool("helm_list", map[string]interface{}{}) - t.Run("helm_list with no releases, returns not found", func(t *testing.T) { - if err != nil { - t.Fatalf("call tool failed %v", err) - } - if toolResult.IsError { - t.Fatalf("call tool failed") - } - if toolResult.Content[0].(mcp.TextContent).Text != "No Helm releases found" { - t.Fatalf("unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) - } +func (s *HelmSuite) TestHelmListNoReleases() { + s.InitMcpClient() + s.Run("helm_list() with no releases", func() { + toolResult, err := s.CallTool("helm_list", map[string]interface{}{}) + s.Run("no error", func() { + s.Nilf(err, "call tool failed %v", err) + s.Falsef(toolResult.IsError, "call tool failed") }) - _, _ = kc.CoreV1().Secrets("default").Create(c.ctx, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sh.helm.release.v1.release-to-list", - Labels: map[string]string{"owner": "helm", "name": "release-to-list"}, - }, - Data: map[string][]byte{ - "release": []byte(base64.StdEncoding.EncodeToString([]byte("{" + - "\"name\":\"release-to-list\"," + - "\"info\":{\"status\":\"deployed\"}" + - "}"))), - }, - }, metav1.CreateOptions{}) - toolResult, err = c.callTool("helm_list", map[string]interface{}{}) - t.Run("helm_list with deployed release, returns release", func(t *testing.T) { - if err != nil { - t.Fatalf("call tool failed %v", err) - } - if toolResult.IsError { - t.Fatalf("call tool failed") - } - var decoded []map[string]interface{} - err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded) - if err != nil { - t.Fatalf("invalid tool result content %v", err) - } - if len(decoded) != 1 { - t.Fatalf("invalid helm list count, expected 1, got %v", len(decoded)) - } - if decoded[0]["name"] != "release-to-list" { - t.Fatalf("invalid helm list name, expected release-to-list, got %v", decoded[0]["name"]) - } - if decoded[0]["status"] != "deployed" { - t.Fatalf("invalid helm list status, expected deployed, got %v", decoded[0]["status"]) - } - }) - toolResult, err = c.callTool("helm_list", map[string]interface{}{"namespace": "ns-1"}) - t.Run("helm_list with deployed release in other namespaces, returns not found", func(t *testing.T) { - if err != nil { - t.Fatalf("call tool failed %v", err) - } - if toolResult.IsError { - t.Fatalf("call tool failed") - } - if toolResult.Content[0].(mcp.TextContent).Text != "No Helm releases found" { - t.Fatalf("unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) - } - }) - toolResult, err = c.callTool("helm_list", map[string]interface{}{"namespace": "ns-1", "all_namespaces": true}) - t.Run("helm_list with deployed release in all namespaces, returns release", func(t *testing.T) { - if err != nil { - t.Fatalf("call tool failed %v", err) - } - if toolResult.IsError { - t.Fatalf("call tool failed") - } - var decoded []map[string]interface{} - err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded) - if err != nil { - t.Fatalf("invalid tool result content %v", err) - } - if len(decoded) != 1 { - t.Fatalf("invalid helm list count, expected 1, got %v", len(decoded)) - } - if decoded[0]["name"] != "release-to-list" { - t.Fatalf("invalid helm list name, expected release-to-list, got %v", decoded[0]["name"]) - } - if decoded[0]["status"] != "deployed" { - t.Fatalf("invalid helm list status, expected deployed, got %v", decoded[0]["status"]) - } + s.Run("returns not found", func() { + s.Equalf("No Helm releases found", toolResult.Content[0].(mcp.TextContent).Text, "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) }) }) } -func TestHelmUninstall(t *testing.T) { - testCase(t, func(c *mcpContext) { - c.withEnvTest() - kc := c.newKubernetesClient() - clearHelmReleases(c.ctx, kc) - toolResult, err := c.callTool("helm_uninstall", map[string]interface{}{ +func (s *HelmSuite) TestHelmList() { + kc := kubernetes.NewForConfigOrDie(envTestRestConfig) + _, err := kc.CoreV1().Secrets("default").Create(s.T().Context(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "sh.helm.release.v1.release-to-list", + Labels: map[string]string{"owner": "helm", "name": "release-to-list"}, + }, + Data: map[string][]byte{ + "release": []byte(base64.StdEncoding.EncodeToString([]byte("{" + + "\"name\":\"release-to-list\"," + + "\"info\":{\"status\":\"deployed\"}" + + "}"))), + }, + }, metav1.CreateOptions{}) + s.Require().NoError(err) + s.InitMcpClient() + s.Run("helm_list() with deployed release", func() { + toolResult, err := s.CallTool("helm_list", map[string]interface{}{}) + s.Run("no error", func() { + s.Nilf(err, "call tool failed %v", err) + s.Falsef(toolResult.IsError, "call tool failed") + }) + s.Run("returns release", func() { + var decoded []map[string]interface{} + err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded) + s.Run("has yaml content", func() { + s.Nilf(err, "invalid tool result content %v", err) + }) + s.Run("has 1 item", func() { + s.Lenf(decoded, 1, "invalid helm list count, expected 1, got %v", len(decoded)) + }) + s.Run("has valid name", func() { + s.Equalf("release-to-list", decoded[0]["name"], "invalid helm list name, expected release-to-list, got %v", decoded[0]["name"]) + }) + s.Run("has valid status", func() { + s.Equalf("deployed", decoded[0]["status"], "invalid helm list status, expected deployed, got %v", decoded[0]["status"]) + }) + }) + }) + s.Run("helm_list(namespace=ns-1) with deployed release in other namespaces", func() { + toolResult, err := s.CallTool("helm_list", map[string]interface{}{"namespace": "ns-1"}) + s.Run("no error", func() { + s.Nilf(err, "call tool failed %v", err) + s.Falsef(toolResult.IsError, "call tool failed") + }) + s.Run("returns not found", func() { + s.Equalf("No Helm releases found", toolResult.Content[0].(mcp.TextContent).Text, "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) + }) + }) + s.Run("helm_list(namespace=ns-1, all_namespaces=true) with deployed release in all namespaces", func() { + toolResult, err := s.CallTool("helm_list", map[string]interface{}{"namespace": "ns-1", "all_namespaces": true}) + s.Run("no error", func() { + s.Nilf(err, "call tool failed %v", err) + s.Falsef(toolResult.IsError, "call tool failed") + }) + s.Run("returns release", func() { + var decoded []map[string]interface{} + err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded) + s.Run("has yaml content", func() { + s.Nilf(err, "invalid tool result content %v", err) + }) + s.Run("has 1 item", func() { + s.Lenf(decoded, 1, "invalid helm list count, expected 1, got %v", len(decoded)) + }) + s.Run("has valid name", func() { + s.Equalf("release-to-list", decoded[0]["name"], "invalid helm list name, expected release-to-list, got %v", decoded[0]["name"]) + }) + s.Run("has valid status", func() { + s.Equalf("deployed", decoded[0]["status"], "invalid helm list status, expected deployed, got %v", decoded[0]["status"]) + }) + }) + }) +} + +func (s *HelmSuite) TestHelmUninstallNoReleases() { + s.InitMcpClient() + s.Run("helm_uninstall(name=release-to-uninstall) with no releases", func() { + toolResult, err := s.CallTool("helm_uninstall", map[string]interface{}{ "name": "release-to-uninstall", }) - t.Run("helm_uninstall with no releases, returns not found", func(t *testing.T) { - if err != nil { - t.Fatalf("call tool failed %v", err) - } - if toolResult.IsError { - t.Fatalf("call tool failed") - } - if toolResult.Content[0].(mcp.TextContent).Text != "Release release-to-uninstall not found" { - t.Fatalf("unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) - } + s.Run("no error", func() { + s.Nilf(err, "call tool failed %v", err) + s.Falsef(toolResult.IsError, "call tool failed") }) - _, _ = kc.CoreV1().Secrets("default").Create(c.ctx, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sh.helm.release.v1.existent-release-to-uninstall.v0", - Labels: map[string]string{"owner": "helm", "name": "existent-release-to-uninstall"}, - }, - Data: map[string][]byte{ - "release": []byte(base64.StdEncoding.EncodeToString([]byte("{" + - "\"name\":\"existent-release-to-uninstall\"," + - "\"info\":{\"status\":\"deployed\"}" + - "}"))), - }, - }, metav1.CreateOptions{}) - toolResult, err = c.callTool("helm_uninstall", map[string]interface{}{ - "name": "existent-release-to-uninstall", - }) - t.Run("helm_uninstall with deployed release, returns uninstalled", func(t *testing.T) { - if err != nil { - t.Fatalf("call tool failed %v", err) - } - if toolResult.IsError { - t.Fatalf("call tool failed") - } - if !strings.HasPrefix(toolResult.Content[0].(mcp.TextContent).Text, "Uninstalled release existent-release-to-uninstall") { - t.Fatalf("unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) - } - _, err = kc.CoreV1().Secrets("default").Get(c.ctx, "sh.helm.release.v1.existent-release-to-uninstall.v0", metav1.GetOptions{}) - if !errors.IsNotFound(err) { - t.Fatalf("expected release to be deleted, but it still exists") - } + s.Run("returns not found", func() { + s.Equalf("Release release-to-uninstall not found", toolResult.Content[0].(mcp.TextContent).Text, "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) }) }) } -func TestHelmUninstallDenied(t *testing.T) { - deniedResourcesServer := test.Must(config.ReadToml([]byte(` - denied_resources = [ { version = "v1", kind = "Secret" } ] - `))) - testCaseWithContext(t, &mcpContext{staticConfig: deniedResourcesServer}, func(c *mcpContext) { - c.withEnvTest() - kc := c.newKubernetesClient() - clearHelmReleases(c.ctx, kc) - _, _ = kc.CoreV1().Secrets("default").Create(c.ctx, &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sh.helm.release.v1.existent-release-to-uninstall.v0", - Labels: map[string]string{"owner": "helm", "name": "existent-release-to-uninstall"}, - }, - Data: map[string][]byte{ - "release": []byte(base64.StdEncoding.EncodeToString([]byte("{" + - "\"name\":\"existent-release-to-uninstall\"," + - "\"info\":{\"status\":\"deployed\"}," + - "\"manifest\":\"apiVersion: v1\\nkind: Secret\\nmetadata:\\n name: secret-to-deny\\n namespace: default\\n\"" + - "}"))), - }, - }, metav1.CreateOptions{}) - helmUninstall, _ := c.callTool("helm_uninstall", map[string]interface{}{ +func (s *HelmSuite) TestHelmUninstall() { + kc := kubernetes.NewForConfigOrDie(envTestRestConfig) + _, err := kc.CoreV1().Secrets("default").Create(s.T().Context(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "sh.helm.release.v1.existent-release-to-uninstall.v0", + Labels: map[string]string{"owner": "helm", "name": "existent-release-to-uninstall"}, + }, + Data: map[string][]byte{ + "release": []byte(base64.StdEncoding.EncodeToString([]byte("{" + + "\"name\":\"existent-release-to-uninstall\"," + + "\"info\":{\"status\":\"deployed\"}" + + "}"))), + }, + }, metav1.CreateOptions{}) + s.Require().NoError(err) + s.InitMcpClient() + s.Run("helm_uninstall(name=existent-release-to-uninstall) with deployed release", func() { + toolResult, err := s.CallTool("helm_uninstall", map[string]interface{}{ "name": "existent-release-to-uninstall", }) - t.Run("helm_uninstall has error", func(t *testing.T) { - if !helmUninstall.IsError { - t.Fatalf("call tool should fail") - } + s.Run("no error", func() { + s.Nilf(err, "call tool failed %v", err) + s.Falsef(toolResult.IsError, "call tool failed") + }) + s.Run("returns uninstalled", func() { + s.Truef(strings.HasPrefix(toolResult.Content[0].(mcp.TextContent).Text, "Uninstalled release existent-release-to-uninstall"), "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text) + _, err = kc.CoreV1().Secrets("default").Get(s.T().Context(), "sh.helm.release.v1.existent-release-to-uninstall.v0", metav1.GetOptions{}) + s.Truef(errors.IsNotFound(err), "expected release to be deleted, but it still exists") + }) + + }) +} + +func (s *HelmSuite) TestHelmUninstallDenied() { + s.Require().NoError(toml.Unmarshal([]byte(` + denied_resources = [ { version = "v1", kind = "Secret" } ] + `), s.Cfg), "Expected to parse denied resources config") + kc := kubernetes.NewForConfigOrDie(envTestRestConfig) + _, err := kc.CoreV1().Secrets("default").Create(s.T().Context(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "sh.helm.release.v1.existent-release-to-uninstall.v0", + Labels: map[string]string{"owner": "helm", "name": "existent-release-to-uninstall"}, + }, + Data: map[string][]byte{ + "release": []byte(base64.StdEncoding.EncodeToString([]byte("{" + + "\"name\":\"existent-release-to-uninstall\"," + + "\"info\":{\"status\":\"deployed\"}," + + "\"manifest\":\"apiVersion: v1\\nkind: Secret\\nmetadata:\\n name: secret-to-deny\\n namespace: default\\n\"" + + "}"))), + }, + }, metav1.CreateOptions{}) + s.Require().NoError(err) + s.InitMcpClient() + s.Run("helm_uninstall(name=existent-release-to-uninstall) with deployed release (denied)", func() { + toolResult, err := s.CallTool("helm_uninstall", map[string]interface{}{ + "name": "existent-release-to-uninstall", + }) + s.Run("has error", func() { + s.Truef(toolResult.IsError, "call tool should fail") + s.Nilf(err, "call tool should not return error object") + }) + s.Run("describes denial", func() { + s.T().Skipf("Helm won't report what underlying resource caused the failure, so we can't assert on it") + expectedMessage := "failed to uninstall release: resource not allowed: /v1, Kind=Secret" + s.Equalf(expectedMessage, toolResult.Content[0].(mcp.TextContent).Text, "expected descriptive error '%s', got %v", expectedMessage, toolResult.Content[0].(mcp.TextContent).Text) }) }) } @@ -269,3 +274,7 @@ func clearHelmReleases(ctx context.Context, kc *kubernetes.Clientset) { } } } + +func TestHelm(t *testing.T) { + suite.Run(t, new(HelmSuite)) +} diff --git a/pkg/mcp/namespaces_test.go b/pkg/mcp/namespaces_test.go index 26c92ee..a0a6ff2 100644 --- a/pkg/mcp/namespaces_test.go +++ b/pkg/mcp/namespaces_test.go @@ -50,7 +50,7 @@ func (s *NamespacesSuite) TestNamespacesList() { func (s *NamespacesSuite) TestNamespacesListDenied() { s.Require().NoError(toml.Unmarshal([]byte(` denied_resources = [ { version = "v1", kind = "Namespace" } ] - `), s.Cfg), "Expected to parse denied resources config") + `), s.Cfg), "Expected to parse denied resources config") s.InitMcpClient() s.Run("namespaces_list (denied)", func() { toolResult, err := s.CallTool("namespaces_list", map[string]interface{}{}) diff --git a/pkg/mcp/toolsets_test.go b/pkg/mcp/toolsets_test.go index 4e01186..a8a1ef3 100644 --- a/pkg/mcp/toolsets_test.go +++ b/pkg/mcp/toolsets_test.go @@ -2,9 +2,6 @@ package mcp import ( "encoding/json" - "os" - "path/filepath" - "runtime" "testing" "github.com/mark3labs/mcp-go/mcp" @@ -75,13 +72,10 @@ func (s *ToolsetsSuite) TestDefaultToolsetsTools() { s.NoError(err, "Expected no error from ListTools") }) s.Run("ListTools returns correct Tool metadata", func() { - _, file, _, _ := runtime.Caller(0) - expectedMetadataPath := filepath.Join(filepath.Dir(file), "testdata", "toolsets-full-tools.json") - expectedMetadataBytes, err := os.ReadFile(expectedMetadataPath) - s.Require().NoErrorf(err, "failed to read expected tools metadata file: %v", err) + expectedMetadata := test.ReadFile("testdata", "toolsets-full-tools.json") metadata, err := json.MarshalIndent(tools.Tools, "", " ") s.Require().NoErrorf(err, "failed to marshal tools metadata: %v", err) - s.JSONEq(string(expectedMetadataBytes), string(metadata), "tools metadata does not match expected") + s.JSONEq(expectedMetadata, string(metadata), "tools metadata does not match expected") }) }) } @@ -96,13 +90,10 @@ func (s *ToolsetsSuite) TestDefaultToolsetsToolsInOpenShift() { s.NoError(err, "Expected no error from ListTools") }) s.Run("ListTools returns correct Tool metadata", func() { - _, file, _, _ := runtime.Caller(0) - expectedMetadataPath := filepath.Join(filepath.Dir(file), "testdata", "toolsets-full-tools-openshift.json") - expectedMetadataBytes, err := os.ReadFile(expectedMetadataPath) - s.Require().NoErrorf(err, "failed to read expected tools metadata file: %v", err) + expectedMetadata := test.ReadFile("testdata", "toolsets-full-tools-openshift.json") metadata, err := json.MarshalIndent(tools.Tools, "", " ") s.Require().NoErrorf(err, "failed to marshal tools metadata: %v", err) - s.JSONEq(string(expectedMetadataBytes), string(metadata), "tools metadata does not match expected") + s.JSONEq(expectedMetadata, string(metadata), "tools metadata does not match expected") }) }) } @@ -125,13 +116,10 @@ func (s *ToolsetsSuite) TestGranularToolsetsTools() { s.NoError(err, "Expected no error from ListTools") }) s.Run("ListTools returns correct Tool metadata", func() { - _, file, _, _ := runtime.Caller(0) - expectedMetadataPath := filepath.Join(filepath.Dir(file), "testdata", "toolsets-"+testCase.GetName()+"-tools.json") - expectedMetadataBytes, err := os.ReadFile(expectedMetadataPath) - s.Require().NoErrorf(err, "failed to read expected tools metadata file: %v", err) + expectedMetadata := test.ReadFile("testdata", "toolsets-"+testCase.GetName()+"-tools.json") metadata, err := json.MarshalIndent(tools.Tools, "", " ") s.Require().NoErrorf(err, "failed to marshal tools metadata: %v", err) - s.JSONEq(string(expectedMetadataBytes), string(metadata), "tools metadata does not match expected") + s.JSONEq(expectedMetadata, string(metadata), "tools metadata does not match expected") }) }) }