in src/LibraryTest/Library/TelemetryGeneratorTests.cs [428:653]
public void TelemetryGeneratorTests_RequestIdIsCorrectlyPropagatedWhenApplicationsSupportPropagation()
{
//!!!
Assert.Inconclusive("TODO");
// ARRANGE
var telemetryGenerator = new TelemetryGenerator(new []{"default"}, new string[]{});
// incoming request, reported by outbound proxy of the gateway
var instance1 = Common.GetStandardInstanceMsg();
instance1.SpanTags["context.reporter.uid"].StringValue = "kubernetes://istio-ingressgateway";
instance1.SpanTags["context.reporter.kind"].StringValue = "outbound";
instance1.SpanTags["source.workload.namespace"].StringValue = "istio-system";
instance1.SpanTags["source.name"].StringValue = "istio-ingressgateway";
instance1.SpanTags["source.labels.appinsights.monitoring.enabled"].StringValue = "";
instance1.SpanTags["source.labels.istio.isingressgateway"].BoolValue = true;
instance1.SpanTags["source.role.name"].StringValue = "istio-ingressway";
instance1.SpanTags["source.role.instance"].StringValue = "istio-ingressway-1";
instance1.SpanTags["destination.workload.namespace"].StringValue = "default";
instance1.SpanTags["destination.name"].StringValue = "destination-deployment-1";
instance1.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue = "";
instance1.SpanTags["destination.role.name"].StringValue = "destination-deployment";
instance1.SpanTags["destination.role.instance"].StringValue = "destination-deployment-1";
instance1.SpanTags["request.scheme"].StringValue = "http";
instance1.SpanTags["request.path"].StringValue = "/some/path";
instance1.SpanTags["http.useragent"].StringValue = "Mozilla";
instance1.SpanTags["host"].StringValue = "destination-deployment-1";
instance1.SpanTags["http.status_code"].StringValue = "200";
instance1.SpanTags["http.path"].StringValue = "/some/path";
instance1.SpanTags["http.method"].StringValue = "GET";
instance1.SpanTags["destination.port"].StringValue = "8888";
instance1.SpanTags["request.headers.request.id"].StringValue = "|original-guid.";
instance1.SpanTags["request.headers.synthetictest.runid"].StringValue = "";
instance1.SpanTags["request.headers.synthetictest.location"].StringValue = "";
instance1.SpanTags["request.headers.request.context"].StringValue = "";
instance1.SpanTags["response.headers.request.context"].StringValue = "";
// same incoming request, reported by inbound proxy of the destination-deployment-1 pod
var instance2 = Common.GetStandardInstanceMsg();
instance2.SpanTags["context.reporter.uid"].StringValue = "kubernetes://destination-deployment-1";
instance2.SpanTags["context.reporter.kind"].StringValue = "inbound";
instance2.SpanTags["source.workload.namespace"].StringValue = "istio-system";
instance2.SpanTags["source.name"].StringValue = "istio-ingressgateway";
instance2.SpanTags["source.labels.appinsights.monitoring.enabled"].StringValue = "";
instance2.SpanTags["source.labels.istio.isingressgateway"].BoolValue = true;
instance2.SpanTags["source.role.name"].StringValue = "istio-ingressway";
instance2.SpanTags["source.role.instance"].StringValue = "istio-ingressway-1";
instance2.SpanTags["destination.workload.namespace"].StringValue = "default";
instance2.SpanTags["destination.name"].StringValue = "destination-deployment-1";
instance2.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue = "";
instance2.SpanTags["destination.role.name"].StringValue = "destination-deployment";
instance2.SpanTags["destination.role.instance"].StringValue = "destination-deployment-1";
instance2.SpanTags["request.scheme"].StringValue = "http";
instance2.SpanTags["request.path"].StringValue = "/some/path";
instance2.SpanTags["http.useragent"].StringValue = "Mozilla";
instance2.SpanTags["host"].StringValue = "destination-deployment-1";
instance2.SpanTags["http.status_code"].StringValue = "200";
instance2.SpanTags["http.path"].StringValue = "/some/path";
instance2.SpanTags["http.method"].StringValue = "GET";
instance2.SpanTags["destination.port"].StringValue = "8888";
instance2.SpanTags["request.headers.request.id"].StringValue = "|original-guid.";
instance2.SpanTags["request.headers.synthetictest.runid"].StringValue = "";
instance2.SpanTags["request.headers.synthetictest.location"].StringValue = "";
instance2.SpanTags["request.headers.request.context"].StringValue = "";
instance2.SpanTags["response.headers.request.context"].StringValue = "";
// request destination-deployment-1 --> another-destination-deployment-1, reported by outbound proxy of the destination-deployment-1 pod
var instance3 = Common.GetStandardInstanceMsg();
instance3.SpanTags["context.reporter.uid"].StringValue = "kubernetes://destination-deployment-1";
instance3.SpanTags["context.reporter.kind"].StringValue = "outbound";
instance3.SpanTags["source.workload.namespace"].StringValue = "default";
instance3.SpanTags["source.name"].StringValue = "destination-deployment-1";
instance3.SpanTags["source.labels.appinsights.monitoring.enabled"].StringValue = "";
instance3.SpanTags["source.labels.istio.isingressgateway"].BoolValue = false;
instance3.SpanTags["source.role.name"].StringValue = "destination-deployment";
instance3.SpanTags["source.role.instance"].StringValue = "destination-deployment-1";
instance3.SpanTags["destination.workload.namespace"].StringValue = "default";
instance3.SpanTags["destination.name"].StringValue = "another-destination-deployment";
instance3.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue = "";
instance3.SpanTags["destination.role.name"].StringValue = "another-destination-deployment-1";
instance3.SpanTags["destination.role.instance"].StringValue = "another-destination-deployment-1";
instance3.SpanTags["request.scheme"].StringValue = "http";
instance3.SpanTags["request.path"].StringValue = "/some/path";
instance3.SpanTags["http.useragent"].StringValue = "Mozilla";
instance3.SpanTags["host"].StringValue = "destination-deployment-1";
instance3.SpanTags["http.status_code"].StringValue = "200";
instance3.SpanTags["http.path"].StringValue = "/some/path";
instance3.SpanTags["http.method"].StringValue = "GET";
instance3.SpanTags["destination.port"].StringValue = "8888";
instance3.SpanTags["request.headers.request.id"].StringValue = "|original-guid.1."; // Request-Id header is propagated by the app
instance3.SpanTags["request.headers.synthetictest.runid"].StringValue = "";
instance3.SpanTags["request.headers.synthetictest.location"].StringValue = "";
instance3.SpanTags["request.headers.request.context"].StringValue = "";
instance3.SpanTags["response.headers.request.context"].StringValue = "";
// request destination-deployment-1 --> another-destination-deployment-1, reported by inbound proxy of the another-destination-deployment-1 pod
var instance4 = Common.GetStandardInstanceMsg();
instance4.SpanTags["context.reporter.uid"].StringValue = "kubernetes://another-destination-deployment-1";
instance4.SpanTags["context.reporter.kind"].StringValue = "inbound";
instance4.SpanTags["source.workload.namespace"].StringValue = "default";
instance4.SpanTags["source.name"].StringValue = "destination-deployment-1";
instance4.SpanTags["source.labels.appinsights.monitoring.enabled"].StringValue = "";
instance4.SpanTags["source.labels.istio.isingressgateway"].BoolValue = false;
instance4.SpanTags["source.role.name"].StringValue = "destination-deployment";
instance4.SpanTags["source.role.instance"].StringValue = "destination-deployment-1";
instance4.SpanTags["destination.workload.namespace"].StringValue = "default";
instance4.SpanTags["destination.name"].StringValue = "another-destination-deployment-1";
instance4.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue = "";
instance4.SpanTags["destination.role.name"].StringValue = "another-destination-deployment";
instance4.SpanTags["destination.role.instance"].StringValue = "another-destination-deployment-1";
instance4.SpanTags["request.scheme"].StringValue = "http";
instance4.SpanTags["request.path"].StringValue = "/some/path";
instance4.SpanTags["http.useragent"].StringValue = "Mozilla";
instance4.SpanTags["host"].StringValue = "destination-deployment-1";
instance4.SpanTags["http.status_code"].StringValue = "200";
instance4.SpanTags["http.path"].StringValue = "/some/path";
instance4.SpanTags["http.method"].StringValue = "GET";
instance4.SpanTags["destination.port"].StringValue = "8888";
instance4.SpanTags["request.headers.request.id"].StringValue = "|original-guid.1."; // Request-Id header is propagated by the app
instance4.SpanTags["request.headers.synthetictest.runid"].StringValue = "";
instance4.SpanTags["request.headers.synthetictest.location"].StringValue = "";
instance4.SpanTags["request.headers.request.context"].StringValue = "";
instance4.SpanTags["response.headers.request.context"].StringValue = "";
// request another-destination-deployment-1 --> yet-another-destination-deployment-1, reported by outbound proxy of the another-destination-deployment-1 pod
var instance5 = Common.GetStandardInstanceMsg();
instance5.SpanTags["context.reporter.uid"].StringValue = "kubernetes://another-destination-deployment-1";
instance5.SpanTags["context.reporter.kind"].StringValue = "outbound";
instance5.SpanTags["source.workload.namespace"].StringValue = "default";
instance5.SpanTags["source.name"].StringValue = "another-destination-deployment";
instance5.SpanTags["source.labels.appinsights.monitoring.enabled"].StringValue = "";
instance5.SpanTags["source.labels.istio.isingressgateway"].BoolValue = false;
instance5.SpanTags["source.role.name"].StringValue = "another-destination-deployment";
instance5.SpanTags["source.role.instance"].StringValue = "another-destination-deployment-1";
instance5.SpanTags["destination.workload.namespace"].StringValue = "default";
instance5.SpanTags["destination.name"].StringValue = "yet-another-destination-deployment-1";
instance5.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue = "";
instance5.SpanTags["destination.role.name"].StringValue = "yet-another-destination-deployment";
instance5.SpanTags["destination.role.instance"].StringValue = "yet-another-destination-deployment-1";
instance5.SpanTags["request.scheme"].StringValue = "http";
instance5.SpanTags["request.path"].StringValue = "/some/path";
instance5.SpanTags["http.useragent"].StringValue = "Mozilla";
instance5.SpanTags["host"].StringValue = "yet-destination-deployment-1";
instance5.SpanTags["http.status_code"].StringValue = "200";
instance5.SpanTags["http.path"].StringValue = "/some/path";
instance5.SpanTags["http.method"].StringValue = "GET";
instance5.SpanTags["destination.port"].StringValue = "8888";
instance5.SpanTags["request.headers.request.id"].StringValue = "|original-guid.1.dep1kj4_"; // Request-Id header is propagated by the app
instance5.SpanTags["request.headers.synthetictest.runid"].StringValue = "";
instance5.SpanTags["request.headers.synthetictest.location"].StringValue = "";
instance5.SpanTags["request.headers.request.context"].StringValue = "";
instance5.SpanTags["response.headers.request.context"].StringValue = "";
// request another-destination-deployment-1 --> yet-another-destination-deployment-1, reported by inbound proxy of the yet-another-destination-deployment-1 pod
var instance6 = Common.GetStandardInstanceMsg();
instance6.SpanTags["context.reporter.uid"].StringValue = "kubernetes://yet-another-destination-deployment-1";
instance6.SpanTags["context.reporter.kind"].StringValue = "inbound";
instance6.SpanTags["source.workload.namespace"].StringValue = "default";
instance6.SpanTags["source.name"].StringValue = "another-destination-deployment-1";
instance6.SpanTags["source.labels.appinsights.monitoring.enabled"].StringValue = "";
instance6.SpanTags["source.labels.istio.isingressgateway"].BoolValue = false;
instance6.SpanTags["source.role.name"].StringValue = "another-destination-deployment";
instance6.SpanTags["source.role.instance"].StringValue = "another-destination-deployment-1";
instance6.SpanTags["destination.workload.namespace"].StringValue = "default";
instance6.SpanTags["destination.name"].StringValue = "yet-another-destination-deployment-1";
instance6.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue = "";
instance6.SpanTags["destination.role.name"].StringValue = "yet-another-destination-deployment";
instance6.SpanTags["destination.role.instance"].StringValue = "yet-another-destination-deployment-1";
instance6.SpanTags["request.scheme"].StringValue = "http";
instance6.SpanTags["request.path"].StringValue = "/some/path";
instance6.SpanTags["http.useragent"].StringValue = "Mozilla";
instance6.SpanTags["host"].StringValue = "yet-destination-deployment-1";
instance6.SpanTags["http.status_code"].StringValue = "200";
instance6.SpanTags["http.path"].StringValue = "/some/path";
instance6.SpanTags["http.method"].StringValue = "GET";
instance6.SpanTags["destination.port"].StringValue = "8888";
instance6.SpanTags["request.headers.request.id"].StringValue = "|original-guid.1.dep1kj4_"; // Request-Id header is propagated by the app
instance6.SpanTags["request.headers.synthetictest.runid"].StringValue = "";
instance6.SpanTags["request.headers.synthetictest.location"].StringValue = "";
instance6.SpanTags["request.headers.request.context"].StringValue = "";
instance6.SpanTags["response.headers.request.context"].StringValue = "";
// ACT
ITelemetry[] telemetryItems = telemetryGenerator.Generate(instance1, instance2, instance3, instance4, instance5, instance6).ToArray();
// ASSERT
// 2 items for gateway, 2 items for destination-deployment, 2 items for another-destination-deployment, 1 item for yet-another-destination-deployment
Assert.AreEqual(7, telemetryItems.Length);
var gatewayRequest = telemetryItems[0] as RequestTelemetry;
var gatewayDependency = telemetryItems[1] as DependencyTelemetry;
var destinationRequest = telemetryItems[2] as RequestTelemetry;
var destinationDependency = telemetryItems[3] as DependencyTelemetry;
var anotherDestinationRequest = telemetryItems[4] as RequestTelemetry;
var anotherDestinationDependency = telemetryItems[5] as DependencyTelemetry;
var yetAnotherDestinationRequest = telemetryItems[6] as RequestTelemetry;
Assert.IsNotNull(gatewayRequest);
Assert.IsNotNull(gatewayDependency);
Assert.IsNotNull(destinationDependency);
Assert.IsNotNull(destinationRequest);
Assert.IsNotNull(anotherDestinationRequest);
Assert.IsNotNull(anotherDestinationDependency);
Assert.IsNotNull(yetAnotherDestinationRequest);
ValidateTelemetrySource(gatewayRequest, "istio-ingressgateway", "istio-ingressgateway", "istio-system", "destination-deployment-1", "destination-deployment", "default", "kubernetes://destination-deployment-1", "inbound");
ValidateTelemetrySource(gatewayDependency, "istio-ingressgateway", "istio-ingressgateway", "istio-system", "destination-deployment-1", "destination-deployment", "default", "kubernetes://destination-deployment-1", "inbound");
ValidateTelemetrySource(destinationRequest, "istio-ingressgateway", "istio-ingressgateway", "istio-system", "destination-deployment-1", "destination-deployment", "default", "kubernetes://destination-deployment-1", "inbound");
ValidateTelemetrySource(destinationDependency, "destination-deployment-1", "destination-deployment", "default", "another-destination-deployment-1", "another-destination-deployment", "default", "kubernetes://another-destination-deployment-1", "inbound");
ValidateTelemetrySource(anotherDestinationRequest, "destination-deployment-1", "destination-deployment", "default", "another-destination-deployment-1", "default", "another-destination-deployment", "kubernetes://another-destination-deployment-1", "inbound");
ValidateTelemetrySource(anotherDestinationDependency, "another-destination-deployment-1", "another-destination-deployment", "default", "yet-another-destination-deployment-1", "yet-another-destination-deployment", "default", "kubernetes://yet-another-destination-deployment-1", "inbound");
ValidateTelemetrySource(yetAnotherDestinationRequest, "another-destination-deployment-1", "another-destination-deployment", "default", "yet-another-destination-deployment-1", "yet-another-destination-deployment", "default", "kubernetes://yet-another-destination-deployment-1", "inbound");
// Request-Id is propagated by applications, so it is expected to be maintained all the way through the trace
ValidateTelemetryOperationData(gatewayRequest, @"^\|original-guid\.[A-Za-z0-9]{8}_$", @"^\|original-guid\.$", @"^original-guid$");
ValidateTelemetryOperationData(gatewayDependency, @"^\|original-guid\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.$", @"^\|original-guid\.[A-Za-z0-9]{8}_$", @"^original-guid$");
ValidateTelemetryOperationData(destinationRequest, @"^\|original-guid\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.[A-Za-z0-9]{8}_$", @"^\|original-guid\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.$", @"^original-guid$");
ValidateTelemetryOperationData(destinationDependency, @"^\|original-guid\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.$", @"^\|original-guid\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.[A-Za-z0-9]{8}_$", @"^original-guid$");
ValidateTelemetryOperationData(anotherDestinationRequest, @"^\|original-guid\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.[A-Za-z0-9]{8}_$", @"^\|original-guid\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.[A-Za-z0-9]{8}_[A-Za-z0-9]{8}\.$", @"^original-guid$");
Assert.AreEqual(gatewayRequest.Id, gatewayDependency.Context.Operation.ParentId);
Assert.AreEqual(gatewayDependency.Id, destinationRequest.Context.Operation.ParentId);
// headers are not propogated, so the trace context is lost here
Assert.AreNotEqual(destinationRequest.Id, destinationDependency.Context.Operation.ParentId);
Assert.AreEqual(destinationDependency.Id, anotherDestinationRequest.Context.Operation.ParentId);
}