Skip to content

Commit b82dce7

Browse files
committed
progress on network and k8s cluster validation suite
1 parent c27a80a commit b82dce7

11 files changed

Lines changed: 524 additions & 158 deletions

File tree

internal/validation/suite.go

Lines changed: 179 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"time"
77

88
"github.com/brevdev/cloud/internal/ssh"
9-
"github.com/brevdev/cloud/v1"
9+
v1 "github.com/brevdev/cloud/v1"
1010
"github.com/stretchr/testify/require"
1111
)
1212

@@ -127,7 +127,15 @@ func RunInstanceLifecycleValidation(t *testing.T, config ProviderConfig) {
127127
})
128128
}
129129

130-
func RunNetworkValidation(t *testing.T, config ProviderConfig) {
130+
type NetworkValidationOpts struct {
131+
Name string
132+
RefID string
133+
Location string
134+
CidrBlock string
135+
PublicSubnetCidrBlock string
136+
}
137+
138+
func RunNetworkValidation(t *testing.T, config ProviderConfig, opts NetworkValidationOpts) {
131139
if testing.Short() {
132140
t.Skip("Skipping validation tests in short mode")
133141
}
@@ -140,35 +148,89 @@ func RunNetworkValidation(t *testing.T, config ProviderConfig) {
140148
t.Fatalf("Failed to create client for %s: %v", config.Credential.GetCloudProviderID(), err)
141149
}
142150

151+
var vpcID v1.CloudProviderResourceID
143152
t.Run("ValidateCreateVPC", func(t *testing.T) {
144-
err := v1.ValidateCreateVPC(ctx, client, v1.CreateVPCArgs{
145-
Name: "test-vpc",
146-
RefID: "test-vpc",
147-
Location: "test-location",
148-
CidrBlock: "172.16.0.0/16",
153+
vpc, err := v1.ValidateCreateVPC(ctx, client, v1.CreateVPCArgs{
154+
Name: opts.Name,
155+
RefID: opts.RefID,
156+
Location: opts.Location,
157+
CidrBlock: opts.CidrBlock,
149158
Subnets: []v1.CreateSubnetArgs{
150-
{CidrBlock: "172.16.0.0/24", Type: v1.SubnetTypePublic},
159+
{CidrBlock: opts.PublicSubnetCidrBlock, Type: v1.SubnetTypePublic},
151160
},
152161
})
153162
require.NoError(t, err, "ValidateCreateVPC should pass")
163+
vpcID = vpc.ID
154164
})
155165

166+
deletionSucceeded := false
167+
defer func() {
168+
if !deletionSucceeded && vpcID != "" {
169+
t.Logf("Cleaning up VPC after failed tests: %s", vpcID)
170+
err = v1.ValidateDeleteVPC(ctx, client, v1.DeleteVPCArgs{
171+
ID: vpcID,
172+
})
173+
if err != nil {
174+
t.Fatalf("Failed to cleanup after validation of VPC: %v", err)
175+
}
176+
}
177+
}()
178+
156179
t.Run("ValidateGetVPC", func(t *testing.T) {
157-
err := v1.ValidateGetVPC(ctx, client, v1.GetVPCArgs{
158-
ID: v1.CloudProviderResourceID("test-vpc"),
180+
vpc, err := v1.ValidateGetVPC(ctx, client, v1.GetVPCArgs{
181+
ID: vpcID,
159182
})
160183
require.NoError(t, err, "ValidateGetVPC should pass")
184+
require.NotNil(t, vpc)
185+
})
186+
187+
t.Run("WaitForVPCToBeAvailable", func(t *testing.T) {
188+
err := v1.WaitForVPCPredicate(ctx, client, v1.GetVPCArgs{ID: vpcID},
189+
v1.WaitForVPCPredicateOpts{
190+
Predicate: func(vpc *v1.VPC) bool {
191+
return vpc.Status == v1.VPCStatusAvailable
192+
},
193+
Timeout: 5 * time.Minute,
194+
Interval: 5 * time.Second,
195+
},
196+
)
197+
require.NoError(t, err, "WaitForVPCToBeAvailable should pass")
161198
})
162199

163200
t.Run("ValidateDeleteVPC", func(t *testing.T) {
164201
err := v1.ValidateDeleteVPC(ctx, client, v1.DeleteVPCArgs{
165-
ID: v1.CloudProviderResourceID("test-vpc"),
202+
ID: vpcID,
166203
})
167204
require.NoError(t, err, "ValidateDeleteVPC should pass")
205+
deletionSucceeded = true
168206
})
207+
208+
t.Run("ValidateVPCNotFound", func(t *testing.T) {
209+
vpc, err := v1.ValidateGetVPC(ctx, client, v1.GetVPCArgs{
210+
ID: vpcID,
211+
})
212+
require.Nil(t, vpc)
213+
require.ErrorIs(t, err, v1.ErrResourceNotFound)
214+
})
215+
}
216+
217+
type KubernetesValidationOpts struct {
218+
Name string
219+
RefID string
220+
KubernetesVersion string
221+
NetworkOpts *KubernetesValidationNetworkOpts
222+
}
223+
224+
type KubernetesValidationNetworkOpts struct {
225+
Name string
226+
RefID string
227+
Location string
228+
CidrBlock string
229+
PublicSubnetCidrBlock string
230+
PrivateSubnetCidrBlock string
169231
}
170232

171-
func RunKubernetesValidation(t *testing.T, config ProviderConfig) {
233+
func RunKubernetesValidation(t *testing.T, config ProviderConfig, opts KubernetesValidationOpts) {
172234
if testing.Short() {
173235
t.Skip("Skipping validation tests in short mode")
174236
}
@@ -181,56 +243,127 @@ func RunKubernetesValidation(t *testing.T, config ProviderConfig) {
181243
t.Fatalf("Failed to create client for %s: %v", config.Credential.GetCloudProviderID(), err)
182244
}
183245

246+
if opts.NetworkOpts == nil {
247+
t.Fatalf("KubernetesValidationOpts.NetworkOpts is required")
248+
}
249+
250+
// Create the initial VPC
251+
vpc, err := v1.ValidateCreateVPC(ctx, client, v1.CreateVPCArgs{
252+
Name: opts.NetworkOpts.Name,
253+
RefID: opts.NetworkOpts.RefID,
254+
Location: opts.NetworkOpts.Location,
255+
CidrBlock: opts.NetworkOpts.CidrBlock,
256+
Subnets: []v1.CreateSubnetArgs{
257+
{CidrBlock: opts.NetworkOpts.PublicSubnetCidrBlock, Type: v1.SubnetTypePublic},
258+
{CidrBlock: opts.NetworkOpts.PrivateSubnetCidrBlock, Type: v1.SubnetTypePrivate},
259+
},
260+
})
261+
require.NoError(t, err, "ValidateCreateVPC should pass")
262+
263+
// Wait for the VPC to be available
264+
err = v1.WaitForVPCPredicate(ctx, client, v1.GetVPCArgs{ID: vpc.ID},
265+
v1.WaitForVPCPredicateOpts{
266+
Predicate: func(vpc *v1.VPC) bool {
267+
return vpc.Status == v1.VPCStatusAvailable
268+
},
269+
Timeout: 5 * time.Minute,
270+
Interval: 5 * time.Second,
271+
},
272+
)
273+
require.NoError(t, err, "WaitForVPCToBeAvailable should pass")
274+
275+
defer func() {
276+
// Clean up the VPC if it was created
277+
if vpc != nil {
278+
err = v1.ValidateDeleteVPC(ctx, client, v1.DeleteVPCArgs{
279+
ID: vpc.ID,
280+
})
281+
if err != nil {
282+
t.Fatalf("Failed to cleanup after validation of VPC: %v", err)
283+
}
284+
}
285+
}()
286+
287+
var clusterID v1.CloudProviderResourceID
184288
t.Run("ValidateCreateKubernetesCluster", func(t *testing.T) {
185-
err := v1.ValidateCreateKubernetesCluster(ctx, client, v1.CreateClusterArgs{
186-
Name: "test-cluster",
187-
RefID: "test-cluster",
188-
VPCID: "test-vpc",
189-
SubnetIDs: []string{"test-subnet"},
190-
KubernetesVersion: "1.24",
191-
Location: "test-location",
289+
cluster, err := v1.ValidateCreateKubernetesCluster(ctx, client, v1.CreateClusterArgs{
290+
Name: opts.Name,
291+
RefID: opts.RefID,
292+
VPCID: vpc.ID,
293+
SubnetIDs: []v1.CloudProviderResourceID{vpc.Subnets[0].ID},
294+
KubernetesVersion: opts.KubernetesVersion,
295+
Location: opts.NetworkOpts.Location,
192296
})
193297
require.NoError(t, err, "ValidateCreateKubernetesCluster should pass")
298+
require.NotNil(t, cluster)
299+
clusterID = cluster.ID
194300
})
195301

196302
t.Run("ValidateGetKubernetesCluster", func(t *testing.T) {
197-
err := v1.ValidateGetKubernetesCluster(ctx, client, v1.GetClusterArgs{
198-
ID: v1.CloudProviderResourceID("test-cluster"),
303+
cluster, err := v1.ValidateGetKubernetesCluster(ctx, client, v1.GetClusterArgs{
304+
ID: clusterID,
199305
})
200306
require.NoError(t, err, "ValidateGetKubernetesCluster should pass")
307+
require.NotNil(t, cluster)
201308
})
202309

203-
t.Run("ValidateGetKubernetesClusterCredentials", func(t *testing.T) {
204-
err := v1.ValidateGetKubernetesClusterCredentials(ctx, client, v1.GetClusterArgs{
205-
ID: v1.CloudProviderResourceID("test-cluster"),
206-
})
207-
require.NoError(t, err, "ValidateGetKubernetesClusterCredentials should pass")
208-
})
209-
210-
t.Run("ValidateCreateKubernetesNodeGroup", func(t *testing.T) {
211-
err := v1.ValidateCreateKubernetesNodeGroup(ctx, client, v1.CreateNodeGroupArgs{
212-
ClusterID: v1.CloudProviderResourceID("test-cluster"),
213-
Name: "test-node-group",
214-
RefID: "test-node-group",
215-
MinNodeCount: 1,
216-
MaxNodeCount: 1,
217-
InstanceType: "test-instance-type",
218-
DiskSizeGiB: 100,
219-
})
220-
require.NoError(t, err, "ValidateCreateKubernetesNodeGroup should pass")
310+
t.Run("WaitForKubernetesClusterToBeAvailable", func(t *testing.T) {
311+
err := v1.WaitForKubernetesClusterPredicate(ctx, client, v1.GetClusterArgs{ID: clusterID},
312+
v1.WaitForKubernetesClusterPredicateOpts{
313+
Predicate: func(cluster *v1.Cluster) bool {
314+
return cluster.Status == v1.ClusterStatusAvailable
315+
},
316+
Timeout: 20 * time.Minute,
317+
Interval: 15 * time.Second,
318+
},
319+
)
320+
require.NoError(t, err, "WaitForKubernetesClusterToBeAvailable should pass")
221321
})
222322

223-
t.Run("ValidateDeleteKubernetesNodeGroup", func(t *testing.T) {
224-
err := v1.ValidateDeleteKubernetesNodeGroup(ctx, client, v1.DeleteNodeGroupArgs{
225-
ID: v1.CloudProviderResourceID("test-node-group"),
226-
})
227-
require.NoError(t, err, "ValidateDeleteKubernetesNodeGroup should pass")
228-
})
323+
// t.Run("ValidateGetKubernetesClusterCredentials", func(t *testing.T) {
324+
// err := v1.ValidateGetKubernetesClusterCredentials(ctx, client, v1.GetClusterArgs{
325+
// ID: v1.CloudProviderResourceID("test-cluster"),
326+
// })
327+
// require.NoError(t, err, "ValidateGetKubernetesClusterCredentials should pass")
328+
// })
329+
330+
// t.Run("ValidateCreateKubernetesNodeGroup", func(t *testing.T) {
331+
// err := v1.ValidateCreateKubernetesNodeGroup(ctx, client, v1.CreateNodeGroupArgs{
332+
// ClusterID: v1.CloudProviderResourceID("test-cluster"),
333+
// Name: "test-node-group",
334+
// RefID: "test-node-group",
335+
// MinNodeCount: 1,
336+
// MaxNodeCount: 1,
337+
// InstanceType: "test-instance-type",
338+
// DiskSizeGiB: 100,
339+
// })
340+
// require.NoError(t, err, "ValidateCreateKubernetesNodeGroup should pass")
341+
// })
342+
343+
// t.Run("ValidateDeleteKubernetesNodeGroup", func(t *testing.T) {
344+
// err := v1.ValidateDeleteKubernetesNodeGroup(ctx, client, v1.DeleteNodeGroupArgs{
345+
// ID: v1.CloudProviderResourceID("test-node-group"),
346+
// })
347+
// require.NoError(t, err, "ValidateDeleteKubernetesNodeGroup should pass")
348+
// })
229349

230350
t.Run("ValidateDeleteKubernetesCluster", func(t *testing.T) {
231351
err := v1.ValidateDeleteKubernetesCluster(ctx, client, v1.DeleteClusterArgs{
232-
ID: v1.CloudProviderResourceID("test-cluster"),
352+
ID: clusterID,
233353
})
234354
require.NoError(t, err, "ValidateDeleteKubernetesCluster should pass")
235355
})
356+
357+
t.Run("WaitForKubernetesClusterToBeDeleted", func(t *testing.T) {
358+
err := v1.WaitForKubernetesClusterPredicate(ctx, client, v1.GetClusterArgs{ID: clusterID},
359+
v1.WaitForKubernetesClusterPredicateOpts{
360+
Predicate: func(_ *v1.Cluster) bool {
361+
return false // continue until failure
362+
},
363+
Timeout: 5 * time.Minute,
364+
Interval: 5 * time.Second,
365+
},
366+
)
367+
require.ErrorIs(t, err, v1.ErrResourceNotFound)
368+
})
236369
}

v1/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ var (
88
ErrImageNotFound = errors.New("image not found")
99
ErrDuplicateFirewallRule = errors.New("duplicate firewall rule")
1010
ErrInstanceNotFound = errors.New("instance not found")
11+
ErrResourceNotFound = errors.New("resource not found")
1112
ErrServiceUnavailable = errors.New("api is temporarily unavailable")
1213
)

0 commit comments

Comments
 (0)