Skip to content

Commit

Permalink
Timeouts tests to be unit test to be able to run without TF_ACC
Browse files Browse the repository at this point in the history
  • Loading branch information
aayushrangwala committed Aug 28, 2023
1 parent f3725b4 commit e949259
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 88 deletions.
6 changes: 3 additions & 3 deletions equinix/resource_metal_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ func resourceMetalDeviceCreate(ctx context.Context, d *schema.ResourceData, meta

d.SetId(newDevice.ID)

createTimeout := d.Timeout(schema.TimeoutCreate) - time.Minute - time.Since(start)
createTimeout := d.Timeout(schema.TimeoutCreate) - 30*time.Second - time.Since(start)
if err = waitForActiveDevice(ctx, d, meta, createTimeout); err != nil {
return err
}
Expand Down Expand Up @@ -806,7 +806,7 @@ func doReinstall(ctx context.Context, client *packngo.Client, d *schema.Resource
return friendlyError(err)
}

deleteTimeout := d.Timeout(schema.TimeoutUpdate) - time.Minute - time.Since(start)
deleteTimeout := d.Timeout(schema.TimeoutUpdate) - 30*time.Second - time.Since(start)
if err := waitForActiveDevice(ctx, d, meta, deleteTimeout); err != nil {
return err
}
Expand Down Expand Up @@ -837,7 +837,7 @@ func resourceMetalDeviceDelete(ctx context.Context, d *schema.ResourceData, meta
wfrd, wfrdOK := d.GetOk("wait_for_reservation_deprovision")
if wfrdOK && wfrd.(bool) {
// avoid "context: deadline exceeded"
timeout := d.Timeout(schema.TimeoutDelete) - time.Minute - time.Since(start)
timeout := d.Timeout(schema.TimeoutDelete) - 30*time.Second - time.Since(start)

err := waitUntilReservationProvisionable(ctx, client, resId.(string), d.Id(), 10*time.Second, timeout, 3*time.Second)
if err != nil {
Expand Down
121 changes: 51 additions & 70 deletions equinix/resource_metal_device_acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package equinix

import (
"context"
"errors"
"fmt"
"log"
"net"
Expand All @@ -12,7 +11,6 @@ import (
"testing"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -559,23 +557,6 @@ func testAccMetalDeviceExists(n string, device *packngo.Device) resource.TestChe
}
}

func testAccWaitForMetalDeviceActive(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
defaultTimeout := 20 * time.Minute

rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Record ID is set")
}
rd := new(schema.ResourceData)
rd.SetId(rs.Primary.ID)
return waitForActiveDevice(context.Background(), rd, testAccProvider.Meta(), defaultTimeout)
}
}

func testAccMetalSameDevice(t *testing.T, before, after *packngo.Device) resource.TestCheckFunc {
return func(s *terraform.State) error {
if before.ID != after.ID {
Expand Down Expand Up @@ -949,6 +930,7 @@ resource "equinix_metal_device" "test" {
operating_system = "ubuntu_20_04"
project_id = "${equinix_metal_project.test.id}"
termination_time = "%s"
depends_on = [equinix_metal_project.test]
timeouts {
create = "10s"
Expand Down Expand Up @@ -1151,68 +1133,67 @@ func TestAccMetalDevice_readErrorHandling(t *testing.T) {
}
}

func TestAccMetalDevice_timeouts(t *testing.T) {
d1 := &packngo.Device{
State: "active",
}
projSuffix := acctest.RandString(10)
func testAccWaitForMetalDeviceActive(project, deviceHostName string) resource.ImportStateIdFunc {
return func(state *terraform.State) (string, error) {
defaultTimeout := 20 * time.Minute

mockMetalDeviceService := &mockDeviceService{
CreateFn: func(device *packngo.DeviceCreateRequest) (*packngo.Device, *packngo.Response, error) {
return d1, &packngo.Response{Response: &http.Response{Status: matchErrDeviceReadyTimeout.String(), StatusCode: 500}},
errors.New(matchErrDeviceReadyTimeout.String())
},
GetFn: func(deviceID string, opts *packngo.GetOptions) (*packngo.Device, *packngo.Response, error) {
return d1, &packngo.Response{Response: &http.Response{Status: "Success", StatusCode: 200}}, nil
},
}
mockMetalProjectService := &mockProjectService{
GetFn: func(projectID string, opts *packngo.GetOptions) (*packngo.Project, *packngo.Response, error) {
project := &packngo.Project{ID: "test"}
httpResp := &http.Response{Status: "Success", StatusCode: 200}
return project, &packngo.Response{Response: httpResp}, nil
},
CreateFn: func(pcr *packngo.ProjectCreateRequest) (*packngo.Project, *packngo.Response, error) {
project := &packngo.Project{ID: "test"}
httpResp := &http.Response{Status: "Success", StatusCode: 200}
return project, &packngo.Response{Response: httpResp}, nil
},
DeleteFn: func(projectID string) (*packngo.Response, error) {
httpResp := &http.Response{Status: "Success", StatusCode: 200}
return &packngo.Response{Response: httpResp}, nil
},
}
mockBgpsvc := &mockBgpConfigService{
GetFn: func(projectID string, getOpt *packngo.GetOptions) (*packngo.BGPConfig, *packngo.Response, error) {
return nil, nil, nil
},
}
rs, ok := state.RootModule().Resources[project]
if !ok {
return "", fmt.Errorf("Project Not found in the state: %s", project)
}
if rs.Primary.ID == "" {
return "", fmt.Errorf("No Record ID is set")
}

mockEquinix := Provider()
mockEquinix.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
config := Config{
metal: &packngo.Client{
Devices: mockMetalDeviceService,
Projects: mockMetalProjectService,
BGPConfig: mockBgpsvc,
},
meta := testAccProvider.Meta()
rd := new(schema.ResourceData)
meta.(*Config).addModuleToMetalUserAgent(rd)
client := meta.(*Config).metal
devices, _, err := client.Devices.List(rs.Primary.ID, &packngo.ListOptions{Search: deviceHostName})
if err != nil {
return "", fmt.Errorf("error while fetching devices for project [%s], error: %w", rs.Primary.ID, err)
}
if len(devices) == 0 {
return "", fmt.Errorf("Not able to find devices in project [%s]", rs.Primary.ID)
}
if len(devices) > 1 {
return "", fmt.Errorf("Found more than one device with the hostname in project [%s]", rs.Primary.ID)
}
return &config, nil
}

mockProviders := map[string]func() (*schema.Provider, error){
"equinix": func() (*schema.Provider, error) {
return mockEquinix, nil
},
rd.SetId(devices[0].ID)
return devices[0].ID, waitForActiveDevice(context.Background(), rd, testAccProvider.Meta(), defaultTimeout)
}
}

func TestAccMetalDevice_importBasicTimeout(t *testing.T) {
rs := acctest.RandString(10)
r := "equinix_metal_device.test"
hostname := "tfacc-test-device"
project := "equinix_metal_project.test"

resource.ParallelTest(t, resource.TestCase{
ProviderFactories: mockProviders,
PreCheck: func() { testAccPreCheck(t) },
ExternalProviders: testExternalProviders,
ProviderFactories: testAccProviderFactories,
CheckDestroy: testAccMetalDeviceCheckDestroyed,
Steps: []resource.TestStep{
{
Config: testAccMetalDeviceConfig_timeout(projSuffix),
Config: testAccMetalDeviceConfig_timeout(rs),
ExpectError: matchErrDeviceReadyTimeout,
},
{
/**
Step 1 errors out, state doesnt have device, need to import that in the state before deleting
*/
ResourceName: r,
ImportState: true,
ImportStateIdFunc: testAccWaitForMetalDeviceActive(project, hostname),
ImportStatePersist: true,
},
{
Config: testAccMetalDeviceConfig_timeout(rs),
Destroy: true,
},
},
})
}
15 changes: 0 additions & 15 deletions equinix/resource_network_bgp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package equinix

import (
"context"
"github.com/packethost/packngo"
"testing"
"time"

Expand Down Expand Up @@ -101,20 +100,6 @@ func (r *mockedBGPUpdateRequest) Execute() error {
return nil
}

var _ packngo.BGPConfigService = &mockBgpConfigService{}

type mockBgpConfigService struct {
GetFn func(projectID string, getOpt *packngo.GetOptions) (*packngo.BGPConfig, *packngo.Response, error)
CreateFn func(projectID string, request packngo.CreateBGPConfigRequest) (*packngo.Response, error)
}

func (s *mockBgpConfigService) Get(projectID string, getOpt *packngo.GetOptions) (*packngo.BGPConfig, *packngo.Response, error) {
return s.GetFn(projectID, getOpt)
}
func (s *mockBgpConfigService) Create(projectID string, request packngo.CreateBGPConfigRequest) (*packngo.Response, error) {
return s.CreateFn(projectID, request)
}

func TestNetworkBGP_createUpdateRequest(t *testing.T) {
// given
req := &mockedBGPUpdateRequest{data: make(map[string]interface{})}
Expand Down

0 comments on commit e949259

Please sign in to comment.