public void OnResponse(HttpResponseHead response) { current = new ResponseInfo() { Head = response }; }
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); }