diff --git a/Tests/ContainerAPIClientTests/ParserTest.swift b/Tests/ContainerAPIClientTests/ParserTest.swift index 9c35a6b9..9c9328e3 100644 --- a/Tests/ContainerAPIClientTests/ParserTest.swift +++ b/Tests/ContainerAPIClientTests/ParserTest.swift @@ -280,30 +280,85 @@ struct ParserTest { } @Test - func testMountBindRelativePath() throws { - - let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-bind-\(UUID().uuidString)") - try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true) - defer { - try? FileManager.default.removeItem(at: tempDir) - } - + func testRelativePaths() throws { let originalDir = FileManager.default.currentDirectoryPath - FileManager.default.changeCurrentDirectoryPath(tempDir.path) defer { FileManager.default.changeCurrentDirectoryPath(originalDir) } - let result = try Parser.mount("type=bind,src=.,dst=/foo") + func realpath(_ path: String) -> String { + let resolved = UnsafeMutablePointer.allocate(capacity: Int(PATH_MAX)) + defer { resolved.deallocate() } + guard let result = Darwin.realpath(path, resolved) else { + return path + } + return String(cString: result) + } - switch result { - case .filesystem(let fs): - let expectedPath = URL(filePath: ".").absoluteURL.path - #expect(fs.source == expectedPath) - #expect(fs.destination == "/foo") - #expect(!fs.isVolume) - case .volume: - #expect(Bool(false), "Expected filesystem mount, got volume") + // Test bind mount with relative path "." + do { + let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-bind-\(UUID().uuidString)") + try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true) + defer { + try? FileManager.default.removeItem(at: tempDir) + } + + FileManager.default.changeCurrentDirectoryPath(tempDir.path) + let result = try Parser.mount("type=bind,src=.,dst=/foo") + + switch result { + case .filesystem(let fs): + #expect(fs.source == realpath(tempDir.path)) + #expect(fs.destination == "/foo") + #expect(!fs.isVolume) + case .volume: + #expect(Bool(false), "Expected filesystem mount, got volume") + } + } + + // Test volume with relative path "./" + do { + let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-volume-rel-\(UUID().uuidString)") + try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true) + defer { + try? FileManager.default.removeItem(at: tempDir) + } + + FileManager.default.changeCurrentDirectoryPath(tempDir.path) + let result = try Parser.volume("./:/foo") + + switch result { + case .filesystem(let fs): + let expectedPath = realpath(tempDir.path) + // Normalize trailing slashes for comparison + #expect(fs.source.trimmingCharacters(in: CharacterSet(charactersIn: "/")) == expectedPath.trimmingCharacters(in: CharacterSet(charactersIn: "/"))) + #expect(fs.destination == "/foo") + case .volume: + #expect(Bool(false), "Expected filesystem mount, got volume") + } + } + + // Test volume with nested relative path "./subdir" + do { + let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-volume-rel-nested-\(UUID().uuidString)") + let nestedDir = tempDir.appendingPathComponent("subdir") + try FileManager.default.createDirectory(at: nestedDir, withIntermediateDirectories: true) + defer { + try? FileManager.default.removeItem(at: tempDir) + } + + FileManager.default.changeCurrentDirectoryPath(tempDir.path) + let result = try Parser.volume("./subdir:/foo") + + switch result { + case .filesystem(let fs): + let expectedPath = realpath(nestedDir.path) + // Normalize trailing slashes for comparison + #expect(fs.source.trimmingCharacters(in: CharacterSet(charactersIn: "/")) == expectedPath.trimmingCharacters(in: CharacterSet(charactersIn: "/"))) + #expect(fs.destination == "/foo") + case .volume: + #expect(Bool(false), "Expected filesystem mount, got volume") + } } } @@ -382,61 +437,6 @@ struct ParserTest { } } - @Test - func testVolumeRelativePath() throws { - let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-volume-rel-\(UUID().uuidString)") - try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true) - defer { - try? FileManager.default.removeItem(at: tempDir) - } - - let originalDir = FileManager.default.currentDirectoryPath - FileManager.default.changeCurrentDirectoryPath(tempDir.path) - defer { - FileManager.default.changeCurrentDirectoryPath(originalDir) - } - - let result = try Parser.volume("./:/foo") - - switch result { - case .filesystem(let fs): - let expectedPath = URL(filePath: ".").absoluteURL.path - // Normalize trailing slashes for comparison - #expect(fs.source.trimmingCharacters(in: CharacterSet(charactersIn: "/")) == expectedPath.trimmingCharacters(in: CharacterSet(charactersIn: "/"))) - #expect(fs.destination == "/foo") - case .volume: - #expect(Bool(false), "Expected filesystem mount, got volume") - } - } - - @Test - func testVolumeRelativePathNested() throws { - let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-volume-rel-nested-\(UUID().uuidString)") - let nestedDir = tempDir.appendingPathComponent("subdir") - try FileManager.default.createDirectory(at: nestedDir, withIntermediateDirectories: true) - defer { - try? FileManager.default.removeItem(at: tempDir) - } - - let originalDir = FileManager.default.currentDirectoryPath - FileManager.default.changeCurrentDirectoryPath(tempDir.path) - defer { - FileManager.default.changeCurrentDirectoryPath(originalDir) - } - - let result = try Parser.volume("./subdir:/foo") - - switch result { - case .filesystem(let fs): - let expectedPath = URL(filePath: "./subdir").absoluteURL.path - // Normalize trailing slashes for comparison - #expect(fs.source.trimmingCharacters(in: CharacterSet(charactersIn: "/")) == expectedPath.trimmingCharacters(in: CharacterSet(charactersIn: "/"))) - #expect(fs.destination == "/foo") - case .volume: - #expect(Bool(false), "Expected filesystem mount, got volume") - } - } - @Test func testIsValidDomainNameOk() throws { let names = [