@@ -1879,17 +1879,20 @@ fileprivate struct ClangCompilationCachingTests: CoreBasedTests {
18791879 """
18801880 }
18811881
1882+ let specificCAS = casPath. join ( usePlugin ? " plugin " : " builtin " )
1883+ let ruleInfo = " ValidateCAS \( specificCAS. str) \( try await ConditionTraitContext . shared. llvmCasToolPath. str) "
1884+
18821885 let checkBuild = { ( expectedOutput: ByteString ? ) in
18831886 try await tester. checkBuild ( runDestination: . macOS, persistent: true ) { results in
1884- let specificCAS = casPath . join ( usePlugin ? " plugin " : " builtin " )
1887+
18851888 if enableCaching {
1886- results. check ( contains: . activityStarted( ruleInfo: " ValidateCAS \( specificCAS . str ) " ) )
1889+ results. check ( contains: . activityStarted( ruleInfo: ruleInfo ) )
18871890 if let expectedOutput {
1888- results. check ( contains: . activityEmittedData( ruleInfo: " ValidateCAS \( specificCAS . str ) " , expectedOutput. bytes) )
1891+ results. check ( contains: . activityEmittedData( ruleInfo: ruleInfo , expectedOutput. bytes) )
18891892 }
1890- results. check ( contains: . activityEnded( ruleInfo: " ValidateCAS \( specificCAS . str ) " , status: . succeeded) )
1893+ results. check ( contains: . activityEnded( ruleInfo: ruleInfo , status: . succeeded) )
18911894 } else {
1892- results. check ( notContains: . activityStarted( ruleInfo: " ValidateCAS \( specificCAS . str ) " ) )
1895+ results. check ( notContains: . activityStarted( ruleInfo: ruleInfo ) )
18931896 }
18941897 results. checkNoDiagnostics ( )
18951898 }
@@ -1947,14 +1950,16 @@ fileprivate struct ClangCompilationCachingTests: CoreBasedTests {
19471950 """
19481951 }
19491952
1953+ let specificCAS = casPath. join ( " builtin " )
1954+ let ruleInfo = " ValidateCAS \( specificCAS. str) \( try await ConditionTraitContext . shared. llvmCasToolPath. str) "
1955+
19501956 let checkBuild = { ( expectedOutput: ByteString ? ) in
19511957 try await tester. checkBuild ( runDestination: . macOS, persistent: true ) { results in
1952- let specificCAS = casPath. join ( " builtin " )
1953- results. check ( contains: . activityStarted( ruleInfo: " ValidateCAS \( specificCAS. str) " ) )
1958+ results. check ( contains: . activityStarted( ruleInfo: ruleInfo) )
19541959 if let expectedOutput {
1955- results. check ( contains: . activityEmittedData( ruleInfo: " ValidateCAS \( specificCAS . str ) " , expectedOutput. bytes) )
1960+ results. check ( contains: . activityEmittedData( ruleInfo: ruleInfo , expectedOutput. bytes) )
19561961 }
1957- results. check ( contains: . activityEnded( ruleInfo: " ValidateCAS \( specificCAS . str ) " , status: . succeeded) )
1962+ results. check ( contains: . activityEnded( ruleInfo: ruleInfo , status: . succeeded) )
19581963 results. checkNoDiagnostics ( )
19591964 }
19601965 }
@@ -1969,6 +1974,76 @@ fileprivate struct ClangCompilationCachingTests: CoreBasedTests {
19691974 try await checkBuild ( " recovered from invalid data \n " )
19701975 }
19711976 }
1977+
1978+ @Test ( . requireCASValidation, . requireSDKs( . macOS) )
1979+ func validateCASMultipleExec( ) async throws {
1980+ try await withTemporaryDirectory { ( tmpDirPath: Path ) in
1981+ let casPath = tmpDirPath. join ( " CompilationCache " )
1982+ let buildSettings : [ String : String ] = [
1983+ " PRODUCT_NAME " : " $(TARGET_NAME) " ,
1984+ " CLANG_ENABLE_COMPILE_CACHE " : " YES " ,
1985+ " CLANG_ENABLE_MODULES " : " NO " ,
1986+ " COMPILATION_CACHE_CAS_PATH " : casPath. str,
1987+ ]
1988+ let llvmCasExec = try await ConditionTraitContext . shared. llvmCasToolPath
1989+ // Create a trivially different path. If we ever canonicalize the path it will be harder to test this.
1990+ let llvmCasExec2 = Path ( " \( llvmCasExec. dirname. str) \( Path . pathSeparator) \( Path . pathSeparator) \( llvmCasExec. basename) " )
1991+ let testWorkspace = TestWorkspace (
1992+ " Test " ,
1993+ sourceRoot: tmpDirPath. join ( " Test " ) ,
1994+ projects: [
1995+ TestProject (
1996+ " aProject " ,
1997+ groupTree: TestGroup (
1998+ " Sources " ,
1999+ children: [
2000+ TestFile ( " file.c " ) ,
2001+ ] ) ,
2002+ buildConfigurations: [ TestBuildConfiguration (
2003+ " Debug " ,
2004+ buildSettings: buildSettings) ] ,
2005+ targets: [
2006+ TestStandardTarget (
2007+ " Library1 " ,
2008+ type: . staticLibrary,
2009+ buildPhases: [
2010+ TestSourcesBuildPhase ( [ " file.c " ] ) ,
2011+ ] ) ,
2012+ TestStandardTarget (
2013+ " Library2 " ,
2014+ type: . staticLibrary,
2015+ buildConfigurations: [ TestBuildConfiguration (
2016+ " Debug " ,
2017+ buildSettings: [
2018+ " VALIDATE_CAS_EXEC " : llvmCasExec2. str,
2019+ ] ) ] ,
2020+ buildPhases: [
2021+ TestSourcesBuildPhase ( [ " file.c " ] ) ,
2022+ ] ) ,
2023+ ] ) ] )
2024+
2025+ let tester = try await BuildOperationTester ( getCore ( ) , testWorkspace, simulated: false )
2026+ try await tester. fs. writeFileContents ( testWorkspace. sourceRoot. join ( " aProject/file.c " ) ) { stream in
2027+ stream <<<
2028+ """
2029+ #include <stdio.h>
2030+ int something = 1;
2031+ """
2032+ }
2033+
2034+ let specificCAS = casPath. join ( " builtin " )
2035+ let parameters = BuildParameters ( configuration: " Debug " , activeRunDestination: . macOS)
2036+ let targets = tester. workspace. allTargets. map ( { BuildRequest . BuildTargetInfo ( parameters: parameters, target: $0) } )
2037+
2038+ try await tester. checkBuild ( runDestination: . macOS, buildRequest: BuildRequest ( parameters: parameters, buildTargets: targets, continueBuildingAfterErrors: false , useParallelTargets: true , useImplicitDependencies: true , useDryRun: false ) , persistent: true ) { results in
2039+ for ruleInfo in [ " ValidateCAS \( specificCAS. str) \( llvmCasExec. str) " , " ValidateCAS \( specificCAS. str) \( llvmCasExec2. str) " ] {
2040+ results. check ( contains: . activityStarted( ruleInfo: ruleInfo) )
2041+ results. check ( contains: . activityEnded( ruleInfo: ruleInfo, status: . succeeded) )
2042+ }
2043+ results. checkNoDiagnostics ( )
2044+ }
2045+ }
2046+ }
19722047}
19732048
19742049extension BuildOperationTester . BuildResults {
0 commit comments