public async Task TestBasicReceiveAndResponseEventsWitPassThroughSampling(string method)
        {
            using var eventRecords = new ActivitySourceRecorder(activityDataRequest: ActivityDataRequest.PropagationData);

            // Send a random Http request to generate some events
            using (var client = new HttpClient())
            {
                (method == "GET"
                    ? await client.GetAsync(this.BuildRequestUrl())
                    : await client.PostAsync(this.BuildRequestUrl(), new StringContent("hello world"))).Dispose();
            }

            // We should have exactly one Start and one Stop event
            Assert.Equal(2, eventRecords.Records.Count);
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            // Check to make sure: The first record must be a request, the next record must be a response.
            (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);

            VerifyHeaders(startRequest);

            Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
            Assert.Equal("Stop", stopEvent.Key);
            HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty("HttpWebRequest.Response");

            Assert.NotNull(response);

            Assert.Empty(activity.Tags);
        }
        public async Task TestBasicReceiveAndResponseEvents(string method, string queryString = null)
        {
            var url = this.BuildRequestUrl(queryString: queryString);

            using var eventRecords = new ActivitySourceRecorder();

            // Send a random Http request to generate some events
            using (var client = new HttpClient())
            {
                (method == "GET"
                    ? await client.GetAsync(url)
                    : await client.PostAsync(url, new StringContent("hello world"))).Dispose();
            }

            // We should have exactly one Start and one Stop event
            Assert.Equal(2, eventRecords.Records.Count);
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            // Check to make sure: The first record must be a request, the next record must be a response.
            (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);

            VerifyHeaders(startRequest);
            VerifyActivityStartTags(this.hostNameAndPort, method, url, activity);

            Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
            Assert.Equal("Stop", stopEvent.Key);
            HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty("HttpWebRequest.Response");

            Assert.NotNull(response);

            VerifyActivityStopTags(200, "OK", activity);
        }
Exemple #3
0
        public async Task TestInvalidBaggage()
        {
            Baggage
            .SetBaggage("key", "value")
            .SetBaggage("bad/key", "value")
            .SetBaggage("goodkey", "bad/value");

            using var eventRecords = new ActivitySourceRecorder();

            using (var client = new HttpClient())
            {
                (await client.GetAsync(this.BuildRequestUrl())).Dispose();
            }

            Assert.Equal(2, eventRecords.Records.Count());
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            WebRequest thisRequest = (WebRequest)eventRecords.Records.First().Value.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);

            string[] baggage = thisRequest.Headers["Baggage"].Split(',');

            Assert.Equal(3, baggage.Length);
            Assert.Contains("key=value", baggage);
            Assert.Contains("bad%2Fkey=value", baggage);
            Assert.Contains("goodkey=bad%2Fvalue", baggage);
        }
        public async Task TestSecureTransportFailureRequest(string method)
        {
            string url = "https://expired.badssl.com/";

            using var eventRecords = new ActivitySourceRecorder();

            using (var client = new HttpClient())
            {
                var ex = await Assert.ThrowsAnyAsync <Exception>(() =>
                {
                    // https://expired.badssl.com/ has an expired certificae.
                    return(method == "GET"
                        ? client.GetAsync(url)
                        : client.PostAsync(url, new StringContent("hello world")));
                });

                Assert.True(ex is HttpRequestException);
            }

            // We should have one Start event and one Stop event with an exception.
            Assert.Equal(2, eventRecords.Records.Count());
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);
            VerifyHeaders(startRequest);
            VerifyActivityStartTags(null, method, url, activity);

            Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair <string, Activity> exceptionEvent));
            Assert.Equal("Stop", exceptionEvent.Key);
            Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Exception");

            Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusCodeKey);
            Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusDescriptionKey);
        }
        public async Task TestInvalidBaggage()
        {
            var parentActivity = new Activity("parent")
                                 .AddBaggage("key", "value")
                                 .AddBaggage("bad/key", "value")
                                 .AddBaggage("goodkey", "bad/value")
                                 .Start();

            using (var eventRecords = new ActivitySourceRecorder())
            {
                using (var client = new HttpClient())
                {
                    (await client.GetAsync(this.BuildRequestUrl())).Dispose();
                }

                Assert.Equal(2, eventRecords.Records.Count());
                Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
                Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

                WebRequest thisRequest        = (WebRequest)eventRecords.Records.First().Value.GetCustomProperty("HttpWebRequest.Request");
                string[]   correlationContext = thisRequest.Headers["Correlation-Context"].Split(',');

                Assert.Equal(3, correlationContext.Length);
                Assert.Contains("key=value", correlationContext);
                Assert.Contains("bad%2Fkey=value", correlationContext);
                Assert.Contains("goodkey=bad%2Fvalue", correlationContext);
            }

            parentActivity.Stop();
        }
