Files
satellite-provider/SatelliteProvider.IntegrationTests/GrpcTestHelpers.cs
T
Oleksandr Bezdieniezhnykh 7633134a8a
ci/woodpecker/push/01-test Pipeline failed
ci/woodpecker/push/02-build-push unknown status
[AZ-1074] [AZ-1075] gRPC tile stream tests and shared proto
Extract tile_provision.proto into GrpcContracts, add integration
tests and validation hardening for DeliverRouteTiles streaming.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 10:04:41 +03:00

109 lines
3.5 KiB
C#

using Grpc.Core;
using Grpc.Net.Client;
using Satellite.V1;
namespace SatelliteProvider.IntegrationTests;
public static class GrpcTestHelpers
{
public static GrpcChannel CreateChannel(string apiUrl)
{
return GrpcChannel.ForAddress(apiUrl, new GrpcChannelOptions
{
HttpHandler = new SocketsHttpHandler
{
EnableMultipleHttp2Connections = true,
},
});
}
public static RouteTileDelivery.RouteTileDeliveryClient CreateClient(string apiUrl, string jwtToken)
{
var channel = CreateChannel(apiUrl);
var client = new RouteTileDelivery.RouteTileDeliveryClient(channel);
return client;
}
public static Metadata AuthMetadata(string jwtToken)
{
return new Metadata { { "Authorization", $"Bearer {jwtToken}" } };
}
public static DeliverRouteTilesRequest BuildValidRequest(
Guid? routeId = null,
double lat1 = 48.276067180586544,
double lon1 = 37.38445758819581,
double lat2 = 48.27074009522731,
double lon2 = 37.374029159545906,
double regionSizeMeters = 500,
int zoom = 18)
{
return new DeliverRouteTilesRequest
{
Route = new RouteSpec
{
RouteId = (routeId ?? Guid.NewGuid()).ToString(),
RegionSizeMeters = regionSizeMeters,
Zoom = zoom,
Waypoints =
{
new Waypoint { Lat = lat1, Lon = lon1 },
new Waypoint { Lat = lat2, Lon = lon2 },
},
},
};
}
public static async Task<(RouteManifest? Manifest, List<TilePayload> Tiles, DeliveryComplete? Complete, DeliveryError? Error)>
CollectStreamAsync(AsyncServerStreamingCall<RouteTileEvent> call, int? delayMsBetweenEvents = null)
{
RouteManifest? manifest = null;
var tiles = new List<TilePayload>();
DeliveryComplete? complete = null;
DeliveryError? error = null;
await foreach (var evt in call.ResponseStream.ReadAllAsync())
{
switch (evt.PayloadCase)
{
case RouteTileEvent.PayloadOneofCase.Manifest:
manifest = evt.Manifest;
break;
case RouteTileEvent.PayloadOneofCase.Batch:
tiles.AddRange(evt.Batch.Tiles);
break;
case RouteTileEvent.PayloadOneofCase.Complete:
complete = evt.Complete;
break;
case RouteTileEvent.PayloadOneofCase.Error:
error = evt.Error;
break;
}
if (delayMsBetweenEvents.HasValue)
{
await Task.Delay(delayMsBetweenEvents.Value);
}
}
return (manifest, tiles, complete, error);
}
public static async Task ExpectInvalidArgumentAsync(Func<Task> action, string context)
{
try
{
await action();
throw new Exception($"{context}: expected RpcException with InvalidArgument, but call succeeded");
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.InvalidArgument)
{
Console.WriteLine($" ✓ {context}: InvalidArgument — {ex.Status.Detail}");
}
catch (RpcException ex)
{
throw new Exception($"{context}: expected InvalidArgument, got {ex.StatusCode} — {ex.Status.Detail}");
}
}
}