Ejemplo n.º 1
0
 public void OnResponse(HttpResponseHead response)
 {
     current = new ResponseInfo()
     {
         Head = response
     };
 }
Ejemplo n.º 2
0
 public void OnResponseEnd()
 {
     if (current == null)
         throw new Exception("Transaction got OnResponseEnd when there was no current response");
     receivedResponses.Add(current);
     current = null;
 }
        public void Transaction_tests(
            [Values(
                 CallKayakWhen.OnRequest,
                 CallKayakWhen.AfterOnRequest,
                 //CallKayakWhen.OnRequestBodyData,
                 //CallKayakWhen.AfterOnRequestBodyData,
                 CallKayakWhen.OnRequestBodyEnd,
                 CallKayakWhen.AfterOnRequestBodyEnd//,
                 //CallKayakWhen.OnRequestBodyError,
                 //CallKayakWhen.AfterOnRequestBodyError
                 )]
            CallKayakWhen respondWhen,

            [Values(
                 CallKayakWhen.OnRequest,
                 CallKayakWhen.AfterOnRequest,
                 CallKayakWhen.OnConnectResponseBody,
                 CallKayakWhen.AfterOnConnectResponseBody//,
                 //CallKayakWhen.DisconnectResponseBody,
                 //CallKayakWhen.AfterDisconnectResponseBody
                 )]
            CallKayakWhen connectRequestBodyWhen,
            [Values(true, false)] bool reverseConnectAndRespondOnRequest,
            [ValueSource(typeof(TransactionTestCases), "GetValues")] TransactionTestCases inputOutput)
        {
            // some permutations are impossible. for example, it's impossible to ConnectRequestBody
            // OnConnectResponseBody if OnResponse is invoked during an OnRequestBody event...neither would ever happen.
            //
            // it's easier to blacklist impossible ones than to construct a whitelist of possible ones:
            if (
                (respondWhen == CallKayakWhen.OnRequestBodyData ||
                 respondWhen == CallKayakWhen.AfterOnRequestBodyData ||
                 respondWhen == CallKayakWhen.OnRequestBodyError ||
                 respondWhen == CallKayakWhen.AfterOnRequestBodyError ||
                 respondWhen == CallKayakWhen.OnRequestBodyEnd ||
                 respondWhen == CallKayakWhen.AfterOnRequestBodyEnd)
                &&
                (connectRequestBodyWhen == CallKayakWhen.OnConnectResponseBody ||
                 connectRequestBodyWhen == CallKayakWhen.AfterOnConnectResponseBody ||
                 connectRequestBodyWhen == CallKayakWhen.OnDisconnectResponseBody ||
                 connectRequestBodyWhen == CallKayakWhen.AfterOnDisconnectResponseBody)
                )
            {
                Assert.Pass("Permutation being tested is not possible.");
            }

            var requests          = inputOutput.Requests;
            var responses         = inputOutput.UserResponses;
            var expectedResponses = inputOutput.ExpectedResponses;

            var          numResponded       = 0;
            var          responseEnumerator = Enumerable.Empty <ResponseInfo>().Concat(responses).GetEnumerator();
            ResponseInfo currentResponse    = null;

            Action <UserKayak> onResponse = kayak =>
            {
                responseEnumerator.MoveNext();
                currentResponse = responseEnumerator.Current;
                numResponded++;
                kayak.OnResponse(currentResponse.Head, currentResponse.Data != null);
            };

            var continueWillBeSuppressed = (respondWhen == CallKayakWhen.OnRequest && connectRequestBodyWhen == CallKayakWhen.AfterOnRequest) ||
                                           connectRequestBodyWhen == CallKayakWhen.OnConnectResponseBody ||
                                           connectRequestBodyWhen == CallKayakWhen.AfterOnConnectResponseBody ||
                                           (reverseConnectAndRespondOnRequest &&
                                            (
                                                // a couple special cases where reversing the order of the calls will modify the behavior
                                                (respondWhen == CallKayakWhen.OnRequest && connectRequestBodyWhen == CallKayakWhen.OnRequest) ||
                                                (respondWhen == CallKayakWhen.AfterOnRequest && connectRequestBodyWhen == CallKayakWhen.AfterOnRequest)
                                            ))
            ;

            requestCallbacker.OnRequestAction = (kayak, head) =>
            {
                var expectContinue = head.IsContinueExpected();

                if (expectContinue && !continueWillBeSuppressed)
                {
                    expectedResponses = expectedResponses
                                        .Take(numResponded)
                                        .Concat(new[] { Response.OneHundredContinue })
                                        .Concat(expectedResponses.Skip(numResponded));
                }

                if (reverseConnectAndRespondOnRequest)
                {
                    if (respondWhen == CallKayakWhen.OnRequest)
                    {
                        onResponse(kayak);
                    }

                    if (respondWhen == CallKayakWhen.AfterOnRequest)
                    {
                        Post(() => onResponse(kayak));
                    }

                    if (connectRequestBodyWhen == CallKayakWhen.OnRequest)
                    {
                        kayak.ConnectRequestBody();
                    }

                    if (connectRequestBodyWhen == CallKayakWhen.AfterOnRequest)
                    {
                        Post(() => kayak.ConnectRequestBody());
                    }
                }
                else
                {
                    if (connectRequestBodyWhen == CallKayakWhen.OnRequest)
                    {
                        kayak.ConnectRequestBody();
                    }

                    if (connectRequestBodyWhen == CallKayakWhen.AfterOnRequest)
                    {
                        Post(() => kayak.ConnectRequestBody());
                    }

                    if (respondWhen == CallKayakWhen.OnRequest)
                    {
                        onResponse(kayak);
                    }

                    if (respondWhen == CallKayakWhen.AfterOnRequest)
                    {
                        Post(() => onResponse(kayak));
                    }
                }
            };

            requestCallbacker.OnRequestBodyEndAction = kayak =>
            {
                if (respondWhen == CallKayakWhen.OnRequestBodyEnd)
                {
                    onResponse(kayak);
                }

                if (respondWhen == CallKayakWhen.AfterOnRequestBodyEnd)
                {
                    Post(() => onResponse(kayak));
                }
            };

            requestCallbacker.ConnectResponseBodyAction = kayak =>
            {
                if (connectRequestBodyWhen == CallKayakWhen.OnConnectResponseBody)
                {
                    kayak.ConnectRequestBody();
                }

                if (connectRequestBodyWhen == CallKayakWhen.AfterOnConnectResponseBody)
                {
                    Post(() => kayak.ConnectRequestBody());
                }

                // XXX test sync also
                var    responseDataEnumerator = currentResponse.Data.GetEnumerator();
                Action send = null;
                send = () =>
                {
                    if (responseDataEnumerator.MoveNext())
                    {
                        kayak.OnResponseBodyData(responseDataEnumerator.Current);
                        Post(send);
                    }
                    else
                    {
                        kayak.OnResponseBodyEnd();
                    }
                };

                Post(send);
            };

            Drive(Interleave(GetInputActions(requests, transactionInput), GetPostedActions()));

            requestAccumulator.AssertRequests(requests);
            responseAccumulator.AssertResponses(expectedResponses);

            Assert.That(responseAccumulator.GotEnd, Is.True);
            Assert.That(responseAccumulator.GotDispose, Is.True);
        }