public void TelemetryGeneratorTests_RequestIdIsCorrectlyPropagatedWhenPassedFromOutsideThroughIngressGateway()

in src/LibraryTest/Library/TelemetryGeneratorTests.cs [251:425]


        public void TelemetryGeneratorTests_RequestIdIsCorrectlyPropagatedWhenPassedFromOutsideThroughIngressGateway()
        {
            // 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.uid"].StringValue = "kubernetes://istio-ingressgateway.istio-system";
            instance1.SpanTags["source.workload.name"].StringValue = "istio-ingressgateway";
            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.uid"].StringValue = "kubernetes://istio-ingressgateway.istio-system";
            instance1.SpanTags["destination.workload.name"].StringValue = "istio-ingressgateway";
            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.uid"].StringValue = "kubernetes://istio-ingressgateway.istio-system";
            instance2.SpanTags["source.workload.name"].StringValue = "istio-ingressgateway";
            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.uid"].StringValue = "kubernetes://destination-deployment-1.default";
            instance2.SpanTags["destination.workload.name"].StringValue = "destination-deployment";
            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.uid"].StringValue = "kubernetes://destination-deployment-1.default";
            instance3.SpanTags["source.workload.name"].StringValue = "destination-deployment";
            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.uid"].StringValue = "kubernetes://another-destination-deployment-1.default";
            instance3.SpanTags["destination.workload.name"].StringValue = "another-destination-deployment";
            instance3.SpanTags["destination.workload.namespace"].StringValue = "default";
            instance3.SpanTags["destination.name"].StringValue = "another-destination-deployment-1";
            instance3.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue = "";
            instance3.SpanTags["destination.role.name"].StringValue = "another-destination-deployment";
            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 = "";
            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.uid"].StringValue = "kubernetes://destination-deployment-1.default";
            instance4.SpanTags["source.workload.name"].StringValue = "destination-deployment";
            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.uid"].StringValue = "kubernetes://another-destination-deployment-1.default";
            instance4.SpanTags["destination.workload.name"].StringValue = "another-destination-deployment";
            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 = "";
            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 = "";

            // ACT
            ITelemetry[] telemetryItems = telemetryGenerator.Generate(instance1, instance2, instance3, instance4).ToArray();

            // ASSERT
            // 2 items for gateway, 2 items for destination-deployment, 1 items for destination-deployment
            Assert.AreEqual(5, 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;

            Assert.IsNotNull(gatewayRequest);
            Assert.IsNotNull(gatewayDependency);
            Assert.IsNotNull(destinationDependency);
            Assert.IsNotNull(destinationRequest);
            Assert.IsNotNull(anotherDestinationRequest);

            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", "another-destination-deployment", "default", "kubernetes://another-destination-deployment-1", "inbound");

            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$");
            // destination-deployment-1 does not propagate Request-Id header, so the original trace is lost and regenerated here
            ValidateTelemetryOperationData(destinationDependency,        @"^\|[A-Za-z0-9]{32}\.[A-Za-z0-9]{8}.$",                                                            @"^\|[A-Za-z0-9]{32}\.$",                                                     @"^[A-Za-z0-9]{32}$");
            ValidateTelemetryOperationData(anotherDestinationRequest,    @"^\|[A-Za-z0-9]{32}\.[A-Za-z0-9]{8}.[A-Za-z0-9]{8}_$",                                            @"^\|[A-Za-z0-9]{32}\.[A-Za-z0-9]{8}.$",                                     @"^[A-Za-z0-9]{32}$");

            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);
        }