예제 #1
0
        public async Task Invoke_Trace()
        {
            var accessor = new HttpContextAccessor {
                HttpContext = new DefaultHttpContext()
            };
            var context    = CreateHttpContext();
            var tracerMock = CreateIManagedTracerMock(context);

            var delegateMock = new Mock <RequestDelegate>();

            delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask);

            Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object;

            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer(accessor));

            var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, accessor);
            await middleware.Invoke(context, _traceHeaderContext);

            Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor));

            Assert.True(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader));
            Assert.Equal(_traceHeaderContext.ToString(), context.Response.Headers[TraceHeaderContext.TraceHeader]);

            delegateMock.VerifyAll();
            tracerMock.VerifyAll();
        }
예제 #2
0
        internal void BeginRequest(object sender, EventArgs e)
        {
            var    request       = HttpContext.Current.Request;
            string header        = request.Headers.Get(TraceHeaderContext.TraceHeader);
            var    headerContext = TraceHeaderContext.FromHeader(
                header, () => _traceFallbackPredicate?.ShouldTrace(request));

            var tracer = _tracerFactory(headerContext);

            if (tracer.GetCurrentTraceId() == null)
            {
                return;
            }

            ContextTracerManager.SetCurrentTracer(tracer);

            if (headerContext.TraceId != null)
            {
                // Set the updated trace header on the response.
                var updatedHeaderContext = TraceHeaderContext.Create(
                    tracer.GetCurrentTraceId(), tracer.GetCurrentSpanId() ?? 0, true);
                HttpContext.Current.Response.Headers.Set(
                    TraceHeaderContext.TraceHeader, updatedHeaderContext.ToString());
            }

            // Start the span and annotate it with information from the current request.
            var span = tracer.StartSpan(HttpContext.Current.Request.Path);

            ContextInstanceManager.Set(span);
            tracer.AnnotateSpan(Labels.FromHttpRequest(HttpContext.Current.Request));
            tracer.AnnotateSpan(Labels.AgentLabel);
        }
예제 #3
0
        public async Task TraceSingleAsync(Func <IHostBuilder> createHostBuilder)
        {
            IHost host = null;

            try
            {
                host = createHostBuilder().Build();
                await host.StartAsync();

                ITraceContext  traceContext  = new SimpleTraceContext(null, null, true);
                var            tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >();
                IManagedTracer tracer        = tracerFactory(traceContext);
                ContextTracerManager.SetCurrentTracer(tracer);

                using (tracer.StartSpan(_testId))
                {
                    IManagedTracer currentTracer = host.Services.GetRequiredService <IManagedTracer>();
                    currentTracer.RunInSpan(
                        () => Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app"),
                        "testing_tracing");
                }

                var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime);
                TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "testing_tracing");
            }
            finally
            {
                if (host is object)
                {
                    await host.StopAsync();
                }
            }
        }
        public async Task Invoke_Trace()
        {
            var accessor = new HttpContextAccessor {
                HttpContext = new DefaultHttpContext()
            };
            var context    = CreateHttpContext();
            var tracerMock = CreateIManagedTracerMock(context);

            var delegateMock = new Mock <RequestDelegate>();

            delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask);

            var tracerFactoryMock = new Mock <IManagedTracerFactory>();

            tracerFactoryMock.Setup(f => f.CreateTracer(_traceHeaderContext)).Returns(tracerMock.Object);

            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer(accessor));

            var middleware = new CloudTraceMiddleware(delegateMock.Object, tracerFactoryMock.Object, accessor);
            await middleware.Invoke(context, _traceHeaderContext);

            Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor));

            delegateMock.VerifyAll();
            tracerMock.VerifyAll();
        }
