@@ -3,10 +3,12 @@ package rabbitmq_test
33import (
44 "context"
55 "fmt"
6+ "net/http"
67 "regexp"
78 "strings"
89 "testing"
910
11+ "github.com/google/uuid"
1012 "github.com/hashicorp/terraform-plugin-testing/helper/resource"
1113 "github.com/hashicorp/terraform-plugin-testing/terraform"
1214 "github.com/stackitcloud/stackit-sdk-go/core/config"
@@ -243,6 +245,198 @@ func TestAccRabbitMQResource(t *testing.T) {
243245 })
244246}
245247
248+ // Run apply for an instance and produce an error in the waiter. By erroring out state checks are not run in this step.
249+ // The second step imports the resource and runs a state check to verify that the first step wrote the IDs, despite the error.
250+ // When importing we append "-import" to the credential ID to verify that the import isn't overwriting the instance
251+ // ID from the first step
252+ func TestRabbitMQInstanceSavesIDsOnError (t * testing.T ) {
253+ projectId := uuid .NewString ()
254+ instanceId := uuid .NewString ()
255+ const (
256+ name = "instance-name"
257+ planName = "plan-name"
258+ planId = "plan-id"
259+ version = "version"
260+ )
261+ s := testutil .NewMockServer (t )
262+ defer s .Server .Close ()
263+ tfConfig := fmt .Sprintf (`
264+ provider "stackit" {
265+ rabbitmq_custom_endpoint = "%s"
266+ service_account_token = "mock-server-needs-no-auth"
267+ }
268+
269+ resource "stackit_rabbitmq_instance" "instance" {
270+ project_id = "%s"
271+ name = "%s"
272+ plan_name = "%s"
273+ version = "%s"
274+ }
275+ ` , s .Server .URL , projectId , name , planName , version )
276+ offerings := testutil.MockResponse {
277+ ToJsonBody : & rabbitmq.ListOfferingsResponse {
278+ Offerings : & []rabbitmq.Offering {
279+ {
280+ Version : utils .Ptr (version ),
281+ Plans : & []rabbitmq.Plan {
282+ {
283+ Name : utils .Ptr (planName ),
284+ Id : utils .Ptr (planId ),
285+ },
286+ },
287+ },
288+ },
289+ },
290+ }
291+ resource .UnitTest (t , resource.TestCase {
292+ ProtoV6ProviderFactories : testutil .TestAccProtoV6ProviderFactories ,
293+ Steps : []resource.TestStep {
294+ {
295+ PreConfig : func () {
296+ s .Reset (
297+ // respond to listing offerings
298+ offerings ,
299+ // initial post response
300+ testutil.MockResponse {
301+ ToJsonBody : rabbitmq.CreateInstanceResponse {
302+ InstanceId : utils .Ptr (instanceId ),
303+ },
304+ },
305+ // failing waiter
306+ testutil.MockResponse {
307+ ToJsonBody : rabbitmq.Instance {
308+ Status : utils .Ptr (rabbitmq .INSTANCESTATUS_FAILED ),
309+ },
310+ },
311+ )
312+ },
313+ Config : tfConfig ,
314+ ExpectError : regexp .MustCompile ("Error creating instance.*" ),
315+ },
316+ {
317+ PreConfig : func () {
318+ s .Reset (
319+ // read from import
320+ testutil.MockResponse {
321+ ToJsonBody : rabbitmq.Instance {
322+ Status : utils .Ptr (rabbitmq .INSTANCESTATUS_ACTIVE ),
323+ InstanceId : utils .Ptr (instanceId + "-import" ),
324+ PlanId : utils .Ptr (planId ),
325+ },
326+ },
327+ // list offerings in import
328+ offerings ,
329+ // delete
330+ testutil.MockResponse {StatusCode : http .StatusAccepted },
331+ // delete waiter
332+ testutil.MockResponse {
333+ StatusCode : http .StatusGone ,
334+ },
335+ )
336+ },
337+ ImportStateCheck : func (states []* terraform.InstanceState ) error {
338+ if len (states ) != 1 {
339+ return fmt .Errorf ("expected exactly one state to be imported, got %d" , len (states ))
340+ }
341+ state := states [0 ]
342+ if state .Attributes ["instance_id" ] != instanceId {
343+ return fmt .Errorf ("expected instance_id to be %s, got %s" , instanceId , state .Attributes ["instance_id" ])
344+ }
345+ if state .Attributes ["project_id" ] != projectId {
346+ return fmt .Errorf ("expected project_id to be %s, got %s" , projectId , state .Attributes ["project_id" ])
347+ }
348+ return nil
349+ },
350+ ImportState : true ,
351+ ImportStateId : fmt .Sprintf ("%s,%s" , projectId , instanceId ),
352+ ResourceName : "stackit_rabbitmq_instance.instance" ,
353+ },
354+ },
355+ })
356+ }
357+
358+ // Run apply for credentials and produce an error in the waiter. By erroring out state checks are not run in this step.
359+ // The second step imports the resource and runs a state check to verify that the first step wrote the IDs, despite the error.
360+ // When importing we append "-import" to the credential ID to verify that the import isn't overwriting the credential
361+ // ID from the first step
362+ func TestRabbitMQCredentialsSavesIDsOnError (t * testing.T ) {
363+ var (
364+ projectId = uuid .NewString ()
365+ instanceId = uuid .NewString ()
366+ credentialId = uuid .NewString ()
367+ )
368+ s := testutil .NewMockServer (t )
369+ t .Cleanup (s .Server .Close )
370+ tfConfig := fmt .Sprintf (`
371+ provider "stackit" {
372+ rabbitmq_custom_endpoint = "%s"
373+ service_account_token = "mock-server-needs-no-auth"
374+ }
375+
376+ resource "stackit_rabbitmq_credential" "credential" {
377+ project_id = "%s"
378+ instance_id = "%s"
379+ }
380+ ` , s .Server .URL , projectId , instanceId )
381+ resource .UnitTest (t , resource.TestCase {
382+ ProtoV6ProviderFactories : testutil .TestAccProtoV6ProviderFactories ,
383+ Steps : []resource.TestStep {
384+ {
385+ PreConfig : func () {
386+ s .Reset (
387+ // initial post response
388+ testutil.MockResponse {
389+ ToJsonBody : rabbitmq.CredentialsResponse {
390+ Id : utils .Ptr (credentialId ),
391+ },
392+ },
393+ // failing waiter
394+ testutil.MockResponse {StatusCode : http .StatusInternalServerError },
395+ )
396+ },
397+ Config : tfConfig ,
398+ ExpectError : regexp .MustCompile ("Error creating credential.*" ),
399+ },
400+ {
401+ PreConfig : func () {
402+ s .Reset (
403+ // read from import
404+ testutil.MockResponse {
405+ ToJsonBody : rabbitmq.CredentialsResponse {
406+ Id : utils .Ptr (credentialId + "-import" ),
407+ Raw : & rabbitmq.RawCredentials {},
408+ },
409+ },
410+ // delete
411+ testutil.MockResponse {StatusCode : http .StatusAccepted },
412+ // delete waiter
413+ testutil.MockResponse {StatusCode : http .StatusGone },
414+ )
415+ },
416+ ImportStateCheck : func (states []* terraform.InstanceState ) error {
417+ if len (states ) != 1 {
418+ return fmt .Errorf ("expected exactly one state to be imported, got %d" , len (states ))
419+ }
420+ state := states [0 ]
421+ if state .Attributes ["instance_id" ] != instanceId {
422+ return fmt .Errorf ("expected instance_id to be %s, got %s" , instanceId , state .Attributes ["instance_id" ])
423+ }
424+ if state .Attributes ["project_id" ] != projectId {
425+ return fmt .Errorf ("expected project_id to be %s, got %s" , projectId , state .Attributes ["project_id" ])
426+ }
427+ if state .Attributes ["credential_id" ] != credentialId {
428+ return fmt .Errorf ("expected credential_id to be %s, got %s" , credentialId , state .Attributes ["credential_id" ])
429+ }
430+ return nil
431+ },
432+ ImportState : true ,
433+ ImportStateId : fmt .Sprintf ("%s,%s,%s" , projectId , instanceId , credentialId ),
434+ ResourceName : "stackit_rabbitmq_credential.credential" ,
435+ },
436+ },
437+ })
438+ }
439+
246440func testAccCheckRabbitMQDestroy (s * terraform.State ) error {
247441 ctx := context .Background ()
248442 var client * rabbitmq.APIClient
0 commit comments