Skip to content

Commit dafb4a2

Browse files
author
Yago Carlos Fernandez Gou
committed
Reshape resource_acc_test
1 parent 2cf3dde commit dafb4a2

File tree

5 files changed

+229
-166
lines changed

5 files changed

+229
-166
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package intake_test
2+
3+
import (
4+
"context"
5+
_ "embed"
6+
"errors"
7+
"fmt"
8+
"maps"
9+
"net/http"
10+
"testing"
11+
12+
"github.com/hashicorp/terraform-plugin-testing/config"
13+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
14+
"github.com/hashicorp/terraform-plugin-testing/terraform"
15+
sdkConfig "github.com/stackitcloud/stackit-sdk-go/core/config"
16+
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
17+
"github.com/stackitcloud/stackit-sdk-go/services/intake"
18+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil"
19+
)
20+
21+
//go:embed testdata/resource-min.tf
22+
var resourceMin string
23+
24+
//go:embed testdata/resource-max.tf
25+
var resourceMax string
26+
27+
const intakeRunnerResource = "stackit_intake_runner.example"
28+
29+
const (
30+
intakeRunnerMinName = "intake-min-runner"
31+
intakeRunnerMinNameUpdated = "intake-min-runner-upd"
32+
intakeRunnerMaxName = "intake-max-runner"
33+
intakeRunnerMaxNameUpdated = "intake-max-runner-upd"
34+
)
35+
36+
var testConfigVarsMin = config.Variables{
37+
"project_id": config.StringVariable(testutil.ProjectId),
38+
"name": config.StringVariable(intakeRunnerMinName),
39+
}
40+
41+
var testConfigVarsMax = config.Variables{
42+
"project_id": config.StringVariable(testutil.ProjectId),
43+
"name": config.StringVariable(intakeRunnerMaxName),
44+
}
45+
46+
func testConfigVarsMinUpdated() config.Variables {
47+
tempConfig := make(config.Variables, len(testConfigVarsMin))
48+
maps.Copy(tempConfig, testConfigVarsMin)
49+
tempConfig["name"] = config.StringVariable(intakeRunnerMinNameUpdated)
50+
return tempConfig
51+
}
52+
53+
func testConfigVarsMaxUpdated() config.Variables {
54+
tempConfig := make(config.Variables, len(testConfigVarsMax))
55+
maps.Copy(tempConfig, testConfigVarsMax)
56+
tempConfig["name"] = config.StringVariable(intakeRunnerMaxNameUpdated)
57+
return tempConfig
58+
}
59+
60+
func TestAccIntakeRunnerMin(t *testing.T) {
61+
resource.Test(t, resource.TestCase{
62+
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
63+
CheckDestroy: testAccCheckIntakeRunnerDestroy,
64+
Steps: []resource.TestStep{
65+
// Create the minimum runner from the HCL file
66+
{
67+
ConfigVariables: testConfigVarsMin,
68+
Config: testutil.IntakeProviderConfig() + "\n" + resourceMin,
69+
Check: resource.ComposeAggregateTestCheckFunc(
70+
// Verify project_id, name and the existence of runner_id
71+
resource.TestCheckResourceAttr(intakeRunnerResource, "project_id", testutil.ProjectId),
72+
resource.TestCheckResourceAttr(intakeRunnerResource, "name", intakeRunnerMinName),
73+
resource.TestCheckResourceAttrSet(intakeRunnerResource, "runner_id"),
74+
),
75+
},
76+
// Data source check: creates config that includes resource and data source
77+
{
78+
ConfigVariables: testConfigVarsMin,
79+
Config: fmt.Sprintf(`
80+
%s
81+
data "stackit_intake_runner" "example" {
82+
project_id = %s.project_id
83+
runner_id = %s.runner_id
84+
region = %s.region
85+
}`, testutil.IntakeProviderConfig()+"\n"+resourceMin, intakeRunnerResource, intakeRunnerResource, intakeRunnerResource),
86+
Check: resource.ComposeAggregateTestCheckFunc(
87+
// Make sure it's correctly found resource by comparing runner_id attribute
88+
resource.TestCheckResourceAttrPair(intakeRunnerResource, "runner_id", "data.stackit_intake_runner.example", "runner_id"),
89+
),
90+
},
91+
// Simulate terraform import
92+
{
93+
ConfigVariables: testConfigVarsMin,
94+
Config: testutil.IntakeProviderConfig() + "\n" + resourceMin,
95+
ResourceName: intakeRunnerResource,
96+
ImportState: true,
97+
ImportStateVerify: true,
98+
ImportStateIdFunc: func(s *terraform.State) (string, error) {
99+
// Construct ID string
100+
r, ok := s.RootModule().Resources[intakeRunnerResource]
101+
if !ok {
102+
return "", fmt.Errorf("couldn't find resource %s", intakeRunnerResource)
103+
}
104+
return fmt.Sprintf("%s,%s,%s", r.Primary.Attributes["project_id"], r.Primary.Attributes["region"], r.Primary.Attributes["runner_id"]), nil
105+
},
106+
},
107+
// Update check: verifies API updated resource name without crashing
108+
{
109+
ConfigVariables: testConfigVarsMinUpdated(),
110+
Config: testutil.IntakeProviderConfig() + "\n" + resourceMin,
111+
Check: resource.ComposeAggregateTestCheckFunc(
112+
resource.TestCheckResourceAttr(intakeRunnerResource, "name", intakeRunnerMinNameUpdated),
113+
),
114+
},
115+
},
116+
})
117+
}
118+
119+
func TestAccIntakeRunnerMax(t *testing.T) {
120+
resource.Test(t, resource.TestCase{
121+
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
122+
CheckDestroy: testAccCheckIntakeRunnerDestroy,
123+
Steps: []resource.TestStep{
124+
// Create the max intake runner from HCL files and verify comparison
125+
{
126+
ConfigVariables: testConfigVarsMax,
127+
Config: testutil.IntakeProviderConfig() + "\n" + resourceMax,
128+
Check: resource.ComposeAggregateTestCheckFunc(
129+
resource.TestCheckResourceAttr(intakeRunnerResource, "name", intakeRunnerMaxName),
130+
resource.TestCheckResourceAttr(intakeRunnerResource, "description", "An example runner for Intake"),
131+
resource.TestCheckResourceAttr(intakeRunnerResource, "max_message_size_kib", "1024"),
132+
),
133+
},
134+
// Update and verify changes are reflected
135+
{
136+
ConfigVariables: testConfigVarsMaxUpdated(),
137+
Config: testutil.IntakeProviderConfig() + "\n" + resourceMax,
138+
Check: resource.ComposeAggregateTestCheckFunc(
139+
resource.TestCheckResourceAttr(intakeRunnerResource, "name", intakeRunnerMaxNameUpdated),
140+
),
141+
},
142+
},
143+
})
144+
}
145+
146+
// testAccCheckIntakeRunnerDestroy act as independent auditor to verify destroy operation
147+
func testAccCheckIntakeRunnerDestroy(s *terraform.State) error {
148+
// Create own raw API client
149+
ctx := context.Background()
150+
var client *intake.APIClient
151+
var err error
152+
153+
// todo: check this again
154+
effectiveRegion := testutil.Region
155+
if effectiveRegion == "" {
156+
effectiveRegion = "eu01"
157+
}
158+
159+
if testutil.IntakeCustomEndpoint == "" {
160+
client, err = intake.NewAPIClient(sdkConfig.WithRegion(effectiveRegion))
161+
} else {
162+
client, err = intake.NewAPIClient(
163+
sdkConfig.WithEndpoint(testutil.IntakeCustomEndpoint),
164+
sdkConfig.WithRegion(effectiveRegion),
165+
)
166+
}
167+
if err != nil {
168+
return fmt.Errorf("creating client: %w", err)
169+
}
170+
171+
// Loop through resources that should have been deleted
172+
for _, rs := range s.RootModule().Resources {
173+
if rs.Type != "stackit_intake_runner" {
174+
continue
175+
}
176+
177+
pID := rs.Primary.Attributes["project_id"]
178+
reg := rs.Primary.Attributes["region"]
179+
rID := rs.Primary.Attributes["runner_id"]
180+
181+
// If it still exists, destroy operation was unsuccessful
182+
_, err := client.GetIntakeRunner(ctx, pID, reg, rID).Execute()
183+
if err == nil {
184+
// Delete to prevent orphaned instances
185+
errDel := client.DeleteIntakeRunner(ctx, pID, reg, rID).Execute()
186+
if errDel != nil {
187+
return fmt.Errorf("resource leaked and manual cleanup failed: %w", errDel)
188+
}
189+
190+
return fmt.Errorf("intake runner %s still exists in region %s", rID, reg)
191+
}
192+
193+
var oapiErr *oapierror.GenericOpenAPIError
194+
if !errors.As(err, &oapiErr) || oapiErr.StatusCode != http.StatusNotFound {
195+
return fmt.Errorf("unexpected error checking destruction: %w", err)
196+
}
197+
}
198+
return nil
199+
}