예제 #5
0
        public async Task Invoke_Trace()
        {
            var context    = CreateHttpContext();
            var tracerMock = CreateIManagedTracerMock(context);

            var delegateMock = new Mock <RequestDelegate>();

            delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask);

            Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object;

            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer());

            var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, new DefaultCloudTraceNameProvider());
            await middleware.Invoke(context, _traceHeaderContext);

            // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke
            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer());

            Assert.True(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader));
            Assert.Equal(_traceHeaderContext.ToString(), context.Response.Headers[TraceHeaderContext.TraceHeader]);

            delegateMock.VerifyAll();
            tracerMock.VerifyAll();
        }
        public async Task SetAndGetInDifferentAsyncContexts()
        {
            var mockedManagedTracer = new Mock <IManagedTracer>(MockBehavior.Strict).Object;

            async Task setTracer()
            {
                ContextTracerManager.SetCurrentTracer(mockedManagedTracer);
                await Task.Yield();
            }

            async Task <IManagedTracer> getTracer()
            {
                var tracer = ContextTracerManager.GetCurrentTracer();
                await Task.Yield();

                return(tracer);
            }

            await setTracer();

            var actualManagedTracer = await getTracer();

            // The "intuitive" thing would be to
            // Assert.Equal(mockedManagedTracer, actualManagedTracer);
            // but, we have implemented the ContextTraceManager using AsyncLocal
            // and since in this test we have set the mocked tracer in an independent
            // async context from the one we are then obtaining the tracer, the tracer set
            // on the first async context is not propagated to the second async context where
            // we are trying to obtain it.
            Assert.Equal(NullManagedTracer.Instance, actualManagedTracer);
        }
        public void FromGoogleTrace()
        {
            var oldTracer = ContextTracerManager.GetCurrentTracer();

            try
            {
                string traceId = "dummy_trace_id";
                ulong  spanId  = 0x12D687;
                // The spanId set on the log entry should confirm to x16
                // format so that the backend can really associate the log entry
                // to the span.
                string expectedSpanId = "000000000012d687";

                ContextTracerManager.SetCurrentTracer(MockTracer(traceId, spanId));

                var traceContext = TraceContextForLogEntry.FromGoogleTrace();

                Assert.Equal(traceId, traceContext.TraceId);
                Assert.Equal(expectedSpanId, traceContext.SpanId);
            }
            finally
            {
                ContextTracerManager.SetCurrentTracer(oldTracer);
            }
        }
        public void Set()
        {
            var mockedManagedTracer = new Mock <IManagedTracer>(MockBehavior.Strict).Object;

            ContextTracerManager.SetCurrentTracer(mockedManagedTracer);

            Assert.Equal(mockedManagedTracer, ContextTracerManager.GetCurrentTracer());
        }
        public ErrorReportingContextExceptionLoggerTest()
        {
            var tracerMock = new Mock <IManagedTracer>(MockBehavior.Strict);

            tracerMock.Setup(t => t.GetCurrentTraceId()).Returns(_traceId);
            tracerMock.Setup(t => t.GetCurrentSpanId()).Returns(_spanId);
            ContextTracerManager.SetCurrentTracer(tracerMock.Object);
        }
