@@ -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