field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

TeraMediaBudgetTests.swift (9397B)


      1 import Foundation
      2 @testable import TeraApp
      3 import UIKit
      4 import XCTest
      5 
      6 final class TeraMediaBudgetTests: XCTestCase {
      7   func testStartupLimitsRejectZeroAndEveryMaximumPlusOne() throws {
      8     let maximum = [8 * 1024 * 1024, 16_000_000, 1024, 32 * 1024 * 1024, 64, 2, 16, 4096]
      9     func limits(_ values: [Int]) -> TeraMediaPresentationLimits? {
     10       TeraMediaPresentationLimits(encodedBytes: values[0], sourcePixels: values[1],
     11                                   thumbnailDimension: values[2], cacheBytes: values[3], cacheEntries: values[4],
     12                                   workers: values[5], queuedRequests: values[6], visibilityEntries: values[7])
     13     }
     14     XCTAssertEqual(limits(maximum), .standard)
     15     for index in maximum.indices {
     16       var invalid = maximum
     17       invalid[index] += 1
     18       XCTAssertNil(limits(invalid))
     19       invalid[index] = 0
     20       XCTAssertNil(limits(invalid))
     21     }
     22     let policy = try XCTUnwrap(limits(maximum))
     23     XCTAssertTrue(policy.accepts(byteCount: maximum[0], width: 4000, height: 4000))
     24     XCTAssertFalse(policy.accepts(byteCount: maximum[0] + 1, width: 4000, height: 4000))
     25     XCTAssertFalse(policy.accepts(byteCount: maximum[0], width: 16_000_001, height: 1))
     26     XCTAssertFalse(policy.accepts(byteCount: 1, width: Int.max, height: Int.max))
     27   }
     28 
     29   @MainActor
     30   func testDecodeUsesBoundedRasterOffUIActorAndRejectsCorruption() async throws {
     31     let renderer = UIGraphicsImageRenderer(size: CGSize(width: 2048, height: 1024), format: {
     32       let format = UIGraphicsImageRendererFormat()
     33       format.scale = 1
     34       return format
     35     }())
     36     let bytes = renderer.pngData { context in
     37       UIColor.green.setFill()
     38       context.fill(CGRect(x: 0, y: 0, width: 2048, height: 1024))
     39     }
     40     let artifact = try XCTUnwrap(TeraVerifiedMediaArtifact(artifactID: String(repeating: "a", count: 64),
     41                                                            bytes: bytes, byteSize: UInt64(bytes.count), mediaType: "image/png", width: 2048, height: 1024))
     42     let image = try await TeraMediaThumbnail.prepare(artifact, limits: .standard)
     43     XCTAssertEqual(image.width, 1024)
     44     XCTAssertEqual(image.height, 512)
     45     do {
     46       _ = try await TeraMediaThumbnail.prepare(TeraScopeFixtures.artifact("a", corrupt: true), limits: .standard)
     47       XCTFail("Corrupt raster must fail")
     48     } catch TeraMediaThumbnailFailure.corrupt {}
     49   }
     50 
     51   func testActualDecoderRejectsEncodedAndDeclaredPixelMaximumPlusOne() async throws {
     52     let original = try TeraScopeFixtures.artifact("a")
     53     for (bytes, width, height) in [(Data(repeating: 0, count: 8 * 1024 * 1024 + 1), UInt32(1), UInt32(1)),
     54                                    (original.bytes, UInt32(16_000_001), UInt32(1))]
     55     {
     56       let artifact = try XCTUnwrap(TeraVerifiedMediaArtifact(artifactID: original.artifactID,
     57                                                              bytes: bytes, byteSize: UInt64(bytes.count), mediaType: "image/png", width: width, height: height))
     58       do {
     59         _ = try await TeraMediaThumbnail.prepare(artifact, limits: .standard)
     60         XCTFail("Resource admission must precede raster decoding")
     61       } catch TeraMediaThumbnailFailure.resourceLimit {}
     62     }
     63   }
     64 
     65   @MainActor
     66   func testQueueMaxPlusOneAndCancellationKeepPhysicalWorkersBounded() async {
     67     let queue = TeraMediaWorkQueue(limits: .standard)
     68     let firstPause = ResourceTestPause()
     69     let secondPause = ResourceTestPause()
     70     let first = UUID()
     71     var started = 0
     72     XCTAssertTrue(queue.submit(id: first) { started += 1; await firstPause.wait() })
     73     XCTAssertTrue(queue.submit(id: UUID()) { started += 1; await secondPause.wait() })
     74     for _ in 0 ..< 16 {
     75       XCTAssertTrue(queue.submit(id: UUID()) { started += 1 })
     76     }
     77     await firstPause.entered.wait()
     78     await secondPause.entered.wait()
     79     XCTAssertEqual(started, 2)
     80     XCTAssertEqual(queue.activeCount, 2)
     81     XCTAssertEqual(queue.queuedCount, 16)
     82     XCTAssertFalse(queue.submit(id: UUID()) {})
     83     queue.cancel(id: first)
     84     XCTAssertEqual(queue.activeCount, 2)
     85     XCTAssertFalse(queue.submit(id: UUID()) {})
     86     queue.cancelAll()
     87     XCTAssertEqual(queue.activeCount, 2)
     88     XCTAssertEqual(queue.queuedCount, 0)
     89     await firstPause.resume.open()
     90     await secondPause.resume.open()
     91     await TeraScopeFixtures.eventually { queue.activeCount == 0 }
     92     XCTAssertEqual(started, 2)
     93   }
     94 
     95   @MainActor
     96   func testPresentationCacheEvictsOnlyTransientBytesAtCapacity() async throws {
     97     let backend = try TeraScopeBackend()
     98     let client = try await TeraScopeFixtures.client(backend)
     99     let policy = try XCTUnwrap(TeraMediaPresentationLimits(encodedBytes: 1024, sourcePixels: 16_000_000,
    100                                                            thumbnailDimension: 1024, cacheBytes: 200, cacheEntries: 3, workers: 1, queuedRequests: 1,
    101                                                            visibilityEntries: 4096))
    102     let store = TeraMediaStore(runtimeClient: client, limits: policy)
    103     let context = TeraLocalNetwork.defaultContext(snapshot: TeraScopeFixtures.snapshot())
    104     for index in 0 ..< 4 {
    105       var reference = TeraScopeFixtures.reference()
    106       reference = TeraMediaReference(referenceFingerprint: String(repeating: String(index), count: 64),
    107                                      url: reference.url, sha256: reference.sha256, mediaType: reference.mediaType,
    108                                      width: reference.width, height: reference.height, byteSize: reference.byteSize,
    109                                      alt: reference.alt, verification: reference.verification)
    110       store.load(media: reference, context: context)
    111       await TeraScopeFixtures.eventually { store.state(for: reference, context: context) != .loading }
    112       XCTAssertLessThanOrEqual(store.stateCount, policy.cacheEntries)
    113       XCTAssertLessThanOrEqual(store.cachedByteCount, policy.cacheBytes)
    114       XCTAssertGreaterThan(store.cachedByteCount, 0)
    115     }
    116     let invalidations = await backend.counts[.invalidate]
    117     XCTAssertNil(invalidations)
    118     store.reset()
    119     XCTAssertEqual(store.cachedByteCount, 0)
    120     _ = try await client.stop()
    121   }
    122 
    123   @MainActor
    124   func testVisibilityCapacityFailsClosedAndExplicitCurrentReferencesCanReturn() async throws {
    125     let backend = try TeraScopeBackend()
    126     let client = try await TeraScopeFixtures.client(backend)
    127     let limits = try XCTUnwrap(TeraMediaPresentationLimits(encodedBytes: 1024,
    128                                                            sourcePixels: 16_000_000, thumbnailDimension: 1024, cacheBytes: 1024,
    129                                                            cacheEntries: 64, workers: 2, queuedRequests: 16, visibilityEntries: 2))
    130     let store = TeraMediaStore(runtimeClient: client, limits: limits)
    131     let context = TeraLocalNetwork.defaultContext(snapshot: TeraScopeFixtures.snapshot())
    132     let references = (0 ..< 3).map { reference($0, verification: .unavailable) }
    133     store.reconcileVisibility(previous: Array(references.prefix(2)), current: [], context: context)
    134     store.reconcileVisibility(previous: [references[0]], current: [], context: context)
    135     let artifact = try TeraScopeFixtures.artifact("a")
    136     store.load(media: references[2], context: context)
    137     await TeraScopeFixtures.eventually { store.state(for: references[2], context: context) == .ready(artifact) }
    138     store.reconcileVisibility(previous: [references[2]], current: [], context: context)
    139     for value in references {
    140       store.load(media: value, context: context)
    141       store.retry(media: value, context: context)
    142       XCTAssertEqual(store.state(for: value, context: context), .unavailable)
    143     }
    144     let calls = await backend.counts[.media]
    145     XCTAssertEqual(calls, 1)
    146     store.reconcileVisibility(previous: [], current: [references[2]], context: context)
    147     store.load(media: references[2], context: context)
    148     await TeraScopeFixtures.eventually { store.state(for: references[2], context: context) == .ready(artifact) }
    149     store.retry(media: references[0], context: context)
    150     let finalCalls = await backend.counts[.media]
    151     XCTAssertEqual(finalCalls, 2)
    152     store.reset()
    153     _ = try await client.stop()
    154   }
    155 
    156   @MainActor
    157   func testPendingStateEntryMaximumPlusOneIsBounded() async throws {
    158     let backend = try TeraScopeBackend()
    159     let client = try await TeraScopeFixtures.client(backend)
    160     let store = TeraMediaStore(runtimeClient: client)
    161     let context = TeraLocalNetwork.defaultContext(snapshot: TeraScopeFixtures.snapshot())
    162     for index in 0 ..< 64 {
    163       store.load(media: reference(index, verification: .pending), context: context)
    164     }
    165     XCTAssertEqual(store.stateCount, 64)
    166     store.load(media: reference(64, verification: .pending), context: context)
    167     XCTAssertEqual(store.stateCount, 64)
    168     let calls = await backend.counts[.media]
    169     XCTAssertNil(calls)
    170     store.reset()
    171     _ = try await client.stop()
    172   }
    173 
    174   private func reference(_ index: Int, verification: TeraMediaVerificationState) -> TeraMediaReference {
    175     let original = TeraScopeFixtures.reference()
    176     return TeraMediaReference(referenceFingerprint: String(format: "%064x", index),
    177                               url: original.url, sha256: original.sha256, mediaType: original.mediaType,
    178                               width: original.width, height: original.height, byteSize: original.byteSize,
    179                               alt: original.alt, verification: verification)
    180   }
    181 }