Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Examples/GraphicsPreviewExternalBufferSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ enum GraphicsPreviewExternalBufferSmoke {
count: pool.buffers.count
)
var releaseCount = 0
for frameIndex in 0..<frameCount {
let firstRenderLease = try await lease.reserveExternalBuffer(pool.buffers[0])
receipts[0] = try await firstRenderLease.submit()

for frameIndex in 1..<frameCount {
let bufferIndex = frameIndex % pool.buffers.count
if let receipt = receipts[bufferIndex] {
let release = await releaseStatus(receipt)
Expand All @@ -119,10 +122,7 @@ enum GraphicsPreviewExternalBufferSmoke {
releaseCount += 1
}

let frameLease =
frameIndex == 0
? lease
: try await backing.nextFrame()
let frameLease = try await backing.nextFrame()
guard frameLease.contract.generation == pool.generation else {
throw WaylandGraphicsError.staleFrameContract(
rendered: pool.generation,
Expand All @@ -146,7 +146,7 @@ enum GraphicsPreviewExternalBufferSmoke {

private static func registerStressPool(
backing: WaylandGraphicsWindowBacking,
lease: WaylandGraphicsFrameLease,
lease: borrowing WaylandGraphicsFrameLease,
configuration: WaylandGraphicsExternalBufferConfiguration
) async throws -> StressPool {
var renderers: [ExternalDmabufRenderer] = []
Expand Down Expand Up @@ -204,6 +204,7 @@ enum GraphicsPreviewExternalBufferSmoke {
let configuration = try requireExternalConfiguration(
firstLease.contract
)
let synchronization = firstLease.contract.synchronization
let renderer: ExternalDmabufRenderer
do {
renderer = try ExternalDmabufRenderer(
Expand Down Expand Up @@ -264,7 +265,7 @@ enum GraphicsPreviewExternalBufferSmoke {
log("release count: 2")
log("same-registration submissions: 2")
log("reuse count: 1")
log("sync mode: \(firstLease.contract.synchronization)")
log("sync mode: \(synchronization)")
log("release mechanism: \(result.releaseMechanism)")
log("release synchronization: \(releaseSynchronizationStatus(result))")
log("target device: \(configuration.renderNode)")
Expand Down Expand Up @@ -338,7 +339,6 @@ enum GraphicsPreviewExternalBufferSmoke {
log("release: not observed")
log("fallback reason: none")
log("failure: expected-negative-test(\(error))")
await lease.cancel()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ struct WaylandGraphicsPreviewClientTests {
let configuration = try #require(
lease.contract.externalBufferConfigurations.first
)
_ = lease.runtimePath
let plane = try WaylandGraphicsExternalBufferPlane(
fileDescriptor: try OwnedFileDescriptor(adopting: -1),
offset: 0,
Expand Down
15 changes: 15 additions & 0 deletions IntegrationTests/InvalidGraphicsLeaseClient/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions IntegrationTests/InvalidGraphicsLeaseClient/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// swift-tools-version: 6.3.2
import PackageDescription

let swiftSettings: [SwiftSetting] = [
.swiftLanguageMode(.v6),
.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
.enableUpcomingFeature("InferIsolatedConformances"),
]

let package = Package(
name: "InvalidGraphicsLeaseClient",
dependencies: [
.package(name: "WaylandClientKit", path: "../..")
],
targets: [
.executableTarget(
name: "FrameLeaseCopyClient",
dependencies: [
.product(name: "WaylandGraphicsPreview", package: "WaylandClientKit")
],
swiftSettings: swiftSettings
),
.executableTarget(
name: "FrameLeaseTransferClient",
dependencies: [
.product(name: "WaylandGraphicsPreview", package: "WaylandClientKit")
],
swiftSettings: swiftSettings
),
.executableTarget(
name: "RenderLeaseCopyClient",
dependencies: [
.product(name: "WaylandGraphicsPreview", package: "WaylandClientKit")
],
swiftSettings: swiftSettings
),
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import WaylandGraphicsPreview

func useFrameLeaseTwice(_ frameLease: consuming WaylandGraphicsFrameLease) async {
let duplicate = frameLease
await frameLease.cancel()
await duplicate.cancel()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import WaylandGraphicsPreview

func useTransferredFrameLease(
_ frameLease: consuming WaylandGraphicsFrameLease,
buffer: WaylandGraphicsExternalBuffer
) async throws {
let renderLease = try await frameLease.reserveExternalBuffer(buffer)
await frameLease.cancel()
await renderLease.cancel()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import WaylandGraphicsPreview

func useRenderLeaseTwice(
_ renderLease: consuming WaylandGraphicsExternalBufferRenderLease
) async {
let duplicate = renderLease
await renderLease.cancel()
await duplicate.cancel()
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ swift run wck identity verify-generated
```

`ci cheap` runs static checks. `ci required` adds the public API baseline,
strict build, unit tests, external integration packages, and the expected-failure
graphics policy client. `ci check` also verifies Markdown and DocC.
strict build, unit tests, external integration packages, and expected-failure
clients for invalid graphics policy and graphics-lease copying or reuse. `ci check`
also verifies Markdown and DocC.

See [Tooling](docs/tooling.md) and
[Protocol Generation](docs/generation.md) for command ownership and generated
Expand Down
37 changes: 37 additions & 0 deletions Sources/WaylandClientKitTool/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,42 @@ private func verifyInvalidGraphicsPolicyClientIsRejected(context: ToolContext) t
}
}

private func verifyGraphicsLeaseOwnershipIsEnforced(context: ToolContext) throws {
let packagePath = context.repository.url(
"IntegrationTests/InvalidGraphicsLeaseClient"
).path
let targets = [
("FrameLeaseCopyClient", "frameLease"),
("FrameLeaseTransferClient", "frameLease"),
("RenderLeaseCopyClient", "renderLease"),
]
let scratch = try context.fileSystem.createTemporaryDirectory(
prefix: "waylandclientkit-invalid-graphics-leases"
)
defer { ignoreCleanupError { try context.fileSystem.removeItem(scratch) } }

for (target, variableName) in targets {
let result = try context.swift.runSwift(
[
"build", "--disable-index-store", "--package-path", packagePath,
"--scratch-path", scratch.path, "--target", target,
],
repository: context.repository,
environment: try compilerFilterEnvironment(context: context),
requireSuccess: false
)
guard result.exitCode != 0 else {
throw ToolError("invalid graphics lease client unexpectedly compiled \(target)")
}
let diagnostics = result.stdout + result.stderr
guard diagnostics.contains("'\(variableName)' consumed more than once") else {
throw ToolError(
"invalid graphics lease client failed before move-only ownership was checked"
)
}
}
}

private func verifyManagedIdentityConstructionIsRejected(context: ToolContext) throws {
let packagePath = context.repository.url(
"IntegrationTests/InvalidManagedIdentityClient"
Expand Down Expand Up @@ -1363,6 +1399,7 @@ private func runRequired(context: ToolContext) throws {
context: context, packagePath: Test.IntegrationFrameworkHost.packagePath)
try runIntegrationPackage(context: context, packagePath: Test.IntegrationTinyUI.packagePath)
try verifyInvalidGraphicsPolicyClientIsRejected(context: context)
try verifyGraphicsLeaseOwnershipIsEnforced(context: context)
Comment thread
conxlgtm marked this conversation as resolved.
try verifyManagedIdentityConstructionIsRejected(context: context)
try verifyMissingApplicationIdentityIsRejected(context: context)
}
Expand Down
20 changes: 18 additions & 2 deletions Sources/WaylandClientKitToolSupport/ProjectAutomation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ public struct SwiftCommandResolver {
"IntegrationTests/GraphicsPreviewClient/Package.swift",
"IntegrationTests/FrameworkHostClient/Package.swift",
"IntegrationTests/TinyUIPrototype/Package.swift",
"IntegrationTests/InvalidGraphicsLeaseClient/Package.swift",
"IntegrationTests/InvalidManagedIdentityClient/Package.swift",
"IntegrationTests/InvalidApplicationIdentityClient/Package.swift",
]
Expand All @@ -449,6 +450,7 @@ public struct SwiftCommandResolver {
"IntegrationTests/GraphicsPreviewClient/Tests",
"IntegrationTests/FrameworkHostClient/Tests",
"IntegrationTests/TinyUIPrototype/Tests",
"IntegrationTests/InvalidGraphicsLeaseClient/Sources",
"IntegrationTests/InvalidManagedIdentityClient/Sources",
"IntegrationTests/InvalidApplicationIdentityClient/Sources",
]
Expand Down Expand Up @@ -930,7 +932,20 @@ public struct PublicAPIAuditor {
let report = try SemanticPublicAPIBaseline(fileSystem: context.fileSystem).render(
symbolGraphs: verifier.publicProductSymbolGraphs()
)
return "# WaylandClientKit Semantic Public API Report\n\n\(report)"
let ownershipReport = try SourceOwnershipAPIBaseline(
fileSystem: context.fileSystem,
runner: context.runner,
swiftCompilerExecutable: context.swift.swiftCompilerExecutable(
environment: context.runner.environment
)
).render(
moduleSources: Dictionary(
uniqueKeysWithValues: DocCVerifier.publicProducts.map { product in
(product.moduleName, context.repository.url("Sources/\(product.moduleName)"))
}
)
)
return "# WaylandClientKit Semantic Public API Report\n\n\(report)\n\(ownershipReport)"
}

public func verify(update: Bool, environment: [String: String] = [:]) throws {
Expand All @@ -954,7 +969,8 @@ public struct PublicAPIAuditor {
# WaylandClientKit Public API Baseline

This baseline records compiler-emitted public symbols and relationships for
vended library products. Source locations and formatting are excluded, while
vended library products, plus compiler-checked ownership markers omitted by
Swift symbol graphs. Source locations and formatting are excluded, while
continuation-line signature changes remain visible. Preview products are
included so source-breaking preview API drift is reviewed.

Expand Down
Loading
Loading