From 089e65e6609a3a74249e82530bfc7598163f2bc9 Mon Sep 17 00:00:00 2001 From: Ayush Rangwala Date: Wed, 23 Aug 2023 19:31:32 +0530 Subject: [PATCH 1/3] Acceptance tests for metal device timeouts --- equinix/resource_network_bgp_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/equinix/resource_network_bgp_test.go b/equinix/resource_network_bgp_test.go index b4131f3c1..f40bafb6b 100644 --- a/equinix/resource_network_bgp_test.go +++ b/equinix/resource_network_bgp_test.go @@ -2,6 +2,7 @@ package equinix import ( "context" + "github.com/packethost/packngo" "testing" "time" @@ -100,6 +101,20 @@ 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{})} From f814932bc458ec3e1a83faffbcd1e04a2d7478ed Mon Sep 17 00:00:00 2001 From: Ayush Rangwala Date: Thu, 24 Aug 2023 18:49:13 +0530 Subject: [PATCH 2/3] Timeouts tests to be unit test to be able to run without TF_ACC --- equinix/resource_network_bgp_test.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/equinix/resource_network_bgp_test.go b/equinix/resource_network_bgp_test.go index f40bafb6b..b4131f3c1 100644 --- a/equinix/resource_network_bgp_test.go +++ b/equinix/resource_network_bgp_test.go @@ -2,7 +2,6 @@ package equinix import ( "context" - "github.com/packethost/packngo" "testing" "time" @@ -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{})} From 0aa12879ca80627bbd772e4c18f9b677fbee66c4 Mon Sep 17 00:00:00 2001 From: Ayush Rangwala Date: Thu, 14 Sep 2023 20:42:29 +0530 Subject: [PATCH 3/3] Update TF Virtual Circuit to use timeouts --- equinix/data_source_metal_virtual_circuit.go | 8 +++-- equinix/resource_metal_virtual_circuit.go | 31 ++++++++++--------- ...resource_metal_virtual_circuit_acc_test.go | 2 +- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/equinix/data_source_metal_virtual_circuit.go b/equinix/data_source_metal_virtual_circuit.go index df5d290be..dafcfc110 100644 --- a/equinix/data_source_metal_virtual_circuit.go +++ b/equinix/data_source_metal_virtual_circuit.go @@ -1,12 +1,14 @@ package equinix import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func dataSourceMetalVirtualCircuit() *schema.Resource { return &schema.Resource{ - Read: dataSourceMetalVirtualCircuitRead, + ReadContext: diagnosticsWrapper(dataSourceMetalVirtualCircuitRead), Schema: map[string]*schema.Schema{ "virtual_circuit_id": { @@ -112,8 +114,8 @@ func dataSourceMetalVirtualCircuit() *schema.Resource { } } -func dataSourceMetalVirtualCircuitRead(d *schema.ResourceData, meta interface{}) error { +func dataSourceMetalVirtualCircuitRead(ctx context.Context, d *schema.ResourceData, meta interface{}) error { vcId := d.Get("virtual_circuit_id").(string) d.SetId(vcId) - return resourceMetalVirtualCircuitRead(d, meta) + return resourceMetalVirtualCircuitRead(ctx, d, meta) } diff --git a/equinix/resource_metal_virtual_circuit.go b/equinix/resource_metal_virtual_circuit.go index 9d24f7763..7d9ded70e 100644 --- a/equinix/resource_metal_virtual_circuit.go +++ b/equinix/resource_metal_virtual_circuit.go @@ -1,6 +1,7 @@ package equinix import ( + "context" "fmt" "log" "reflect" @@ -15,12 +16,12 @@ import ( func resourceMetalVirtualCircuit() *schema.Resource { return &schema.Resource{ - Read: resourceMetalVirtualCircuitRead, - Create: resourceMetalVirtualCircuitCreate, - Update: resourceMetalVirtualCircuitUpdate, - Delete: resourceMetalVirtualCircuitDelete, + ReadWithoutTimeout: diagnosticsWrapper(resourceMetalVirtualCircuitRead), + CreateContext: diagnosticsWrapper(resourceMetalVirtualCircuitCreate), + UpdateWithoutTimeout: diagnosticsWrapper(resourceMetalVirtualCircuitUpdate), + DeleteContext: diagnosticsWrapper(resourceMetalVirtualCircuitDelete), Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -137,7 +138,7 @@ func resourceMetalVirtualCircuit() *schema.Resource { } } -func resourceMetalVirtualCircuitCreate(d *schema.ResourceData, meta interface{}) error { +func resourceMetalVirtualCircuitCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) error { meta.(*Config).addModuleToMetalUserAgent(d) client := meta.(*Config).metal vncr := packngo.VCCreateRequest{ @@ -182,22 +183,22 @@ func resourceMetalVirtualCircuitCreate(d *schema.ResourceData, meta interface{}) createWaiter := getVCStateWaiter( client, vc.ID, - d.Timeout(schema.TimeoutCreate), + d.Timeout(schema.TimeoutCreate)-30*time.Second, []string{string(packngo.VCStatusActivating)}, []string{string(packngo.VCStatusActive)}, ) - _, err = createWaiter.WaitForState() + _, err = createWaiter.WaitForStateContext(ctx) if err != nil { return fmt.Errorf("Error waiting for virtual circuit %s to be created: %s", vc.ID, err.Error()) } d.SetId(vc.ID) - return resourceMetalVirtualCircuitRead(d, meta) + return resourceMetalVirtualCircuitRead(ctx, d, meta) } -func resourceMetalVirtualCircuitRead(d *schema.ResourceData, meta interface{}) error { +func resourceMetalVirtualCircuitRead(ctx context.Context, d *schema.ResourceData, meta interface{}) error { meta.(*Config).addModuleToMetalUserAgent(d) client := meta.(*Config).metal vcId := d.Id() @@ -278,7 +279,7 @@ func getVCStateWaiter(client *packngo.Client, id string, timeout time.Duration, } } -func resourceMetalVirtualCircuitUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceMetalVirtualCircuitUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) error { meta.(*Config).addModuleToMetalUserAgent(d) client := meta.(*Config).metal @@ -323,10 +324,10 @@ func resourceMetalVirtualCircuitUpdate(d *schema.ResourceData, meta interface{}) return friendlyError(err) } } - return resourceMetalVirtualCircuitRead(d, meta) + return resourceMetalVirtualCircuitRead(ctx, d, meta) } -func resourceMetalVirtualCircuitDelete(d *schema.ResourceData, meta interface{}) error { +func resourceMetalVirtualCircuitDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) error { meta.(*Config).addModuleToMetalUserAgent(d) client := meta.(*Config).metal @@ -338,12 +339,12 @@ func resourceMetalVirtualCircuitDelete(d *schema.ResourceData, meta interface{}) deleteWaiter := getVCStateWaiter( client, d.Id(), - d.Timeout(schema.TimeoutDelete), + d.Timeout(schema.TimeoutDelete)-30*time.Second, []string{string(packngo.VCStatusDeleting)}, []string{}, ) - _, err = deleteWaiter.WaitForState() + _, err = deleteWaiter.WaitForStateContext(ctx) if ignoreResponseErrors(httpForbidden, httpNotFound)(nil, err) != nil { return fmt.Errorf("Error deleting virtual circuit %s: %s", d.Id(), err) } diff --git a/equinix/resource_metal_virtual_circuit_acc_test.go b/equinix/resource_metal_virtual_circuit_acc_test.go index 144b956fa..13a111734 100644 --- a/equinix/resource_metal_virtual_circuit_acc_test.go +++ b/equinix/resource_metal_virtual_circuit_acc_test.go @@ -123,7 +123,7 @@ func TestAccMetalVirtualCircuit_dedicated(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ // Error: Error waiting for virtual circuit 863d4df5-b3ea-46ee-8497-858cb0cbfcb9 to be created: GET https://api.equinix.com/metal/v1/virtual-circuits/863d4df5-b3ea-46ee-8497-858cb0cbfcb9?include=project%2Cport%2Cvirtual_network%2Cvrf: 500 Oh snap, something went wrong! We've logged the error and will take a look - please reach out to us if you continue having trouble. PreCheck: func() { testAccPreCheck(t) }, ExternalProviders: testExternalProviders, - Providers: testAccProviders, + ProviderFactories: testAccProviderFactories, CheckDestroy: testAccMetalVirtualCircuitCheckDestroyed, Steps: []resource.TestStep{ {