Skip to content

Commit 05cc76d

Browse files
chore: Adjust tests creating free tier cluster to have dedicated project (#3596)
* adjust tests creating free tier cluster to have dedicated project * adding comment * refactor ProjectIDExecutionWithCluster to contemplate restriction of free tier clusters * separate function to avoid making ProjectIDExecutionWithCluster more complex
1 parent 0907017 commit 05cc76d

File tree

4 files changed

+43
-38
lines changed

4 files changed

+43
-38
lines changed

internal/service/advancedcluster/resource_advanced_cluster_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,8 @@ func TestGetReplicationSpecAttributesFromOldAPI(t *testing.T) {
122122
}
123123
}
124124

125-
func testAccAdvancedClusterFlexUpgrade(t *testing.T, instanceSize string, includeDedicated bool) resource.TestCase {
125+
func testAccAdvancedClusterFlexUpgrade(t *testing.T, projectID, clusterName, instanceSize string, includeDedicated bool) resource.TestCase {
126126
t.Helper()
127-
projectID, clusterName := acc.ProjectIDExecutionWithCluster(t, 1)
128127
defaultZoneName := "Zone 1" // Uses backend default as in existing tests
129128

130129
// avoid checking plural data source to reduce risk of being impacted from failure in other test using same project, allows running in parallel
@@ -154,15 +153,17 @@ func testAccAdvancedClusterFlexUpgrade(t *testing.T, instanceSize string, includ
154153
}
155154

156155
func TestAccAdvancedCluster_basicTenant_flexUpgrade_dedicatedUpgrade(t *testing.T) {
157-
resource.ParallelTest(t, testAccAdvancedClusterFlexUpgrade(t, freeInstanceSize, true))
156+
projectID, clusterName := acc.ProjectIDExecutionWithFreeCluster(t, 3, 1)
157+
resource.ParallelTest(t, testAccAdvancedClusterFlexUpgrade(t, projectID, clusterName, freeInstanceSize, true))
158158
}
159159

160160
func TestAccAdvancedCluster_sharedTier_flexUpgrade(t *testing.T) {
161-
resource.ParallelTest(t, testAccAdvancedClusterFlexUpgrade(t, sharedInstanceSize, false))
161+
projectID, clusterName := acc.ProjectIDExecutionWithCluster(t, 1)
162+
resource.ParallelTest(t, testAccAdvancedClusterFlexUpgrade(t, projectID, clusterName, sharedInstanceSize, false))
162163
}
163164
func TestAccMockableAdvancedCluster_tenantUpgrade(t *testing.T) {
164165
var (
165-
projectID, clusterName = acc.ProjectIDExecutionWithCluster(t, 1)
166+
projectID, clusterName = acc.ProjectIDExecutionWithFreeCluster(t, 3, 1)
166167
defaultZoneName = "Zone 1" // Uses backend default to avoid non-empty plan, see CLOUDP-294339
167168
)
168169
unit.CaptureOrMockTestCaseAndRun(t, mockConfig, &resource.TestCase{

internal/testutil/acc/atlas.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,6 @@ func createStreamInstance(tb testing.TB, projectID, name string) {
104104
require.NoError(tb, err, "Stream instance creation failed: %s, err: %s", name, err)
105105
}
106106

107-
// ProjectID returns the id for a project name.
108-
// When `MONGODB_ATLAS_PROJECT_ID` is defined, it is used instead of creating a project. This is useful for local execution but not intended for CI executions.
109-
func ProjectID(tb testing.TB, name string) string {
110-
tb.Helper()
111-
SkipInUnitTest(tb)
112-
113-
if id := projectIDLocal(); id != "" {
114-
return id
115-
}
116-
117-
resp, _, _ := ConnV2().ProjectsApi.GetProjectByName(tb.Context(), name).Execute()
118-
id := resp.GetId()
119-
require.NotEmpty(tb, id, "Project name not found: %s", name)
120-
return id
121-
}
122-
123107
func projectIDLocal() string {
124108
return os.Getenv("MONGODB_ATLAS_PROJECT_ID")
125109
}

internal/testutil/acc/shared_resource.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515

1616
const (
1717
MaxClusterNodesPerProject = 30 // Choose to be conservative, 40 clusters per project is the limit before `CROSS_REGION_NETWORK_PERMISSIONS_LIMIT_EXCEEDED` error, see https://www.mongodb.com/docs/atlas/reference/atlas-limits/
18+
MaxFreeTierClusterCount = 1 // Project can have at most 1 free tier cluster
1819
)
1920

2021
// SetupSharedResources must be called from TestMain test package in order to use ProjectIDExecution.
@@ -79,23 +80,29 @@ func ProjectIDExecution(tb testing.TB) string {
7980
return sharedInfo.projectID
8081
}
8182

82-
// ProjectIDExecutionWithCluster creates a project and reuses it for `MaxClusterNodesPerProject ` nodes. The clusterName is always unique.
83-
// TotalNodeCount = sum(specs.node_count) * num_shards (1 if new schema)
84-
// This avoids the `CROSS_REGION_NETWORK_PERMISSIONS_LIMIT_EXCEEDED` error when creating too many clusters within the same project.
85-
// When `MONGODB_ATLAS_PROJECT_ID` and `MONGODB_ATLAS_CLUSTER_NAME` are defined, they are used instead of creating a project and clusterName.
86-
func ProjectIDExecutionWithCluster(tb testing.TB, totalNodeCount int) (projectID, clusterName string) {
83+
// ProjectIDExecutionWithFreeCluster is identical to ProjectIDExecutionWithCluster but also contemplates the restriction of `MaxFreeTierClusterCount`
84+
func ProjectIDExecutionWithFreeCluster(tb testing.TB, totalNodeCount, freeTierClusterCount int) (projectID, clusterName string) {
8785
tb.Helper()
8886
if ExistingClusterUsed() {
8987
return existingProjectIDClusterName()
9088
}
9189
// Only skip after ExistingClusterUsed() to allow MacT (Mocked-Acceptance Tests) to return early instead of being skipped.
9290
SkipInUnitTest(tb)
9391
require.True(tb, sharedInfo.init, "SetupSharedResources must called from TestMain test package")
94-
return NextProjectIDClusterName(totalNodeCount, func(projectName string) string {
92+
return NextProjectIDClusterName(totalNodeCount, freeTierClusterCount, func(projectName string) string {
9593
return createProject(tb, projectName)
9694
})
9795
}
9896

97+
// ProjectIDExecutionWithCluster creates a project and reuses it with other tests respecting `MaxClusterNodesPerProject` restrictions. The clusterName is always unique.
98+
// TotalNodeCount = sum(specs.node_count) * num_shards (1 if new schema)
99+
// This avoids `CROSS_REGION_NETWORK_PERMISSIONS_LIMIT_EXCEEDED` and `project has reached the limit for the number of free clusters` errors when creating too many clusters within the same project.
100+
// When `MONGODB_ATLAS_PROJECT_ID` and `MONGODB_ATLAS_CLUSTER_NAME` are defined, they are used instead of creating a project and clusterName.
101+
func ProjectIDExecutionWithCluster(tb testing.TB, totalNodeCount int) (projectID, clusterName string) {
102+
tb.Helper()
103+
return ProjectIDExecutionWithFreeCluster(tb, totalNodeCount, 0)
104+
}
105+
99106
// ClusterNameExecution returns the name of a created cluster for the execution of the tests in the resource package.
100107
// This function relies on using an execution project and returns its id.
101108
// When `MONGODB_ATLAS_CLUSTER_NAME` and `MONGODB_ATLAS_PROJECT_ID` are defined it will be used instead of creating resources. This is useful for local execution but not intended for CI executions.
@@ -171,9 +178,10 @@ func SerialSleep(tb testing.TB) {
171178
}
172179

173180
type projectInfo struct {
174-
id string
175-
name string
176-
nodeCount int
181+
id string
182+
name string
183+
nodeCount int
184+
freeTierClusterCount int
177185
}
178186

179187
var sharedInfo = struct {
@@ -189,12 +197,14 @@ var sharedInfo = struct {
189197
projects: []projectInfo{},
190198
}
191199

192-
// NextProjectIDClusterName is an internal method used when we want to reuse a projectID `MaxClustersPerProject` times
193-
func NextProjectIDClusterName(totalNodeCount int, projectCreator func(string) string) (projectID, clusterName string) {
200+
// NextProjectIDClusterName is an internal method used when we want to reuse a projectID respecting `MaxClustersNodesPerProject` and `MaxFreeTierClusterCount`
201+
func NextProjectIDClusterName(totalNodeCount, freeTierClusterCount int, projectCreator func(string) string) (projectID, clusterName string) {
194202
sharedInfo.mu.Lock()
195203
defer sharedInfo.mu.Unlock()
196204
var project projectInfo
197-
if len(sharedInfo.projects) == 0 || sharedInfo.projects[len(sharedInfo.projects)-1].nodeCount+totalNodeCount > MaxClusterNodesPerProject {
205+
if len(sharedInfo.projects) == 0 ||
206+
sharedInfo.projects[len(sharedInfo.projects)-1].nodeCount+totalNodeCount > MaxClusterNodesPerProject ||
207+
sharedInfo.projects[len(sharedInfo.projects)-1].freeTierClusterCount+freeTierClusterCount > MaxFreeTierClusterCount {
198208
project = projectInfo{
199209
name: RandomProjectName(),
200210
nodeCount: totalNodeCount,
@@ -204,6 +214,7 @@ func NextProjectIDClusterName(totalNodeCount int, projectCreator func(string) st
204214
} else {
205215
project = sharedInfo.projects[len(sharedInfo.projects)-1]
206216
sharedInfo.projects[len(sharedInfo.projects)-1].nodeCount += totalNodeCount
217+
sharedInfo.projects[len(sharedInfo.projects)-1].freeTierClusterCount += freeTierClusterCount
207218
}
208219
return project.id, RandomClusterName()
209220
}

internal/testutil/acc/shared_resource_test.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,29 @@ func Test_NextProjectIDClusterName(t *testing.T) {
1515
projectIDs := map[string]int{}
1616
clusterNames := map[string]int{}
1717

18-
addProjectIDClusterName := func(nodeCount int) {
19-
projectID, clusterName := acc.NextProjectIDClusterName(nodeCount, projectIDReturner)
18+
addProjectIDClusterName := func(nodeCount int, freeTierClusterCount int) {
19+
projectID, clusterName := acc.NextProjectIDClusterName(nodeCount, freeTierClusterCount, projectIDReturner)
2020
projectIDs[projectID]++
2121
clusterNames[clusterName]++
2222
}
2323
for range acc.MaxClusterNodesPerProject {
24-
addProjectIDClusterName(1)
24+
addProjectIDClusterName(1, 0)
2525
}
2626
assert.Len(t, projectIDs, 1)
2727
assert.Len(t, clusterNames, acc.MaxClusterNodesPerProject)
28-
addProjectIDClusterName(1)
28+
addProjectIDClusterName(1, 0)
2929
assert.Len(t, projectIDs, 2)
3030
assert.Len(t, clusterNames, acc.MaxClusterNodesPerProject+1)
31-
addProjectIDClusterName(acc.MaxClusterNodesPerProject)
31+
addProjectIDClusterName(acc.MaxClusterNodesPerProject, 0)
3232
assert.Len(t, projectIDs, 3)
3333
assert.Len(t, clusterNames, acc.MaxClusterNodesPerProject+2)
34+
addProjectIDClusterName(1, 0)
35+
assert.Len(t, projectIDs, 4)
36+
assert.Len(t, clusterNames, acc.MaxClusterNodesPerProject+3)
37+
addProjectIDClusterName(0, 1) // adds free tier, shares existing project
38+
assert.Len(t, projectIDs, 4)
39+
assert.Len(t, clusterNames, acc.MaxClusterNodesPerProject+4)
40+
addProjectIDClusterName(0, 1) // second free tier cluster creates a new project
41+
assert.Len(t, projectIDs, 5)
42+
assert.Len(t, clusterNames, acc.MaxClusterNodesPerProject+5)
3443
}

0 commit comments

Comments
 (0)