Skip to content

Commit ff6ff79

Browse files
committed
fix comments
1 parent 07a7db3 commit ff6ff79

File tree

8 files changed

+449
-454
lines changed

8 files changed

+449
-454
lines changed

Sources/Containerization/SandboxContext/SandboxContext.pb.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ public enum Com_Apple_Containerization_Sandbox_V3_FileSystemEventType: SwiftProt
4444
case link // = 2
4545
case unlink // = 3
4646
case modify // = 4
47-
case undefined // = 99
4847
case UNRECOGNIZED(Int)
4948

5049
public init() {
@@ -58,7 +57,6 @@ public enum Com_Apple_Containerization_Sandbox_V3_FileSystemEventType: SwiftProt
5857
case 2: self = .link
5958
case 3: self = .unlink
6059
case 4: self = .modify
61-
case 99: self = .undefined
6260
default: self = .UNRECOGNIZED(rawValue)
6361
}
6462
}
@@ -70,7 +68,6 @@ public enum Com_Apple_Containerization_Sandbox_V3_FileSystemEventType: SwiftProt
7068
case .link: return 2
7169
case .unlink: return 3
7270
case .modify: return 4
73-
case .undefined: return 99
7471
case .UNRECOGNIZED(let i): return i
7572
}
7673
}
@@ -82,7 +79,6 @@ public enum Com_Apple_Containerization_Sandbox_V3_FileSystemEventType: SwiftProt
8279
.link,
8380
.unlink,
8481
.modify,
85-
.undefined,
8682
]
8783

8884
}
@@ -1100,7 +1096,6 @@ extension Com_Apple_Containerization_Sandbox_V3_FileSystemEventType: SwiftProtob
11001096
2: .same(proto: "LINK"),
11011097
3: .same(proto: "UNLINK"),
11021098
4: .same(proto: "MODIFY"),
1103-
99: .same(proto: "UNDEFINED"),
11041099
]
11051100
}
11061101

Sources/Containerization/SandboxContext/SandboxContext.proto

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ enum FileSystemEventType {
291291
LINK = 2;
292292
UNLINK = 3;
293293
MODIFY = 4;
294-
UNDEFINED = 99;
295294
}
296295