예제 #10
0
        /// <summary>
        /// Invokes the next <see cref="RequestDelegate"/> and traces the time
        /// taken for the next delegate to run, reporting the results to the
        /// Google Cloud Trace API.
        /// </summary>
        /// <param name="httpContext">The current HTTP context.</param>
        /// <param name="traceContext">Trace information from the current request. Must not be null.</param>
        /// <param name="fallback">Predicate to be used if the trace context has no information about whether
        /// the request should be traced or not.</param>
        /// <param name="traceContextPropagator">Trace context propagator to be used to set the trace context
        /// on the <see cref="HttpResponse"/>. Must not be null.</param>
        public async Task Invoke(
            HttpContext httpContext, ITraceContext traceContext, TraceDecisionPredicate fallback, Action <HttpResponse, ITraceContext> traceContextPropagator)
        {
            GaxPreconditions.CheckNotNull(traceContext, nameof(traceContext));
            GaxPreconditions.CheckNotNull(traceContextPropagator, nameof(traceContextPropagator));

            // Applies the trace decision fallback, if needed.
            traceContext = WithShouldTraceFallback(traceContext, fallback.ShouldTrace(httpContext.Request));

            // Create a tracer for the given request and set it on the context manager so
            // the tracer can be used in other places.
            var tracer = _tracerFactory(traceContext);

            ContextTracerManager.SetCurrentTracer(tracer);

            if (tracer.GetCurrentTraceId() == null)
            {
                await _next(httpContext).ConfigureAwait(false);
            }
            else
            {
                if (traceContext.TraceId != null)
                {
                    // Set the current trace context on the response.
                    var currentTraceContext = ContextTracerManager.GetCurrentTraceContext();
                    traceContextPropagator.Invoke(httpContext.Response, currentTraceContext);
                }

                // Trace the delegate and annotate it with information from the current
                // HTTP context.
                var traceName = await _nameProvider.GetTraceNameAsync(httpContext).ConfigureAwait(false);

                var span = tracer.StartSpan(traceName);
                try
                {
                    await _next(httpContext).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    try
                    {
                        StackTrace stackTrace = new StackTrace(exception, true);
                        tracer.SetStackTrace(stackTrace);
                    }
                    catch (Exception innerException)
                    {
                        throw new AggregateException(innerException, exception);
                    }
                    throw;
                }
                finally
                {
                    tracer.AnnotateSpan(Labels.AgentLabel);
                    tracer.AnnotateSpan(Labels.FromHttpContext(httpContext));
                    span.Dispose();
                }
            }
        }
        public void Set_NullTraceId_NullTraceContext()
        {
            var managedTracerMock = new Mock <IManagedTracer>(MockBehavior.Strict);

            managedTracerMock.Setup(t => t.GetCurrentTraceId()).Returns <IManagedTracer, string>(null);
            ContextTracerManager.SetCurrentTracer(managedTracerMock.Object);

            Assert.Null(ContextTracerManager.GetCurrentTraceContext());
        }
        /// <summary>
        /// Invokes the next <see cref="RequestDelegate"/> and traces the time
        /// taken for the next delegate to run, reporting the results to the
        /// Stackdriver Trace API.
        /// </summary>
        /// <param name="httpContext">The current HTTP context.</param>
        /// <param name="traceHeaderContext">Information from the current request header. Must not be null.</param>
        public async Task Invoke(HttpContext httpContext, TraceHeaderContext traceHeaderContext)
        {
            GaxPreconditions.CheckNotNull(traceHeaderContext, nameof(traceHeaderContext));

            // Create a tracer for the given request and set it on the context manager so
            // the tracer can be used in other places.
            var tracer = _tracerFactory(traceHeaderContext);

            ContextTracerManager.SetCurrentTracer(tracer);

            if (tracer.GetCurrentTraceId() == null)
            {
                await _next(httpContext).ConfigureAwait(false);
            }
            else
            {
                if (traceHeaderContext.TraceId != null)
                {
                    // Set the trace updated trace header on the response.
                    var updatedHeaderContext = TraceHeaderContext.Create(
                        tracer.GetCurrentTraceId(), tracer.GetCurrentSpanId() ?? 0, true);
                    httpContext.Response.Headers.Add(
                        TraceHeaderContext.TraceHeader, updatedHeaderContext.ToString());
                }

                // Trace the delegate and annotate it with information from the current
                // HTTP context.
                var traceName = await _nameProvider.GetTraceNameAsync(httpContext).ConfigureAwait(false);

                var span = tracer.StartSpan(traceName);
                try
                {
                    await _next(httpContext).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    try
                    {
                        StackTrace stackTrace = new StackTrace(exception, true);
                        tracer.SetStackTrace(stackTrace);
                    }
                    catch (Exception innerException)
                    {
                        throw new AggregateException(innerException, exception);
                    }
                    throw;
                }
                finally
                {
                    tracer.AnnotateSpan(Labels.AgentLabel);
                    tracer.AnnotateSpan(Labels.FromHttpContext(httpContext));
                    span.Dispose();
                }
            }
        }
예제 #13
0
        public void CreateManagedTracer()
        {
            var    mockProvider = new Mock <IServiceProvider>();
            var    mockTracer   = new Mock <IManagedTracer>();
            string traceId      = Guid.NewGuid().ToString("N");

            mockTracer.Setup(p => p.GetCurrentTraceId()).Returns(traceId);
            ContextTracerManager.SetCurrentTracer(mockTracer.Object);
            var tracer = ManagedTracer.CreateDelegatingTracer(() => ContextTracerManager.GetCurrentTracer());

            Assert.IsType <DelegatingTracer>(tracer);
            Assert.Equal(traceId, tracer.GetCurrentTraceId());
            mockTracer.Verify();
        }
        public void FromGoogleTrace_NoTrace()
        {
            var oldTracer = ContextTracerManager.GetCurrentTracer();

            try
            {
                ContextTracerManager.SetCurrentTracer(MockTracer());

                Assert.Null(TraceContextForLogEntry.FromGoogleTrace());
            }
            finally
            {
                ContextTracerManager.SetCurrentTracer(oldTracer);
            }
        }
        public void Set_TraceContext()
        {
            var managedTracerMock = new Mock <IManagedTracer>(MockBehavior.Strict);

            managedTracerMock.Setup(t => t.GetCurrentTraceId()).Returns("dummyTraceId");
            managedTracerMock.Setup(t => t.GetCurrentSpanId()).Returns(123456789u);
            ContextTracerManager.SetCurrentTracer(managedTracerMock.Object);

            var traceContext = ContextTracerManager.GetCurrentTraceContext();

            Assert.NotNull(traceContext);

            Assert.Equal("dummyTraceId", traceContext.TraceId);
            Assert.Equal(123456789u, traceContext.SpanId);
            Assert.True(traceContext.ShouldTrace);
        }
