Skip to content

Commit 1f00601

Browse files
committed
test(profiles): bootstrap initial testing support for profiles
1 parent f23c153 commit 1f00601

File tree

3 files changed

+109
-82
lines changed

3 files changed

+109
-82
lines changed

pkg/mcp/common_test.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ func TestMain(m *testing.M) {
9292
}
9393

9494
type mcpContext struct {
95+
profile Profile
96+
before *func(*mcpContext)
97+
after *func(*mcpContext)
9598
ctx context.Context
9699
tempDir string
97100
cancel context.CancelFunc
@@ -102,10 +105,13 @@ type mcpContext struct {
102105

103106
func (c *mcpContext) beforeEach(t *testing.T) {
104107
var err error
105-
c.ctx, c.cancel = context.WithCancel(context.Background())
108+
c.ctx, c.cancel = context.WithCancel(t.Context())
106109
c.tempDir = t.TempDir()
107110
c.withKubeConfig(nil)
108-
if c.mcpServer, err = NewSever(Configuration{Profile: &FullProfile{}}); err != nil {
111+
if c.before != nil {
112+
(*c.before)(c)
113+
}
114+
if c.mcpServer, err = NewSever(Configuration{Profile: c.profile}); err != nil {
109115
t.Fatal(err)
110116
return
111117
}
@@ -129,14 +135,20 @@ func (c *mcpContext) beforeEach(t *testing.T) {
129135
}
130136

131137
func (c *mcpContext) afterEach() {
138+
if c.after != nil {
139+
(*c.after)(c)
140+
}
132141
c.cancel()
133142
c.mcpServer.Close()
134143
_ = c.mcpClient.Close()
135144
c.mcpHttpServer.Close()
136145
}
137146

138147
func testCase(t *testing.T, test func(c *mcpContext)) {
139-
mcpCtx := &mcpContext{}
148+
testCaseWithContext(t, &mcpContext{profile: &FullProfile{}}, test)
149+
}
150+
151+
func testCaseWithContext(t *testing.T, mcpCtx *mcpContext, test func(c *mcpContext)) {
140152
mcpCtx.beforeEach(t)
141153
defer mcpCtx.afterEach()
142154
test(mcpCtx)

pkg/mcp/mcp_test.go

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import (
66
"os"
77
"path/filepath"
88
"runtime"
9-
"slices"
10-
"strings"
119
"testing"
1210
"time"
1311
)
@@ -49,80 +47,3 @@ func TestWatchKubeConfig(t *testing.T) {
4947
})
5048
})
5149
}
52-
53-
func TestTools(t *testing.T) {
54-
expectedNames := []string{
55-
"configuration_view",
56-
"events_list",
57-
"helm_install",
58-
"helm_list",
59-
"helm_uninstall",
60-
"namespaces_list",
61-
"pods_list",
62-
"pods_list_in_namespace",
63-
"pods_get",
64-
"pods_delete",
65-
"pods_log",
66-
"pods_run",
67-
"pods_exec",
68-
"resources_list",
69-
"resources_get",
70-
"resources_create_or_update",
71-
"resources_delete",
72-
}
73-
testCase(t, func(c *mcpContext) {
74-
tools, err := c.mcpClient.ListTools(c.ctx, mcp.ListToolsRequest{})
75-
t.Run("ListTools returns tools", func(t *testing.T) {
76-
if err != nil {
77-
t.Fatalf("call ListTools failed %v", err)
78-
return
79-
}
80-
})
81-
nameSet := make(map[string]bool)
82-
for _, tool := range tools.Tools {
83-
nameSet[tool.Name] = true
84-
}
85-
for _, name := range expectedNames {
86-
t.Run("ListTools has "+name+" tool", func(t *testing.T) {
87-
if nameSet[name] != true {
88-
t.Fatalf("tool %s not found", name)
89-
return
90-
}
91-
})
92-
}
93-
})
94-
}
95-
96-
func TestToolsInOpenShift(t *testing.T) {
97-
testCase(t, func(c *mcpContext) {
98-
defer c.inOpenShift()() // n.b. two sets of parentheses to invoke the first function
99-
c.mcpServer.server.AddTools(c.mcpServer.initNamespaces()...)
100-
c.mcpServer.server.AddTools(c.mcpServer.initResources()...)
101-
tools, err := c.mcpClient.ListTools(c.ctx, mcp.ListToolsRequest{})
102-
t.Run("ListTools returns tools", func(t *testing.T) {
103-
if err != nil {
104-
t.Fatalf("call ListTools failed %v", err)
105-
}
106-
})
107-
t.Run("ListTools contains projects_list tool", func(t *testing.T) {
108-
idx := slices.IndexFunc(tools.Tools, func(tool mcp.Tool) bool {
109-
return tool.Name == "projects_list"
110-
})
111-
if idx == -1 {
112-
t.Fatalf("tool projects_list not found")
113-
}
114-
})
115-
t.Run("ListTools has resources_list tool with OpenShift hint", func(t *testing.T) {
116-
idx := slices.IndexFunc(tools.Tools, func(tool mcp.Tool) bool {
117-
return tool.Name == "resources_list"
118-
})
119-
if idx == -1 {
120-
t.Fatalf("tool resources_list not found")
121-
}
122-
if !strings.Contains(tools.Tools[idx].Description, ", route.openshift.io/v1 Route") {
123-
t.Fatalf("tool resources_list does not have OpenShift hint, got %s", tools.Tools[9].Description)
124-
}
125-
})
126-
})
127-
128-
}

pkg/mcp/profiles_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package mcp
2+
3+
import (
4+
"github.com/mark3labs/mcp-go/mcp"
5+
"slices"
6+
"strings"
7+
"testing"
8+
)
9+
10+
func TestFullProfileTools(t *testing.T) {
11+
expectedNames := []string{
12+
"configuration_view",
13+
"events_list",
14+
"helm_install",
15+
"helm_list",
16+
"helm_uninstall",
17+
"namespaces_list",
18+
"pods_list",
19+
"pods_list_in_namespace",
20+
"pods_get",
21+
"pods_delete",
22+
"pods_log",
23+
"pods_run",
24+
"pods_exec",
25+
"resources_list",
26+
"resources_get",
27+
"resources_create_or_update",
28+
"resources_delete",
29+
}
30+
mcpCtx := &mcpContext{profile: &FullProfile{}}
31+
testCaseWithContext(t, mcpCtx, func(c *mcpContext) {
32+
tools, err := c.mcpClient.ListTools(c.ctx, mcp.ListToolsRequest{})
33+
t.Run("ListTools returns tools", func(t *testing.T) {
34+
if err != nil {
35+
t.Fatalf("call ListTools failed %v", err)
36+
return
37+
}
38+
})
39+
nameSet := make(map[string]bool)
40+
for _, tool := range tools.Tools {
41+
nameSet[tool.Name] = true
42+
}
43+
for _, name := range expectedNames {
44+
t.Run("ListTools has "+name+" tool", func(t *testing.T) {
45+
if nameSet[name] != true {
46+
t.Fatalf("tool %s not found", name)
47+
return
48+
}
49+
})
50+
}
51+
})
52+
}
53+
54+
func TestFullProfileToolsInOpenShift(t *testing.T) {
55+
var after func(c *mcpContext)
56+
before := func(c *mcpContext) {
57+
cleanCrds := c.inOpenShift()
58+
after = func(_ *mcpContext) {
59+
cleanCrds()
60+
}
61+
}
62+
mcpCtx := &mcpContext{
63+
profile: &FullProfile{},
64+
before: &before,
65+
after: &after,
66+
}
67+
testCaseWithContext(t, mcpCtx, func(c *mcpContext) {
68+
tools, err := c.mcpClient.ListTools(c.ctx, mcp.ListToolsRequest{})
69+
t.Run("ListTools returns tools", func(t *testing.T) {
70+
if err != nil {
71+
t.Fatalf("call ListTools failed %v", err)
72+
}
73+
})
74+
t.Run("ListTools contains projects_list tool", func(t *testing.T) {
75+
idx := slices.IndexFunc(tools.Tools, func(tool mcp.Tool) bool {
76+
return tool.Name == "projects_list"
77+
})
78+
if idx == -1 {
79+
t.Fatalf("tool projects_list not found")
80+
}
81+
})
82+
t.Run("ListTools has resources_list tool with OpenShift hint", func(t *testing.T) {
83+
idx := slices.IndexFunc(tools.Tools, func(tool mcp.Tool) bool {
84+
return tool.Name == "resources_list"
85+
})
86+
if idx == -1 {
87+
t.Fatalf("tool resources_list not found")
88+
}
89+
if !strings.Contains(tools.Tools[idx].Description, ", route.openshift.io/v1 Route") {
90+
t.Fatalf("tool resources_list does not have OpenShift hint, got %s", tools.Tools[9].Description)
91+
}
92+
})
93+
})
94+
}

0 commit comments

Comments
 (0)