apple_kit

Apple-native services for Radroots iOS and macOS apps
git clone https://radroots.dev/git/apple_kit.git
Log | Files | Refs | README | LICENSE

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 }