From bf97f8f75b3eca96afc089a84d966f8b3db51e67 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 27 Jun 2022 11:36:21 +0100 Subject: [PATCH] Adding acceptance tests to verify upgrading to framework does not trigger unexpected replace (#177) --- .../provider/provider_resource_id_test.go | 47 +++- .../provider_resource_integer_test.go | 60 ++++- .../provider_resource_password_test.go | 95 +++++++- .../provider/provider_resource_pet_test.go | 50 ++++- .../provider_resource_shuffle_test.go | 207 +++++++++--------- .../provider/provider_resource_string_test.go | 92 +++++++- .../provider/provider_resource_uuid_test.go | 43 +++- internal/provider/provider_test.go | 12 +- internal/random/random.go | 4 +- internal/resources/password/resource.go | 4 +- .../{string => stringresource}/resource.go | 168 +++++++++++++- .../uuid/{resource_uuid.go => resource.go} | 0 12 files changed, 615 insertions(+), 167 deletions(-) rename internal/resources/{string => stringresource}/resource.go (67%) rename internal/resources/uuid/{resource_uuid.go => resource.go} (100%) diff --git a/internal/provider/provider_resource_id_test.go b/internal/provider/provider_resource_id_test.go index 82106148..be04a020 100644 --- a/internal/provider/provider_resource_id_test.go +++ b/internal/provider/provider_resource_id_test.go @@ -8,7 +8,7 @@ import ( func TestAccResourceID(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_id" "foo" { @@ -30,9 +30,9 @@ func TestAccResourceID(t *testing.T) { }) } -func TestAccResourceID_importWithPrefix(t *testing.T) { +func TestAccResourceID_ImportWithPrefix(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_id" "bar" { @@ -55,3 +55,44 @@ func TestAccResourceID_importWithPrefix(t *testing.T) { }, }) } + +func TestAccResourceID_UpgradeFromVersion3_3_2(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion332(), + Config: `resource "random_id" "bar" { + byte_length = 4 + prefix = "cloud-" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_id.bar", "b64_url", testCheckLen(12)), + resource.TestCheckResourceAttrWith("random_id.bar", "b64_std", testCheckLen(14)), + resource.TestCheckResourceAttrWith("random_id.bar", "hex", testCheckLen(14)), + resource.TestCheckResourceAttrWith("random_id.bar", "dec", testCheckMinLen(1)), + ), + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_id" "bar" { + byte_length = 4 + prefix = "cloud-" + }`, + PlanOnly: true, + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_id" "bar" { + byte_length = 4 + prefix = "cloud-" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_id.bar", "b64_url", testCheckLen(12)), + resource.TestCheckResourceAttrWith("random_id.bar", "b64_std", testCheckLen(14)), + resource.TestCheckResourceAttrWith("random_id.bar", "hex", testCheckLen(14)), + resource.TestCheckResourceAttrWith("random_id.bar", "dec", testCheckMinLen(1)), + ), + }, + }, + }) +} diff --git a/internal/provider/provider_resource_integer_test.go b/internal/provider/provider_resource_integer_test.go index 9878fd05..18925e10 100644 --- a/internal/provider/provider_resource_integer_test.go +++ b/internal/provider/provider_resource_integer_test.go @@ -7,10 +7,10 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccResourceIntegerBasic(t *testing.T) { +func TestAccResourceInteger(t *testing.T) { t.Parallel() resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_integer" "integer_1" { @@ -32,10 +32,10 @@ func TestAccResourceIntegerBasic(t *testing.T) { }) } -func TestAccResourceIntegerUpdate(t *testing.T) { +func TestAccResourceInteger_ChangeSeed(t *testing.T) { t.Parallel() resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_integer" "integer_1" { @@ -61,10 +61,10 @@ func TestAccResourceIntegerUpdate(t *testing.T) { }) } -func TestAccResourceIntegerSeedless_to_seeded(t *testing.T) { +func TestAccResourceInteger_SeedlessToSeeded(t *testing.T) { t.Parallel() resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_integer" "integer_1" { @@ -89,10 +89,10 @@ func TestAccResourceIntegerSeedless_to_seeded(t *testing.T) { }) } -func TestAccResourceIntegerSeeded_to_seedless(t *testing.T) { +func TestAccResourceInteger_SeededToSeedless(t *testing.T) { t.Parallel() resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_integer" "integer_1" { @@ -117,10 +117,10 @@ func TestAccResourceIntegerSeeded_to_seedless(t *testing.T) { }) } -func TestAccResourceIntegerBig(t *testing.T) { +func TestAccResourceInteger_Big(t *testing.T) { t.Parallel() resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_integer" "integer_1" { @@ -139,10 +139,48 @@ func TestAccResourceIntegerBig(t *testing.T) { }) } +func TestAccResourceInteger_UpgradeFromVersion3_3_2(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion332(), + Config: `resource "random_integer" "integer_1" { + min = 1 + max = 3 + seed = "12345" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("random_integer.integer_1", "result", "3"), + ), + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_integer" "integer_1" { + min = 1 + max = 3 + seed = "12345" + }`, + PlanOnly: true, + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_integer" "integer_1" { + min = 1 + max = 3 + seed = "12345" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("random_integer.integer_1", "result", "3"), + ), + }, + }, + }) +} + func testCheckNotEmptyString(field string) func(input string) error { return func(input string) error { if input == "" { - return fmt.Errorf("%s is empty string", field) + return fmt.Errorf("%s is empty stringresource", field) } return nil diff --git a/internal/provider/provider_resource_password_test.go b/internal/provider/provider_resource_password_test.go index c3f909a5..91599ba1 100644 --- a/internal/provider/provider_resource_password_test.go +++ b/internal/provider/provider_resource_password_test.go @@ -9,9 +9,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) -func TestAccResourcePasswordBasic(t *testing.T) { +func TestAccResourcePassword(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_password" "basic" { @@ -46,9 +46,9 @@ func TestAccResourcePasswordBasic(t *testing.T) { }) } -func TestAccResourcePasswordOverride(t *testing.T) { +func TestAccResourcePassword_Override(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_password" "override" { @@ -67,11 +67,11 @@ func TestAccResourcePasswordOverride(t *testing.T) { }) } -// TestAccResourcePassword_StateUpgrade_V0toV2 covers the state upgrades from V0 to V2. +// TestAccResourcePassword_StateUpgradeV0toV2 covers the state upgrades from V0 to V2. // This includes the deprecation and removal of `number` and the addition of `numeric` // and `bcrypt_hash` attributes. // v3.1.3 is used as this is last version before `bcrypt_hash` attributed was added. -func TestAccResourcePassword_StateUpgrade_V0toV2(t *testing.T) { +func TestAccResourcePassword_StateUpgradeV0toV2(t *testing.T) { t.Parallel() cases := []struct { @@ -275,7 +275,7 @@ func TestAccResourcePassword_StateUpgrade_V0toV2(t *testing.T) { Check: resource.ComposeTestCheckFunc(c.beforeStateUpgrade...), }, { - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Config: c.configDuringUpgrade, Check: resource.ComposeTestCheckFunc(c.afterStateUpgrade...), }, @@ -289,7 +289,7 @@ func TestAccResourcePassword_StateUpgrade_V0toV2(t *testing.T) { // This includes the deprecation and removal of `number` and the addition of `numeric` attributes. // v3.2.0 was used as this is the last version before `number` was deprecated and `numeric` attribute // was added. -func TestAccResourcePassword_StateUpgrade_V1toV2(t *testing.T) { +func TestAccResourcePassword_StateUpgradeV1toV2(t *testing.T) { t.Parallel() cases := []struct { @@ -484,7 +484,7 @@ func TestAccResourcePassword_StateUpgrade_V1toV2(t *testing.T) { Check: resource.ComposeTestCheckFunc(c.beforeStateUpgrade...), }, { - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Config: c.configDuringUpgrade, Check: resource.ComposeTestCheckFunc(c.afterStateUpgrade...), }, @@ -494,9 +494,9 @@ func TestAccResourcePassword_StateUpgrade_V1toV2(t *testing.T) { } } -func TestAccResourcePasswordMin(t *testing.T) { +func TestAccResourcePassword_Min(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_password" "min" { @@ -518,3 +518,76 @@ func TestAccResourcePasswordMin(t *testing.T) { }, }) } + +func TestAccResourcePassword_UpgradeFromVersion3_3_2(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion332(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_password.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_password.min", "special", "true"), + resource.TestCheckResourceAttr("random_password.min", "upper", "true"), + resource.TestCheckResourceAttr("random_password.min", "lower", "true"), + resource.TestCheckResourceAttr("random_password.min", "numeric", "true"), + resource.TestCheckResourceAttr("random_password.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_password.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_password.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_password.min", "min_numeric", "4"), + resource.TestCheckResourceAttrSet("random_password.min", "bcrypt_hash"), + ), + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + PlanOnly: true, + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_password.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_password.min", "special", "true"), + resource.TestCheckResourceAttr("random_password.min", "upper", "true"), + resource.TestCheckResourceAttr("random_password.min", "lower", "true"), + resource.TestCheckResourceAttr("random_password.min", "numeric", "true"), + resource.TestCheckResourceAttr("random_password.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_password.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_password.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_password.min", "min_numeric", "4"), + resource.TestCheckResourceAttrSet("random_password.min", "bcrypt_hash"), + ), + }, + }, + }) +} diff --git a/internal/provider/provider_resource_pet_test.go b/internal/provider/provider_resource_pet_test.go index a2ab2867..3a5fc832 100644 --- a/internal/provider/provider_resource_pet_test.go +++ b/internal/provider/provider_resource_pet_test.go @@ -9,9 +9,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccResourcePet_basic(t *testing.T) { +func TestAccResourcePet(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_pet" "pet_1" { @@ -24,9 +24,9 @@ func TestAccResourcePet_basic(t *testing.T) { }) } -func TestAccResourcePet_length(t *testing.T) { +func TestAccResourcePet_Length(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_pet" "pet_1" { @@ -40,9 +40,9 @@ func TestAccResourcePet_length(t *testing.T) { }) } -func TestAccResourcePet_prefix(t *testing.T) { +func TestAccResourcePet_Prefix(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_pet" "pet_1" { @@ -57,9 +57,9 @@ func TestAccResourcePet_prefix(t *testing.T) { }) } -func TestAccResourcePet_separator(t *testing.T) { +func TestAccResourcePet_Separator(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_pet" "pet_1" { @@ -74,6 +74,40 @@ func TestAccResourcePet_separator(t *testing.T) { }) } +func TestAccResourcePet_UpgradeFromVersion3_3_2(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion332(), + Config: `resource "random_pet" "pet_1" { + prefix = "consul" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_pet.pet_1", "id", testCheckPetLen("-", 3)), + resource.TestMatchResourceAttr("random_pet.pet_1", "id", regexp.MustCompile("^consul-")), + ), + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_pet" "pet_1" { + prefix = "consul" + }`, + PlanOnly: true, + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_pet" "pet_1" { + prefix = "consul" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_pet.pet_1", "id", testCheckPetLen("-", 3)), + resource.TestMatchResourceAttr("random_pet.pet_1", "id", regexp.MustCompile("^consul-")), + ), + }, + }, + }) +} + func testCheckPetLen(separator string, expectedLen int) func(input string) error { return func(input string) error { petNameParts := strings.Split(input, separator) diff --git a/internal/provider/provider_resource_shuffle_test.go b/internal/provider/provider_resource_shuffle_test.go index 79ddfa34..a5670e5d 100644 --- a/internal/provider/provider_resource_shuffle_test.go +++ b/internal/provider/provider_resource_shuffle_test.go @@ -2,11 +2,9 @@ package provider import ( "fmt" - "strconv" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) // These results are current as of Go 1.6. The Go @@ -18,156 +16,167 @@ import ( // document them when they arise, but the docs for this // resource specifically warn that results are not // guaranteed consistent across Terraform releases. -func TestAccResourceShuffleDefault(t *testing.T) { +func TestAccResourceShuffle(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { - Config: testAccResourceShuffleConfigDefault, + Config: `resource "random_shuffle" "default_length" { + input = ["a", "b", "c", "d", "e"] + seed = "-" + }`, Check: resource.ComposeTestCheckFunc( - testAccResourceShuffleCheck( - "random_shuffle.default_length", - []string{"a", "c", "b", "e", "d"}, - ), + resource.TestCheckResourceAttrWith("random_shuffle.default_length", "result.#", testAccResourceShuffleCheckLength("5")), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.0", "a"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.1", "c"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.2", "b"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.3", "e"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.4", "d"), ), }, }, }) } -func TestAccResourceShuffleShorter(t *testing.T) { +func TestAccResourceShuffle_Shorter(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { - Config: testAccResourceShuffleConfigShorter, + Config: `resource "random_shuffle" "shorter_length" { + input = ["a", "b", "c", "d", "e"] + seed = "-" + result_count = 3 + }`, Check: resource.ComposeTestCheckFunc( - testAccResourceShuffleCheck( - "random_shuffle.shorter_length", - []string{"a", "c", "b"}, - ), + resource.TestCheckResourceAttrWith("random_shuffle.shorter_length", "result.#", testAccResourceShuffleCheckLength("3")), + resource.TestCheckResourceAttr("random_shuffle.shorter_length", "result.0", "a"), + resource.TestCheckResourceAttr("random_shuffle.shorter_length", "result.1", "c"), + resource.TestCheckResourceAttr("random_shuffle.shorter_length", "result.2", "b"), ), }, }, }) } -func TestAccResourceShuffleLonger(t *testing.T) { +func TestAccResourceShuffle_Longer(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { - Config: testAccResourceShuffleConfigLonger, + Config: `resource "random_shuffle" "longer_length" { + input = ["a", "b", "c", "d", "e"] + seed = "-" + result_count = 12 + }`, Check: resource.ComposeTestCheckFunc( - testAccResourceShuffleCheck( - "random_shuffle.longer_length", - []string{"a", "c", "b", "e", "d", "a", "e", "d", "c", "b", "a", "b"}, - ), + resource.TestCheckResourceAttrWith("random_shuffle.longer_length", "result.#", testAccResourceShuffleCheckLength("12")), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.0", "a"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.1", "c"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.2", "b"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.3", "e"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.4", "d"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.5", "a"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.6", "e"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.7", "d"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.8", "c"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.9", "b"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.10", "a"), + resource.TestCheckResourceAttr("random_shuffle.longer_length", "result.11", "b"), ), }, }, }) } -func TestAccResourceShuffleEmpty(t *testing.T) { +func TestAccResourceShuffle_Empty(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { - Config: testAccResourceShuffleConfigEmpty, + Config: `resource "random_shuffle" "empty_length" { + input = [] + seed = "-" + result_count = 12 + }`, Check: resource.ComposeTestCheckFunc( - testAccResourceShuffleCheck( - "random_shuffle.empty_length", - []string{}, - ), + resource.TestCheckResourceAttrWith("random_shuffle.empty_length", "result.#", testAccResourceShuffleCheckLength("0")), ), }, }, }) } -func TestAccResourceShuffleOne(t *testing.T) { +func TestAccResourceShuffle_One(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { - Config: testAccResourceShuffleConfigOne, + Config: `resource "random_shuffle" "one_length" { + input = ["a"] + seed = "-" + result_count = 1 + }`, Check: resource.ComposeTestCheckFunc( - testAccResourceShuffleCheck( - "random_shuffle.one_length", - []string{"a"}, - ), + resource.TestCheckResourceAttrWith("random_shuffle.one_length", "result.#", testAccResourceShuffleCheckLength("1")), + resource.TestCheckResourceAttr("random_shuffle.one_length", "result.0", "a"), ), }, }, }) } -func testAccResourceShuffleCheck(id string, wants []string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[id] - if !ok { - return fmt.Errorf("Not found: %s", id) - } - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - - attrs := rs.Primary.Attributes - - gotLen := attrs["result.#"] - wantLen := strconv.Itoa(len(wants)) - if gotLen != wantLen { - return fmt.Errorf("got %s result items; want %s", gotLen, wantLen) - } +func TestAccResourceShuffle_UpgradeFromVersion3_3_2(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion332(), + Config: `resource "random_shuffle" "default_length" { + input = ["a", "b", "c", "d", "e"] + seed = "-" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_shuffle.default_length", "result.#", testAccResourceShuffleCheckLength("5")), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.0", "a"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.1", "c"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.2", "b"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.3", "e"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.4", "d"), + ), + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_shuffle" "default_length" { + input = ["a", "b", "c", "d", "e"] + seed = "-" + }`, + PlanOnly: true, + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_shuffle" "default_length" { + input = ["a", "b", "c", "d", "e"] + seed = "-" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_shuffle.default_length", "result.#", testAccResourceShuffleCheckLength("5")), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.0", "a"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.1", "c"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.2", "b"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.3", "e"), + resource.TestCheckResourceAttr("random_shuffle.default_length", "result.4", "d"), + ), + }, + }, + }) +} - for i, want := range wants { - key := fmt.Sprintf("result.%d", i) - if got := attrs[key]; got != want { - return fmt.Errorf("index %d is %q; want %q", i, got, want) - } +func testAccResourceShuffleCheckLength(expectedLength string) func(input string) error { + return func(input string) error { + if input != expectedLength { + return fmt.Errorf("got length %s; expected length %s", input, expectedLength) } return nil } } - -const ( - testAccResourceShuffleConfigDefault = ` -resource "random_shuffle" "default_length" { - input = ["a", "b", "c", "d", "e"] - seed = "-" -}` - - testAccResourceShuffleConfigShorter = ` -resource "random_shuffle" "shorter_length" { - input = ["a", "b", "c", "d", "e"] - seed = "-" - result_count = 3 -} -` - - testAccResourceShuffleConfigLonger = ` -resource "random_shuffle" "longer_length" { - input = ["a", "b", "c", "d", "e"] - seed = "-" - result_count = 12 -} -` - - testAccResourceShuffleConfigEmpty = ` -resource "random_shuffle" "empty_length" { - input = [] - seed = "-" - result_count = 12 -} -` - - testAccResourceShuffleConfigOne = ` -resource "random_shuffle" "one_length" { - input = ["a"] - seed = "-" - result_count = 1 -} -` -) diff --git a/internal/provider/provider_resource_string_test.go b/internal/provider/provider_resource_string_test.go index 8bb5c0be..19fcdb36 100644 --- a/internal/provider/provider_resource_string_test.go +++ b/internal/provider/provider_resource_string_test.go @@ -10,7 +10,7 @@ import ( func TestAccResourceString(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_string" "basic" { @@ -29,9 +29,9 @@ func TestAccResourceString(t *testing.T) { }) } -func TestAccResourceStringOverride(t *testing.T) { +func TestAccResourceString_Override(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_string" "override" { @@ -50,9 +50,9 @@ func TestAccResourceStringOverride(t *testing.T) { }) } -func TestAccResourceStringMin(t *testing.T) { +func TestAccResourceString_Min(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_string" "min" { @@ -75,11 +75,11 @@ func TestAccResourceStringMin(t *testing.T) { }) } -// TestAccResourceString_StateUpgrade_V1toV2 covers the state upgrade from V1 to V2. +// TestAccResourceString_StateUpgradeV1toV2 covers the state upgrade from V1 to V2. // This includes the deprecation and removal of `number` and the addition of `numeric` attributes. // v3.2.0 was used as this is the last version before `number` was deprecated and `numeric` attribute // was added. -func TestAccResourceString_StateUpgrade_V1toV2(t *testing.T) { +func TestAccResourceString_StateUpgradeV1toV2(t *testing.T) { t.Parallel() cases := []struct { @@ -269,7 +269,7 @@ func TestAccResourceString_StateUpgrade_V1toV2(t *testing.T) { Check: resource.ComposeTestCheckFunc(c.beforeStateUpgrade...), }, { - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Config: c.configDuringUpgrade, Check: resource.ComposeTestCheckFunc(c.afterStateUpgrade...), }, @@ -279,9 +279,9 @@ func TestAccResourceString_StateUpgrade_V1toV2(t *testing.T) { } } -func TestAccResourceStringErrors(t *testing.T) { +func TestAccResourceString_LengthErrors(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { Config: `resource "random_string" "invalid_length" { @@ -300,6 +300,77 @@ func TestAccResourceStringErrors(t *testing.T) { }) } +func TestAccResourceString_UpgradeFromVersion3_3_2(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion332(), + Config: `resource "random_string" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_string.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_string.min", "special", "true"), + resource.TestCheckResourceAttr("random_string.min", "upper", "true"), + resource.TestCheckResourceAttr("random_string.min", "lower", "true"), + resource.TestCheckResourceAttr("random_string.min", "numeric", "true"), + resource.TestCheckResourceAttr("random_string.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_string.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_string.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_string.min", "min_numeric", "4"), + ), + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_string" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + PlanOnly: true, + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_string" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_string.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_string.min", "special", "true"), + resource.TestCheckResourceAttr("random_string.min", "upper", "true"), + resource.TestCheckResourceAttr("random_string.min", "lower", "true"), + resource.TestCheckResourceAttr("random_string.min", "numeric", "true"), + resource.TestCheckResourceAttr("random_string.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_string.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_string.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_string.min", "min_numeric", "4"), + ), + }, + }, + }) +} + func testCheckLen(expectedLen int) func(input string) error { return func(input string) error { if len(input) != expectedLen { @@ -310,6 +381,7 @@ func testCheckLen(expectedLen int) func(input string) error { } } +//nolint:unparam func testCheckMinLen(minLen int) func(input string) error { return func(input string) error { if len(input) < minLen { diff --git a/internal/provider/provider_resource_uuid_test.go b/internal/provider/provider_resource_uuid_test.go index 9643d7fd..94ec0577 100644 --- a/internal/provider/provider_resource_uuid_test.go +++ b/internal/provider/provider_resource_uuid_test.go @@ -9,16 +9,13 @@ import ( func TestAccResourceUUID(t *testing.T) { resource.UnitTest(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(), + ProtoV6ProviderFactories: protoV6ProviderFactories(), Steps: []resource.TestStep{ { - Config: testAccResourceUUIDConfig, + Config: `resource "random_uuid" "basic" { + }`, Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr( - "random_uuid.basic", - "result", - regexp.MustCompile(`[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}`), - ), + resource.TestMatchResourceAttr("random_uuid.basic", "result", regexp.MustCompile(`[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}`)), ), }, { @@ -30,9 +27,31 @@ func TestAccResourceUUID(t *testing.T) { }) } -const ( - testAccResourceUUIDConfig = ` -resource "random_uuid" "basic" { +func TestAccResourceUUID_UpgradeFromVersion3_3_2(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion332(), + Config: `resource "random_uuid" "basic" { + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestMatchResourceAttr("random_uuid.basic", "result", regexp.MustCompile(`[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}`)), + ), + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_uuid" "basic" { + }`, + PlanOnly: true, + }, + { + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Config: `resource "random_uuid" "basic" { + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestMatchResourceAttr("random_uuid.basic", "result", regexp.MustCompile(`[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}`)), + ), + }, + }, + }) } -` -) diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 46d1e872..90bdd00a 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -3,13 +3,23 @@ package provider import ( "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) //nolint:unparam -func testAccProtoV6ProviderFactories() map[string]func() (tfprotov6.ProviderServer, error) { +func protoV6ProviderFactories() map[string]func() (tfprotov6.ProviderServer, error) { return map[string]func() (tfprotov6.ProviderServer, error){ "random": func() (tfprotov6.ProviderServer, error) { return providerserver.NewProtocol6(NewProvider())(), nil }, } } + +func providerVersion332() map[string]resource.ExternalProvider { + return map[string]resource.ExternalProvider{ + "tls": { + VersionConstraint: "3.3.2", + Source: "hashicorp/random", + }, + } +} diff --git a/internal/random/random.go b/internal/random/random.go index 3bf98bc3..f3494050 100644 --- a/internal/random/random.go +++ b/internal/random/random.go @@ -6,7 +6,7 @@ import ( "sort" ) -type RandomStringParams struct { +type StringParams struct { Length int64 Upper bool MinUpper int64 @@ -19,7 +19,7 @@ type RandomStringParams struct { OverrideSpecial string } -func CreateRandomString(input RandomStringParams) ([]byte, error) { +func CreateString(input StringParams) ([]byte, error) { const numChars = "0123456789" const lowerChars = "abcdefghijklmnopqrstuvwxyz" const upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/internal/resources/password/resource.go b/internal/resources/password/resource.go index f874bbf8..55fa930c 100644 --- a/internal/resources/password/resource.go +++ b/internal/resources/password/resource.go @@ -45,7 +45,7 @@ func (r *resource) Create(ctx context.Context, req tfsdk.CreateResourceRequest, return } - params := random.RandomStringParams{ + params := random.StringParams{ Length: plan.Length.Value, Upper: plan.Upper.Value, MinUpper: plan.MinUpper.Value, @@ -58,7 +58,7 @@ func (r *resource) Create(ctx context.Context, req tfsdk.CreateResourceRequest, OverrideSpecial: plan.OverrideSpecial.Value, } - result, err := random.CreateRandomString(params) + result, err := random.CreateString(params) if err != nil { resp.Diagnostics.Append(diagnostics.RandomReadError(err.Error())...) return diff --git a/internal/resources/string/resource.go b/internal/resources/stringresource/resource.go similarity index 67% rename from internal/resources/string/resource.go rename to internal/resources/stringresource/resource.go index d56bf199..45a98aa2 100644 --- a/internal/resources/string/resource.go +++ b/internal/resources/stringresource/resource.go @@ -1,4 +1,4 @@ -package string +package stringresource import ( "context" @@ -24,7 +24,159 @@ var _ tfsdk.ResourceType = (*resourceType)(nil) type resourceType struct{} func (r resourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { - return schemaV2(), nil + return tfsdk.Schema{ + Version: 2, + Description: "The resource `random_string` generates a random permutation of alphanumeric " + + "characters and optionally special characters.\n" + + "\n" + + "This resource *does* use a cryptographic random number generator.\n" + + "\n" + + "Historically this resource's intended usage has been ambiguous as the original example used " + + "it in a password. For backwards compatibility it will continue to exist. For unique ids please " + + "use [random_id](id.html), for sensitive random values please use [random_password](password.html).", + Attributes: map[string]tfsdk.Attribute{ + "keepers": { + Description: "Arbitrary map of values that, when changed, will trigger recreation of " + + "resource. See [the main provider documentation](../index.html) for more information.", + Type: types.MapType{ + ElemType: types.StringType, + }, + Optional: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + tfsdk.RequiresReplace(), + }, + }, + + "length": { + Description: "The length of the stringresource desired. The minimum value for length is 1 and, length " + + "must also be >= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).", + Type: types.Int64Type, + Required: true, + PlanModifiers: []tfsdk.AttributePlanModifier{tfsdk.RequiresReplace()}, + Validators: []tfsdk.AttributeValidator{ + int64validator.AtLeast(1), + validators.NewIntIsAtLeastSumOfValidator( + tftypes.NewAttributePath().WithAttributeName("min_upper"), + tftypes.NewAttributePath().WithAttributeName("min_lower"), + tftypes.NewAttributePath().WithAttributeName("min_numeric"), + tftypes.NewAttributePath().WithAttributeName("min_special"), + ), + }, + }, + + "special": { + Description: "Include special characters in the result. These are `!@#$%&*()-_=+[]{}<>:?`. Default value is `true`.", + Type: types.BoolType, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Bool{Value: true}), + planmodifiers.RequiresReplace(), + }, + }, + + "upper": { + Description: "Include uppercase alphabet characters in the result. Default value is `true`.", + Type: types.BoolType, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Bool{Value: true}), + planmodifiers.RequiresReplace(), + }, + }, + + "lower": { + Description: "Include lowercase alphabet characters in the result. Default value is `true`.", + Type: types.BoolType, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Bool{Value: true}), + planmodifiers.RequiresReplace(), + }, + }, + + "numeric": { + Description: "Include numeric characters in the result. Default value is `true`.", + Type: types.BoolType, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Bool{Value: true}), + planmodifiers.RequiresReplace(), + }, + }, + + "min_numeric": { + Description: "Minimum number of numeric characters in the result. Default value is `0`.", + Type: types.Int64Type, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Int64{Value: 0}), + planmodifiers.RequiresReplace(), + }, + }, + + "min_upper": { + Description: "Minimum number of uppercase alphabet characters in the result. Default value is `0`.", + Type: types.Int64Type, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Int64{Value: 0}), + planmodifiers.RequiresReplace(), + }, + }, + + "min_lower": { + Description: "Minimum number of lowercase alphabet characters in the result. Default value is `0`.", + Type: types.Int64Type, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Int64{Value: 0}), + planmodifiers.RequiresReplace(), + }, + }, + + "min_special": { + Description: "Minimum number of special characters in the result. Default value is `0`.", + Type: types.Int64Type, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + planmodifiers.DefaultValue(types.Int64{Value: 0}), + planmodifiers.RequiresReplace(), + }, + }, + + "override_special": { + Description: "Supply your own list of special characters to use for stringresource generation. This " + + "overrides the default character list in the special argument. The `special` argument must " + + "still be set to true for any overwritten characters to be used in generation.", + Type: types.StringType, + Optional: true, + Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + tfsdk.RequiresReplace(), + }, + }, + + "result": { + Description: "The generated random stringresource.", + Type: types.StringType, + Computed: true, + }, + + "id": { + Description: "The generated random stringresource.", + Computed: true, + Type: types.StringType, + }, + }, + }, nil } func (r resourceType) NewResource(_ context.Context, p tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) { @@ -48,7 +200,7 @@ func (r *resource) Create(ctx context.Context, req tfsdk.CreateResourceRequest, return } - params := random.RandomStringParams{ + params := random.StringParams{ Length: plan.Length.Value, Upper: plan.Upper.Value, MinUpper: plan.MinUpper.Value, @@ -61,7 +213,7 @@ func (r *resource) Create(ctx context.Context, req tfsdk.CreateResourceRequest, OverrideSpecial: plan.OverrideSpecial.Value, } - result, err := random.CreateRandomString(params) + result, err := random.CreateString(params) if err != nil { resp.Diagnostics.Append(diagnostics.RandomReadError(err.Error())...) return @@ -155,7 +307,7 @@ func (r *resource) UpgradeState(context.Context) map[int64]tfsdk.ResourceStateUp }, "length": { - Description: "The length of the string desired. The minimum value for length is 1 and, length " + + Description: "The length of the stringresource desired. The minimum value for length is 1 and, length " + "must also be >= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).", Type: types.Int64Type, Required: true, @@ -260,7 +412,7 @@ func (r *resource) UpgradeState(context.Context) map[int64]tfsdk.ResourceStateUp }, "override_special": { - Description: "Supply your own list of special characters to use for string generation. This " + + Description: "Supply your own list of special characters to use for stringresource generation. This " + "overrides the default character list in the special argument. The `special` argument must " + "still be set to true for any overwritten characters to be used in generation.", Type: types.StringType, @@ -272,13 +424,13 @@ func (r *resource) UpgradeState(context.Context) map[int64]tfsdk.ResourceStateUp }, "result": { - Description: "The generated random string.", + Description: "The generated random stringresource.", Type: types.StringType, Computed: true, }, "id": { - Description: "The generated random string.", + Description: "The generated random stringresource.", Computed: true, Type: types.StringType, }, diff --git a/internal/resources/uuid/resource_uuid.go b/internal/resources/uuid/resource.go similarity index 100% rename from internal/resources/uuid/resource_uuid.go rename to internal/resources/uuid/resource.go