Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Update getRegionsWithCaps function to also accept a list of plans that must be available in the identified region #555

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions test/integration/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func TestImage_CreateUpload(t *testing.T) {
defer teardown()

image, uploadURL, err := client.CreateImageUpload(context.Background(), ImageCreateUploadOptions{
Region: getRegionsWithCaps(t, client, []string{"Metadata"})[0],
Region: getRegionsWithCaps(t, client, []string{"Metadata"}, []string{})[0],
Label: "linodego-image-create-upload",
Description: "An image that does stuff.",
CloudInit: true,
Expand All @@ -132,7 +132,7 @@ func TestImage_CloudInit(t *testing.T) {
client, instance, teardown, err := setupInstance(
t, "fixtures/TestImage_CloudInit", true,
func(client *Client, options *InstanceCreateOptions) {
options.Region = getRegionsWithCaps(t, client, []string{"Metadata"})[0]
options.Region = getRegionsWithCaps(t, client, []string{"Metadata"}, []string{})[0]
})
if err != nil {
t.Fatal(err)
Expand Down
10 changes: 5 additions & 5 deletions test/integration/instance_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func setupInstanceWithVPCAndNATOneToOne(t *testing.T, fixturesYaml string) (
t,
fixturesYaml,
func(client *Client, opts *InstanceCreateOptions) {
opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0]
opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"}, []string{})[0]
},
)
if err != nil {
Expand Down Expand Up @@ -110,7 +110,7 @@ func setupInstanceWith3Interfaces(t *testing.T, fixturesYaml string) (
t,
fixturesYaml,
func(client *Client, opts *InstanceCreateOptions) {
opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0]
opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"}, []string{})[0]
},
)
if err != nil {
Expand Down Expand Up @@ -153,7 +153,7 @@ func TestInstance_ConfigInterfaces_AppendDelete(t *testing.T) {
"fixtures/TestInstance_ConfigInterfaces_AppendDelete",
func(client *Client, opts *InstanceCreateOptions) {
// Ensure we're in a region that supports VLANs
opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"})[0]
opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"}, []string{})[0]
},
)
defer teardown()
Expand Down Expand Up @@ -303,7 +303,7 @@ func TestInstance_ConfigInterfaces_Update(t *testing.T) {
"fixtures/TestInstance_ConfigInterfaces_Update",
func(client *Client, opts *InstanceCreateOptions) {
// Ensure we're in a region that supports VLANs
opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"})[0]
opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"}, []string{})[0]
},
)
defer teardown()
Expand Down Expand Up @@ -377,7 +377,7 @@ func TestInstance_ConfigInterface_Update(t *testing.T) {
"fixtures/TestInstance_ConfigInterface_Update",
func(client *Client, opts *InstanceCreateOptions) {
// Ensure we're in a region that supports VLANs
opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"})[0]
opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"}, []string{})[0]
},
)
defer teardown()
Expand Down
10 changes: 5 additions & 5 deletions test/integration/instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func TestInstance_Rebuild(t *testing.T) {
t,
"fixtures/TestInstance_Rebuild", true,
func(client *linodego.Client, options *linodego.InstanceCreateOptions) {
options.Region = getRegionsWithCaps(t, client, []string{"Metadata"})[0]
options.Region = getRegionsWithCaps(t, client, []string{"Metadata"}, []string{})[0]
},
)
defer teardown()
Expand Down Expand Up @@ -392,7 +392,7 @@ func TestInstance_Clone(t *testing.T) {
client, instance, teardownOriginalLinode, err := setupInstance(
t, "fixtures/TestInstance_Clone", true,
func(client *linodego.Client, options *linodego.InstanceCreateOptions) {
targetRegion = getRegionsWithCaps(t, client, []string{"Metadata"})[0]
targetRegion = getRegionsWithCaps(t, client, []string{"Metadata"}, []string{})[0]

options.Region = targetRegion
})
Expand Down Expand Up @@ -470,7 +470,7 @@ func TestInstance_withMetadata(t *testing.T) {
options.Metadata = &linodego.InstanceMetadataOptions{
UserData: base64.StdEncoding.EncodeToString([]byte("reallycoolmetadata")),
}
options.Region = getRegionsWithCaps(t, client, []string{"Metadata"})[0]
options.Region = getRegionsWithCaps(t, client, []string{"Metadata"}, []string{})[0]
})
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -519,7 +519,7 @@ func createInstance(t *testing.T, client *linodego.Client, enableCloudFirewall b
createOpts := linodego.InstanceCreateOptions{
Label: "go-test-ins-" + randLabel(),
RootPass: randPassword(),
Region: getRegionsWithCaps(t, client, []string{"linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"linodes"}, []string{})[0],
Type: "g6-nanode-1",
Image: "linode/debian9",
Booted: linodego.Pointer(false),
Expand Down Expand Up @@ -567,7 +567,7 @@ func createInstanceWithoutDisks(

createOpts := linodego.InstanceCreateOptions{
Label: "go-test-ins-wo-disk-" + randLabel(),
Region: getRegionsWithCaps(t, client, []string{"linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"linodes"}, []string{})[0],
Type: "g6-nanode-1",
Booted: linodego.Pointer(false),
}
Expand Down
43 changes: 40 additions & 3 deletions test/integration/integration_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,38 @@ func transportRecorderWrapper(t *testing.T, fixtureYaml string) (transport.Wrapp
}, teardown
}

// getRegionsWithCaps returns a list of regions that support the given capabilities.
func getRegionsWithCaps(t *testing.T, client *linodego.Client, capabilities []string) []string {
/*
Helper function getRegionsWithCaps returns a list of regions that support the given capabilities and plans.
It filters regions based on their capabilities and the availability of specified plans.
If the plans list is empty, it only checks for the capabilities.

Parameters:
- capabilities: A list of required capabilities that regions must support.
- plans (optional): A list of required plans that must be available in the regions.

Returns:
- string values representing the IDs of regions that meet the given criteria.
*/
func getRegionsWithCaps(t *testing.T, client *linodego.Client, capabilities, plans []string) []string {
Copy link
Contributor

@lgarber-akamai lgarber-akamai Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional: We can considerably reduce the number of iterations we need to run by aggregating all availabilities into a map hashing on (region, plan):

regionsAvailabilities, err := client.ListRegionsAvailability(context.Background(), nil)
require.NoError(t, err)

type availKey struct {
	Region string
	Plan   string
}

availMap := make(map[availKey]linodego.RegionAvailability, len(regionsAvailabilities))
for _, avail := range regionsAvailabilities {
	availMap[availKey{Region: avail.Region, Plan: avail.Plan}] = avail
}

// ...

regionHasPlans := func(regionID string) bool {
	for _, plan := range plans {
		if avail, ok := availMap[availKey{Region: regionID, Plan: plan}]; !ok || !avail.Available {
			return false
		}
	}

	return true
}

Since this is just for tests I don't think it's a big deal either way; just thought I'd share another approach 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great suggestion! I didn't think of putting it into a hash map but this will for sure be faster than my previous solution 🚀

result := make([]string, 0)

regions, err := client.ListRegions(context.Background(), nil)
if err != nil {
t.Fatal(err)
}

regionsAvailabilities, err := client.ListRegionsAvailability(context.Background(), nil)

type availKey struct {
Region string
Plan string
}

availMap := make(map[availKey]linodego.RegionAvailability, len(regionsAvailabilities))
for _, avail := range regionsAvailabilities {
availMap[availKey{Region: avail.Region, Plan: avail.Plan}] = avail
}

regionHasCaps := func(r linodego.Region) bool {
capsMap := make(map[string]bool)

Expand All @@ -191,8 +214,22 @@ func getRegionsWithCaps(t *testing.T, client *linodego.Client, capabilities []st
return true
}

// Function to check if a region has the required plans available
regionHasPlans := func(regionID string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice use of closures!

if len(plans) == 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still left this check in to avoid any unnecessary map lookups when there are no plans to check.

return true
}

for _, plan := range plans {
if avail, ok := availMap[availKey{Region: regionID, Plan: plan}]; !ok || !avail.Available {
return false
}
}
return true
}

for _, region := range regions {
if region.Status != "ok" || !regionHasCaps(region) {
if region.Status != "ok" || !regionHasCaps(region) || !regionHasPlans(region.ID) {
continue
}

Expand Down
2 changes: 1 addition & 1 deletion test/integration/lke_clusters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func setupLKECluster(t *testing.T, clusterModifiers []clusterModifier, fixturesY

createOpts := linodego.LKEClusterCreateOptions{
Label: label,
Region: getRegionsWithCaps(t, client, []string{"Kubernetes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Kubernetes"}, []string{})[0],
K8sVersion: "1.29",
Tags: []string{"testing"},
NodePools: []linodego.LKENodePoolCreateOptions{{Count: 1, Type: "g6-standard-2", Tags: []string{"test"}}},
Expand Down
2 changes: 1 addition & 1 deletion test/integration/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func createMySQLDatabase(t *testing.T, client *linodego.Client,

createOpts := linodego.MySQLCreateOptions{
Label: "go-mysql-test-def" + randLabel(),
Region: getRegionsWithCaps(t, client, []string{"Managed Databases"})[0],
Region: getRegionsWithCaps(t, client, []string{"Managed Databases"}, []string{})[0],
Type: "g6-nanode-1",
Engine: "mysql/8.0.30",
Encrypted: false,
Expand Down
2 changes: 1 addition & 1 deletion test/integration/nodebalancers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func setupNodeBalancer(t *testing.T, fixturesYaml string) (*linodego.Client, *li
client, fixtureTeardown := createTestClient(t, fixturesYaml)
createOpts := linodego.NodeBalancerCreateOptions{
Label: &label,
Region: getRegionsWithCaps(t, client, []string{"NodeBalancers"})[0],
Region: getRegionsWithCaps(t, client, []string{"NodeBalancers"}, []string{})[0],
ClientConnThrottle: &clientConnThrottle,
FirewallID: GetFirewallID(),
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/object_storage_buckets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestObjectStorageBucket_Create_smoke(t *testing.T) {
func TestObjectStorageBucket_Regional(t *testing.T) {
// t.Skip("skipping region test before GA")
client, teardown := createTestClient(t, "fixtures/TestObjectStorageBucket_Regional")
regions := getRegionsWithCaps(t, client, []string{"Object Storage"})
regions := getRegionsWithCaps(t, client, []string{"Object Storage"}, []string{})
if len(regions) < 1 {
t.Fatal("Can't get region with Object Storage capability")
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/object_storage_keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func TestObjectStorageKeys_Limited_NoAccess(t *testing.T) {
func TestObjectStorageKeys_Regional_Limited(t *testing.T) {
// t.Skip("skipping region test before GA")
client, teardown := createTestClient(t, "fixtures/TestObjectStorageKeys_Regional_Limited")
regions := getRegionsWithCaps(t, client, []string{"Object Storage"})
regions := getRegionsWithCaps(t, client, []string{"Object Storage"}, []string{})
if len(regions) < 1 {
t.Fatal("Can't get region with Object Storage capability")
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/placement_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func createPlacementGroup(
t.Helper()
createOpts := linodego.PlacementGroupCreateOptions{
Label: "linodego-test-" + getUniqueText(),
Region: getRegionsWithCaps(t, client, []string{"Placement Group"})[0],
Region: getRegionsWithCaps(t, client, []string{"Placement Group"}, []string{})[0],
AffinityType: linodego.AffinityTypeAntiAffinityLocal,
IsStrict: false,
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/postgres_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func createPostgresDatabase(t *testing.T, client *linodego.Client,

createOpts := linodego.PostgresCreateOptions{
Label: "go-postgres-testing-def" + randLabel(),
Region: getRegionsWithCaps(t, client, []string{"Managed Databases"})[0],
Region: getRegionsWithCaps(t, client, []string{"Managed Databases"}, []string{})[0],
Type: "g6-nanode-1",
Engine: "postgresql/14.6",
Encrypted: false,
Expand Down
2 changes: 1 addition & 1 deletion test/integration/tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func setupTaggedInstance(t *testing.T, fixturesYaml string) (*Client, *Instance,
client, fixtureTeardown := createTestClient(t, fixturesYaml)
createOpts := InstanceCreateOptions{
Label: "go-ins-test-tag",
Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes"}, []string{})[0],
Type: "g6-nanode-1",
Tags: []string{"go-tag-test"},
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/vlans_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func createVLANInstance(t *testing.T, client *linodego.Client, instanceName, vla

opts.Booted = &trueBool
opts.Label = instanceName
opts.Region = getRegionsWithCaps(t, client, []string{"Vlans"})[0]
opts.Region = getRegionsWithCaps(t, client, []string{"Vlans"}, []string{})[0]
})
if err != nil {
return nil, nil, err
Expand Down
6 changes: 3 additions & 3 deletions test/integration/volumes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestVolume_Create_smoke(t *testing.T) {

createOpts := linodego.VolumeCreateOptions{
Label: "go-vol-test-create",
Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes"}, []string{})[0],
}
volume, err := client.CreateVolume(context.Background(), createOpts)
if err != nil {
Expand Down Expand Up @@ -175,7 +175,7 @@ func setupVolume(t *testing.T, fixturesYaml string) (*linodego.Client, *linodego
client, fixtureTeardown := createTestClient(t, fixturesYaml)
createOpts := linodego.VolumeCreateOptions{
Label: "go-vol-test-def",
Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes"}, []string{})[0],
}
volume, err := client.CreateVolume(context.Background(), createOpts)
if err != nil {
Expand All @@ -201,7 +201,7 @@ func createVolume(
t.Helper()
createOpts := linodego.VolumeCreateOptions{
Label: "go-vol-test" + randLabel(),
Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes"}, []string{})[0],
}

for _, mod := range vModifier {
Expand Down
2 changes: 1 addition & 1 deletion test/integration/vpc_subnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func createVPCWithSubnet(t *testing.T, client *linodego.Client, vpcModifier ...v
t.Helper()
createOpts := linodego.VPCCreateOptions{
Label: "go-test-vpc-" + getUniqueText(),
Region: getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"}, []string{})[0],
Subnets: []VPCSubnetCreateOptions{
{
Label: "linodego-vpc-test-" + getUniqueText(),
Expand Down
4 changes: 2 additions & 2 deletions test/integration/vpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func createVPC(t *testing.T, client *linodego.Client, vpcModifier ...vpcModifier
t.Helper()
createOpts := linodego.VPCCreateOptions{
Label: "go-test-vpc-" + getUniqueText(),
Region: getRegionsWithCaps(t, client, []string{"VPCs"})[0],
Region: getRegionsWithCaps(t, client, []string{"VPCs"}, []string{})[0],
}

for _, mod := range vpcModifier {
Expand All @@ -59,7 +59,7 @@ func createVPC_invalid_label(t *testing.T, client *linodego.Client) error {
t.Helper()
createOpts := linodego.VPCCreateOptions{
Label: "gotest_vpc_invalid_label" + getUniqueText(),
Region: getRegionsWithCaps(t, client, []string{"VPCs"})[0],
Region: getRegionsWithCaps(t, client, []string{"VPCs"}, []string{})[0],
}
_, err := client.CreateVPC(context.Background(), createOpts)

Expand Down
6 changes: 3 additions & 3 deletions test/integration/waitfor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestEventPoller_InstancePower(t *testing.T) {
}

instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{
Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes"}, []string{})[0],
Type: "g6-nanode-1",
Image: "linode/ubuntu22.04",
RootPass: randPassword(),
Expand Down Expand Up @@ -102,7 +102,7 @@ func TestWaitForResourceFree(t *testing.T) {

// Create a booted instance
instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{
Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes"}, []string{})[0],
Type: "g6-nanode-1",
Image: "linode/ubuntu22.04",
RootPass: randPassword(),
Expand Down Expand Up @@ -145,7 +145,7 @@ func TestEventPoller_Secondary(t *testing.T) {
}

instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{
Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0],
Region: getRegionsWithCaps(t, client, []string{"Linodes"}, []string{})[0],
Type: "g6-nanode-1",
Label: "go-ins-poll-test",
Booted: linodego.Pointer(false),
Expand Down