diff --git a/fake_client.go b/fake_client.go index 7d4b0e0..392f701 100644 --- a/fake_client.go +++ b/fake_client.go @@ -1290,6 +1290,25 @@ func (c *FakeClient) NewVolume(v *VolumeConfig) (*VolumeResult, error) { func (c *FakeClient) ResizeVolume(id string, size int) (*SimpleResponse, error) { for i, volume := range c.Volumes { if volume.ID == id { + // Check if volume is attached + if volume.InstanceID != "" { + err := fmt.Errorf("cannot resize volume while it is still attached to an instance") + return nil, DatabaseVolumeStillAttachedCannotResizeError.wrap(err) + } + + // Check if new size is valid (must be larger than current) + if size <= volume.SizeGigabytes { + err := fmt.Errorf("new size must be larger than current size") + return nil, ParameterVolumeSizeMustIncreaseError.wrap(err) + } + + // Simulate occasional resize failures (1 in 10 chance) + if rand.Float32() < 0.1 { + err := fmt.Errorf("volume resize operation failed, please retry") + return nil, CannotResizeVolumeError.wrap(err) + } + + // If all checks pass, perform the resize c.Volumes[i].SizeGigabytes = size return &SimpleResponse{Result: "success"}, nil } diff --git a/instance_size.go b/instance_size.go index 8336f40..2278a10 100644 --- a/instance_size.go +++ b/instance_size.go @@ -9,17 +9,19 @@ import ( // InstanceSize represents an available size for instances to launch type InstanceSize struct { - Type string `json:"type,omitempty"` - Name string `json:"name,omitempty"` - NiceName string `json:"nice_name,omitempty"` - CPUCores int `json:"cpu_cores,omitempty"` - GPUCount int `json:"gpu_count,omitempty"` - GPUType string `json:"gpu_type,omitempty"` - RAMMegabytes int `json:"ram_mb,omitempty"` - DiskGigabytes int `json:"disk_gb,omitempty"` - TransferTerabytes int `json:"transfer_tb,omitempty"` - Description string `json:"description,omitempty"` - Selectable bool `json:"selectable,omitempty"` + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + NiceName string `json:"nice_name,omitempty"` + CPUCores int `json:"cpu_cores,omitempty"` + GPUCount int `json:"gpu_count,omitempty"` + GPUType string `json:"gpu_type,omitempty"` + RAMMegabytes int `json:"ram_mb,omitempty"` + DiskGigabytes int `json:"disk_gb,omitempty"` + TransferTerabytes int `json:"transfer_tb,omitempty"` + Description string `json:"description,omitempty"` + Selectable bool `json:"selectable,omitempty"` + PriceMonthly float64 `json:"price_monthly,omitempty"` + PriceHourly float64 `json:"price_hourly,omitempty"` } // ListInstanceSizes returns all availble sizes of instances diff --git a/instance_size_test.go b/instance_size_test.go index cccd3b6..7ba3efe 100644 --- a/instance_size_test.go +++ b/instance_size_test.go @@ -18,7 +18,9 @@ func TestListInstanceSizes(t *testing.T) { "disk_gb": 25, "transfer_tb": 1, "description": "xSmall - Standard", - "selectable": true + "selectable": true, + "price_monthly": 5.00, + "price_hourly": 0.00684 } ] `, @@ -54,6 +56,12 @@ func TestListInstanceSizes(t *testing.T) { if got[0].Description != "xSmall - Standard" { t.Errorf("Expected %s, got %s", "xSmall - Standard", got[0].Description) } + if got[0].PriceMonthly != 5.00 { + t.Errorf("Expected monthly price %f, got %f", 5.00, got[0].PriceMonthly) + } + if got[0].PriceHourly != 0.00684 { + t.Errorf("Expected hourly price %f, got %f", 0.00684, got[0].PriceHourly) + } } func TestFindInstanceSizes(t *testing.T) { @@ -70,7 +78,9 @@ func TestFindInstanceSizes(t *testing.T) { "disk_gb": 25, "transfer_tb": 1, "description": "Extra Small", - "selectable": true + "selectable": true, + "price_monthly": 5.00, + "price_hourly": 0.00684 }, { "type": "Instance", @@ -83,7 +93,9 @@ func TestFindInstanceSizes(t *testing.T) { "disk_gb": 25, "transfer_tb": 2, "description": "Small", - "selectable": true + "selectable": true, + "price_monthly": 10.00, + "price_hourly": 0.01369 } ] `, diff --git a/volume_test.go b/volume_test.go index e2190b6..d16e7fd 100644 --- a/volume_test.go +++ b/volume_test.go @@ -2,6 +2,7 @@ package civogo import ( "reflect" + "strings" "testing" ) @@ -245,19 +246,49 @@ func TestDeleteVolumes(t *testing.T) { } func TestResizeVolume(t *testing.T) { - client, server, _ := NewClientForTesting(map[string]string{ - "/v2/volumes/12346/resize": `{"result": "success"}`, - }) - defer server.Close() - got, err := client.ResizeVolume("12346", 20) + client, _ := NewFakeClient() + + // Test case 1: Successful resize + volume := Volume{ + ID: "test-vol-1", + Name: "test-volume-1", + SizeGigabytes: 20, + Status: "available", + } + client.Volumes = append(client.Volumes, volume) + + got, err := client.ResizeVolume("test-vol-1", 25) if err != nil { - t.Errorf("Request returned an error: %s", err) - return + t.Errorf("Expected successful resize, got error: %s", err) + } + if got.Result != "success" { + t.Errorf("Expected result 'success', got %s", got.Result) } - expected := &SimpleResponse{Result: "success"} - if !reflect.DeepEqual(got, expected) { - t.Errorf("Expected %+v, got %+v", expected, got) + // Test case 2: Volume not found + _, err = client.ResizeVolume("non-existent", 25) + if err == nil || !strings.Contains(err.Error(), "zero matches") { + t.Errorf("Expected 'zero matches' error, got %v", err) + } + + // Test case 3: Volume still attached + attachedVolume := Volume{ + ID: "test-vol-2", + Name: "test-volume-2", + InstanceID: "test-instance-1", + Status: "in-use", + } + client.Volumes = append(client.Volumes, attachedVolume) + + _, err = client.ResizeVolume("test-vol-2", 25) + if err == nil || !strings.Contains(err.Error(), "still attached") { + t.Errorf("Expected 'still attached' error, got %v", err) + } + + // Test case 4: Invalid size (not increasing) + _, err = client.ResizeVolume("test-vol-1", 15) + if err == nil || !strings.Contains(err.Error(), "must be larger than current size") { + t.Errorf("Expected 'must be larger' error, got %v", err) } }