field_ios

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

FieldFileAccessUITestProbe.swift (4108B)


      1 import Foundation
      2 import RadrootsKit
      3 
      4 enum FieldFileAccessUITestProbe {
      5     private static let enabledKey = "RADROOTS_FIELD_IOS_UI_TEST_FILE_ACCESS_PROBE"
      6     private static let destructiveResetSentinel = RadrootsFileReference(
      7         scope: .data,
      8         relativePath: "ui_tests/file_access/destructive_reset_sentinel.txt"
      9     )
     10     private static let identityBoundarySentinel = RadrootsFileReference(
     11         scope: .data,
     12         relativePath: "ui_tests/file_access/identity_boundary_sentinel.txt"
     13     )
     14 
     15     static var isRequested: Bool {
     16         ProcessInfo.processInfo.environment[enabledKey] == "true"
     17     }
     18 
     19     static func seedDestructiveResetSentinelIfRequested(
     20         bundleIdentifier: String,
     21         resetLocalStateRequested: Bool
     22     ) throws {
     23         guard isRequested && resetLocalStateRequested else {
     24             return
     25         }
     26         try access(bundleIdentifier: bundleIdentifier).write(
     27             .inline(Data("destructive-reset-sentinel".utf8)),
     28             to: destructiveResetSentinel
     29         )
     30     }
     31 
     32     static func startupValue(
     33         bundleIdentifier: String,
     34         resetLocalStateRequested: Bool,
     35         loggingFileEnabled: Bool,
     36         loggingFileName: String
     37     ) throws -> String? {
     38         guard isRequested else {
     39             return nil
     40         }
     41         let fileAccess = try access(bundleIdentifier: bundleIdentifier)
     42         try fileAccess.write(
     43             .inline(Data("identity-boundary-sentinel".utf8)),
     44             to: identityBoundarySentinel
     45         )
     46         return try value(
     47             bundleIdentifier: bundleIdentifier,
     48             resetLocalStateRequested: resetLocalStateRequested,
     49             identityResetObserved: false,
     50             loggingFileEnabled: loggingFileEnabled,
     51             loggingFileName: loggingFileName
     52         )
     53     }
     54 
     55     static func identityResetValue(
     56         bundleIdentifier: String,
     57         loggingFileEnabled: Bool,
     58         loggingFileName: String
     59     ) throws -> String? {
     60         guard isRequested else {
     61             return nil
     62         }
     63         return try value(
     64             bundleIdentifier: bundleIdentifier,
     65             resetLocalStateRequested: false,
     66             identityResetObserved: true,
     67             loggingFileEnabled: loggingFileEnabled,
     68             loggingFileName: loggingFileName
     69         )
     70     }
     71 
     72     private static func value(
     73         bundleIdentifier: String,
     74         resetLocalStateRequested: Bool,
     75         identityResetObserved: Bool,
     76         loggingFileEnabled: Bool,
     77         loggingFileName: String
     78     ) throws -> String {
     79         let fileAccess = try access(bundleIdentifier: bundleIdentifier)
     80         let resetSentinelExists = try exists(destructiveResetSentinel, using: fileAccess)
     81         let identitySentinelExists = try exists(identityBoundarySentinel, using: fileAccess)
     82         let logFileURL = try FieldLocalState.logFileURL(bundleIdentifier: bundleIdentifier, fileName: loggingFileName)
     83         let logsRoot = try FieldLocalState.roots(bundleIdentifier: bundleIdentifier).root(for: .logs)
     84         let logURLUnderLogsRoot = logFileURL.path.hasPrefix(logsRoot.path + "/")
     85         let destructiveResetRemovedSentinel = resetLocalStateRequested ? !resetSentinelExists : true
     86         return [
     87             "destructive_reset_removed_sentinel=\(destructiveResetRemovedSentinel)",
     88             "identity_boundary_sentinel_exists=\(identitySentinelExists)",
     89             "identity_reset_observed=\(identityResetObserved)",
     90             "logging_file_enabled=\(loggingFileEnabled)",
     91             "log_url_under_logs_root=\(logURLUnderLogsRoot)"
     92         ].joined(separator: ";")
     93     }
     94 
     95     private static func exists(
     96         _ file: RadrootsFileReference,
     97         using fileAccess: RadrootsAppleFileAccess
     98     ) throws -> Bool {
     99         do {
    100             _ = try fileAccess.read(file, mode: .inline)
    101             return true
    102         } catch RadrootsAppleFileError.notFound(_) {
    103             return false
    104         }
    105     }
    106 
    107     private static func access(bundleIdentifier: String) throws -> RadrootsAppleFileAccess {
    108         try FieldLocalState.fileAccess(bundleIdentifier: bundleIdentifier)
    109     }
    110 }