stackit/internal/services/intake/runner/resource.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -501,14 +501,12 @@ func toUpdatePayload(model, state *Model) (*intake.UpdateIntakeRunnerPayload, er
501501
payload.Description = conversion.StringValueToPointer(model.Description)
502502

503503
var labels map[string]string
504-
if !model.Labels.IsUnknown() {
505-
if !model.Labels.IsNull() {
506-
diags := model.Labels.ElementsAs(context.Background(), &labels, false)
507-
if diags.HasError() {
508-
return nil, fmt.Errorf("failed to convert labels: %w", core.DiagsToError(diags))
509-
}
510-
payload.Labels = &labels
504+
if !model.Labels.IsUnknown() && !model.Labels.IsNull() {
505+
diags := model.Labels.ElementsAs(context.Background(), &labels, false)
506+
if diags.HasError() {
507+
return nil, fmt.Errorf("failed to convert labels: %w", core.DiagsToError(diags))
511508
}
509+
payload.Labels = &labels
512510
}
513511

514512
return payload, nil

stackit/internal/services/intake/runner/resource_acc_test.go

Lines changed: 0 additions & 159 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
variable "project_id" {}
3+
variable "name" {}
4+
5+
resource "stackit_intake_runner" "example" {
6+
project_id = var.project_id
7+
name = var.name
8+
description = "An example runner for Intake"
9+
max_message_size_kib = 1024
10+
max_messages_per_hour = 1100
11+
labels = {
12+
"created_by" = "terraform-provider-stackit"
13+
"env" = "development"
14+
}
15+
}

0 commit comments

Comments
 (0)