149 lines · 6.4 KB · Swift
RawDownload
import Foundation#if canImport(SQLite3)import SQLite3import Testing@testable import CodexBarCore /// Regression gates for the two cost-usage scan-storm classes that have shipped before:/// re-parsing unchanged session files on every refresh (#1387, #1392) and re-running the/// full trace-database scan on every refresh (#1392, the pre-memo priority-turns path).@Suite(.serialized)struct CostUsagePerformanceGateTests {    @Test    func `warm codex refresh over an unchanged session corpus must not re-parse it`() throws {        let env = try CostUsageTestEnvironment()        defer { env.cleanup() }        let day = try env.makeLocalNoon(year: 2026, month: 5, day: 10)        let fileURLs = try Self.writeSyntheticCodexCorpus(env: env, day: day, files: 2, turnsPerFile: 4)         var options = CostUsageScanner.Options(            codexSessionsRoot: env.codexSessionsRoot,            claudeProjectsRoots: nil,            cacheRoot: env.cacheRoot,            codexTraceDatabaseURL: env.root.appendingPathComponent("missing.sqlite"))        options.refreshMinIntervalSeconds = 0         let cold = CostUsageScanner.loadDailyReport(            provider: .codex,            since: day,            until: day,            now: day,            options: options)         let changedFile = try #require(fileURLs.first)        let originalAttributes = try FileManager.default.attributesOfItem(atPath: changedFile.path)        let originalModificationDate = try #require(originalAttributes[.modificationDate] as? Date)        let original = try String(contentsOf: changedFile, encoding: .utf8)        let modified = original.replacingOccurrences(            of: #""input_tokens":100,"#,            with: #""input_tokens":900,"#)        #expect(modified != original)        #expect(modified.utf8.count == original.utf8.count)        try modified.write(to: changedFile, atomically: false, encoding: .utf8)        try FileManager.default.setAttributes(            [.modificationDate: originalModificationDate],            ofItemAtPath: changedFile.path)         let warm = CostUsageScanner.loadDailyReport(            provider: .codex,            since: day,            until: day,            now: day,            options: options)         #expect(cold.data.count == 1)        #expect(warm.data.first?.totalTokens == cold.data.first?.totalTokens)    }     @Test    func `priority turns refresh must scan only appended trace rows`() throws {        let env = try CostUsageTestEnvironment()        defer { env.cleanup() }        let dbURL = env.root.appendingPathComponent("logs_2.sqlite")        try CostUsageScannerCodexPriorityTests.createTestLogsDatabase(at: dbURL)         let epoch: Int64 = 1_760_000_000        var rows: [(epochSeconds: Int64, body: String)] = (0..<50).map { index in            (epochSeconds: epoch, body: "thread_id=t-\(index) turn.id=u-\(index) routine trace row")        }        rows.append((            epochSeconds: epoch,            body: "thread_id=thread-a turn.id=turn-a websocket request: "                + #"{"type":"response.create","model":"gpt-5.5","service_tier":"priority"}"#))        try CostUsageScannerCodexPriorityTests.insertTestLogs(dbURL: dbURL, rows: rows)         let full = CostUsageScanner.codexPriorityTurns(databaseURL: dbURL)        #expect(full.keys.sorted() == ["turn-a"])        let scanned = try #require(CostUsageScanner._test_codexPriorityTurnsMemoState(forPath: dbURL.path))         try Self.replaceTraceBody(            dbURL: dbURL,            rowID: 1,            body: "thread_id=mutated turn.id=mutated-old websocket request: "                + #"{"type":"response.create","model":"gpt-5.5","service_tier":"priority"}"#)        try CostUsageScannerCodexPriorityTests.insertTestLogs(dbURL: dbURL, rows: [(            epochSeconds: epoch,            body: "thread_id=thread-b turn.id=turn-b websocket request: "                + #"{"type":"response.create","model":"gpt-5.5","service_tier":"priority"}"#)])         let refreshed = CostUsageScanner.codexPriorityTurns(databaseURL: dbURL)         #expect(refreshed.keys.sorted() == ["turn-a", "turn-b"])        let advanced = try #require(CostUsageScanner._test_codexPriorityTurnsMemoState(forPath: dbURL.path))        #expect(advanced.lastRowID == scanned.lastRowID + 1)    }     private static func writeSyntheticCodexCorpus(        env: CostUsageTestEnvironment,        day: Date,        files: Int,        turnsPerFile: Int) throws -> [URL]    {        let model = "openai/gpt-5.2-codex"        let baseISO = env.isoString(for: day)        var fileURLs: [URL] = []        for fileIndex in 0..<files {            var lines: [String] = []            lines.reserveCapacity(turnsPerFile + 2)            lines.append(                #"{"type":"session_meta","timestamp":"\#(baseISO)","payload":{"session_id":"perf-\#(fileIndex)"}}"#)            lines.append(                #"{"type":"turn_context","timestamp":"\#(baseISO)","payload":{"model":"\#(model)"}}"#)            for turn in 1...turnsPerFile {                lines.append(                    #"{"type":"event_msg","timestamp":"\#(baseISO)","payload":{"type":"token_count","info":"#                        + #"{"total_token_usage":{"input_tokens":\#(turn * 100),"cached_input_tokens":\#(turn * 20),"#                        + #""output_tokens":\#(turn * 10)},"model":"\#(model)"}}}"#)            }            let fileURL = try env.writeCodexSessionFile(                day: day,                filename: "session-\(fileIndex).jsonl",                contents: lines.joined(separator: "\n") + "\n")            fileURLs.append(fileURL)        }        return fileURLs    }     private static func replaceTraceBody(dbURL: URL, rowID: Int64, body: String) throws {        var db: OpaquePointer?        guard sqlite3_open(dbURL.path, &db) == SQLITE_OK else {            throw CocoaError(.fileReadUnknown)        }        defer { sqlite3_close(db) }         var statement: OpaquePointer?        guard sqlite3_prepare_v2(db, "update logs set feedback_log_body = ? where id = ?", -1, &statement, nil)            == SQLITE_OK        else {            throw CocoaError(.fileWriteUnknown)        }        defer { sqlite3_finalize(statement) }         sqlite3_bind_text(statement, 1, body, -1, unsafeBitCast(-1, to: sqlite3_destructor_type.self))        sqlite3_bind_int64(statement, 2, rowID)        guard sqlite3_step(statement) == SQLITE_DONE else {            throw CocoaError(.fileWriteUnknown)        }    }}#endif