@@ -126,14 +126,93 @@ fileprivate struct SwiftCompilationCachingTests: CoreBasedTests {
126
126
#expect( try readMetrics ( " two " ) . contains ( " \" swiftCacheHits \" : \( numCompile) , \" swiftCacheMisses \" :0 " ) )
127
127
}
128
128
}
129
+
130
+ @Test ( . requireSDKs( . macOS) )
131
+ func swiftCASLimiting( ) async throws {
132
+ try await withTemporaryDirectory { ( tmpDirPath: Path ) async throws -> Void in
133
+ let testWorkspace = try await TestWorkspace (
134
+ " Test " ,
135
+ sourceRoot: tmpDirPath. join ( " Test " ) ,
136
+ projects: [
137
+ TestProject (
138
+ " aProject " ,
139
+ groupTree: TestGroup (
140
+ " Sources " ,
141
+ children: [
142
+ TestFile ( " main.swift " ) ,
143
+ ] ) ,
144
+ buildConfigurations: [
145
+ TestBuildConfiguration (
146
+ " Debug " ,
147
+ buildSettings: [
148
+ " PRODUCT_NAME " : " $(TARGET_NAME) " ,
149
+ " SDKROOT " : " macosx " ,
150
+ " SWIFT_VERSION " : swiftVersion,
151
+ " SWIFT_ENABLE_EXPLICIT_MODULES " : " YES " ,
152
+ " SWIFT_ENABLE_COMPILE_CACHE " : " YES " ,
153
+ " COMPILATION_CACHE_ENABLE_DIAGNOSTIC_REMARKS " : " YES " ,
154
+ " COMPILATION_CACHE_LIMIT_SIZE " : " 1 " ,
155
+ " COMPILATION_CACHE_CAS_PATH " : tmpDirPath. join ( " CompilationCache " ) . str,
156
+ " DSTROOT " : tmpDirPath. join ( " dstroot " ) . str,
157
+ ] ) ,
158
+ ] ,
159
+ targets: [
160
+ TestStandardTarget (
161
+ " tool " ,
162
+ type: . framework,
163
+ buildPhases: [
164
+ TestSourcesBuildPhase ( [
165
+ " main.swift " ,
166
+ ] ) ,
167
+ ]
168
+ )
169
+ ] )
170
+ ] )
171
+ let tester = try await BuildOperationTester ( getCore ( ) , testWorkspace, simulated: false )
172
+
173
+ try await tester. fs. writeFileContents ( tmpDirPath. join ( " Test/aProject/main.swift " ) ) {
174
+ $0 <<< " let x = 1 \n "
175
+ }
176
+
177
+ try await tester. checkBuild ( runDestination: . macOS, persistent: true ) { results in
178
+ results. checkTask ( . matchRuleType( " SwiftCompile " ) ) { results. checkKeyQueryCacheMiss ( $0) }
179
+ }
180
+ try await tester. checkBuild ( runDestination: . macOS, buildCommand: . cleanBuildFolder( style: . regular) , body: { _ in } )
181
+
182
+ // Update the source file and rebuild.
183
+ try await tester. fs. writeFileContents ( tmpDirPath. join ( " Test/aProject/main.swift " ) ) {
184
+ $0 <<< " let x = 2 \n "
185
+ }
186
+ try await tester. checkBuild ( runDestination: . macOS, persistent: true ) { results in
187
+ results. checkTask ( . matchRuleType( " SwiftCompile " ) ) { results. checkKeyQueryCacheMiss ( $0) }
188
+ }
189
+ try await tester. checkBuild ( runDestination: . macOS, buildCommand: . cleanBuildFolder( style: . regular) , body: { _ in } )
190
+
191
+ // Revert the source change and rebuild. It should still be a cache miss because of CAS size limiting.
192
+ try await tester. fs. writeFileContents ( tmpDirPath. join ( " Test/aProject/main.swift " ) ) {
193
+ $0 <<< " let x = 1 \n "
194
+ }
195
+ try await tester. checkBuild ( runDestination: . macOS, persistent: true ) { results in
196
+ results. checkTask ( . matchRuleType( " SwiftCompile " ) ) { results. checkKeyQueryCacheMiss ( $0) }
197
+ }
198
+ }
199
+ }
129
200
}
130
201
131
202
extension BuildOperationTester . BuildResults {
132
- fileprivate func checkKeyQueryCacheMiss( _ task: Task , file: StaticString = #file, line: UInt = #line) {
133
- checkRemark ( . contains( " cache key query miss " ) )
203
+ fileprivate func checkKeyQueryCacheMiss( _ task: Task , sourceLocation: SourceLocation = #_sourceLocation) {
204
+ let found = ( getDiagnosticMessageForTask ( . contains( " cache miss " ) , kind: . remark, task: task) != nil )
205
+ guard found else {
206
+ Issue . record ( " Unable to find cache miss diagnostic for task \( task) " , sourceLocation: sourceLocation)
207
+ return
208
+ }
134
209
}
135
210
136
- fileprivate func checkKeyQueryCacheHit( _ task: Task , file: StaticString = #file, line: UInt = #line) {
137
- checkRemark ( . contains( " cache key query hit " ) )
211
+ fileprivate func checkKeyQueryCacheHit( _ task: Task , sourceLocation: SourceLocation = #_sourceLocation) {
212
+ let found = ( getDiagnosticMessageForTask ( . contains( " cache found for key " ) , kind: . remark, task: task) != nil )
213
+ guard found else {
214
+ Issue . record ( " Unable to find cache hit diagnostic for task \( task) " , sourceLocation: sourceLocation)
215
+ return
216
+ }
138
217
}
139
218
}
0 commit comments