@@ -6,6 +6,268 @@ import (
66 "testing"
77)
88
9+ func TestKubernetesClusterConfigValidation (t * testing.T ) {
10+ db := GetTestDB (t )
11+ ctx := context .Background ()
12+
13+ t .Run ("cluster kubeconfig is empty - error code 10021" , func (t * testing.T ) {
14+ tx , err := db .BeginTx (ctx , nil )
15+ if err != nil {
16+ t .Fatalf ("failed to begin transaction: %v" , err )
17+ }
18+ defer func () {
19+ _ = tx .Rollback ()
20+ }()
21+
22+ // Try to insert cluster with empty kubeconfig
23+ _ , err = tx .ExecContext (ctx , `
24+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
25+ VALUES (
26+ 'v1',
27+ 'Cluster',
28+ ROW('kubernetes', '{"kubeconfig":"", "router": {"replicas": 2, "resources": {"cpu":"1","memory":"1Gi"},"access_mode":"LoadBalancer"}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
29+ ROW('test-cluster', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
30+ )
31+ ` )
32+
33+ if err == nil {
34+ t .Fatal ("expected validation error: kubeconfig is required for Kubernetes clusters" )
35+ }
36+
37+ // Check that the error message contains the correct error code
38+ if ! strings .Contains (err .Error (), `"code": "10021"` ) {
39+ t .Fatalf ("expected error code 10021, got: %v" , err )
40+ }
41+
42+ t .Logf ("validation correctly blocked insert with error code 10021: %v" , err )
43+ })
44+
45+ t .Run ("cluster router.replicas less than 1 - error code 10027" , func (t * testing.T ) {
46+ tx , err := db .BeginTx (ctx , nil )
47+ if err != nil {
48+ t .Fatalf ("failed to begin transaction: %v" , err )
49+ }
50+ defer func () {
51+ _ = tx .Rollback ()
52+ }()
53+
54+ // Try to insert cluster with router.replicas < 1
55+ _ , err = tx .ExecContext (ctx , `
56+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
57+ VALUES (
58+ 'v1',
59+ 'Cluster',
60+ ROW('kubernetes','{"kubeconfig":"xxxx", "router": {"replicas": 0, "resources": {"cpu":"1","memory":"1Gi"},"access_mode":"LoadBalancer"}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
61+ ROW('test-cluster', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
62+ )
63+ ` )
64+
65+ if err == nil {
66+ t .Fatal ("expected validation error: router.replicas must be at least 1" )
67+ }
68+
69+ // Check that the error message contains the correct error code
70+ if ! strings .Contains (err .Error (), `"code": "10027"` ) {
71+ t .Fatalf ("expected error code 10027, got: %v" , err )
72+ }
73+
74+ t .Logf ("validation correctly blocked insert with error code 10027: %v" , err )
75+ })
76+
77+ t .Run ("cluster router.replicas is not int - error code 10028" , func (t * testing.T ) {
78+ tx , err := db .BeginTx (ctx , nil )
79+ if err != nil {
80+ t .Fatalf ("failed to begin transaction: %v" , err )
81+ }
82+ defer func () {
83+ _ = tx .Rollback ()
84+ }()
85+
86+ // Try to insert cluster with router.replicas as string
87+ _ , err = tx .ExecContext (ctx , `
88+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
89+ VALUES (
90+ 'v1',
91+ 'Cluster',
92+ ROW('kubernetes', '{"kubeconfig":"xxxx", "router": {"replicas": "two", "resources": {"cpu":"1","memory":"1Gi"},"access_mode":"LoadBalancer"}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
93+ ROW('test-cluster', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
94+ )
95+ ` )
96+
97+ if err == nil {
98+ t .Fatal ("expected validation error: router.replicas must be an integer" )
99+ }
100+
101+ // Check that the error message contains the correct error code
102+ if ! strings .Contains (err .Error (), `"code": "10028"` ) {
103+ t .Fatalf ("expected error code 10027, got: %v" , err )
104+ }
105+
106+ t .Logf ("validation correctly blocked insert with error code 10028: %v" , err )
107+ })
108+
109+ t .Run ("cluster router.resources missing - error code 10029" , func (t * testing.T ) {
110+ tx , err := db .BeginTx (ctx , nil )
111+ if err != nil {
112+ t .Fatalf ("failed to begin transaction: %v" , err )
113+ }
114+ defer func () {
115+ _ = tx .Rollback ()
116+ }()
117+
118+ // Try to insert cluster without router.resources
119+ _ , err = tx .ExecContext (ctx , `
120+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
121+ VALUES (
122+ 'v1',
123+ 'Cluster',
124+ ROW('kubernetes', '{"kubeconfig":"xxxx", "router": {"replicas": 2, "access_mode":"LoadBalancer"}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
125+ ROW('test-cluster-resources', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
126+ )
127+ ` )
128+
129+ if err == nil {
130+ t .Fatal ("expected validation error: router.resources is required for Kubernetes clusters" )
131+ }
132+
133+ // Check that the error message contains the correct error code
134+ if ! strings .Contains (err .Error (), `"code": "10029"` ) {
135+ t .Fatalf ("expected error code 10029, got: %v" , err )
136+ }
137+
138+ t .Logf ("validation correctly blocked insert with error code 10029: %v" , err )
139+ })
140+
141+ t .Run ("cluster router.resources.cpu is missing - error code 10025" , func (t * testing.T ) {
142+ tx , err := db .BeginTx (ctx , nil )
143+ if err != nil {
144+ t .Fatalf ("failed to begin transaction: %v" , err )
145+ }
146+ defer func () {
147+ _ = tx .Rollback ()
148+ }()
149+
150+ // Try to insert cluster without router.resources.cpu
151+ _ , err = tx .ExecContext (ctx , `
152+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
153+ VALUES (
154+ 'v1',
155+ 'Cluster',
156+ ROW('kubernetes', '{"kubeconfig":"xxxx", "router": {"replicas": 2, "resources": {"memory":"1Gi"}, "access_mode":"LoadBalancer"}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
157+ ROW('test-cluster-resources', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
158+ )
159+ ` )
160+
161+ if err == nil {
162+ t .Fatal ("expected validation error: router.resources is required for Kubernetes clusters" )
163+ }
164+
165+ // Check that the error message contains the correct error code
166+ if ! strings .Contains (err .Error (), `"code": "10025"` ) {
167+ t .Fatalf ("expected error code 10025, got: %v" , err )
168+ }
169+
170+ t .Logf ("validation correctly blocked insert with error code 10025: %v" , err )
171+ })
172+
173+ t .Run ("cluster router.resources.memory is missing - error code 10026" , func (t * testing.T ) {
174+ tx , err := db .BeginTx (ctx , nil )
175+ if err != nil {
176+ t .Fatalf ("failed to begin transaction: %v" , err )
177+ }
178+ defer func () {
179+ _ = tx .Rollback ()
180+ }()
181+
182+ // Try to insert cluster without router.resources.memory
183+ _ , err = tx .ExecContext (ctx , `
184+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
185+ VALUES (
186+ 'v1',
187+ 'Cluster',
188+ ROW('kubernetes', '{"kubeconfig":"xxxx", "router": {"replicas": 2, "resources": {"cpu":"1"}, "access_mode":"LoadBalancer"}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
189+ ROW('test-cluster-resources', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
190+ )
191+ ` )
192+
193+ if err == nil {
194+ t .Fatal ("expected validation error: router.resources is required for Kubernetes clusters" )
195+ }
196+
197+ // Check that the error message contains the correct error code
198+ if ! strings .Contains (err .Error (), `"code": "10026"` ) {
199+ t .Fatalf ("expected error code 10026, got: %v" , err )
200+ }
201+
202+ t .Logf ("validation correctly blocked insert with error code 10026: %v" , err )
203+ })
204+
205+ t .Run ("cluster router.resources.memory invalid - error code 10114" , func (t * testing.T ) {
206+ tx , err := db .BeginTx (ctx , nil )
207+ if err != nil {
208+ t .Fatalf ("failed to begin transaction: %v" , err )
209+ }
210+ defer func () {
211+ _ = tx .Rollback ()
212+ }()
213+
214+ // Try to insert cluster with router.resources.memory invalid
215+ _ , err = tx .ExecContext (ctx , `
216+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
217+ VALUES (
218+ 'v1',
219+ 'Cluster',
220+ ROW('kubernetes', '{"kubeconfig":"xxxx", "router": {"replicas": 2, "resources": {"cpu":"1", "memory":"1XXXX"}, "access_mode":"LoadBalancer"}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
221+ ROW('test-cluster-resources', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
222+ )
223+ ` )
224+
225+ if err == nil {
226+ t .Fatal ("expected validation error: router.resources is required for Kubernetes clusters" )
227+ }
228+
229+ // Check that the error message contains the correct error code
230+ if ! strings .Contains (err .Error (), `"code": "10114"` ) {
231+ t .Fatalf ("expected error code 10114, got: %v" , err )
232+ }
233+
234+ t .Logf ("validation correctly blocked insert with error code 10114: %v" , err )
235+ })
236+
237+ t .Run ("cluster router.access_mode is missing - error code 10023" , func (t * testing.T ) {
238+ tx , err := db .BeginTx (ctx , nil )
239+ if err != nil {
240+ t .Fatalf ("failed to begin transaction: %v" , err )
241+ }
242+ defer func () {
243+ _ = tx .Rollback ()
244+ }()
245+
246+ // Try to insert cluster without router.access_mode
247+ _ , err = tx .ExecContext (ctx , `
248+ INSERT INTO api.clusters (api_version, kind, spec, metadata)
249+ VALUES (
250+ 'v1',
251+ 'Cluster',
252+ ROW('kubernetes', '{"kubeconfig":"xxxx", "router": {"replicas": 2, "resources": {"cpu":"1","memory":"1Gi"}}}'::jsonb, 'test-imageregistry', '')::api.cluster_spec,
253+ ROW('test-cluster-access-mode', NULL, 'test-workspace', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}'::json, '{}'::json)::api.metadata
254+ )
255+ ` )
256+
257+ if err == nil {
258+ t .Fatal ("expected validation error: router.access_mode is required for Kubernetes clusters" )
259+ }
260+
261+ // Check that the error message contains the correct error code
262+ if ! strings .Contains (err .Error (), `"code": "10023"` ) {
263+ t .Fatalf ("expected error code 10023, got: %v" , err )
264+ }
265+
266+ t .Logf ("validation correctly blocked insert with error code 10023: %v" , err )
267+ })
268+
269+ }
270+
9271func TestModelRegistryValidation (t * testing.T ) {
10272 db := GetTestDB (t )
11273 ctx := context .Background ()
0 commit comments