Skip to content

Commit a0a55b4

Browse files
authored
Merge pull request #143 from slashmo/fix/noopspan-context-storage
Store BaggageContext in NoOpSpan
2 parents 0f5171d + 449e94b commit a0a55b4

10 files changed

+270
-165
lines changed

Sources/Instrumentation/InstrumentationSystem.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ public enum InstrumentationSystem {
5555
}
5656

5757
// for our testing we want to allow multiple bootstrapping
58-
internal static func bootstrapInternal(_ instrument: Instrument) {
58+
internal static func bootstrapInternal(_ instrument: Instrument?) {
5959
self.lock.withWriterLock {
60-
self._instrument = instrument
60+
self._instrument = instrument ?? NoOpInstrument()
6161
}
6262
}
6363

Sources/Tracing/NoOpTracer.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public struct NoOpTracer: Tracer {
2222
ofKind kind: SpanKind,
2323
at timestamp: Timestamp
2424
) -> Span {
25-
return NoOpSpan()
25+
return NoOpSpan(context: context.baggage)
2626
}
2727

2828
public func forceFlush() {}
@@ -46,8 +46,11 @@ public struct NoOpTracer: Tracer {
4646
Carrier == Extractor.Carrier {}
4747

4848
public final class NoOpSpan: Span {
49-
public var context: BaggageContext {
50-
return .init()
49+
public let context: BaggageContext
50+
public let isRecording = false
51+
52+
public init(context: BaggageContext) {
53+
self.context = context
5154
}
5255

5356
public func setStatus(_ status: SpanStatus) {}
@@ -67,8 +70,6 @@ public struct NoOpTracer: Tracer {
6770
}
6871
}
6972

70-
public let isRecording = false
71-
7273
public func end(at timestamp: Timestamp) {
7374
// ignore
7475
}

Tests/InstrumentationTests/InstrumentationSystemTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ import Baggage
1616
import XCTest
1717

1818
final class InstrumentationSystemTests: XCTestCase {
19+
override class func tearDown() {
20+
super.tearDown()
21+
InstrumentationSystem.bootstrapInternal(nil)
22+
}
23+
1924
func testItProvidesAccessToASingletonInstrument() {
2025
let tracer = FakeTracer()
2126
let instrument = FakeInstrument()

Tests/LinuxMain.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class LinuxMainRunnerImpl: LinuxMainRunner {
4444
testCase(TimestampTests.allTests),
4545
testCase(TracedLockTests.allTests),
4646
testCase(TracerTests.allTests),
47+
testCase(TracingInstrumentationSystemTests.allTests),
4748
])
4849
}
4950
}

Tests/TracingTests/TestTracer.swift

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import Baggage
15+
import Foundation
16+
import Instrumentation
17+
import Tracing
18+
19+
final class TestTracer: Tracer {
20+
private(set) var spans = [TestSpan]()
21+
22+
func startSpan(
23+
named operationName: String,
24+
context: BaggageContextCarrier,
25+
ofKind kind: SpanKind,
26+
at timestamp: Timestamp
27+
) -> Span {
28+
let span = TestSpan(
29+
operationName: operationName,
30+
startTimestamp: timestamp,
31+
context: context.baggage,
32+
kind: kind
33+
) { _ in }
34+
self.spans.append(span)
35+
return span
36+
}
37+
38+
public func forceFlush() {}
39+
40+
func extract<Carrier, Extractor>(_ carrier: Carrier, into context: inout BaggageContext, using extractor: Extractor)
41+
where
42+
Extractor: ExtractorProtocol,
43+
Carrier == Extractor.Carrier
44+
{
45+
let traceID = extractor.extract(key: "trace-id", from: carrier) ?? UUID().uuidString
46+
context.traceID = traceID
47+
}
48+
49+
func inject<Carrier, Injector>(_ context: BaggageContext, into carrier: inout Carrier, using injector: Injector)
50+
where
51+
Injector: InjectorProtocol,
52+
Carrier == Injector.Carrier
53+
{
54+
guard let traceID = context.traceID else { return }
55+
injector.inject(traceID, forKey: "trace-id", into: &carrier)
56+
}
57+
}
58+
59+
extension TestTracer {
60+
enum TraceIDKey: BaggageContextKey {
61+
typealias Value = String
62+
}
63+
}
64+
65+
extension BaggageContext {
66+
var traceID: String? {
67+
get {
68+
return self[TestTracer.TraceIDKey.self]
69+
}
70+
set {
71+
self[TestTracer.TraceIDKey.self] = newValue
72+
}
73+
}
74+
}
75+
76+
final class TestSpan: Span {
77+
private let operationName: String
78+
private let kind: SpanKind
79+
80+
private var status: SpanStatus?
81+
82+
private let startTimestamp: Timestamp
83+
private(set) var endTimestamp: Timestamp?
84+
85+
let context: BaggageContext
86+
87+
private(set) var events = [SpanEvent]() {
88+
didSet {
89+
self.isRecording = !self.events.isEmpty
90+
}
91+
}
92+
93+
private(set) var links = [SpanLink]()
94+
95+
var attributes: SpanAttributes = [:] {
96+
didSet {
97+
self.isRecording = !self.attributes.isEmpty
98+
}
99+
}
100+
101+
private(set) var isRecording = false
102+
103+
let onEnd: (Span) -> Void
104+
105+
init(
106+
operationName: String,
107+
startTimestamp: Timestamp,
108+
context: BaggageContext,
109+
kind: SpanKind,
110+
onEnd: @escaping (Span) -> Void
111+
) {
112+
self.operationName = operationName
113+
self.startTimestamp = startTimestamp
114+
self.context = context
115+
self.onEnd = onEnd
116+
self.kind = kind
117+
}
118+
119+
func setStatus(_ status: SpanStatus) {
120+
self.status = status
121+
self.isRecording = true
122+
}
123+
124+
func addLink(_ link: SpanLink) {
125+
self.links.append(link)
126+
}
127+
128+
func addEvent(_ event: SpanEvent) {
129+
self.events.append(event)
130+
}
131+
132+
func recordError(_ error: Error) {}
133+
134+
func end(at timestamp: Timestamp) {
135+
self.endTimestamp = timestamp
136+
self.onEnd(self)
137+
}
138+
}

Tests/TracingTests/TracedLockTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ import Tracing
1818
import XCTest
1919

2020
final class TracedLockTests: XCTestCase {
21+
override class func tearDown() {
22+
super.tearDown()
23+
InstrumentationSystem.bootstrapInternal(nil)
24+
}
25+
2126
func test_tracesLockedTime() {
2227
let tracer = TracedLockPrintlnTracer()
2328
InstrumentationSystem.bootstrapInternal(tracer)

Tests/TracingTests/TracerTests+XCTest.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ extension TracerTests {
2525
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
2626
static var allTests : [(String, (TracerTests) -> () throws -> Void)] {
2727
return [
28-
("testPlayground", testPlayground),
29-
("testItProvidesAccessToATracer", testItProvidesAccessToATracer),
28+
("testContextPropagation", testContextPropagation),
29+
("testContextPropagationWithNoOpSpan", testContextPropagationWithNoOpSpan),
3030
]
3131
}
3232
}

0 commit comments

Comments
 (0)