| | |
| | | XCTAssertEqual(AlignerAppInfo.minimumMacOSVersion, "14.0") |
| | | } |
| | | |
| | | func testPerformanceDiagnosticArchiveWriterCreatesInspectableArchive() throws { |
| | | let fileManager = FileManager.default |
| | | let rootURL = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) |
| | | let logURL = rootURL.appendingPathComponent("events.log") |
| | | let archiveURL = rootURL.appendingPathComponent("diagnostics.zip") |
| | | let extractionURL = rootURL.appendingPathComponent("extracted", isDirectory: true) |
| | | defer { try? fileManager.removeItem(at: rootURL) } |
| | | |
| | | try fileManager.createDirectory(at: rootURL, withIntermediateDirectories: true) |
| | | try "event=quickSwitch.snapshot.success durationMilliseconds=42\n".write(to: logURL, atomically: true, encoding: .utf8) |
| | | let summary = try JSONSerialization.data(withJSONObject: ["schemaVersion": 1], options: []) |
| | | |
| | | _ = try PerformanceDiagnosticArchiveWriter.write( |
| | | to: archiveURL, |
| | | summaryJSON: summary, |
| | | eventLogURLs: [logURL] |
| | | ) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: archiveURL.path)) |
| | | |
| | | let unzipProcess = Process() |
| | | unzipProcess.executableURL = URL(fileURLWithPath: "/usr/bin/ditto") |
| | | unzipProcess.arguments = ["-x", "-k", archiveURL.path, extractionURL.path] |
| | | try unzipProcess.run() |
| | | unzipProcess.waitUntilExit() |
| | | XCTAssertEqual(unzipProcess.terminationStatus, 0) |
| | | let contentsURL = extractionURL.appendingPathComponent("Aligner-Diagnostics", isDirectory: true) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: contentsURL.appendingPathComponent("summary.json").path)) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: contentsURL.appendingPathComponent("performance-events.log").path)) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: contentsURL.appendingPathComponent("README.txt").path)) |
| | | } |
| | | |
| | | func testPerformanceDiagnosticArchiveWriterDoesNotOverwriteExistingArchive() throws { |
| | | let fileManager = FileManager.default |
| | | let rootURL = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) |
| | | let archiveURL = rootURL.appendingPathComponent("diagnostics.zip") |
| | | defer { try? fileManager.removeItem(at: rootURL) } |
| | | |
| | | try fileManager.createDirectory(at: rootURL, withIntermediateDirectories: true) |
| | | try Data("existing archive".utf8).write(to: archiveURL) |
| | | let summary = try JSONSerialization.data(withJSONObject: ["schemaVersion": 1], options: []) |
| | | |
| | | XCTAssertThrowsError( |
| | | try PerformanceDiagnosticArchiveWriter.write( |
| | | to: archiveURL, |
| | | summaryJSON: summary, |
| | | eventLogURLs: [] |
| | | ) |
| | | ) |
| | | XCTAssertEqual(try Data(contentsOf: archiveURL), Data("existing archive".utf8)) |
| | | } |
| | | |
| | | func testPerformanceDiagnosticArchiveWriterFiltersSensitiveLogFields() throws { |
| | | let fileManager = FileManager.default |
| | | let rootURL = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) |
| | | let sourceLogURL = rootURL.appendingPathComponent("events.log") |
| | | let archiveURL = rootURL.appendingPathComponent("diagnostics.zip") |
| | | let extractionURL = rootURL.appendingPathComponent("extracted", isDirectory: true) |
| | | defer { try? fileManager.removeItem(at: rootURL) } |
| | | |
| | | try fileManager.createDirectory(at: rootURL, withIntermediateDirectories: true) |
| | | try "event=quickSwitch.snapshot.success ts=2026-08-14T00:00:00Z durationMilliseconds=42 reportPathBasename=private-notes.txt title=secret\n".write(to: sourceLogURL, atomically: true, encoding: .utf8) |
| | | let summary = try JSONSerialization.data(withJSONObject: ["schemaVersion": 1], options: []) |
| | | _ = try PerformanceDiagnosticArchiveWriter.write( |
| | | to: archiveURL, |
| | | summaryJSON: summary, |
| | | eventLogURLs: [sourceLogURL] |
| | | ) |
| | | |
| | | let unzipProcess = Process() |
| | | unzipProcess.executableURL = URL(fileURLWithPath: "/usr/bin/ditto") |
| | | unzipProcess.arguments = ["-x", "-k", archiveURL.path, extractionURL.path] |
| | | try unzipProcess.run() |
| | | unzipProcess.waitUntilExit() |
| | | XCTAssertEqual(unzipProcess.terminationStatus, 0) |
| | | let exportedLogURL = extractionURL |
| | | .appendingPathComponent("Aligner-Diagnostics", isDirectory: true) |
| | | .appendingPathComponent("performance-events.log") |
| | | let exportedLog = try String(contentsOf: exportedLogURL, encoding: .utf8) |
| | | XCTAssertTrue(exportedLog.contains("event=quickSwitch.snapshot.success")) |
| | | XCTAssertTrue(exportedLog.contains("durationMilliseconds=42")) |
| | | XCTAssertFalse(exportedLog.contains("private-notes.txt")) |
| | | XCTAssertFalse(exportedLog.contains("title=secret")) |
| | | } |
| | | |
| | | func testRound0OnlyDefinesQuickSwitchEntryPoint() { |
| | | XCTAssertEqual(EntryPoint.allCases, [.quickSwitch]) |
| | | } |