Skip to content

Commit

Permalink
Refactor Chrome Trace
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladislav Alekseev committed Aug 12, 2019
1 parent 25cb63f commit c0cea8c
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 116 deletions.
9 changes: 9 additions & 0 deletions Sources/ChromeTracing/ChromeTrace.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

public final class ChromeTrace: Encodable {
public let traceEvents: [ChromeTraceEvent]

public init(traceEvents: [ChromeTraceEvent]) {
self.traceEvents = traceEvents
}
}
43 changes: 43 additions & 0 deletions Sources/ChromeTracing/ChromeTraceEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Foundation

open class ChromeTraceEvent: Encodable {
public let category: String
public let name: String
public let timestamp: EventTime
public let phase: Phase
public let processId: String
public let threadId: String
public let args: [String: EventArgumentValue]?
public let color: ColorName?

private enum CodingKeys: String, CodingKey {
case category = "cat"
case name = "name"
case timestamp = "ts"
case phase = "ph"
case processId = "pid"
case threadId = "tid"
case args = "args"
case color = "cname"
}

public init(
category: String,
name: String,
timestamp: EventTime,
phase: Phase,
processId: String,
threadId: String,
args: [String: EventArgumentValue]? = nil,
color: ColorName? = nil
) {
self.category = category
self.name = name
self.timestamp = timestamp
self.phase = phase
self.processId = processId
self.threadId = threadId
self.args = args
self.color = color
}
}
116 changes: 0 additions & 116 deletions Sources/ChromeTracing/ChromeTracing.swift

This file was deleted.

7 changes: 7 additions & 0 deletions Sources/ChromeTracing/ColorName.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Foundation

public enum ColorName: String, Encodable {
case good = "good"
case bad = "bad"
case terrible = "terrible"
}
31 changes: 31 additions & 0 deletions Sources/ChromeTracing/CompleteEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Foundation

public final class CompleteEvent: ChromeTraceEvent {
public let duration: EventTime

private enum CodingKeys: String, CodingKey {
case duration = "dur"
}

public init(
category: String,
name: String,
timestamp: EventTime,
duration: EventTime,
processId: String,
threadId: String,
args: [String: EventArgumentValue]? = nil,
color: ColorName? = nil
) {
self.duration = duration
super.init(
category: category,
name: name,
timestamp: timestamp,
phase: .complete,
processId: processId,
threadId: threadId,
args: args
)
}
}
25 changes: 25 additions & 0 deletions Sources/ChromeTracing/CounterEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Foundation

/// Counter values are provided via args, e.g. ["cats": 10]
public final class CounterEvent: ChromeTraceEvent {
public init(
category: String,
name: String,
timestamp: EventTime,
processId: String,
threadId: String,
args: [String: EventArgumentValue],
color: ColorName? = nil
) {
super.init(
category: category,
name: name,
timestamp: timestamp,
phase: .counter,
processId: processId,
threadId: threadId,
args: args,
color: color
)
}
}
13 changes: 13 additions & 0 deletions Sources/ChromeTracing/EventArgumentValue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Foundation

public final class EventArgumentValue: Encodable {
public let payload: Encodable

public init(payload: Encodable) {
self.payload = payload
}

public func encode(to encoder: Encoder) throws {
try payload.encode(to: encoder)
}
}
18 changes: 18 additions & 0 deletions Sources/ChromeTracing/EventTime.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Foundation

public final class EventTime: Encodable {
public let microTime: TimeInterval

public init(microTime: TimeInterval) {
self.microTime = microTime
}

public static func seconds(_ seconds: TimeInterval) -> EventTime {
return EventTime(microTime: seconds * 1000 * 1000)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(microTime)
}
}
43 changes: 43 additions & 0 deletions Sources/ChromeTracing/InstantEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Foundation

public final class InstantEvent: ChromeTraceEvent {
public let scope: Scope

public enum Scope: String, Encodable {
/// will draw instant event time from the top to the bottom of the timeline
case global = "g"

/// will draw instant event time through all threads of a given process
case process = "p"

/// will draw instant event time of a single thread
case thread = "t"
}

private enum CodingKeys: String, CodingKey {
case scope = "s"
}

public init(
category: String,
name: String,
timestamp: EventTime,
scope: Scope = .thread,
processId: String,
threadId: String,
args: [String: EventArgumentValue]? = nil,
color: ColorName? = nil
) {
self.scope = scope
super.init(
category: category,
name: name,
timestamp: timestamp,
phase: .instant,
processId: processId,
threadId: threadId,
args: args,
color: color
)
}
}
9 changes: 9 additions & 0 deletions Sources/ChromeTracing/Phase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Extensions
import Foundation
import Models

public enum Phase: String, Encodable {
case complete = "X"
case instant = "i"
case counter = "C"
}
38 changes: 38 additions & 0 deletions Sources/EmceeLib/Utils/ChromeTraceGenerator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import ChromeTracing
import Foundation
import Models

public final class ChromeTraceGenerator {
private let testingResult: CombinedTestingResults

public init(testingResult: CombinedTestingResults) {
self.testingResult = testingResult
}

private func createEventsForTest(
testResult: TestEntryResult
) -> [ChromeTraceEvent] {
let testName = testResult.testEntry.testName

return testResult.testRunResults.map { testRunResult -> ChromeTraceEvent in
return CompleteEvent(
category: "test_run",
name: testName.stringValue,
timestamp: .seconds(testRunResult.startTime),
duration: .seconds(testRunResult.duration),
processId: testRunResult.hostName,
threadId: testRunResult.simulatorId,
color: testRunResult.succeeded ? .good : .bad
)
}
}

public func writeReport(path: String) throws {
let events = testingResult.unfilteredResults.flatMap { (testResult: TestEntryResult) in
createEventsForTest(testResult: testResult)
}
let chromeTrace = ChromeTrace(traceEvents: events)
let report = try JSONEncoder.pretty().encode(chromeTrace)
try report.write(to: URL(fileURLWithPath: path), options: [.atomicWrite])
}
}

0 comments on commit c0cea8c

Please sign in to comment.