예제 #16
0
        public async Task TraceIncomingAsync()
        {
            IHost host = null;
            // Hides that we use different classes so that we can have multiple CreateHostBuilder methods.
            Func <IHostBuilder> CreateHostBuilder = DefaultHostBuilder.CreateHostBuilder;

            try
            {
                // Sample: Start
                host = CreateHostBuilder().Build();
                await host.StartAsync();

                // End sample

                object request = null;
                // Sample: IncomingContext
                ITraceContext  traceContext  = GetTraceContextFromIncomingRequest(request);
                var            tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >();
                IManagedTracer tracer        = tracerFactory(traceContext);
                ContextTracerManager.SetCurrentTracer(tracer);
                // End sample

                // Let's just start a span with the test ID so we can find it faster.
                // But we don't show this in sample code.
                using (tracer.StartSpan(_testId))
                {
                    // Sample: Trace
                    IManagedTracer currentTracer = host.Services.GetRequiredService <IManagedTracer>();
                    using (currentTracer.StartSpan("testing_tracing"))
                    {
                        Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app");
                    }
                    // End sample
                }

                var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime);
                TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "testing_tracing");
                Assert.Equal(traceContext.TraceId, trace.TraceId);
            }
            finally
            {
                if (host is object)
                {
                    await host.StopAsync();
                }
            }
        }
        public async Task TraceAsync()
        {
            // Naming it like an instance variable so that it looks like that on sample code.
            IHost _host = null;

            try
            {
                // Sample: Start
                _host = CreateHostBuilder().Build();
                await _host.StartAsync();

                // End sample

                // Sample: IncomingContext
                ITraceContext  traceContext  = GetTraceContextFromIncomingRequest();
                var            tracerFactory = _host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >();
                IManagedTracer tracer        = tracerFactory(traceContext);
                ContextTracerManager.SetCurrentTracer(tracer);
                // End sample

                // Let's just start a span with the test ID so we can find it faster.
                // But we don't show this in sample code.
                using (tracer.StartSpan(_testId))
                {
                    // Sample: Trace
                    IManagedTracer currentTracer = _host.Services.GetRequiredService <IManagedTracer>();
                    using (currentTracer.StartSpan("standalone_tracing"))
                    {
                        Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app");
                    }
                    // End sample
                }

                var trace = s_polling.GetTrace(_testId, _startTime);
                TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "standalone_tracing");
                Assert.Equal(traceContext.TraceId, trace.TraceId);
            }
            finally
            {
                if (_host != null)
                {
                    await _host.StopAsync();
                }
            }
        }
        public async Task Invoke_NoTrace()
        {
            var context      = new DefaultHttpContext();
            var delegateMock = new Mock <RequestDelegate>();
            var tracerMock   = new Mock <IManagedTracer>();

            Func <ITraceContext, IManagedTracer> fakeFactory = f => tracerMock.Object;

            var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, new DefaultCloudTraceNameProvider());
            await middleware.Invoke(context, _traceContext, TraceDecisionPredicate.Default, CustomTraceContextPropagator);

            // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke
            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer());

            AssertNoTraceContext(context.Response);

            delegateMock.Verify(d => d(context), Times.Once());
            tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never());
        }
예제 #19
0
        public async Task Invoke_NoTrace()
        {
            var context      = new DefaultHttpContext();
            var delegateMock = new Mock <RequestDelegate>();
            var tracerMock   = new Mock <IManagedTracer>();

            Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object;

            var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory);
            await middleware.Invoke(context, _traceHeaderContext);

            // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke
            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer());

            Assert.False(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader));

            delegateMock.Verify(d => d(context), Times.Once());
            tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never());
        }
예제 #20
0
        public async Task Invoke_NoTrace()
        {
            var accessor = new HttpContextAccessor {
                HttpContext = new DefaultHttpContext()
            };
            var context      = new DefaultHttpContext();
            var delegateMock = new Mock <RequestDelegate>();
            var tracerMock   = new Mock <IManagedTracer>();

            Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object;

            var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, accessor);
            await middleware.Invoke(context, _traceHeaderContext);

            Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor));
            Assert.False(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader));

            delegateMock.Verify(d => d(context), Times.Once());
            tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never());
        }
        public void FromGoogleTrace_NoSpan()
        {
            var oldTracer = ContextTracerManager.GetCurrentTracer();

            try
            {
                string traceId = "dummy_trace_id";

                ContextTracerManager.SetCurrentTracer(MockTracer(traceId));

                var traceContext = TraceContextForLogEntry.FromGoogleTrace();

                Assert.Equal(traceId, traceContext.TraceId);
                Assert.Null(traceContext.SpanId);
            }
            finally
            {
                ContextTracerManager.SetCurrentTracer(oldTracer);
            }
        }
        public async Task Invoke_NoTrace()
        {
            var accessor = new HttpContextAccessor {
                HttpContext = new DefaultHttpContext()
            };
            var context      = new DefaultHttpContext();
            var delegateMock = new Mock <RequestDelegate>();
            var tracerMock   = new Mock <IManagedTracer>();

            var tracerFactoryMock = new Mock <IManagedTracerFactory>();

            tracerFactoryMock.Setup(f => f.CreateTracer(_traceHeaderContext)).Returns(tracerMock.Object);

            var middleware = new CloudTraceMiddleware(delegateMock.Object, tracerFactoryMock.Object, accessor);
            await middleware.Invoke(context, _traceHeaderContext);

            Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor));

            delegateMock.Verify(d => d(context), Times.Once());
            tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never());
            tracerMock.Verify(t => t.EndSpan(), Times.Never());
        }
