@@ -100,16 +100,28 @@ func hashTemplateFilesAndTestName(t *testing.T, testName string, templateFiles m
100
100
}
101
101
sort .Strings (sortedFileNames )
102
102
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
+
103
110
hasher := sha256 .New ()
104
111
for _ ,fileName := range sortedFileNames {
105
112
file := templateFiles [fileName ]
106
113
_ ,err := hasher .Write ([]byte (fileName ))
107
114
require .NoError (t ,err )
115
+ _ ,err = hasher .Write (delimiter )
116
+ require .NoError (t ,err )
108
117
_ ,err = hasher .Write ([]byte (file ))
109
118
require .NoError (t ,err )
110
119
}
111
- _ ,err := hasher .Write ([]byte (testName ))
120
+ _ ,err := hasher .Write (delimiter )
121
+ require .NoError (t ,err )
122
+ _ ,err = hasher .Write ([]byte (testName ))
112
123
require .NoError (t ,err )
124
+
113
125
return hex .EncodeToString (hasher .Sum (nil ))
114
126
}
115
127
@@ -156,19 +168,26 @@ func runCmd(t *testing.T, dir string, args ...string) {
156
168
}
157
169
}
158
170
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.
160
183
// Uses `terraform init` then `mirror` to populate the cache if needed.
161
184
// 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 {
163
186
t .Helper ()
164
187
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 )
170
189
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 )
172
191
return dir
173
192
}
174
193
filesDir := filepath .Join (dir ,cacheTemplateFilesDirName )
@@ -182,6 +201,8 @@ func downloadProviders(t *testing.T, rootDir string, templateFiles map[string]st
182
201
if ! t .Failed () {
183
202
return
184
203
}
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.
185
206
if err := os .RemoveAll (dir );err != nil {
186
207
t .Logf ("failed to remove dir %s: %s" ,dir ,err )
187
208
}
@@ -191,10 +212,8 @@ func downloadProviders(t *testing.T, rootDir string, templateFiles map[string]st
191
212
192
213
for fileName ,file := range templateFiles {
193
214
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 ))
198
217
}
199
218
200
219
providersDir := filepath .Join (dir ,cacheProvidersDirName )
@@ -226,10 +245,10 @@ func downloadProviders(t *testing.T, rootDir string, templateFiles map[string]st
226
245
// This setup prevents network access for providers during `terraform init`, improving reliability
227
246
// in subsequent test runs.
228
247
// 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 {
230
249
t .Helper ()
231
250
232
- providersParentDir := downloadProviders (t ,rootDir ,templateFiles )
251
+ providersParentDir := downloadProviders (t ,rootDir ,testName , templateFiles )
233
252
cliConfigPath := writeCliConfig (t ,providersParentDir )
234
253
return cliConfigPath
235
254
}
@@ -991,6 +1010,23 @@ func TestProvision(t *testing.T) {
991
1010
},
992
1011
}
993
1012
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
+
994
1030
for _ ,testCase := range testCases {
995
1031
testCase := testCase
996
1032
t .Run (testCase .Name ,func (t * testing.T ) {
@@ -1004,8 +1040,9 @@ func TestProvision(t *testing.T) {
1004
1040
if ! testCase .SkipCacheProviders {
1005
1041
cliConfigPath = cacheProviders (
1006
1042
t ,
1043
+ cacheRootDir ,
1044
+ testCase .Name ,
1007
1045
testCase .Files ,
1008
- filepath .Join (testutil .PersistentCacheDir (t ),"terraform_provision_test" ),
1009
1046
)
1010
1047
}
1011
1048
ctx ,api := setupProvisioner (t ,& provisionerServeOptions {