RadrootsFileCapacityPreflightTests.swift (3258B)
1 import Darwin 2 import Foundation 3 @testable import RadrootsKit 4 import Testing 5 6 @Test func capacityPreflightUsesOverflowSafeBlockAdmission() { 7 #expect(RadrootsFileCapacity.admits(0, availableBlocks: 0, blockSize: 4096)) 8 #expect(RadrootsFileCapacity.admits(4096, availableBlocks: 1, blockSize: 4096)) 9 #expect(!RadrootsFileCapacity.admits(4097, availableBlocks: 1, blockSize: 4096)) 10 #expect(!RadrootsFileCapacity.admits(1, availableBlocks: 0, blockSize: 4096)) 11 #expect(!RadrootsFileCapacity.admits(1, availableBlocks: .max, blockSize: 0)) 12 #expect(RadrootsFileCapacity.admits(.max, availableBlocks: .max, blockSize: 4096)) 13 #expect(!RadrootsFileCapacity.admits(.max, availableBlocks: 1, blockSize: 4096)) 14 } 15 16 @Test func capacityPreflightUsesTheOwnedDirectoryAndFailsClosedOnInvalidProbe() throws { 17 let fixture = try CapacityFixture() 18 defer { fixture.remove() } 19 let descriptor = fixture.base.path.withCString { Darwin.open($0, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC) } 20 #expect(descriptor >= 0) 21 defer { Darwin.close(descriptor) } 22 try RadrootsFileCapacity.require(0, on: descriptor) 23 try RadrootsFileCapacity.require(1, on: descriptor) 24 #expect(throws: RadrootsAppleFileError.permanentFailure) { 25 try RadrootsFileCapacity.require(1, on: -1) 26 } 27 #expect(throws: RadrootsAppleFileError.invalidRequest) { 28 try RadrootsFileCapacity.require(-1, on: descriptor) 29 } 30 } 31 32 @Test func capacityPreflightRefusesBeforeCreatingTemporaryBytesAndRetainsTheOldFile() throws { 33 for phase in [RadrootsAtomicFile.Phase.beforeCapacityCheck, .afterCapacityCheck] { 34 let fixture = try CapacityFixture() 35 defer { fixture.remove() } 36 let url = fixture.base.appendingPathComponent("value") 37 let old = Data("acknowledged".utf8) 38 try RadrootsAtomicFile.install(old, at: url) 39 #expect(throws: RadrootsAppleFileError.spaceInsufficient) { 40 try RadrootsAtomicFile.installForTesting(Data("pending".utf8), at: url) { 41 if $0 == phase { throw RadrootsAppleFileError.spaceInsufficient } 42 } 43 } 44 #expect(try Data(contentsOf: url) == old) 45 #expect(!(try FileManager.default.contentsOfDirectory(atPath: fixture.base.path)).contains { $0.hasPrefix(".radroots_pending_") }) 46 } 47 } 48 49 @Test func capacityPreflightRetainsExactStagedLeaseReplayAndOriginalFailure() throws { 50 let fixture = try CapacityFixture() 51 defer { fixture.remove() } 52 let live = RadrootsAppleFileAccess(roots: fixture.roots) 53 let data = Data("pending upload".utf8) 54 let blob = try live.stageBlob(data) 55 let digest = RadrootsAppleFileDigest.sha256(data) 56 let exact = try live.leaseStagedBlob(blob, expectedSHA256: digest, identifier: "exact") 57 let refused = RadrootsAppleFileAccess(roots: fixture.roots, persistence: capacityPersistence(.beforeCapacityCheck)) 58 #expect(try refused.leaseStagedBlob(blob, expectedSHA256: digest, identifier: "exact") == exact) 59 #expect(throws: RadrootsAppleFileError.spaceInsufficient) { 60 _ = try refused.leaseStagedBlob(blob, expectedSHA256: digest, identifier: "new") 61 } 62 #expect(try live.readStagedBlob(blob) == data) 63 #expect(try Data(contentsOf: exact.fileURL) == data) 64 }