File tree Expand file tree Collapse file tree 2 files changed +40
-0
lines changed
Sources/GRPCHealthService
Tests/GRPCHealthServiceTests Expand file tree Collapse file tree 2 files changed +40
-0
lines changed Original file line number Diff line number Diff line change @@ -22,6 +22,9 @@ private import Synchronization
2222extension HealthService {
2323 internal struct Service : Grpc_Health_V1_Health . ServiceProtocol {
2424 private let state = Self . State ( )
25+ /// Defines the maximum number of resources a `List` request can return.
26+ /// An `RPCError` with the code `ResourceExhaused` is thrown if this limit is exceeded.
27+ private let listMaxAllowedServices = 100
2528 }
2629}
2730
@@ -49,6 +52,13 @@ extension HealthService.Service {
4952 ) async throws -> ServerResponse < Grpc_Health_V1_HealthListResponse > {
5053 let serviceStatuses = self . state. listStatuses ( )
5154
55+ guard serviceStatuses. count <= listMaxAllowedServices else {
56+ throw RPCError (
57+ code: . resourceExhausted,
58+ message: " Server health list exceeds maximum capacity: \( listMaxAllowedServices) . "
59+ )
60+ }
61+
5262 var listResponse = Grpc_Health_V1_HealthListResponse ( )
5363
5464 for (service, status) in serviceStatuses {
Original file line number Diff line number Diff line change @@ -344,6 +344,36 @@ final class HealthTests: XCTestCase {
344344 XCTAssertEqual ( try XCTUnwrap ( response. statuses [ " " ] ? . status) , . serving)
345345 }
346346 }
347+
348+ func testListExceedingMaxAllowedServices( ) async throws {
349+ try await withHealthClient { ( healthClient, healthProvider) in
350+ let message = Grpc_Health_V1_HealthListRequest ( )
351+ let listMaxAllowedServices = 100
352+
353+ for index in 1 ... listMaxAllowedServices {
354+ healthProvider. updateStatus (
355+ . notServing,
356+ forService: ServiceDescriptor ( package : " test " , service: " Service \( index) " )
357+ )
358+
359+ let response = try await healthClient. list ( message)
360+ XCTAssertTrue ( response. statuses. count == index)
361+ }
362+
363+ healthProvider. updateStatus ( . notServing, forService: ServiceDescriptor . testService)
364+
365+ do {
366+ _ = try await healthClient. list ( message)
367+ XCTFail ( " should error " )
368+ } catch {
369+ let resolvedError = try XCTUnwrap (
370+ error as? RPCError ,
371+ " health client list throws unexpected error: \( error) "
372+ )
373+ XCTAssertEqual ( resolvedError. code, . resourceExhausted)
374+ }
375+ }
376+ }
347377}
348378
349379@available ( gRPCSwiftExtras 2 . 0 , * )
You can’t perform that action at this time.
0 commit comments