Exemple #6
0
        public async Task TestCanceledRequest(string method)
        {
            string url = this.BuildRequestUrl();

            CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

            using var eventRecords = new ActivitySourceRecorder(_ => { cts.Cancel(); });

            using (var client = new HttpClient())
            {
                var ex = await Assert.ThrowsAnyAsync <Exception>(() =>
                {
                    return(method == "GET"
                        ? client.GetAsync(url, cts.Token)
                        : client.PostAsync(url, new StringContent("hello world"), cts.Token));
                });

                Assert.True(ex is TaskCanceledException || ex is WebException);
            }

            // We should have one Start event and one Stop event with an exception.
            Assert.Equal(2, eventRecords.Records.Count());
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            Activity activity = AssertFirstEventWasStart(eventRecords);

            VerifyActivityStartTags(this.hostNameAndPort, method, url, activity);

            Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair <string, Activity> exceptionEvent));
            Assert.Equal("Stop", exceptionEvent.Key);

            Assert.NotNull(exceptionEvent.Value.GetTagValue(SpanAttributeConstants.StatusCodeKey));
            Assert.Null(exceptionEvent.Value.GetTagValue(SpanAttributeConstants.StatusDescriptionKey));
        }
Exemple #7
0
        public async Task TestResponseWithoutContentEvents(string method)
        {
            string url = this.BuildRequestUrl(queryString: "responseCode=204");

            using var eventRecords = new ActivitySourceRecorder();

            // Send a random Http request to generate some events
            using (var client = new HttpClient())
            {
                using HttpResponseMessage response = method == "GET"
                    ? await client.GetAsync(url)
                    : await client.PostAsync(url, new StringContent ("hello world"));
            }

            // We should have exactly one Start and one Stop event
            Assert.Equal(2, eventRecords.Records.Count);
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            // Check to make sure: The first record must be a request, the next record must be a response.
            Activity activity = AssertFirstEventWasStart(eventRecords);

            VerifyActivityStartTags(this.hostNameAndPort, method, url, activity);

            Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
            Assert.Equal("Stop", stopEvent.Key);

            VerifyActivityStopTags(204, activity);
        }
Exemple #8
0
        public async Task TestTraceStateAndBaggage()
        {
            try
            {
                using var eventRecords = new ActivitySourceRecorder();

                var parent = new Activity("w3c activity");
                parent.SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom());
                parent.TraceStateString = "some=state";
                parent.Start();

                Baggage.SetBaggage("k", "v");

                // Send a random Http request to generate some events
                using (var client = new HttpClient())
                {
                    (await client.GetAsync(this.BuildRequestUrl())).Dispose();
                }

                parent.Stop();

                Assert.Equal(2, eventRecords.Records.Count());

                // Check to make sure: The first record must be a request, the next record must be a response.
                _ = AssertFirstEventWasStart(eventRecords);
            }
            finally
            {
                this.CleanUpActivity();
            }
        }
        public async Task DoNotInjectTraceParentWhenPresent(string method)
        {
            try
            {
                using var eventRecords = new ActivitySourceRecorder();

                // Send a random Http request to generate some events
                using (var client = new HttpClient())
                    using (var request = new HttpRequestMessage(HttpMethod.Get, this.BuildRequestUrl()))
                    {
                        request.Headers.Add("traceparent", "00-abcdef0123456789abcdef0123456789-abcdef0123456789-01");

                        if (method == "GET")
                        {
                            request.Method = HttpMethod.Get;
                        }
                        else
                        {
                            request.Method  = HttpMethod.Post;
                            request.Content = new StringContent("hello world");
                        }

                        (await client.SendAsync(request)).Dispose();
                    }

                // No events are sent.
                Assert.Empty(eventRecords.Records);
            }
            finally
            {
                this.CleanUpActivity();
            }
        }
        private static (Activity, HttpWebRequest) AssertFirstEventWasStart(ActivitySourceRecorder eventRecords)
        {
            Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair <string, Activity> startEvent));
            Assert.Equal("Start", startEvent.Key);
            HttpWebRequest startRequest = (HttpWebRequest)startEvent.Value.GetCustomProperty("HttpWebRequest.Request");

            Assert.NotNull(startRequest);
            return(startEvent.Value, startRequest);
        }
