Skip to content

Commit 2236dd4

Browse files
committed
address feedback: hashing, file exists check, cache clean up
1 parent 3a9e0b3 commit 2236dd4

File tree

1 file changed

+53
-16
lines changed

1 file changed

+53
-16
lines changed

provisioner/terraform/provision_test.go

+53-16
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,28 @@ func hashTemplateFilesAndTestName(t *testing.T, testName string, templateFiles m
100100
}
101101
sort.Strings(sortedFileNames)
102102

103+
// Inserting a delimiter between the file name and the file content
104+
// ensures that a file named `ab` with content `cd`
105+
// will not hash to the same value as a file named `abc` with content `d`.
106+
// This can still happen if the file name or content include the delimiter,
107+
// but hopefully they won't.
108+
delimiter := []byte("🎉 🌱 🌷")
109+
103110
hasher := sha256.New()
104111
for _, fileName := range sortedFileNames {
105112
file := templateFiles[fileName]
106113
_, err := hasher.Write([]byte(fileName))
107114
require.NoError(t, err)
115+
_, err = hasher.Write(delimiter)
116+
require.NoError(t, err)
108117
_, err = hasher.Write([]byte(file))
109118
require.NoError(t, err)
110119
}
111-
_, err := hasher.Write([]byte(testName))
120+
_, err := hasher.Write(delimiter)
121+
require.NoError(t, err)
122+
_, err = hasher.Write([]byte(testName))
112123
require.NoError(t, err)
124+
113125
return hex.EncodeToString(hasher.Sum(nil))
114126
}
115127

@@ -156,19 +168,26 @@ func runCmd(t *testing.T, dir string, args ...string) {
156168
}
157169
}
158170

159-
// Ensures Terraform providers are downloaded and cached locally in a unique directory for this test.
171+
// Each test gets a unique cache dir based on its name and template files.
172+
// This ensures that tests can download providers in parallel and that they
173+
// will redownload providers if the template files change.
174+
func getTestCacheDir(t *testing.T, rootDir string, testName string, templateFiles map[string]string) string {
175+
t.Helper()
176+
177+
hash := hashTemplateFilesAndTestName(t, testName, templateFiles)
178+
dir := filepath.Join(rootDir, hash[:12])
179+
return dir
180+
}
181+
182+
// Ensures Terraform providers are downloaded and cached locally in a unique directory for the test.
160183
// Uses `terraform init` then `mirror` to populate the cache if needed.
161184
// Returns the cache directory path.
162-
func downloadProviders(t *testing.T, rootDir string, templateFiles map[string]string) string {
185+
func downloadProviders(t *testing.T, rootDir string, testName string, templateFiles map[string]string) string {
163186
t.Helper()
164187

165-
// Each test gets a unique cache dir based on its name and template files.
166-
// This ensures that tests can download providers in parallel and that they
167-
// will redownload providers if the template files change.
168-
hash := hashTemplateFilesAndTestName(t, t.Name(), templateFiles)
169-
dir := filepath.Join(rootDir, hash[:12])
188+
dir := getTestCacheDir(t, rootDir, testName, templateFiles)
170189
if _, err := os.Stat(dir); err == nil {
171-
t.Logf("%s: using cached terraform providers", t.Name())
190+
t.Logf("%s: using cached terraform providers", testName)
172191
return dir
173192
}
174193
filesDir := filepath.Join(dir, cacheTemplateFilesDirName)
@@ -182,6 +201,8 @@ func downloadProviders(t *testing.T, rootDir string, templateFiles map[string]st
182201
if !t.Failed() {
183202
return
184203
}
204+
// If `downloadProviders` function failed, clean up the cache dir.
205+
// We don't want to leave it around because it may be incomplete or corrupted.
185206
if err := os.RemoveAll(dir); err != nil {
186207
t.Logf("failed to remove dir %s: %s", dir, err)
187208
}
@@ -191,10 +212,8 @@ func downloadProviders(t *testing.T, rootDir string, templateFiles map[string]st
191212

192213
for fileName, file := range templateFiles {
193214
filePath := filepath.Join(filesDir, fileName)
194-
if _, err := os.Stat(filePath); os.IsNotExist(err) {
195-
require.NoError(t, os.MkdirAll(filepath.Dir(filePath), 0o700))
196-
require.NoError(t, os.WriteFile(filePath, []byte(file), 0o600))
197-
}
215+
require.NoError(t, os.MkdirAll(filepath.Dir(filePath), 0o700))
216+
require.NoError(t, os.WriteFile(filePath, []byte(file), 0o600))
198217
}
199218

200219
providersDir := filepath.Join(dir, cacheProvidersDirName)
@@ -226,10 +245,10 @@ func downloadProviders(t *testing.T, rootDir string, templateFiles map[string]st
226245
// This setup prevents network access for providers during `terraform init`, improving reliability
227246
// in subsequent test runs.
228247
// Returns the path to the generated CLI config file.
229-
func cacheProviders(t *testing.T, templateFiles map[string]string, rootDir string) string {
248+
func cacheProviders(t *testing.T, rootDir string, testName string, templateFiles map[string]string) string {
230249
t.Helper()
231250

232-
providersParentDir := downloadProviders(t, rootDir, templateFiles)
251+
providersParentDir := downloadProviders(t, rootDir, testName, templateFiles)
233252
cliConfigPath := writeCliConfig(t, providersParentDir)
234253
return cliConfigPath
235254
}
@@ -991,6 +1010,23 @@ func TestProvision(t *testing.T) {
9911010
},
9921011
}
9931012

1013+
// Remove unused cache dirs before running tests.
1014+
// This cleans up any cache dirs that were created by tests that no longer exist.
1015+
cacheRootDir := filepath.Join(testutil.PersistentCacheDir(t), "terraform_provision_test")
1016+
expectedCacheDirs := make(map[string]bool)
1017+
for _, testCase := range testCases {
1018+
cacheDir := getTestCacheDir(t, cacheRootDir, testCase.Name, testCase.Files)
1019+
expectedCacheDirs[cacheDir] = true
1020+
}
1021+
currentCacheDirs, err := filepath.Glob(filepath.Join(cacheRootDir, "*"))
1022+
require.NoError(t, err)
1023+
for _, cacheDir := range currentCacheDirs {
1024+
if _, ok := expectedCacheDirs[cacheDir]; !ok {
1025+
t.Logf("removing unused cache dir: %s", cacheDir)
1026+
require.NoError(t, os.RemoveAll(cacheDir))
1027+
}
1028+
}
1029+
9941030
for _, testCase := range testCases {
9951031
testCase := testCase
9961032
t.Run(testCase.Name, func(t *testing.T) {
@@ -1004,8 +1040,9 @@ func TestProvision(t *testing.T) {
10041040
if !testCase.SkipCacheProviders {
10051041
cliConfigPath = cacheProviders(
10061042
t,
1043+
cacheRootDir,
1044+
testCase.Name,
10071045
testCase.Files,
1008-
filepath.Join(testutil.PersistentCacheDir(t), "terraform_provision_test"),
10091046
)
10101047
}
10111048
ctx, api := setupProvisioner(t, &provisionerServeOptions{

0 commit comments

Comments
 (0)