/// <summary> /// Initializes a new instance of the <see cref="MockHttpServer" /> class that record or /// playback responses for requests in a session. /// </summary> /// <param name="exceptionManager"> /// The exception manager that captures all async exceptions. /// </param> /// <param name="baseUri">The server prefix to use.</param> /// <param name="session">The object that stores request/response information.</param> public MockHttpServer( AsyncExceptionManager exceptionManager, Uri baseUri, HttpSession session) : this(exceptionManager, baseUri) { this.stopListenerUri = new Uri(baseUri, Guid.NewGuid().ToString()); this.listener = this.CreateListener( context => HandleMockRequest( context, this.baseUri, session), int.MaxValue); }
/// <summary> /// The async delegate that handles an incoming request, passing it through to a real /// service and record the response if <paramref name="serviceBaseUri"/> was specified, /// or plays back responses from a pre-recorded <paramref name="session"/> if it was not. /// </summary> /// <param name="context">The context for the incoming request.</param> /// <param name="baseUri">The incoming request's base Uri.</param> /// <param name="session">The object that stores request/response information.</param> private static void HandleMockRequest( HttpListenerContext context, Uri baseUri, HttpSession session) { if (session.ServiceBaseUri != null) { // Issue the request to a real service and record the response HttpMessage message = GetResponseInfoFromService( context.Request, baseUri, session.ServiceBaseUri, session); session.Messages.RecordMessage(message); } // Construct the mock response from responses in the session. HttpMessage recordedMessage = session.Messages.GetMessage(context.Request.Url); if (session.RequestValidator != null) { HttpMessage.Request actualRequestInfo = ConstructRequestInfo(context.Request); session.RequestValidator(recordedMessage, actualRequestInfo); } if (session.ResponseModifier != null) { session.ResponseModifier(recordedMessage); } ConstructListenerResponse(recordedMessage.ResponseInfo, baseUri, context.Response); context.Response.Close(); }
/// <summary> /// Retrieves an <see cref="HttpMessage"/> object from a real service. /// </summary> /// <param name="request">The request to mimic on the real service.</param> /// <param name="baseUri">The request's base Uri.</param> /// <param name="serviceBaseUri">The real service's base Uri.</param> /// <param name="session">The object that stores request/response information.</param> /// <returns>An <see cref="HttpMessage"/> object containing the request/response.</returns> private static HttpMessage GetResponseInfoFromService( HttpListenerRequest request, Uri baseUri, Uri serviceBaseUri, HttpSession session) { // Construct the request to make HttpMessage message = new HttpMessage(); message.RequestInfo = ConstructRequestInfo(request); // Clone the request and modify it for the real service HttpMessage.Request requestToSend = message.RequestInfo.Clone(); requestToSend.RequestUri = ChangeUriBase(request.Url, baseUri, serviceBaseUri); if (session.RequestModifier != null) { session.RequestModifier(requestToSend); } HttpWebResponse response = MakeServiceRequest(requestToSend); message.ResponseInfo = ConstructResponseInfo(serviceBaseUri, response); return message; }
/// <summary> /// Wait for Continuous Copy operation to become catchup. /// </summary> /// <param name="powershell">The powershell instance containing the context.</param> /// <param name="contextVariable">The variable name that holds the server context.</param> /// <param name="dbCopyVariable">The variable name that holds the db copy object.</param> public static void WaitContinuousCopyCatchup( System.Management.Automation.PowerShell powershell, string contextVariable, string dbCopyVariable) { if (DatabaseTestHelper.CommonServiceBaseUri == null) { // Don't need to wait during playback return; } HttpSession testSession = new HttpSession(); testSession.Messages = new HttpMessageCollection(); DatabaseTestHelper.SetDefaultTestSessionSettings(testSession); using (AsyncExceptionManager exceptionManager = new AsyncExceptionManager()) { using (new MockHttpServer( exceptionManager, MockHttpServer.DefaultServerPrefixUri, testSession)) { for (int i = 0; i < 20; i++) { Collection<PSObject> databaseCopy = powershell.InvokeBatchScript( string.Format( CultureInfo.InvariantCulture, @"{0} | Get-AzureSqlDatabaseCopy " + @"-Context $context", dbCopyVariable)); Assert.AreEqual(0, powershell.Streams.Error.Count, "Errors during run!"); Assert.AreEqual(0, powershell.Streams.Warning.Count, "Warnings during run!"); powershell.Streams.ClearStreams(); Assert.IsTrue( databaseCopy.First().BaseObject is Services.Server.DatabaseCopy, "Expecting a Database Copy object"); Services.Server.DatabaseCopy databaseCopyObj = (Services.Server.DatabaseCopy)databaseCopy.Single().BaseObject; if (databaseCopyObj.ReplicationStateDescription == "CATCH_UP") { break; } Thread.Sleep(TimeSpan.FromSeconds(1)); } } } }
/// <summary> /// Set the default mock session settings to modify request and responses. /// </summary> /// <param name="testSession"></param> public static void SetDefaultTestSessionSettings(HttpSession testSession) { testSession.ServiceBaseUri = DatabaseTestHelper.CommonServiceBaseUri; testSession.ResponseModifier = new Action<HttpMessage>( (message) => { DatabaseTestHelper.FixODataResponseUri( message.ResponseInfo, testSession.ServiceBaseUri, MockHttpServer.DefaultServerPrefixUri); }); testSession.RequestModifier = new Action<HttpMessage.Request>( (request) => { DatabaseTestHelper.FixODataRequestPayload( request, testSession.ServiceBaseUri, MockHttpServer.DefaultServerPrefixUri); }); }
/// <summary> /// Helper method for wait for all copy to terminate. /// </summary> /// <param name="powershell">The powershell instance containing the context.</param> /// <param name="contextVariable">The variable name that will hold the new context.</param> public static void WaitForCopyTermination( System.Management.Automation.PowerShell powershell, string contextVariable) { if (DatabaseTestHelper.CommonServiceBaseUri == null) { // Don't need to wait during playback return; } HttpSession testSession = new HttpSession(); testSession.Messages = new HttpMessageCollection(); DatabaseTestHelper.SetDefaultTestSessionSettings(testSession); Collection<PSObject> databaseCopies = null; using (AsyncExceptionManager exceptionManager = new AsyncExceptionManager()) { using (new MockHttpServer( exceptionManager, MockHttpServer.DefaultServerPrefixUri, testSession)) { for (int i = 0; i < 20; i++) { databaseCopies = powershell.InvokeBatchScript( string.Format( CultureInfo.InvariantCulture, @"Get-AzureSqlDatabaseCopy " + @"-Context {0}", contextVariable)); if (databaseCopies.Count == 0) { break; } Thread.Sleep(TimeSpan.FromSeconds(1)); } } } Assert.AreEqual(0, databaseCopies.Count, "Expecting 0 Database Copy objects"); }