Skip to content

Commit

Permalink
Add an extra-debug mode DD_TRACE_DEBUG_CALLSTACK , that also prints c…
Browse files Browse the repository at this point in the history
…allstacks after each log message
  • Loading branch information
Nacho Bonafonte committed Feb 14, 2023
1 parent b72d07f commit 827cf52
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 8 deletions.
7 changes: 6 additions & 1 deletion Sources/DatadogSDKTesting/DDEnvironmentValues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ internal enum ConfigurationValues: String, CaseIterable {
case DD_ENDPOINT
case DD_DONT_EXPORT
case DD_TRACE_DEBUG
case DD_TRACE_DEBUG_CALLSTACK
}

// These configuration values must not be passed to the child app in an UI test
Expand Down Expand Up @@ -134,6 +135,7 @@ internal struct DDEnvironmentValues {

/// The framework has been launched with extra debug information
let extraDebug: Bool
let extraDebugCallstack: Bool

/// Intelligent test runner related environment
let gitUploadEnabled: Bool
Expand Down Expand Up @@ -288,8 +290,11 @@ internal struct DDEnvironmentValues {
let envReportHostname = DDEnvironmentValues.getEnvVariable(ExtraConfigurationValues.DD_CIVISIBILITY_REPORT_HOSTNAME.rawValue) as NSString?
reportHostname = envReportHostname?.boolValue ?? false

let envExtraDebugCallStack = DDEnvironmentValues.getEnvVariable(ConfigurationValues.DD_TRACE_DEBUG_CALLSTACK.rawValue) as NSString?
extraDebugCallstack = envExtraDebugCallStack?.boolValue ?? false

let envExtraDebug = DDEnvironmentValues.getEnvVariable(ConfigurationValues.DD_TRACE_DEBUG.rawValue) as NSString?
extraDebug = envExtraDebug?.boolValue ?? false
extraDebug = envExtraDebug?.boolValue ?? extraDebugCallstack

/// CI values
var branchEnv: String?
Expand Down
2 changes: 1 addition & 1 deletion Sources/DatadogSDKTesting/DDTestModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public class DDTestModule: NSObject, Encodable {
Log.debug("Module loading time interval: \(DDTestMonitor.clock.now.timeIntervalSince(beforeLoadingTime))")
}

func internalEnd(endTime: Date? = nil) {
private func internalEnd(endTime: Date? = nil) {
if DDTestMonitor.instance?.crashedModuleInfo != nil && anyTestExecuted == false {
//The module started after a crash and no test was executed because of ITR dont report it
DDTestMonitor.tracer.flush()
Expand Down
7 changes: 6 additions & 1 deletion Sources/DatadogSDKTesting/DDTestObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,20 @@ class DDTestObserver: NSObject, XCTestObservation {

func testBundleWillStart(_ testBundle: Bundle) {
let bundleName = testBundle.bundleURL.deletingPathExtension().lastPathComponent
Log.debug("testBundleWillStart: \(bundleName)")
module = DDTestModule.start(bundleName: bundleName)
module?.testFramework = "XCTest"
}

func testBundleDidFinish(_ testBundle: Bundle) {
/// We need to wait for all the traces to be written to the backend before exiting
module?.end()
Log.debug("testBundleDidFinish: \(testBundle.bundleURL.deletingPathExtension().lastPathComponent)")
}

func testSuiteWillStart(_ testSuite: XCTestSuite) {
if module?.configError ?? false {
Log.debug("testSuiteWillStart: Failed, module config error")
testSuite.testRun?.stop()
exit(1)
}
Expand All @@ -51,7 +54,6 @@ class DDTestObserver: NSObject, XCTestObservation {
else {
return
}

Log.measure(name: "waiting itrWorkQueue") {
DDTestMonitor.instance?.itrWorkQueue.waitUntilAllOperationsAreFinished()
}
Expand All @@ -62,6 +64,7 @@ class DDTestObserver: NSObject, XCTestObservation {
testSuite.setValue(finalTests, forKey: "_mutableTests")
if !finalTests.isEmpty {
suite = module.suiteStart(name: testSuite.name)
Log.debug("testSuiteWillStart: \(testSuite.name)")
}
let testsToSkip = tests.count - finalTests.count
Log.print("ITR skipped \(testsToSkip) tests")
Expand All @@ -70,6 +73,7 @@ class DDTestObserver: NSObject, XCTestObservation {
}
} else {
suite = module.suiteStart(name: testSuite.name)
Log.debug("testSuiteWillStart: \(testSuite.name)")
}
}

Expand All @@ -78,6 +82,7 @@ class DDTestObserver: NSObject, XCTestObservation {
tests.firstObject is XCTestCase
{
suite?.end()
Log.debug("testSuiteDidFinish: \(testSuite.name)")
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/DatadogSDKTesting/DDTestSuite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class DDTestSuite: NSObject, Encodable {
}
}

func internalEnd(endTime: Date? = nil) {
private func internalEnd(endTime: Date? = nil) {
duration = (endTime ?? DDTestMonitor.clock.now).timeIntervalSince(startTime).toNanoseconds
/// Export module event

Expand Down
10 changes: 7 additions & 3 deletions Sources/DatadogSDKTesting/ImageSymbols/DDSymbolicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -295,11 +295,15 @@ enum DDSymbolicator {
Spawn.commandToFile("/usr/bin/symbols -fullSourcePath -lazy \"\(imagePath)\"", outputPath: symbolsOutputURL.path)
return symbolsOutputURL
}


static func getCallStack() -> [String] {
static func getCallStack(hidesLibrarySymbols: Bool = true) -> [String] {
let callStackSymbols = Thread.callStackSymbols
let index = callStackSymbols.firstIndex { !$0.contains(exactWord: "DatadogSDKTesting") } ?? 0
let index: Array<String>.Index
if hidesLibrarySymbols {
index = callStackSymbols.firstIndex { !$0.contains(exactWord: "DatadogSDKTesting") } ?? callStackSymbols.startIndex
} else {
index = callStackSymbols.index(0, offsetBy: 2)
}

let demangled: [String] = callStackSymbols.dropFirst(index)
.map {
Expand Down
6 changes: 5 additions & 1 deletion Sources/DatadogSDKTesting/Utils/Log.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Foundation

struct Log {
private static var debugTracer = DDTestMonitor.env.extraDebug
private static var debugTracerCallstack = DDTestMonitor.env.extraDebugCallstack

private static func swiftPrint(_ string: String) {
Swift.print(string)
Expand All @@ -18,7 +19,7 @@ struct Log {
NSLog(string)
}

private static var printMethod: () -> (String) -> () = {
private static var printMethod: () -> (String) -> Void = {
let osActivityMode = DDEnvironmentValues.getEnvVariable("OS_ACTIVITY_MODE") ?? ""
if osActivityMode == "disable" {
return swiftPrint
Expand All @@ -30,6 +31,9 @@ struct Log {
static func debug(_ string: @autoclosure () -> String) {
if debugTracer {
Log.printMethod()("[Debug][DatadogSDKTesting] " + string() + "\n")
if debugTracerCallstack {
Swift.print("Callstack:\n" + DDSymbolicator.getCallStack(hidesLibrarySymbols: false).joined(separator: "\n") + "\n")
}
}
}

Expand Down

0 comments on commit 827cf52

Please sign in to comment.