Skip to content

Commit

Permalink
test: Refactors resource tests to use GetClusterInfo `federated_datab…
Browse files Browse the repository at this point in the history
…ase_instance` (#2412)

* test: Support getting cluster info with project

* test: Refactors resource tests to use GetClusterInfo `federated_database_instance`

* test: refactor, use a single GetClusterInfo and support AddDefaults

* test: use renamed argument in test
  • Loading branch information
EspenAlbert authored Jul 15, 2024
1 parent 3110a52 commit 6674f82
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,23 @@ func TestAccFederatedDatabaseInstance_s3bucket(t *testing.T) {

func TestAccFederatedDatabaseInstance_atlasCluster(t *testing.T) {
var (
resourceName = "mongodbatlas_federated_database_instance.test"
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
projectName = acc.RandomProjectName()
clusterName1 = acc.RandomClusterName()
clusterName2 = acc.RandomClusterName()
name = acc.RandomName()
specs = []acc.ReplicationSpecRequest{
{Region: "EU_WEST_2"},
}
clusterRequest = acc.ClusterRequest{
ReplicationSpecs: specs,
}
resourceName = "mongodbatlas_federated_database_instance.test"
name = acc.RandomName()
clusterInfo = acc.GetClusterInfo(t, &clusterRequest)
projectID = clusterInfo.ProjectID
clusterRequest2 = acc.ClusterRequest{
ProjectID: projectID,
ReplicationSpecs: specs,
ResourceSuffix: "cluster2",
}
cluster2Info = acc.GetClusterInfo(t, &clusterRequest2)
dependencyTerraform = fmt.Sprintf("%s\n%s", clusterInfo.ClusterTerraformStr, cluster2Info.ClusterTerraformStr)
)

resource.ParallelTest(t, resource.TestCase{
Expand All @@ -127,7 +138,7 @@ func TestAccFederatedDatabaseInstance_atlasCluster(t *testing.T) {
Steps: []resource.TestStep{
{
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
Config: configWithCluster(orgID, projectName, clusterName1, clusterName2, name),
Config: configWithCluster(dependencyTerraform, projectID, clusterInfo.ClusterResourceName, cluster2Info.ClusterResourceName, name),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttr(resourceName, "name", name),
Expand All @@ -140,34 +151,12 @@ func TestAccFederatedDatabaseInstance_atlasCluster(t *testing.T) {
})
}

func configWithCluster(orgID, projectName, clusterName1, clusterName2, name string) string {
func configWithCluster(terraformStr, projectID, cluster1ResourceName, cluster2ResourceName, name string) string {
return fmt.Sprintf(`
resource "mongodbatlas_project" "project-tf" {
org_id = %[1]q
name = %[2]q
}
resource "mongodbatlas_cluster" "cluster-1" {
project_id = mongodbatlas_project.project-tf.id
provider_name = "AWS"
name = %[3]q
backing_provider_name = "AWS"
provider_region_name = "EU_WEST_2"
provider_instance_size_name = "M10"
}
resource "mongodbatlas_cluster" "cluster-2" {
project_id = mongodbatlas_project.project-tf.id
provider_name = "AWS"
name = %[4]q
backing_provider_name = "AWS"
provider_region_name = "EU_WEST_2"
provider_instance_size_name = "M10"
}
%[1]s
resource "mongodbatlas_federated_database_instance" "test" {
project_id = mongodbatlas_project.project-tf.id
project_id = %[2]q
name = %[5]q
storage_databases {
name = "VirtualDatabase0"
Expand All @@ -176,21 +165,21 @@ func configWithCluster(orgID, projectName, clusterName1, clusterName2, name stri
data_sources {
collection = "listingsAndReviews"
database = "sample_airbnb"
store_name = mongodbatlas_cluster.cluster-1.name
store_name = %[3]s.name
}
data_sources {
collection = "listingsAndReviews"
database = "sample_airbnb"
store_name = mongodbatlas_cluster.cluster-2.name
store_name = %[4]s.name
}
}
}
storage_stores {
name = mongodbatlas_cluster.cluster-1.name
cluster_name = mongodbatlas_cluster.cluster-1.name
project_id = mongodbatlas_project.project-tf.id
name = %[3]s.name
cluster_name = %[3]s.name
project_id = %[2]q
provider = "atlas"
read_preference {
mode = "secondary"
Expand Down Expand Up @@ -218,9 +207,9 @@ func configWithCluster(orgID, projectName, clusterName1, clusterName2, name stri
}
storage_stores {
name = mongodbatlas_cluster.cluster-2.name
cluster_name = mongodbatlas_cluster.cluster-2.name
project_id = mongodbatlas_project.project-tf.id
name = %[4]s.name
cluster_name = %[4]s.name
project_id = %[2]q
provider = "atlas"
read_preference {
mode = "secondary"
Expand All @@ -247,7 +236,7 @@ func configWithCluster(orgID, projectName, clusterName1, clusterName2, name stri
}
}
}
`, orgID, projectName, clusterName1, clusterName2, name)
`, terraformStr, projectID, cluster1ResourceName, cluster2ResourceName, name)
}

func importStateIDFuncS3Bucket(resourceName, s3Bucket string) resource.ImportStateIdFunc {
Expand Down
53 changes: 36 additions & 17 deletions internal/testutil/acc/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ import (

type ClusterRequest struct {
Tags map[string]string
ProjectID string
ResourceSuffix string
ResourceDependencyName string
ClusterNameExplicit string
ClusterName string
ReplicationSpecs []ReplicationSpecRequest
DiskSizeGb int
CloudBackup bool
Geosharded bool
PitEnabled bool
}

func (r *ClusterRequest) AddDefaults() {
if r.ResourceSuffix == "" {
r.ResourceSuffix = defaultClusterResourceSuffix
}
if len(r.ReplicationSpecs) == 0 {
r.ReplicationSpecs = []ReplicationSpecRequest{{}}
}
if r.ClusterName == "" {
r.ClusterName = RandomClusterName()
}
}

type ClusterInfo struct {
ProjectIDStr string
ProjectID string
Expand All @@ -29,6 +43,8 @@ type ClusterInfo struct {
ClusterTerraformStr string
}

const defaultClusterResourceSuffix = "cluster_info"

// GetClusterInfo is used to obtain a project and cluster configuration resource.
// When `MONGODB_ATLAS_CLUSTER_NAME` and `MONGODB_ATLAS_PROJECT_ID` are defined, creation of resources is avoided. This is useful for local execution but not intended for CI executions.
// Clusters will be created in project ProjectIDExecution.
Expand All @@ -37,26 +53,26 @@ func GetClusterInfo(tb testing.TB, req *ClusterRequest) ClusterInfo {
if req == nil {
req = new(ClusterRequest)
}
clusterName := os.Getenv("MONGODB_ATLAS_CLUSTER_NAME")
projectID := os.Getenv("MONGODB_ATLAS_PROJECT_ID")
if clusterName != "" && projectID != "" {
return ClusterInfo{
ProjectIDStr: fmt.Sprintf("%q", projectID),
ProjectID: projectID,
ClusterName: clusterName,
ClusterNameStr: fmt.Sprintf("%q", clusterName),
ClusterTerraformStr: "",
if req.ProjectID == "" {
if ExistingClusterUsed() {
projectID, clusterName := existingProjectIDClusterName()
return ClusterInfo{
ProjectIDStr: fmt.Sprintf("%q", projectID),
ProjectID: projectID,
ClusterName: clusterName,
ClusterNameStr: fmt.Sprintf("%q", clusterName),
ClusterTerraformStr: "",
}
}
req.ProjectID = ProjectIDExecution(tb)
}
projectID = ProjectIDExecution(tb)
clusterTerraformStr, clusterName, err := ClusterResourceHcl(projectID, req)
clusterTerraformStr, clusterName, clusterResourceName, err := ClusterResourceHcl(req)
if err != nil {
tb.Error(err)
}
clusterResourceName := "mongodbatlas_advanced_cluster.cluster_info"
return ClusterInfo{
ProjectIDStr: fmt.Sprintf("%q", projectID),
ProjectID: projectID,
ProjectIDStr: fmt.Sprintf("%q", req.ProjectID),
ProjectID: req.ProjectID,
ClusterName: clusterName,
ClusterNameStr: fmt.Sprintf("%s.name", clusterResourceName),
ClusterResourceName: clusterResourceName,
Expand All @@ -65,11 +81,14 @@ func GetClusterInfo(tb testing.TB, req *ClusterRequest) ClusterInfo {
}

func ExistingClusterUsed() bool {
clusterName := os.Getenv("MONGODB_ATLAS_CLUSTER_NAME")
projectID := os.Getenv("MONGODB_ATLAS_PROJECT_ID")
projectID, clusterName := existingProjectIDClusterName()
return clusterName != "" && projectID != ""
}

func existingProjectIDClusterName() (projectID, clusterName string) {
return os.Getenv("MONGODB_ATLAS_PROJECT_ID"), os.Getenv("MONGODB_ATLAS_CLUSTER_NAME")
}

type ReplicationSpecRequest struct {
ZoneName string
Region string
Expand Down
31 changes: 15 additions & 16 deletions internal/testutil/acc/config_formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package acc

import (
"encoding/json"
"errors"
"fmt"
"regexp"
"sort"
Expand Down Expand Up @@ -75,32 +76,29 @@ func ToSnakeCase(str string) string {
return strings.ToLower(snake)
}

func ClusterResourceHcl(projectID string, req *ClusterRequest) (configStr, clusterName string, err error) {
if req == nil {
req = new(ClusterRequest)
func ClusterResourceHcl(req *ClusterRequest) (configStr, clusterName, resourceName string, err error) {
if req == nil || req.ProjectID == "" {
return "", "", "", errors.New("must specify a ClusterRequest with at least ProjectID set")
}
req.AddDefaults()
specRequests := req.ReplicationSpecs
if len(specRequests) == 0 {
specRequests = append(specRequests, ReplicationSpecRequest{})
}
specs := make([]admin.ReplicationSpec, len(specRequests))
for i, specRequest := range specRequests {
specs[i] = ReplicationSpec(&specRequest)
}
clusterName = req.ClusterNameExplicit
if clusterName == "" {
clusterName = RandomClusterName()
}
clusterName = req.ClusterName
resourceSuffix := req.ResourceSuffix
clusterTypeStr := "REPLICASET"
if req.Geosharded {
clusterTypeStr = "GEOSHARDED"
}

f := hclwrite.NewEmptyFile()
root := f.Body()
cluster := root.AppendNewBlock("resource", []string{"mongodbatlas_advanced_cluster", "cluster_info"}).Body()
resourceType := "mongodbatlas_advanced_cluster"
cluster := root.AppendNewBlock("resource", []string{resourceType, resourceSuffix}).Body()
clusterRootAttributes := map[string]any{
"project_id": projectID,
"project_id": req.ProjectID,
"cluster_type": clusterTypeStr,
"name": clusterName,
"backup_enabled": req.CloudBackup,
Expand All @@ -114,7 +112,7 @@ func ClusterResourceHcl(projectID string, req *ClusterRequest) (configStr, clust
for i, spec := range specs {
err = writeReplicationSpec(cluster, spec)
if err != nil {
return "", "", fmt.Errorf("error writing hcl for replication spec %d: %w", i, err)
return "", "", "", fmt.Errorf("error writing hcl for replication spec %d: %w", i, err)
}
}
if len(req.Tags) > 0 {
Expand All @@ -128,14 +126,15 @@ func ClusterResourceHcl(projectID string, req *ClusterRequest) (configStr, clust
cluster.AppendNewline()
if req.ResourceDependencyName != "" {
if !strings.Contains(req.ResourceDependencyName, ".") {
return "", "", fmt.Errorf("req.ResourceDependencyName must have a '.'")
return "", "", "", fmt.Errorf("req.ResourceDependencyName must have a '.'")
}
err = setAttributeHcl(cluster, fmt.Sprintf("depends_on = [%s]", req.ResourceDependencyName))
if err != nil {
return "", "", err
return "", "", "", err
}
}
return "\n" + string(f.Bytes()), clusterName, err
clusterResourceName := fmt.Sprintf("%s.%s", resourceType, resourceSuffix)
return "\n" + string(f.Bytes()), clusterName, clusterResourceName, err
}

func writeReplicationSpec(cluster *hclwrite.Body, spec admin.ReplicationSpec) error {
Expand Down
19 changes: 11 additions & 8 deletions internal/testutil/acc/config_formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,32 +355,32 @@ func Test_ClusterResourceHcl(t *testing.T) {
}{
"defaults": {
standardClusterResource,
acc.ClusterRequest{ClusterNameExplicit: clusterName},
acc.ClusterRequest{ClusterName: clusterName},
},
"dependsOn": {
dependsOnClusterResource,
acc.ClusterRequest{ClusterNameExplicit: clusterName, ResourceDependencyName: "mongodbatlas_project.project_execution"},
acc.ClusterRequest{ClusterName: clusterName, ResourceDependencyName: "mongodbatlas_project.project_execution"},
},
"dependsOnMulti": {
dependsOnMultiResource,
acc.ClusterRequest{ClusterNameExplicit: clusterName, ResourceDependencyName: "mongodbatlas_private_endpoint_regional_mode.atlasrm, mongodbatlas_privatelink_endpoint_service.atlasple"},
acc.ClusterRequest{ClusterName: clusterName, ResourceDependencyName: "mongodbatlas_private_endpoint_regional_mode.atlasrm, mongodbatlas_privatelink_endpoint_service.atlasple"},
},
"twoReplicationSpecs": {
twoReplicationSpecs,
acc.ClusterRequest{ClusterNameExplicit: clusterName, ReplicationSpecs: []acc.ReplicationSpecRequest{
acc.ClusterRequest{ClusterName: clusterName, ReplicationSpecs: []acc.ReplicationSpecRequest{
{Region: "US_WEST_1", ZoneName: "Zone 1"},
{Region: "EU_WEST_2", ZoneName: "Zone 2"},
}},
},
"overrideClusterResource": {
overrideClusterResource,
acc.ClusterRequest{ClusterNameExplicit: clusterName, Geosharded: true, PitEnabled: true, CloudBackup: true, ReplicationSpecs: []acc.ReplicationSpecRequest{
acc.ClusterRequest{ClusterName: clusterName, Geosharded: true, PitEnabled: true, CloudBackup: true, ReplicationSpecs: []acc.ReplicationSpecRequest{
{Region: "MY_REGION_1", ZoneName: "Zone X", InstanceSize: "M30", NodeCount: 30, ProviderName: constant.AZURE},
}},
},
"twoRegionConfigs": {
twoRegionConfigs,
acc.ClusterRequest{ClusterNameExplicit: clusterName, ReplicationSpecs: []acc.ReplicationSpecRequest{
acc.ClusterRequest{ClusterName: clusterName, ReplicationSpecs: []acc.ReplicationSpecRequest{
{
Region: "US_WEST_1",
InstanceSize: "M10",
Expand All @@ -392,7 +392,7 @@ func Test_ClusterResourceHcl(t *testing.T) {
},
"autoScalingDiskEnabled": {
autoScalingDiskEnabled,
acc.ClusterRequest{ClusterNameExplicit: clusterName, Tags: map[string]string{
acc.ClusterRequest{ClusterName: clusterName, Tags: map[string]string{
"ArchiveTest": "true", "Owner": "test",
}, ReplicationSpecs: []acc.ReplicationSpecRequest{
{AutoScalingDiskGbEnabled: true},
Expand All @@ -402,8 +402,11 @@ func Test_ClusterResourceHcl(t *testing.T) {
)
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
config, actualClusterName, err := acc.ClusterResourceHcl("project", &tc.req)
req := tc.req
req.ProjectID = "project"
config, actualClusterName, actualResourceName, err := acc.ClusterResourceHcl(&req)
require.NoError(t, err)
assert.Equal(t, "mongodbatlas_advanced_cluster.cluster_info", actualResourceName)
assert.Equal(t, clusterName, actualClusterName)
assert.Equal(t, tc.expected, config)
})
Expand Down

0 comments on commit 6674f82

Please sign in to comment.