diff --git a/Sources/CoreMetrics/Metrics.swift b/Sources/CoreMetrics/Metrics.swift index 76af407..8a343fa 100644 --- a/Sources/CoreMetrics/Metrics.swift +++ b/Sources/CoreMetrics/Metrics.swift @@ -231,6 +231,36 @@ public final class Meter { public func set(_ value: DataType) { self._handler.set(Double(value)) } + + /// Increment the Meter. + /// + /// - parameters: + /// - by: Amount to increment by. + @inlinable + public func increment(by amount: DataType) { + self._handler.increment(by: Double(amount)) + } + + /// Increment the Meter by one. + @inlinable + public func increment() { + self.increment(by: 1.0) + } + + /// Decrement the Meter. + /// + /// - parameters: + /// - by: Amount to decrement by. + @inlinable + public func decrement(by amount: DataType) { + self._handler.decrement(by: Double(amount)) + } + + /// Decrement the Meter by one. + @inlinable + public func decrement() { + self.decrement(by: 1.0) + } } extension Meter { @@ -787,6 +817,24 @@ internal final class AccumulatingMeter: MeterHandler { } func increment(by amount: Double) { + // Drop illegal values + // - cannot increment by NaN + guard !amount.isNaN else { + return + } + // - cannot increment by infinite quantities + guard !amount.isInfinite else { + return + } + // - cannot increment by negative values + guard amount.sign == .plus else { + return + } + // - cannot increment by zero + guard !amount.isZero else { + return + } + let newValue: Double = self.lock.withLock { self.value += amount return self.value @@ -795,6 +843,24 @@ internal final class AccumulatingMeter: MeterHandler { } func decrement(by amount: Double) { + // Drop illegal values + // - cannot decrement by NaN + guard !amount.isNaN else { + return + } + // - cannot decrement by infinite quantities + guard !amount.isInfinite else { + return + } + // - cannot decrement by negative values + guard amount.sign == .plus else { + return + } + // - cannot decrement by zero + guard !amount.isZero else { + return + } + let newValue: Double = self.lock.withLock { self.value -= amount return self.value diff --git a/Sources/MetricsTestKit/TestMetrics.swift b/Sources/MetricsTestKit/TestMetrics.swift index 28b045e..30c1941 100644 --- a/Sources/MetricsTestKit/TestMetrics.swift +++ b/Sources/MetricsTestKit/TestMetrics.swift @@ -57,7 +57,7 @@ public final class TestMetrics: MetricsFactory { // nothing to do } - /// Reset method to destroy all created ``TestCounter``, ``TestRecorder`` and ``TestTimer``. + /// Reset method to destroy all created ``TestCounter``, ``TestMeter``, ``TestRecorder`` and ``TestTimer``. /// Invoke this method in between test runs to verify that Counters are created as needed. public func reset() { self.lock.withLock { @@ -361,7 +361,7 @@ public final class TestMeter: TestMetric, MeterHandler, Equatable { private var _values = [(Date, Double)]() init(label: String, dimensions: [(String, String)]) { - self.id = NSUUID().uuidString + self.id = UUID().uuidString self.label = label self.dimensions = dimensions } @@ -378,18 +378,54 @@ public final class TestMeter: TestMetric, MeterHandler, Equatable { } public func increment(by amount: Double) { + // Drop illegal values + // - cannot increment by NaN + guard !amount.isNaN else { + return + } + // - cannot increment by infinite quantities + guard !amount.isInfinite else { + return + } + // - cannot increment by negative values + guard amount.sign == .plus else { + return + } + // - cannot increment by zero + guard !amount.isZero else { + return + } + self.lock.withLock { - let lastValue = self._values.last?.1 ?? 0 - let newValue = lastValue - amount - _values.append((Date(), Double(newValue))) + let lastValue: Double = self._values.last?.1 ?? 0 + let newValue = lastValue + amount + _values.append((Date(), newValue)) } } public func decrement(by amount: Double) { + // Drop illegal values + // - cannot decrement by NaN + guard !amount.isNaN else { + return + } + // - cannot decrement by infinite quantities + guard !amount.isInfinite else { + return + } + // - cannot decrement by negative values + guard amount.sign == .plus else { + return + } + // - cannot decrement by zero + guard !amount.isZero else { + return + } + self.lock.withLock { - let lastValue = self._values.last?.1 ?? 0 + let lastValue: Double = self._values.last?.1 ?? 0 let newValue = lastValue - amount - _values.append((Date(), Double(newValue))) + _values.append((Date(), newValue)) } } @@ -428,7 +464,7 @@ public final class TestRecorder: TestMetric, RecorderHandler, Equatable { private var _values = [(Date, Double)]() init(label: String, dimensions: [(String, String)], aggregate: Bool) { - self.id = NSUUID().uuidString + self.id = UUID().uuidString self.label = label self.dimensions = dimensions self.aggregate = aggregate diff --git a/Tests/MetricsTests/CoreMetricsTests+XCTest.swift b/Tests/MetricsTests/CoreMetricsTests+XCTest.swift index b76f0bd..abdf4c9 100644 --- a/Tests/MetricsTests/CoreMetricsTests+XCTest.swift +++ b/Tests/MetricsTests/CoreMetricsTests+XCTest.swift @@ -46,6 +46,14 @@ extension MetricsTests { ("testGaugeBlock", testGaugeBlock), ("testMeter", testMeter), ("testMeterBlock", testMeterBlock), + ("testMeterInt", testMeterInt), + ("testMeterFloat", testMeterFloat), + ("testMeterIncrement", testMeterIncrement), + ("testMeterDecrement", testMeterDecrement), + ("testDefaultMeterIgnoresNan", testDefaultMeterIgnoresNan), + ("testDefaultMeterIgnoresInfinity", testDefaultMeterIgnoresInfinity), + ("testDefaultMeterIgnoresNegativeValues", testDefaultMeterIgnoresNegativeValues), + ("testDefaultMeterIgnoresZero", testDefaultMeterIgnoresZero), ("testMUX_Counter", testMUX_Counter), ("testMUX_Meter", testMUX_Meter), ("testMUX_Recorder", testMUX_Recorder), diff --git a/Tests/MetricsTests/CoreMetricsTests.swift b/Tests/MetricsTests/CoreMetricsTests.swift index de5c98e..bf62fe4 100644 --- a/Tests/MetricsTests/CoreMetricsTests.swift +++ b/Tests/MetricsTests/CoreMetricsTests.swift @@ -24,17 +24,17 @@ class MetricsTests: XCTestCase { let group = DispatchGroup() let name = "counter-\(UUID().uuidString)" let counter = Counter(label: name) - let testCounter = counter._handler as! TestCounter + let testCounter = try metrics.expectCounter(counter) let total = Int.random(in: 500 ... 1000) - for _ in 0 ... total { + for _ in 0 ..< total { group.enter() DispatchQueue(label: "\(name)-queue").async { + defer { group.leave() } counter.increment(by: Int.random(in: 0 ... 1000)) - group.leave() } } group.wait() - XCTAssertEqual(testCounter.values.count - 1, total, "expected number of entries to match") + XCTAssertEqual(testCounter.values.count, total, "expected number of entries to match") testCounter.reset() XCTAssertEqual(testCounter.values.count, 0, "expected number of entries to match") } @@ -153,17 +153,17 @@ class MetricsTests: XCTestCase { let group = DispatchGroup() let name = "recorder-\(UUID().uuidString)" let recorder = Recorder(label: name) - let testRecorder = recorder._handler as! TestRecorder + let testRecorder = try metrics.expectRecorder(recorder) let total = Int.random(in: 500 ... 1000) - for _ in 0 ... total { + for _ in 0 ..< total { group.enter() DispatchQueue(label: "\(name)-queue").async { + defer { group.leave() } recorder.record(Int.random(in: Int.min ... Int.max)) - group.leave() } } group.wait() - XCTAssertEqual(testRecorder.values.count - 1, total, "expected number of entries to match") + XCTAssertEqual(testRecorder.values.count, total, "expected number of entries to match") } func testRecordersInt() throws { @@ -171,13 +171,13 @@ class MetricsTests: XCTestCase { let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) let recorder = Recorder(label: "test-recorder") - let testRecorder = recorder._handler as! TestRecorder + let testRecorder = try metrics.expectRecorder(recorder) let values = (0 ... 999).map { _ in Int32.random(in: Int32.min ... Int32.max) } - for i in 0 ... values.count - 1 { + for i in 0 ..< values.count { recorder.record(values[i]) } XCTAssertEqual(values.count, testRecorder.values.count, "expected number of entries to match") - for i in 0 ... values.count - 1 { + for i in 0 ..< values.count { XCTAssertEqual(Int32(testRecorder.values[i]), values[i], "expected value #\(i) to match.") } } @@ -187,13 +187,13 @@ class MetricsTests: XCTestCase { let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) let recorder = Recorder(label: "test-recorder") - let testRecorder = recorder._handler as! TestRecorder + let testRecorder = try metrics.expectRecorder(recorder) let values = (0 ... 999).map { _ in Float.random(in: Float(Int32.min) ... Float(Int32.max)) } - for i in 0 ... values.count - 1 { + for i in 0 ..< values.count { recorder.record(values[i]) } XCTAssertEqual(values.count, testRecorder.values.count, "expected number of entries to match") - for i in 0 ... values.count - 1 { + for i in 0 ..< values.count { XCTAssertEqual(Float(testRecorder.values[i]), values[i], "expected value #\(i) to match.") } } @@ -218,17 +218,17 @@ class MetricsTests: XCTestCase { let group = DispatchGroup() let name = "timer-\(UUID().uuidString)" let timer = Timer(label: name) - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) let total = Int.random(in: 500 ... 1000) - for _ in 0 ... total { + for _ in 0 ..< total { group.enter() DispatchQueue(label: "\(name)-queue").async { + defer { group.leave() } timer.recordNanoseconds(Int64.random(in: Int64.min ... Int64.max)) - group.leave() } } group.wait() - XCTAssertEqual(testTimer.values.count - 1, total, "expected number of entries to match") + XCTAssertEqual(testTimer.values.count, total, "expected number of entries to match") } func testTimerBlock() throws { @@ -250,7 +250,7 @@ class MetricsTests: XCTestCase { MetricsSystem.bootstrapInternal(metrics) // run the test let timer = Timer(label: "test-timer") - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) // nano let nano = Int64.random(in: 0 ... 5) timer.recordNanoseconds(nano) @@ -279,7 +279,7 @@ class MetricsTests: XCTestCase { MetricsSystem.bootstrapInternal(metrics) // run the test let timer = Timer(label: "test-timer") - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) // nano (integer) timer.recordNanoseconds(Int64.max) XCTAssertEqual(testTimer.values.count, 1, "expected number of entries to match") @@ -316,7 +316,7 @@ class MetricsTests: XCTestCase { MetricsSystem.bootstrapInternal(metrics) // run the test let timer = Timer(label: "test-timer") - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) // nano timer.recordNanoseconds(UInt64.max) XCTAssertEqual(testTimer.values.count, 1, "expected number of entries to match") @@ -344,7 +344,7 @@ class MetricsTests: XCTestCase { let value = Double.random(in: -1000 ... 1000) let gauge = Gauge(label: name) gauge.record(value) - let recorder = gauge._handler as! TestRecorder + let recorder = try metrics.expectRecorder(gauge) XCTAssertEqual(recorder.values.count, 1, "expected number of entries to match") XCTAssertEqual(recorder.lastValue, value, "expected value to match") } @@ -367,11 +367,11 @@ class MetricsTests: XCTestCase { let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) // run the test - let name = "meter-\(NSUUID().uuidString)" + let name = "meter-\(UUID().uuidString)" let value = Double.random(in: -1000 ... 1000) let meter = Meter(label: name) meter.set(value) - let testMeter = meter._handler as! TestMeter + let testMeter = try metrics.expectMeter(meter) XCTAssertEqual(testMeter.values.count, 1, "expected number of entries to match") XCTAssertEqual(testMeter.values[0], value, "expected value to match") } @@ -381,7 +381,7 @@ class MetricsTests: XCTestCase { let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) // run the test - let name = "meter-\(NSUUID().uuidString)" + let name = "meter-\(UUID().uuidString)" let value = Double.random(in: -1000 ... 1000) Meter(label: name).set(value) let testMeter = try metrics.expectMeter(name) @@ -389,6 +389,134 @@ class MetricsTests: XCTestCase { XCTAssertEqual(testMeter.values[0], value, "expected value to match") } + func testMeterInt() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + let values = (0 ... 999).map { _ in Int32.random(in: Int32.min ... Int32.max) } + for i in 0 ..< values.count { + meter.set(values[i]) + } + XCTAssertEqual(values.count, testMeter.values.count, "expected number of entries to match") + for i in 0 ..< values.count { + XCTAssertEqual(Int32(testMeter.values[i]), values[i], "expected value #\(i) to match.") + } + } + + func testMeterFloat() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + let values = (0 ... 999).map { _ in Float.random(in: Float(Int32.min) ... Float(Int32.max)) } + for i in 0 ..< values.count { + meter.set(values[i]) + } + XCTAssertEqual(values.count, testMeter.values.count, "expected number of entries to match") + for i in 0 ..< values.count { + XCTAssertEqual(Float(testMeter.values[i]), values[i], "expected value #\(i) to match.") + } + } + + func testMeterIncrement() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + // run the test + let group = DispatchGroup() + let name = "meter-\(UUID().uuidString)" + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + let values = (500 ... 1000).map { _ in Double.random(in: 0 ... Double(Int32.max)) } + for i in 0 ..< values.count { + group.enter() + DispatchQueue(label: "\(name)-queue").async { + defer { group.leave() } + meter.increment(by: values[i]) + } + } + group.wait() + XCTAssertEqual(testMeter.values.count, values.count, "expected number of entries to match") + XCTAssertEqual(testMeter.values.last!, values.reduce(0.0, +), accuracy: 0.1, "expected total value to match") + } + + func testMeterDecrement() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + // run the test + let group = DispatchGroup() + let name = "meter-\(UUID().uuidString)" + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + + let values = (500 ... 1000).map { _ in Double.random(in: 0 ... Double(Int32.max)) } + for i in 0 ..< values.count { + group.enter() + DispatchQueue(label: "\(name)-queue").async { + defer { group.leave() } + meter.decrement(by: values[i]) + } + } + group.wait() + XCTAssertEqual(testMeter.values.count, values.count, "expected number of entries to match") + XCTAssertEqual(testMeter.values.last!, values.reduce(0.0, -), accuracy: 0.1, "expected total value to match") + } + + func testDefaultMeterIgnoresNan() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + // run the test + let name = "meter-\(UUID().uuidString)" + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + meter.increment(by: Double.nan) + meter.increment(by: Double.signalingNaN) + XCTAssertEqual(testMeter.values.count, 0, "expected nan values to be ignored") + } + + func testDefaultMeterIgnoresInfinity() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + // run the test + let name = "meter-\(UUID().uuidString)" + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + meter.increment(by: Double.infinity) + meter.increment(by: -Double.infinity) + XCTAssertEqual(testMeter.values.count, 0, "expected infinite values to be ignored") + } + + func testDefaultMeterIgnoresNegativeValues() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + // run the test + let name = "meter-\(UUID().uuidString)" + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + meter.increment(by: -100) + XCTAssertEqual(testMeter.values.count, 0, "expected negative values to be ignored") + } + + func testDefaultMeterIgnoresZero() throws { + // bootstrap with our test metrics + let metrics = TestMetrics() + MetricsSystem.bootstrapInternal(metrics) + // run the test + let name = "meter-\(UUID().uuidString)" + let meter = Meter(label: name) + let testMeter = try metrics.expectMeter(meter) + meter.increment(by: 0) + meter.increment(by: -0) + XCTAssertEqual(testMeter.values.count, 0, "expected zero values to be ignored") + } + func testMUX_Counter() throws { // bootstrap with our test metrics let factories = [TestMetrics(), TestMetrics(), TestMetrics()] @@ -416,7 +544,7 @@ class MetricsTests: XCTestCase { let factories = [TestMetrics(), TestMetrics(), TestMetrics()] MetricsSystem.bootstrapInternal(MultiplexMetricsHandler(factories: factories)) // run the test - let name = NSUUID().uuidString + let name = UUID().uuidString let value = Double.random(in: 0 ... 1) let muxMeter = Meter(label: name) muxMeter.set(value) @@ -486,7 +614,7 @@ class MetricsTests: XCTestCase { let gauge = Gauge(label: name) gauge.record(value) - let recorder = gauge._handler as! TestRecorder + let recorder = try metrics.expectRecorder(gauge) XCTAssertEqual(recorder.values.count, 1, "expected number of entries to match") XCTAssertEqual(recorder.values.first, value, "expected value to match") XCTAssertEqual(metrics.recorders.count, 1, "recorder should have been stored") @@ -498,7 +626,7 @@ class MetricsTests: XCTestCase { let gaugeAgain = Gauge(label: name) gaugeAgain.record(-value) - let recorderAgain = gaugeAgain._handler as! TestRecorder + let recorderAgain = try metrics.expectRecorder(gaugeAgain) XCTAssertEqual(recorderAgain.values.count, 1, "expected number of entries to match") XCTAssertEqual(recorderAgain.values.first, -value, "expected value to match") @@ -510,13 +638,13 @@ class MetricsTests: XCTestCase { let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) - let name = "meter-\(NSUUID().uuidString)" + let name = "meter-\(UUID().uuidString)" let value = Double.random(in: -1000 ... 1000) let meter = Meter(label: name) meter.set(value) - let testMeter = meter._handler as! TestMeter + let testMeter = try metrics.expectMeter(meter) XCTAssertEqual(testMeter.values.count, 1, "expected number of entries to match") XCTAssertEqual(testMeter.values.first, value, "expected value to match") XCTAssertEqual(metrics.meters.count, 1, "recorder should have been stored") @@ -528,7 +656,7 @@ class MetricsTests: XCTestCase { let meterAgain = Meter(label: name) meterAgain.set(-value) - let testMeterAgain = meterAgain._handler as! TestMeter + let testMeterAgain = try metrics.expectMeter(meterAgain) XCTAssertEqual(testMeterAgain.values.count, 1, "expected number of entries to match") XCTAssertEqual(testMeterAgain.values.first, -value, "expected value to match") @@ -546,7 +674,7 @@ class MetricsTests: XCTestCase { let counter = Counter(label: name) counter.increment(by: value) - let testCounter = counter._handler as! TestCounter + let testCounter = try metrics.expectCounter(counter) XCTAssertEqual(testCounter.values.count, 1, "expected number of entries to match") XCTAssertEqual(testCounter.values.first, Int64(value), "expected value to match") XCTAssertEqual(metrics.counters.count, 1, "counter should have been stored") @@ -558,7 +686,7 @@ class MetricsTests: XCTestCase { let counterAgain = Counter(label: name) counterAgain.increment(by: value) - let testCounterAgain = counterAgain._handler as! TestCounter + let testCounterAgain = try metrics.expectCounter(counterAgain) XCTAssertEqual(testCounterAgain.values.count, 1, "expected number of entries to match") XCTAssertEqual(testCounterAgain.values.first, Int64(value), "expected value to match") @@ -576,7 +704,7 @@ class MetricsTests: XCTestCase { let timer = Timer(label: name) timer.recordNanoseconds(value) - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) XCTAssertEqual(testTimer.values.count, 1, "expected number of entries to match") XCTAssertEqual(testTimer.values.first, value, "expected value to match") XCTAssertEqual(metrics.timers.count, 1, "timer should have been stored") @@ -587,7 +715,7 @@ class MetricsTests: XCTestCase { let timerAgain = Timer(label: name) timerAgain.recordNanoseconds(value) - let testTimerAgain = timerAgain._handler as! TestTimer + let testTimerAgain = try metrics.expectTimer(timerAgain) XCTAssertEqual(testTimerAgain.values.count, 1, "expected number of entries to match") XCTAssertEqual(testTimerAgain.values.first, value, "expected value to match") diff --git a/Tests/MetricsTests/MetricsTests.swift b/Tests/MetricsTests/MetricsTests.swift index 9c12bae..14139ad 100644 --- a/Tests/MetricsTests/MetricsTests.swift +++ b/Tests/MetricsTests/MetricsTests.swift @@ -39,7 +39,7 @@ class MetricsExtensionsTests: XCTestCase { MetricsSystem.bootstrapInternal(metrics) // run the test let timer = Timer(label: "test-timer") - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) let timeInterval = TimeInterval(Double.random(in: 1 ... 500)) timer.record(timeInterval) XCTAssertEqual(1, testTimer.values.count, "expected number of entries to match") @@ -52,7 +52,7 @@ class MetricsExtensionsTests: XCTestCase { MetricsSystem.bootstrapInternal(metrics) // run the test let timer = Timer(label: "test-timer") - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) // nano let nano = DispatchTimeInterval.nanoseconds(Int.random(in: 1 ... 500)) timer.record(nano) @@ -79,7 +79,7 @@ class MetricsExtensionsTests: XCTestCase { XCTAssertEqual(testTimer.values[4], 0, "expected value to match") } - func testTimerWithDispatchTimeInterval() { + func testTimerWithDispatchTimeInterval() throws { let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) @@ -90,7 +90,7 @@ class MetricsExtensionsTests: XCTestCase { let end = DispatchTime(uptimeNanoseconds: start.uptimeNanoseconds + 1000 * 1000 * 1000) timer.recordInterval(since: start, end: end) - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) XCTAssertEqual(testTimer.values.count, 1, "expected number of entries to match") XCTAssertEqual(UInt64(testTimer.values.first!), end.uptimeNanoseconds - start.uptimeNanoseconds, "expected value to match") XCTAssertEqual(metrics.timers.count, 1, "timer should have been stored") @@ -106,7 +106,7 @@ class MetricsExtensionsTests: XCTestCase { let timer = Timer(label: name) timer.recordNanoseconds(value) - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) XCTAssertEqual(testTimer.values.count, 1, "expected number of entries to match") XCTAssertEqual(testTimer.values.first, value, "expected value to match") XCTAssertEqual(metrics.timers.count, 1, "timer should have been stored") @@ -116,12 +116,12 @@ class MetricsExtensionsTests: XCTestCase { let secondsTimer = Timer(label: secondsName, preferredDisplayUnit: .seconds) secondsTimer.recordSeconds(secondsValue) - let testSecondsTimer = secondsTimer._handler as! TestTimer + let testSecondsTimer = try metrics.expectTimer(secondsTimer) XCTAssertEqual(testSecondsTimer.values.count, 1, "expected number of entries to match") XCTAssertEqual(metrics.timers.count, 2, "timer should have been stored") } - func testPreferDisplayUnit() { + func testPreferDisplayUnit() throws { let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) @@ -129,7 +129,7 @@ class MetricsExtensionsTests: XCTestCase { let timer = Timer(label: "test", preferredDisplayUnit: .seconds) timer.recordSeconds(value) - let testTimer = timer._handler as! TestTimer + let testTimer = try metrics.expectTimer(timer) testTimer.preferDisplayUnit(.nanoseconds) XCTAssertEqual(testTimer.valueInPreferredUnit(atIndex: 0), value * 1000 * 1000 * 1000, accuracy: 1.0, "expected value to match") diff --git a/Tests/MetricsTests/TestSendable.swift b/Tests/MetricsTests/TestSendable.swift index aa3191c..0ab0778 100644 --- a/Tests/MetricsTests/TestSendable.swift +++ b/Tests/MetricsTests/TestSendable.swift @@ -19,7 +19,7 @@ import XCTest class SendableTest: XCTestCase { #if compiler(>=5.6) - func testSendableMetrics() async { + func testSendableMetrics() async throws { // bootstrap with our test metrics let metrics = TestMetrics() MetricsSystem.bootstrapInternal(metrics) @@ -31,10 +31,10 @@ class SendableTest: XCTestCase { let task = Task.detached { () -> [Int64] in counter.increment(by: value) - let handler = counter._handler as! TestCounter + let handler = try metrics.expectCounter(counter) return handler.values } - let values = await task.value + let values = try await task.value XCTAssertEqual(values.count, 1, "expected number of entries to match") XCTAssertEqual(values[0], Int64(value), "expected value to match") } @@ -60,25 +60,25 @@ class SendableTest: XCTestCase { let task = Task.detached { () -> [Double] in recorder.record(value) - let handler = recorder._handler as! TestRecorder + let handler = try metrics.expectRecorder(recorder) return handler.values } - let values = await task.value + let values = try await task.value XCTAssertEqual(values.count, 1, "expected number of entries to match") XCTAssertEqual(values[0], value, "expected value to match") } do { - let name = "meter-\(NSUUID().uuidString)" + let name = "meter-\(UUID().uuidString)" let value = Double.random(in: -1000 ... 1000) let meter = Meter(label: name) let task = Task.detached { () -> [Double] in meter.set(value) - let handler = meter._handler as! TestMeter + let handler = try metrics.expectMeter(meter) return handler.values } - let values = await task.value + let values = try await task.value XCTAssertEqual(values.count, 1, "expected number of entries to match") XCTAssertEqual(values[0], value, "expected value to match") } @@ -90,10 +90,10 @@ class SendableTest: XCTestCase { let task = Task.detached { () -> [Int64] in timer.recordNanoseconds(value) - let handler = timer._handler as! TestTimer + let handler = try metrics.expectTimer(timer) return handler.values } - let values = await task.value + let values = try await task.value XCTAssertEqual(values.count, 1, "expected number of entries to match") XCTAssertEqual(values[0], value, "expected value to match") }