Skip to content
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
27 changes: 27 additions & 0 deletions v1/providers/shadeform/instancetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,30 @@ func (c *ShadeformClient) getShadeformCloudAndInstanceType(instanceType string)
return shadeformCloud, shadeformInstanceType, nil
}

func (c *ShadeformClient) getEstimatedDeployTime(shadeformInstanceType openapi.InstanceType) *time.Duration {
bootTime := shadeformInstanceType.BootTime
if bootTime == nil {
return nil
}

minSec := bootTime.MinBootInSec
maxSec := bootTime.MaxBootInSec

var estimatedDeployTime *time.Duration
if minSec != nil && maxSec != nil { //nolint:gocritic // if else fine
avg := (*minSec + *maxSec) / 2
avgDuration := time.Duration(avg) * time.Second
estimatedDeployTime = &avgDuration
} else if minSec != nil {
d := time.Duration(*minSec) * time.Second
estimatedDeployTime = &d
} else if maxSec != nil {
d := time.Duration(*maxSec) * time.Second
estimatedDeployTime = &d
}
return estimatedDeployTime
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor but could reduce indentation here:

func (c *ShadeformClient) getEstimatedDeployTime(shadeformInstanceType openapi.InstanceType) *time.Duration {
	bootTime := shadeformInstanceType.BootTime
	if bootTime == nil {
		return nil
	}

	minSec := bootTime.MinBootInSec
	maxSec := bootTime.MaxBootInSec

	var estimatedDeployTime *time.Duration
	if minSec != nil && maxSec != nil { //nolint:gocritic // if else fine
		avg := (*minSec + *maxSec) / 2
		avgDuration := time.Duration(avg) * time.Second
		estimatedDeployTime = &avgDuration
	} else if minSec != nil {
		d := time.Duration(*minSec) * time.Second
		estimatedDeployTime = &d
	} else if maxSec != nil {
		d := time.Duration(*maxSec) * time.Second
		estimatedDeployTime = &d
	}
	return estimatedDeployTime
}

Copy link
Member Author

Choose a reason for hiding this comment

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

love


// convertShadeformInstanceTypeToV1InstanceTypes - converts a shadeform returned instance type to a specific instance type and region of availability
func (c *ShadeformClient) convertShadeformInstanceTypeToV1InstanceType(shadeformInstanceType openapi.InstanceType) ([]v1.InstanceType, error) {
instanceType := c.getInstanceType(string(shadeformInstanceType.Cloud), shadeformInstanceType.ShadeInstanceType)
Expand All @@ -186,6 +210,8 @@ func (c *ShadeformClient) convertShadeformInstanceTypeToV1InstanceType(shadeform
cloud := shadeformCloud(shadeformInstanceType.Cloud)
architecture := shadeformArchitecture(gpuName)

estimatedDeployTime := c.getEstimatedDeployTime(shadeformInstanceType)

for _, region := range shadeformInstanceType.Availability {
instanceTypes = append(instanceTypes, v1.InstanceType{
ID: v1.InstanceTypeID(c.getInstanceTypeID(instanceType, region.Region)),
Expand Down Expand Up @@ -216,6 +242,7 @@ func (c *ShadeformClient) convertShadeformInstanceTypeToV1InstanceType(shadeform
Location: region.Region,
Provider: CloudProviderID,
Cloud: cloud,
EstimatedDeployTime: estimatedDeployTime,
})
}

Expand Down
108 changes: 108 additions & 0 deletions v1/providers/shadeform/instancetype_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package v1

import (
"testing"
"time"

v1 "github.com/brevdev/cloud/v1"
openapi "github.com/brevdev/cloud/v1/providers/shadeform/gen/shadeform"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -95,3 +97,109 @@ func TestIsSelectedByArgs(t *testing.T) {
})
}
}

func TestGetEstimatedDeployTime(t *testing.T) {
t.Parallel()

// Helper function to create int32 pointers
int32Ptr := func(v int32) *int32 {
return &v
}

// Helper function to create time.Duration pointers
durationPtr := func(d time.Duration) *time.Duration {
return &d
}

cases := []struct {
name string
shadeformInstanceType openapi.InstanceType
expectedEstimatedDeploy *time.Duration
}{
{
name: "both min and max boot times provided - should return average",
shadeformInstanceType: openapi.InstanceType{
BootTime: &openapi.BootTime{
MinBootInSec: int32Ptr(60), // 1 minute
MaxBootInSec: int32Ptr(180), // 3 minutes
},
},
expectedEstimatedDeploy: durationPtr(120 * time.Second), // 2 minutes average
},
{
name: "only min boot time provided - should return min",
shadeformInstanceType: openapi.InstanceType{
BootTime: &openapi.BootTime{
MinBootInSec: int32Ptr(90), // 1.5 minutes
MaxBootInSec: nil,
},
},
expectedEstimatedDeploy: durationPtr(90 * time.Second),
},
{
name: "only max boot time provided - should return max",
shadeformInstanceType: openapi.InstanceType{
BootTime: &openapi.BootTime{
MinBootInSec: nil,
MaxBootInSec: int32Ptr(300), // 5 minutes
},
},
expectedEstimatedDeploy: durationPtr(300 * time.Second),
},
{
name: "boot time with both values nil - should return nil",
shadeformInstanceType: openapi.InstanceType{
BootTime: &openapi.BootTime{
MinBootInSec: nil,
MaxBootInSec: nil,
},
},
expectedEstimatedDeploy: nil,
},
{
name: "no boot time provided - should return nil",
shadeformInstanceType: openapi.InstanceType{
BootTime: nil,
},
expectedEstimatedDeploy: nil,
},
{
name: "zero values for min and max - should return zero duration",
shadeformInstanceType: openapi.InstanceType{
BootTime: &openapi.BootTime{
MinBootInSec: int32Ptr(0),
MaxBootInSec: int32Ptr(0),
},
},
expectedEstimatedDeploy: durationPtr(0 * time.Second),
},
{
name: "large values for min and max - should handle correctly",
shadeformInstanceType: openapi.InstanceType{
BootTime: &openapi.BootTime{
MinBootInSec: int32Ptr(3600), // 1 hour
MaxBootInSec: int32Ptr(7200), // 2 hours
},
},
expectedEstimatedDeploy: durationPtr(5400 * time.Second), // 1.5 hours average
},
}

// Create a client instance to test the method
client := &ShadeformClient{}

for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

result := client.getEstimatedDeployTime(tt.shadeformInstanceType)

if tt.expectedEstimatedDeploy == nil {
assert.Nil(t, result)
} else {
assert.NotNil(t, result)
assert.Equal(t, *tt.expectedEstimatedDeploy, *result)
}
})
}
}
Loading