예제 #23
0
        public async Task TraceOutgoingAsync()
        {
            IHost host = null;

            try
            {
                host = OutgoingHostBuilder.CreateHostBuilder().Build();
                await host.StartAsync();

                ITraceContext  traceContext  = new SimpleTraceContext(null, null, true);
                var            tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >();
                IManagedTracer tracer        = tracerFactory(traceContext);
                ContextTracerManager.SetCurrentTracer(tracer);

                // Let's just start a span with the test ID so we can find it faster.
                // But we don't show this in sample code.
                using (tracer.StartSpan(_testId))
                {
                    // Sample: TraceOutgoingClientFactory
                    IHttpClientFactory clientFactory = host.Services.GetRequiredService <IHttpClientFactory>();
                    var httpClient = clientFactory.CreateClient("tracesOutgoing");
                    // Any code that makes outgoing requests.
                    var response = await httpClient.GetAsync("http://weather.com/");

                    // End sample
                }

                var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime);

                TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "http://weather.com/");
            }
            finally
            {
                if (host is object)
                {
                    await host.StopAsync();
                }
            }
        }
예제 #24
0
        public async Task TraceSingleAsync()
        {
            IHost host = null;

            try
            {
                host = TroubleshootingHostBuilder.CreateHostBuilder().Build();
                await host.StartAsync();

                // Sample: SingleContext
                ITraceContext  traceContext  = new SimpleTraceContext(null, null, true);
                var            tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >();
                IManagedTracer tracer        = tracerFactory(traceContext);
                ContextTracerManager.SetCurrentTracer(tracer);
                // End sample

                // Let's just start a span with the test ID so we can find it faster.
                // But we don't show this in sample code.
                using (tracer.StartSpan(_testId))
                {
                    // Sample: RunIn
                    IManagedTracer currentTracer = host.Services.GetRequiredService <IManagedTracer>();
                    currentTracer.RunInSpan(
                        () => Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app"),
                        "testing_tracing");
                    // End sample
                }

                var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime);
                TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "testing_tracing");
            }
            finally
            {
                if (host is object)
                {
                    await host.StopAsync();
                }
            }
        }
        public async Task Invoke_Trace()
        {
            var context    = CreateHttpContext();
            var tracerMock = CreateIManagedTracerMock(context);

            var delegateMock = new Mock <RequestDelegate>();

            delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask);

            Func <ITraceContext, IManagedTracer> fakeFactory = f => tracerMock.Object;

            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer());

            var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, new DefaultCloudTraceNameProvider());
            await middleware.Invoke(context, _traceContext, TraceDecisionPredicate.Default, CustomTraceContextPropagator);

            // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke
            Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer());

            AssertCustomTraceContext(context.Response);

            delegateMock.VerifyAll();
            tracerMock.VerifyAll();
        }
        public async Task SetAndGetInNestedAsyncContexts()
        {
            var mockedManagedTracer = new Mock <IManagedTracer>(MockBehavior.Strict).Object;

            async Task <IManagedTracer> getTracer()
            {
                var tracer = ContextTracerManager.GetCurrentTracer();
                await Task.Yield();

                return(tracer);
            }

            async Task <IManagedTracer> setTracerAndGet()
            {
                ContextTracerManager.SetCurrentTracer(mockedManagedTracer);
                await Task.Yield();

                return(await getTracer());
            }

            var actualManagedTracer = await setTracerAndGet();

            Assert.Equal(mockedManagedTracer, actualManagedTracer);
        }
 public void Unset_NullTraceContext() =>
 Assert.Null(ContextTracerManager.GetCurrentTraceContext());
 public void Unset_NullManagedTracer()
 {
     Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer());
 }