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 }