Exemple #11
0
        public void TestMultipleConcurrentRequests()
        {
            ServicePointManager.DefaultConnectionLimit = int.MaxValue;
            var parentActivity = new Activity("parent").Start();

            using var eventRecords = new ActivitySourceRecorder();

            Dictionary <Uri, Tuple <WebRequest, WebResponse> > requestData = new Dictionary <Uri, Tuple <WebRequest, WebResponse> >();

            for (int i = 0; i < 10; i++)
            {
                Uri uriWithRedirect = new Uri(this.BuildRequestUrl(queryString: $"q={i}&redirects=3"));

                requestData[uriWithRedirect] = null;
            }

            // Issue all requests simultaneously
            HttpClient httpClient = new HttpClient();
            Dictionary <Uri, Task <HttpResponseMessage> > tasks = new Dictionary <Uri, Task <HttpResponseMessage> >();

            CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

            foreach (var url in requestData.Keys)
            {
                tasks.Add(url, httpClient.GetAsync(url, cts.Token));
            }

            // wait up to 10 sec for all requests and suppress exceptions
            Task.WhenAll(tasks.Select(t => t.Value).ToArray()).ContinueWith(tt =>
            {
                foreach (var task in tasks)
                {
                    task.Value.Result?.Dispose();
                }
            }).Wait();

            // Examine the result. Make sure we got all successful requests.

            // Just make sure some events are written, to confirm we successfully subscribed to it. We should have
            // exactly 1 Start event per request and exactly 1 Stop event per response (if request succeeded)
            var successfulTasks = tasks.Where(t => t.Value.Status == TaskStatus.RanToCompletion);

            Assert.Equal(tasks.Count, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(successfulTasks.Count(), eventRecords.Records.Count(rec => rec.Key == "Stop"));

            // Check to make sure: We have a WebRequest and a WebResponse for each successful request
            foreach (var pair in eventRecords.Records)
            {
                Activity activity = pair.Value;

                Assert.True(
                    pair.Key == "Start" ||
                    pair.Key == "Stop",
                    "An unexpected event of name " + pair.Key + "was received");
            }
        }
        public async Task TestReflectInitializationViaSubscription()
        {
            using var eventRecords = new ActivitySourceRecorder();

            // Send a random Http request to generate some events
            using (var client = new HttpClient())
            {
                (await client.GetAsync(this.BuildRequestUrl())).Dispose();
            }

            // Just make sure some events are written, to confirm we successfully subscribed to it.
            // We should have exactly one Start and one Stop event
            Assert.Equal(2, eventRecords.Records.Count);
        }
        public async Task TestBasicReceiveAndResponseEventsWithoutSampling(string method)
        {
            using var eventRecords = new ActivitySourceRecorder(activityDataRequest: ActivityDataRequest.None);

            // Send a random Http request to generate some events
            using (var client = new HttpClient())
            {
                (method == "GET"
                    ? await client.GetAsync(this.BuildRequestUrl())
                    : await client.PostAsync(this.BuildRequestUrl(), new StringContent("hello world"))).Dispose();
            }

            // There should be no events because we turned off sampling.
            Assert.Empty(eventRecords.Records);
        }
        public async Task TestRedirectedRequest(string method)
        {
            using var eventRecords = new ActivitySourceRecorder();

            using (var client = new HttpClient())
            {
                using HttpResponseMessage response = method == "GET"
                    ? await client.GetAsync(this.BuildRequestUrl (queryString : "redirects=10"))
                                                     : await client.PostAsync(this.BuildRequestUrl (queryString : "redirects=10"), new StringContent ("hello world"));
            }

            // We should have exactly one Start and one Stop event
            Assert.Equal(2, eventRecords.Records.Count());
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));
        }
        public async Task TestRequestWithException(string method)
        {
            string url = method == "GET"
                ? $"http://{Guid.NewGuid()}.com"
                : $"http://{Guid.NewGuid()}.com";

            using var eventRecords = new ActivitySourceRecorder();

            var ex = await Assert.ThrowsAsync <HttpRequestException>(() =>
            {
                return(method == "GET"
                    ? new HttpClient().GetAsync(url)
                    : new HttpClient().PostAsync(url, new StringContent("hello world")));
            });

            // check that request failed because of the wrong domain name and not because of reflection
            var webException = (WebException)ex.InnerException;

            Assert.NotNull(webException);
            Assert.True(webException.Status == WebExceptionStatus.NameResolutionFailure);

            // We should have one Start event and one Stop event with an exception.
            Assert.Equal(2, eventRecords.Records.Count());
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            // Check to make sure: The first record must be a request, the next record must be an exception.
            (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);
            VerifyHeaders(startRequest);
            VerifyActivityStartTags(null, method, url, activity);

            Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair <string, Activity> exceptionEvent));
            Assert.Equal("Stop", exceptionEvent.Key);
            HttpWebRequest exceptionRequest = (HttpWebRequest)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Request");

            Assert.Equal(startRequest, exceptionRequest);
            Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Exception");

            Assert.Equal(webException, exceptionException);

            Assert.Contains(activity.Tags, i => i.Key == SpanAttributeConstants.StatusCodeKey);
            Assert.Contains(activity.Tags, i => i.Key == SpanAttributeConstants.StatusDescriptionKey);
        }
