@@ -485,6 +485,13 @@ func runTest(t *testing.T,
485485 customEnv []string ,
486486 envFilters []string ,
487487) {
488+ // Check env filters early, before creating any resources like directories on the file system.
489+ // Creating / deleting too many directories causes this error on the workspace FUSE mount:
490+ // unlinkat <workspace_path>: directory not empty. Thus avoiding unnecessary directory creation
491+ // is important.
492+ testEnv := buildTestEnv (config .Env , customEnv )
493+ checkEnvFilters (t , testEnv , envFilters )
494+
488495 if LogConfig {
489496 configBytes , err := json .MarshalIndent (config , "" , " " )
490497 require .NoError (t , err )
@@ -616,38 +623,12 @@ func runTest(t *testing.T,
616623 uniqueCacheDir := filepath .Join (t .TempDir (), ".cache" )
617624 cmd .Env = append (cmd .Env , "DATABRICKS_CACHE_DIR=" + uniqueCacheDir )
618625
619- for _ , key := range utils .SortedKeys (config .Env ) {
620- if hasKey (customEnv , key ) {
621- // We want EnvMatrix to take precedence.
622- // Skip rather than relying on cmd.Env order, because this might interfere with replacements and substitutions.
623- continue
624- }
625- cmd .Env = addEnvVar (t , cmd .Env , & repls , key , config .Env [key ], config .EnvRepl , false )
626- }
627-
628- for _ , keyvalue := range customEnv {
629- items := strings .SplitN (keyvalue , "=" , 2 )
630- require .Len (t , items , 2 )
631- key := items [0 ]
632- value := items [1 ]
626+ for _ , kv := range testEnv {
627+ key , value , _ := strings .Cut (kv , "=" )
633628 // Only add replacement by default if value is part of EnvMatrix with more than 1 option and length is 4 or more chars
634629 // (to avoid matching "yes" and "no" values from template input parameters)
635- cmd .Env = addEnvVar (t , cmd .Env , & repls , key , value , config .EnvRepl , len (config .EnvMatrix [key ]) > 1 && len (value ) >= 4 )
636- }
637-
638- for filterInd , filterEnv := range envFilters {
639- filterEnvKey := strings .Split (filterEnv , "=" )[0 ]
640- for ind := range cmd .Env {
641- // Search backwards, because the latest settings is what is actually applicable.
642- envPair := cmd .Env [len (cmd .Env )- 1 - ind ]
643- if strings .Split (envPair , "=" )[0 ] == filterEnvKey {
644- if envPair == filterEnv {
645- break
646- } else {
647- t .Skipf ("Skipping because test environment %s does not match ENVFILTER#%d: %s" , envPair , filterInd , filterEnv )
648- }
649- }
650- }
630+ defaultRepl := hasKey (customEnv , key ) && len (config .EnvMatrix [key ]) > 1 && len (value ) >= 4
631+ cmd .Env = addEnvVar (t , cmd .Env , & repls , key , value , config .EnvRepl , defaultRepl )
651632 }
652633
653634 absDir , err := filepath .Abs (dir )
@@ -731,10 +712,44 @@ func runTest(t *testing.T,
731712 }
732713}
733714
715+ // checkEnvFilters skips the test if any env filter doesn't match testEnv.
716+ func checkEnvFilters (t * testing.T , testEnv , envFilters []string ) {
717+ envMap := make (map [string ]string , len (testEnv ))
718+ for _ , kv := range testEnv {
719+ key , value , _ := strings .Cut (kv , "=" )
720+ envMap [key ] = value
721+ }
722+ for i , filter := range envFilters {
723+ key , expected , _ := strings .Cut (filter , "=" )
724+ if actual , ok := envMap [key ]; ok && actual != expected {
725+ t .Skipf ("Skipping because test environment %s=%s does not match ENVFILTER#%d: %s" , key , actual , i , filter )
726+ }
727+ }
728+ }
729+
730+ // buildTestEnv builds the test environment from config.Env and customEnv.
731+ // customEnv (from EnvMatrix) takes precedence over config.Env.
732+ func buildTestEnv (configEnv map [string ]string , customEnv []string ) []string {
733+ env := make ([]string , 0 , len (configEnv )+ len (customEnv ))
734+
735+ // Add config.Env first (but skip keys that exist in customEnv)
736+ for _ , key := range utils .SortedKeys (configEnv ) {
737+ if hasKey (customEnv , key ) {
738+ continue
739+ }
740+ env = append (env , key + "=" + configEnv [key ])
741+ }
742+
743+ // Add customEnv second (takes precedence)
744+ env = append (env , customEnv ... )
745+
746+ return env
747+ }
748+
734749func hasKey (env []string , key string ) bool {
735- for _ , keyvalue := range env {
736- items := strings .SplitN ( keyvalue , "=" , 2 )
737- if len ( items ) == 2 && items [ 0 ] == key {
750+ for _ , kv := range env {
751+ k , _ , ok := strings .Cut ( kv , "=" )
752+ if ok && k == key {
738753 return true
739754 }
740755 }
0 commit comments