297296
message NotifyFileSystemEventRequest {

Sources/Containerization/Vminitd.swift

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ extension Vminitd: VirtualMachineAgent {
273273

274274
/// Vminitd specific rpcs.
275275
extension Vminitd {
276+
public typealias FileSystemEventRequest = Com_Apple_Containerization_Sandbox_V3_NotifyFileSystemEventRequest
277+
public typealias FileSystemEventResponse = Com_Apple_Containerization_Sandbox_V3_NotifyFileSystemEventResponse
276278
/// Sets up an emulator in the guest.
277279
public func setupEmulator(binaryPath: String, configuration: Binfmt.Entry) async throws {
278280
let request = Com_Apple_Containerization_Sandbox_V3_SetupEmulatorRequest.with {
@@ -368,30 +370,44 @@ extension Vminitd {
368370
try await self.sync()
369371
}
370372

371-
/// Send a filesystem event notification to the guest.
373+
/// Send filesystem event notifications to the guest
374+
public func notifyFileSystemEvents(
375+
_ events: [FileSystemEventRequest]
376+
) async throws -> [FileSystemEventResponse] {
377+
let requests = AsyncStream<FileSystemEventRequest> { continuation in
378+
for event in events {
379+
continuation.yield(event)
380+
}
381+
continuation.finish()
382+
}
383+
384+
let responses = client.notifyFileSystemEvent(requests)
385+
var results: [FileSystemEventResponse] = []
386+
387+
for try await response in responses {
388+
results.append(response)
389+
}
390+
391+
guard results.count == events.count else {
392+
throw ContainerizationError(.internalError, message: "Expected \(events.count) responses, got \(results.count)")
393+
}
394+
395+
return results
396+
}
397+
372398
public func notifyFileSystemEvent(
373399
path: String,
374400
eventType: Com_Apple_Containerization_Sandbox_V3_FileSystemEventType,
375401
containerID: String
376-
) async throws -> Com_Apple_Containerization_Sandbox_V3_NotifyFileSystemEventResponse {
377-
let request = Com_Apple_Containerization_Sandbox_V3_NotifyFileSystemEventRequest.with {
402+
) async throws -> FileSystemEventResponse {
403+
let request = FileSystemEventRequest.with {
378404
$0.path = path
379405
$0.eventType = eventType
380406
$0.containerID = containerID
381407
}
382408

383-
let requests = AsyncStream<Com_Apple_Containerization_Sandbox_V3_NotifyFileSystemEventRequest> { continuation in
384-
continuation.yield(request)
385-
continuation.finish()
386-
}
387-
388-
let responses = client.notifyFileSystemEvent(requests)
389-
390-
for try await response in responses {
391-
return response
392-
}
393-
394-
throw ContainerizationError(.internalError, message: "No response received from notifyFileSystemEvent")
409+
let responses = try await notifyFileSystemEvents([request])
410+
return responses[0]
395411
}
396412
}
397413

Sources/Integration/Suite.swift

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,6 @@ struct IntegrationSuite: AsyncParsableCommand {
9595
.appendingPathComponent(name)
9696
}
9797

98-
// Generate a simple hash from the image reference to ensure unique rootfs filenames
99-
private static func hashImageReference(_ reference: String) -> String {
100-
let hash =
101-
reference.data(using: .utf8)?.withUnsafeBytes { bytes in
102-
var hash: Int = 0
103-
for byte in bytes {
104-
hash = hash &* 31 &+ Int(byte)
105-
}
106-
return hash & 0x7FFF_FFFF
107-
} ?? 0
108-
return String(format: "%08x", hash)
109-
}
110-
11198
func bootstrap(reference: String = "ghcr.io/linuxcontainers/alpine:3.20") async throws -> (
11299
rootfs: Containerization.Mount, vmm: VirtualMachineManager, image: Containerization.Image
113100
) {
@@ -137,8 +124,8 @@ struct IntegrationSuite: AsyncParsableCommand {
137124
let platform = Platform(arch: "arm64", os: "linux", variant: "v8")
138125

139126
let fs: Containerization.Mount = try await {
140-
let imageHash = Self.hashImageReference(reference)
141-
let fsPath = Self.testDir.appending(component: "rootfs-\(imageHash).ext4")
127+
let truncatedHash = String(image.digest.suffix(12))
128+
let fsPath = Self.testDir.appending(component: "rootfs-\(truncatedHash).ext4")
142129
do {
143130
let unpacker = EXT4Unpacker(blockSizeInBytes: 2.gib())
144131
return try await unpacker.unpack(image, for: platform, at: fsPath)

Sources/Integration/VMTests.swift

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ extension IntegrationSuite {
355355
let id = "test-fsnotify-events"
356356

357357
let bs = try await bootstrap(reference: "docker.io/library/node:18-alpine")
358-
let directory = try createFSNotifyTestDirectory()
358+
let directory = try createMountDirectory()
359359
let inotifyBuffer: IntegrationSuite.BufferWriter = BufferWriter()
360360
let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
361361
config.process.arguments = [
@@ -378,46 +378,27 @@ extension IntegrationSuite {
378378
let agent = Vminitd(connection: connection, group: group)
379379
try await Task.sleep(for: .seconds(1))
380380

381-
// Test 1: CREATE event on existing file
382-
print("Sending CREATE event...")
383381
let createResponse = try await agent.notifyFileSystemEvent(
384-
path: "/mnt/existing.txt",
382+
path: "/mnt/hi.txt",
385383
eventType: .create,
386384
containerID: id
387385
)
388386

389387
guard createResponse.success else {
390388
throw IntegrationError.assert(msg: "CREATE event failed: \(createResponse.error)")
391389
}
392-
print("CREATE event succeeded")
393390

394-
// Test 2: MODIFY event on existing file
395-
print("Sending MODIFY event...")
396391
let modifyResponse = try await agent.notifyFileSystemEvent(
397-
path: "/mnt/existing.txt",
392+
path: "/mnt/hi.txt",
398393
eventType: .modify,
399394
containerID: id
400395
)
401396
guard modifyResponse.success else {
402397
throw IntegrationError.assert(msg: "MODIFY event failed: \(modifyResponse.error)")
403398
}
404-
print("MODIFY event succeeded")
405399

406-
// Wait for events to be processed
407-
print("Waiting for inotify events to be detected...")
408400
try await Task.sleep(for: .seconds(1))
409401

410-
let inotifyOutput = String(data: inotifyBuffer.data, encoding: .utf8) ?? ""
411-
print("=== Final Container Output ===")
412-
print(inotifyOutput)
413-
print("=== End Container Output ===")
414-
415-
// Verify that inotify detected the modify event
416-
guard inotifyOutput.contains("change") && inotifyOutput.contains("existing.txt") else {
417-
throw IntegrationError.assert(msg: "inotify did not detect FSNotify agent events. Output: '\(inotifyOutput)'")
418-
}
419-
420-
// Test 3: DELETE event on non-existent file
421402
let deleteResponse = try await agent.notifyFileSystemEvent(
422403
path: "/mnt/nonexistent.txt",
423404
eventType: .delete,
@@ -427,27 +408,28 @@ extension IntegrationSuite {
427408
throw IntegrationError.assert(msg: "DELETE event failed: \(deleteResponse.error)")
428409
}
429410

430-
// Clean up
431-
try await agent.close()
432-
try await group.shutdownGracefully()
433-
try await container.stop()
411+
try await Task.sleep(for: .seconds(1))
434412

435-
print("All FSNotify events tested successfully")
436-
}
413+
let inotifyOutput = String(data: inotifyBuffer.data, encoding: .utf8) ?? ""
437414

438-
private func createFSNotifyTestDirectory() throws -> URL {
439-
let dir = FileManager.default.uniqueTemporaryDirectory(create: true)
415+
let expectedLines = ["change hi.txt", "change hi.txt"]
416+
let actualLines = inotifyOutput.trimmingCharacters(in: .whitespacesAndNewlines).components(separatedBy: .newlines).filter { !$0.isEmpty }
440417

441-
// Create some test files and directories
442-
try "initial content".write(to: dir.appendingPathComponent("existing.txt"), atomically: true, encoding: .utf8)
443-
try "hello world".write(to: dir.appendingPathComponent("hello.txt"), atomically: true, encoding: .utf8)
418+
guard actualLines.count >= expectedLines.count else {
419+
throw IntegrationError.assert(msg: "Expected at least \(expectedLines.count) events, got \(actualLines.count). Output: '\(inotifyOutput)'")
420+
}
444421

445-
// Create a subdirectory
446-
let subdir = dir.appendingPathComponent("subdir")
447-
try FileManager.default.createDirectory(at: subdir, withIntermediateDirectories: true)
448-
try "nested file".write(to: subdir.appendingPathComponent("nested.txt"), atomically: true, encoding: .utf8)
422+
let hasExpectedEvents = expectedLines.allSatisfy { expectedLine in
423+
actualLines.contains(expectedLine)
424+
}
449425

450-
return dir
426+
guard hasExpectedEvents else {
427+
throw IntegrationError.assert(msg: "Expected events not found. Expected: \(expectedLines), Actual: \(actualLines)")
428+
}
429+
430+
try await agent.close()
431+
try await group.shutdownGracefully()
432+
try await container.stop()
451433
}
452434

453435
private func createMountDirectory() throws -> URL {

0 commit comments

Comments
 (0)