Exemple #16
0
        public async Task TestInvalidBaggage()
        {
            validateBaggage = true;
            Baggage
            .SetBaggage("key", "value")
            .SetBaggage("bad/key", "value")
            .SetBaggage("goodkey", "bad/value");

            using var eventRecords = new ActivitySourceRecorder();

            using (var client = new HttpClient())
            {
                (await client.GetAsync(this.BuildRequestUrl())).Dispose();
            }

            Assert.Equal(2, eventRecords.Records.Count());
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            validateBaggage = false;
        }
Exemple #17
0
        public async Task TestTraceStateAndBaggage()
        {
            try
            {
                using var eventRecords = new ActivitySourceRecorder();

                var parent = new Activity("w3c activity");
                parent.SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom());
                parent.TraceStateString = "some=state";
                parent.Start();

                Baggage.SetBaggage("k", "v");

                // Send a random Http request to generate some events
                using (var client = new HttpClient())
                {
                    (await client.GetAsync(this.BuildRequestUrl())).Dispose();
                }

                parent.Stop();

                Assert.Equal(2, eventRecords.Records.Count());

                // Check to make sure: The first record must be a request, the next record must be a response.
                (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);

                var traceparent = startRequest.Headers["traceparent"];
                var tracestate  = startRequest.Headers["tracestate"];
                var baggage     = startRequest.Headers["baggage"];
                Assert.NotNull(traceparent);
                Assert.Equal("some=state", tracestate);
                Assert.Equal("k=v", baggage);
                Assert.StartsWith($"00-{parent.TraceId.ToHexString()}-", traceparent);
                Assert.Matches("^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$", traceparent);
            }
            finally
            {
                this.CleanUpActivity();
            }
        }
        public async Task TestSecureTransportRetryFailureRequest(string method)
        {
            // This test sends an https request to an endpoint only set up for http.
            // It should retry. What we want to test for is 1 start, 1 exception event even
            // though multiple are actually sent.

            string url = this.BuildRequestUrl(useHttps: true);

            using var eventRecords = new ActivitySourceRecorder();

            using (var client = new HttpClient())
            {
                var ex = await Assert.ThrowsAnyAsync <Exception>(() =>
                {
                    return(method == "GET"
                        ? client.GetAsync(url)
                        : client.PostAsync(url, new StringContent("hello world")));
                });

                Assert.True(ex is HttpRequestException);
            }

            // We should have one Start event and one Stop event with an exception.
            Assert.Equal(2, eventRecords.Records.Count());
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);
            VerifyHeaders(startRequest);
            VerifyActivityStartTags(this.hostNameAndPort, method, url, activity);

            Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair <string, Activity> exceptionEvent));
            Assert.Equal("Stop", exceptionEvent.Key);
            Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Exception");

            Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusCodeKey);
            Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusDescriptionKey);
        }
        public void TestMultipleConcurrentRequests()
        {
            ServicePointManager.DefaultConnectionLimit = int.MaxValue;
            var parentActivity = new Activity("parent").Start();

            using var eventRecords = new ActivitySourceRecorder();

            Dictionary <Uri, Tuple <WebRequest, WebResponse> > requestData = new Dictionary <Uri, Tuple <WebRequest, WebResponse> >();

            for (int i = 0; i < 10; i++)
            {
                Uri uriWithRedirect = new Uri(this.BuildRequestUrl(queryString: $"q={i}&redirects=3"));

                requestData[uriWithRedirect] = null;
            }

            // Issue all requests simultaneously
            HttpClient httpClient = new HttpClient();
            Dictionary <Uri, Task <HttpResponseMessage> > tasks = new Dictionary <Uri, Task <HttpResponseMessage> >();

            CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

            foreach (var url in requestData.Keys)
            {
                tasks.Add(url, httpClient.GetAsync(url, cts.Token));
            }

            // wait up to 10 sec for all requests and suppress exceptions
            Task.WhenAll(tasks.Select(t => t.Value).ToArray()).ContinueWith(tt =>
            {
                foreach (var task in tasks)
                {
                    task.Value.Result?.Dispose();
                }
            }).Wait();

            // Examine the result. Make sure we got all successful requests.

            // Just make sure some events are written, to confirm we successfully subscribed to it. We should have
            // exactly 1 Start event per request and exactly 1 Stop event per response (if request succeeded)
            var successfulTasks = tasks.Where(t => t.Value.Status == TaskStatus.RanToCompletion);

            Assert.Equal(tasks.Count, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(successfulTasks.Count(), eventRecords.Records.Count(rec => rec.Key == "Stop"));

            // Check to make sure: We have a WebRequest and a WebResponse for each successful request
            foreach (var pair in eventRecords.Records)
            {
                Activity activity = pair.Value;

                Assert.True(
                    pair.Key == "Start" ||
                    pair.Key == "Stop",
                    "An unexpected event of name " + pair.Key + "was received");

                WebRequest request = (WebRequest)activity.GetCustomProperty("HttpWebRequest.Request");
                Assert.Equal("HttpWebRequest", request.GetType().Name);

                if (pair.Key == "Start")
                {
                    // Make sure this is an URL that we recognize. If not, just skip
                    if (!requestData.TryGetValue(request.RequestUri, out var tuple))
                    {
                        continue;
                    }

                    // all requests have traceparent with proper parent Id
                    var traceparent = request.Headers["traceparent"];
                    Assert.StartsWith($"00-{parentActivity.TraceId.ToHexString()}-", traceparent);

                    Assert.Null(requestData[request.RequestUri]);
                    requestData[request.RequestUri] =
                        new Tuple <WebRequest, WebResponse>(request, null);
                }
                else
                {
                    // This must be the response.
                    WebResponse response = (WebResponse)activity.GetCustomProperty("HttpWebRequest.Response");
                    Assert.Equal("HttpWebResponse", response.GetType().Name);

                    // By the time we see the response, the request object may already have been redirected with a different
                    // url. Hence, it's not reliable to just look up requestData by the URL/hostname. Instead, we have to look
                    // through each one and match by object reference on the request object.
                    Tuple <WebRequest, WebResponse> tuple = null;
                    foreach (Tuple <WebRequest, WebResponse> currentTuple in requestData.Values)
                    {
                        if (currentTuple != null && currentTuple.Item1 == request)
                        {
                            // Found it!
                            tuple = currentTuple;
                            break;
                        }
                    }

                    // Update the tuple with the response object
                    Assert.NotNull(tuple);
                    requestData[request.RequestUri] =
                        new Tuple <WebRequest, WebResponse>(request, response);
                }
            }

            // Finally, make sure we have request and response objects for every successful request
            foreach (KeyValuePair <Uri, Tuple <WebRequest, WebResponse> > pair in requestData)
            {
                if (successfulTasks.Any(t => t.Key == pair.Key))
                {
                    Assert.NotNull(pair.Value);
                    Assert.NotNull(pair.Value.Item1);
                    Assert.NotNull(pair.Value.Item2);
                }
            }
        }
Exemple #20
0
 private static Activity AssertFirstEventWasStart(ActivitySourceRecorder eventRecords)
 {
     Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair <string, Activity> startEvent));
     Assert.Equal("Start", startEvent.Key);
     return(startEvent.Value);
 }
        public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int mode)
        {
            string url = this.BuildRequestUrl();

            using var eventRecords = new ActivitySourceRecorder();

            // Send a random Http request to generate some events
            var webRequest = (HttpWebRequest)WebRequest.Create(url);

            if (method == "POST")
            {
                webRequest.Method = method;

                Stream stream = null;
                switch (mode)
                {
                case 0:
                    stream = webRequest.GetRequestStream();
                    break;

                case 1:
                    stream = await webRequest.GetRequestStreamAsync();

                    break;

                case 2:
                {
                    object state = new object();
                    using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset);
                    IAsyncResult asyncResult = webRequest.BeginGetRequestStream(
                        ar =>
                        {
                            Assert.Equal(state, ar.AsyncState);
                            handle.Set();
                        },
                        state);
                    stream = webRequest.EndGetRequestStream(asyncResult);
                    if (!handle.WaitOne(TimeSpan.FromSeconds(30)))
                    {
                        throw new InvalidOperationException();
                    }

                    handle.Dispose();
                }

                break;

                case 3:
                {
                    using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset);
                    object state = new object();
                    webRequest.BeginGetRequestStream(
                        ar =>
                        {
                            stream = webRequest.EndGetRequestStream(ar);
                            Assert.Equal(state, ar.AsyncState);
                            handle.Set();
                        },
                        state);
                    if (!handle.WaitOne(TimeSpan.FromSeconds(30)))
                    {
                        throw new InvalidOperationException();
                    }

                    handle.Dispose();
                }

                break;

                default:
                    throw new NotSupportedException();
                }

                Assert.NotNull(stream);

                using StreamWriter writer = new StreamWriter(stream);

                writer.WriteLine("hello world");
            }

            WebResponse webResponse = null;

            switch (mode)
            {
            case 0:
                webResponse = webRequest.GetResponse();
                break;

            case 1:
                webResponse = await webRequest.GetResponseAsync();

                break;

            case 2:
            {
                object state = new object();
                using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset);
                IAsyncResult asyncResult = webRequest.BeginGetResponse(
                    ar =>
                    {
                        Assert.Equal(state, ar.AsyncState);
                        handle.Set();
                    },
                    state);
                webResponse = webRequest.EndGetResponse(asyncResult);
                if (!handle.WaitOne(TimeSpan.FromSeconds(30)))
                {
                    throw new InvalidOperationException();
                }

                handle.Dispose();
            }

            break;

            case 3:
            {
                using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset);
                object state = new object();
                webRequest.BeginGetResponse(
                    ar =>
                    {
                        webResponse = webRequest.EndGetResponse(ar);
                        Assert.Equal(state, ar.AsyncState);
                        handle.Set();
                    },
                    state);
                if (!handle.WaitOne(TimeSpan.FromSeconds(30)))
                {
                    throw new InvalidOperationException();
                }

                handle.Dispose();
            }

            break;

            default:
                throw new NotSupportedException();
            }

            Assert.NotNull(webResponse);

            using StreamReader reader = new StreamReader(webResponse.GetResponseStream());

            reader.ReadToEnd(); // Make sure response is not disposed.

            // We should have exactly one Start and one Stop event
            Assert.Equal(2, eventRecords.Records.Count);
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
            Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));

            // Check to make sure: The first record must be a request, the next record must be a response.
            (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);

            VerifyHeaders(startRequest);
            VerifyActivityStartTags(this.hostNameAndPort, method, url, activity);

            Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
            Assert.Equal("Stop", stopEvent.Key);
            HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty("HttpWebRequest.Response");

            Assert.NotNull(response);

            VerifyActivityStopTags(200, "OK", activity);
        }