Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Refactors resource tests to use GetClusterInfo federated_database_instance #2412

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to another PR, what about pass clusterInfo to configWithCluster?

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would favour defining as a pointer so it is clear that property is optional, however I see the same applies to all other properties in this struct. Maybe a comment top level of the struct clarifying all properties are optional can be an option as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would keep strings (with empty being optional), but agree a comment can help

Copy link
Collaborator Author

@EspenAlbert EspenAlbert Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea!
Added to list in https://jira.mongodb.org/browse/CLOUDP-260997

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