Skip to content

Commit

Permalink
Add test to ensure http.server.active_requests metric is set (#645)
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler authored Dec 30, 2024
1 parent 643279f commit 507c56e
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions Tests/HummingbirdTests/MetricsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import XCTest
final class TestMetrics: MetricsFactory {
private let lock = NIOLock()
let counters = NIOLockedValueBox([String: CounterHandler]())
let meters = NIOLockedValueBox([String: MeterHandler]())
let recorders = NIOLockedValueBox([String: RecorderHandler]())
let timers = NIOLockedValueBox([String: TimerHandler]())

Expand All @@ -30,6 +31,12 @@ final class TestMetrics: MetricsFactory {
}
}

public func makeMeter(label: String, dimensions: [(String, String)]) -> MeterHandler {
self.meters.withLockedValue { counters in
self.make(label: label, dimensions: dimensions, registry: &counters, maker: TestMeter.init)
}
}

public func makeRecorder(label: String, dimensions: [(String, String)], aggregate: Bool) -> RecorderHandler {
let maker = { (label: String, dimensions: [(String, String)]) -> RecorderHandler in
TestRecorder(label: label, dimensions: dimensions, aggregate: aggregate)
Expand Down Expand Up @@ -64,6 +71,14 @@ final class TestMetrics: MetricsFactory {
}
}

func destroyMeter(_ handler: MeterHandler) {
if let testMeter = handler as? TestMeter {
_ = self.counters.withLockedValue { counters in
counters.removeValue(forKey: testMeter.label)
}
}
}

func destroyRecorder(_ handler: RecorderHandler) {
if let testRecorder = handler as? TestRecorder {
_ = self.recorders.withLockedValue { recorders in
Expand Down Expand Up @@ -112,6 +127,52 @@ internal final class TestCounter: CounterHandler, Equatable {
}
}

internal final class TestMeter: MeterHandler, Equatable {
let id: String
let label: String
let dimensions: [(String, String)]
let values = NIOLockedValueBox([(Date, Double)]())

init(label: String, dimensions: [(String, String)]) {
self.id = NSUUID().uuidString
self.label = label
self.dimensions = dimensions
}

func set(_ value: Int64) {
self.set(Double(value))
}

func set(_ value: Double) {
self.values.withLockedValue { values in
values.append((Date(), value))
}
print("adding \(value) to \(self.label)")
}

func increment(by: Double) {
self.values.withLockedValue { values in
let value = values.last?.1 ?? 0.0
values.append((Date(), value + by))
}
print("incrementing \(by) to \(self.label)")

}

func decrement(by: Double) {
self.values.withLockedValue { values in
let value = values.last?.1 ?? 0.0
values.append((Date(), value - by))
}
print("decrementing \(by) to \(self.label)")

}

static func == (lhs: TestMeter, rhs: TestMeter) -> Bool {
lhs.id == rhs.id
}
}

internal final class TestRecorder: RecorderHandler, Equatable {
let id: String
let label: String
Expand Down Expand Up @@ -314,4 +375,21 @@ final class MetricsTests: XCTestCase {
let timer = try XCTUnwrap(Self.testMetrics.timers.withLockedValue { $0 }["http.server.request.duration"] as? TestTimer)
XCTAssertGreaterThan(timer.values.withLockedValue { $0 }[0].1, 5_000_000)
}

func testActiveRequestsMetric() async throws {
let router = Router()
router.middlewares.add(MetricsMiddleware())
router.get("/hello") { _, _ -> Response in
Response(status: .ok)
}
let app = Application(responder: router.buildResponder())
try await app.test(.router) { client in
try await client.execute(uri: "/hello", method: .get) { _ in }
}

let meter = try XCTUnwrap(Self.testMetrics.meters.withLockedValue { $0 }["http.server.active_requests"] as? TestMeter)
let values = meter.values.withLockedValue { $0 }.map { $0.1 }
let maxValue = values.max() ?? 0.0
XCTAssertGreaterThan(maxValue, 0.0)
}
}

0 comments on commit 507c56e

Please sign in to comment.