Skip to content

Commit 2503269

Browse files
authored
test(kubernetes): add unit tests for ProviderSingle functionality (#376)
Signed-off-by: Marc Nuri <[email protected]>
1 parent dfddf23 commit 2503269

File tree

2 files changed

+136
-1
lines changed

2 files changed

+136
-1
lines changed

pkg/kubernetes/provider_kubeconfig_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ type ProviderKubeconfigTestSuite struct {
1818
}
1919

2020
func (s *ProviderKubeconfigTestSuite) SetupTest() {
21+
// Kubeconfig provider is used when the multi-cluster feature is enabled with the kubeconfig strategy.
22+
// For this test suite we simulate a kubeconfig with multiple contexts.
2123
s.mockServer = test.NewMockServer()
2224
kubeconfig := s.mockServer.Kubeconfig()
2325
for i := 0; i < 10; i++ {
@@ -84,7 +86,7 @@ func (s *ProviderKubeconfigTestSuite) TestVerifyToken() {
8486
s.Len(audiences, 1, "Expected audiences from VerifyToken with empty target")
8587
s.Containsf(audiences, "the-audience", "Expected audience the-audience in %v", audiences)
8688
})
87-
s.Run("VerifyToken returns UserInfo for empty context (default context", func() {
89+
s.Run("VerifyToken returns UserInfo for empty context (default context)", func() {
8890
userInfo, audiences, err := s.provider.VerifyToken(s.T().Context(), "", "the-token", "the-audience")
8991
s.Require().NoError(err, "Expected no error from VerifyToken with empty target")
9092
s.Require().NotNil(userInfo, "Expected UserInfo from VerifyToken with empty target")
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package kubernetes
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/containers/kubernetes-mcp-server/internal/test"
8+
"github.com/containers/kubernetes-mcp-server/pkg/config"
9+
"github.com/stretchr/testify/suite"
10+
"k8s.io/client-go/rest"
11+
)
12+
13+
type ProviderSingleTestSuite struct {
14+
BaseProviderSuite
15+
mockServer *test.MockServer
16+
originalIsInClusterConfig func() (*rest.Config, error)
17+
provider Provider
18+
}
19+
20+
func (s *ProviderSingleTestSuite) SetupTest() {
21+
// Single cluster provider is used when in-cluster or when the multi-cluster feature is disabled.
22+
// For this test suite we simulate an in-cluster deployment.
23+
s.originalIsInClusterConfig = InClusterConfig
24+
s.mockServer = test.NewMockServer()
25+
InClusterConfig = func() (*rest.Config, error) {
26+
return s.mockServer.Config(), nil
27+
}
28+
provider, err := NewProvider(&config.StaticConfig{})
29+
s.Require().NoError(err, "Expected no error creating provider with kubeconfig")
30+
s.provider = provider
31+
}
32+
33+
func (s *ProviderSingleTestSuite) TearDownTest() {
34+
InClusterConfig = s.originalIsInClusterConfig
35+
if s.mockServer != nil {
36+
s.mockServer.Close()
37+
}
38+
}
39+
40+
func (s *ProviderSingleTestSuite) TestType() {
41+
s.IsType(&singleClusterProvider{}, s.provider)
42+
}
43+
44+
func (s *ProviderSingleTestSuite) TestWithNonOpenShiftCluster() {
45+
s.Run("IsOpenShift returns false", func() {
46+
inOpenShift := s.provider.IsOpenShift(s.T().Context())
47+
s.False(inOpenShift, "Expected InOpenShift to return false")
48+
})
49+
}
50+
51+
func (s *ProviderSingleTestSuite) TestWithOpenShiftCluster() {
52+
s.mockServer.Handle(&test.InOpenShiftHandler{})
53+
s.Run("IsOpenShift returns true", func() {
54+
inOpenShift := s.provider.IsOpenShift(s.T().Context())
55+
s.True(inOpenShift, "Expected InOpenShift to return true")
56+
})
57+
}
58+
59+
func (s *ProviderSingleTestSuite) TestVerifyToken() {
60+
s.mockServer.Handle(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
61+
if req.URL.EscapedPath() == "/apis/authentication.k8s.io/v1/tokenreviews" {
62+
w.Header().Set("Content-Type", "application/json")
63+
_, _ = w.Write([]byte(`
64+
{
65+
"kind": "TokenReview",
66+
"apiVersion": "authentication.k8s.io/v1",
67+
"spec": {"token": "the-token"},
68+
"status": {
69+
"authenticated": true,
70+
"user": {
71+
"username": "test-user",
72+
"groups": ["system:authenticated"]
73+
},
74+
"audiences": ["the-audience"]
75+
}
76+
}`))
77+
}
78+
}))
79+
s.Run("VerifyToken returns UserInfo for empty target (default target)", func() {
80+
userInfo, audiences, err := s.provider.VerifyToken(s.T().Context(), "", "the-token", "the-audience")
81+
s.Require().NoError(err, "Expected no error from VerifyToken with empty target")
82+
s.Require().NotNil(userInfo, "Expected UserInfo from VerifyToken with empty target")
83+
s.Equalf(userInfo.Username, "test-user", "Expected username test-user, got: %s", userInfo.Username)
84+
s.Containsf(userInfo.Groups, "system:authenticated", "Expected group system:authenticated in %v", userInfo.Groups)
85+
s.Require().NotNil(audiences, "Expected audiences from VerifyToken with empty target")
86+
s.Len(audiences, 1, "Expected audiences from VerifyToken with empty target")
87+
s.Containsf(audiences, "the-audience", "Expected audience the-audience in %v", audiences)
88+
})
89+
s.Run("VerifyToken returns error for non-empty context", func() {
90+
userInfo, audiences, err := s.provider.VerifyToken(s.T().Context(), "non-empty", "the-token", "the-audience")
91+
s.Require().Error(err, "Expected error from VerifyToken with non-empty target")
92+
s.ErrorContains(err, "unable to get manager for other context/cluster with in-cluster strategy", "Expected error about trying to get other cluster")
93+
s.Nil(userInfo, "Expected no UserInfo from VerifyToken with non-empty target")
94+
s.Nil(audiences, "Expected no audiences from VerifyToken with non-empty target")
95+
})
96+
}
97+
98+
func (s *ProviderSingleTestSuite) TestGetTargets() {
99+
s.Run("GetTargets returns single empty target", func() {
100+
targets, err := s.provider.GetTargets(s.T().Context())
101+
s.Require().NoError(err, "Expected no error from GetTargets")
102+
s.Len(targets, 1, "Expected 1 targets from GetTargets")
103+
s.Contains(targets, "", "Expected empty target from GetTargets")
104+
})
105+
}
106+
107+
func (s *ProviderSingleTestSuite) TestGetDerivedKubernetes() {
108+
s.Run("GetDerivedKubernetes returns Kubernetes for empty target", func() {
109+
k8s, err := s.provider.GetDerivedKubernetes(s.T().Context(), "")
110+
s.Require().NoError(err, "Expected no error from GetDerivedKubernetes with empty target")
111+
s.NotNil(k8s, "Expected Kubernetes from GetDerivedKubernetes with empty target")
112+
})
113+
s.Run("GetDerivedKubernetes returns error for non-empty target", func() {
114+
k8s, err := s.provider.GetDerivedKubernetes(s.T().Context(), "non-empty-target")
115+
s.Require().Error(err, "Expected error from GetDerivedKubernetes with non-empty target")
116+
s.ErrorContains(err, "unable to get manager for other context/cluster with in-cluster strategy", "Expected error about trying to get other cluster")
117+
s.Nil(k8s, "Expected no Kubernetes from GetDerivedKubernetes with non-empty target")
118+
})
119+
}
120+
121+
func (s *ProviderSingleTestSuite) TestGetDefaultTarget() {
122+
s.Run("GetDefaultTarget returns empty string", func() {
123+
s.Empty(s.provider.GetDefaultTarget(), "Expected fake-context as default target")
124+
})
125+
}
126+
127+
func (s *ProviderSingleTestSuite) TestGetTargetParameterName() {
128+
s.Empty(s.provider.GetTargetParameterName(), "Expected empty string as target parameter name")
129+
}
130+
131+
func TestProviderSingle(t *testing.T) {
132+
suite.Run(t, new(ProviderSingleTestSuite))
133+
}

0 commit comments

Comments
 (0)