/// <summary> /// Connects to an endpoint of a server and returns its channel context /// </summary> /// <param name="endpoint">This parameter stores an endpoint of the server.</param> /// <param name="logFileName">File name for logging.</param> /// <returns>This object will contain the channel related information.</returns> private ChannelContext InitializeChannel(ConfiguredEndpoint endpoint, string logFileName) { ChannelContext channelContext = new ChannelContext(); channelContext.PendingAsycnTests = 0; channelContext.AsyncTestsComplete = new AutoResetEvent(false); channelContext.TestCaseComplete = new AutoResetEvent(false); // load random number file. channelContext.Random = new PseudoRandom(m_randomFilePath); // create the proxy. channelContext.Channel = SessionChannel.Create( Configuration, endpoint.Description, endpoint.Configuration, m_configuration.SecurityConfiguration.ApplicationCertificate.Find(true), m_messageContext); channelContext.MessageContext = m_messageContext; channelContext.EndpointDescription = endpoint.Description; // wrap the channel. channelContext.ClientSession = new SessionClient(channelContext.Channel); // open log file. channelContext.EventLogger = new Logger(logFileName, (TestLogDetailMasks)m_sequenceToExecute.LogDetailLevel); channelContext.EventLogger.Open(String.Empty, m_testFilePath, channelContext.Random.FilePath); if (m_testLogEventHandler != null) { channelContext.EventLogger.TestLogEvent += m_testLogEventHandler; } return(channelContext); }
/// <summary> /// This method executes a test using messages that exceed the maximum message size. /// </summary> private void ExecuteTest_LargeMessages( ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { bool isSetupStep = TestUtils.IsSetupIteration(iteration); if (!isSetupStep) { channelContext.EventLogger.LogStartEvent(testCase, iteration); } else { channelContext.ClientSession.OperationTimeout = 30000; } RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; Variant input; Variant output; Variant expectedOutput; ResponseHeader responseHeader; if (isSetupStep) { testCaseContext.ClientMaxMessageSize = channelContext.MessageContext.MaxMessageSize; responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, new Variant(testCaseContext.ClientMaxMessageSize), out output); if (output.Value is int) { testCaseContext.ServerMaxMessageSize = (int)output.Value; } // update the parameters. for (int ii = 0; ii < testCase.Parameter.Length; ii++) { if (testCase.Parameter[ii].Name == TestCases.ServerMaxMessageSize) { testCase.Parameter[ii].Value = Utils.Format("{0}", testCaseContext.ServerMaxMessageSize); continue; } if (testCase.Parameter[ii].Name == TestCases.ClientMaxMessageSize) { testCase.Parameter[ii].Value = Utils.Format("{0}", testCaseContext.ClientMaxMessageSize); continue; } } } else { channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); int messageLength = 0; if (channelContext.Random.GetRandomBoolean()) { messageLength = channelContext.Random.GetInt32Range(1, testCaseContext.ServerMaxMessageSize / 2); } else { messageLength = channelContext.Random.GetInt32Range(testCaseContext.ServerMaxMessageSize, testCaseContext.ServerMaxMessageSize * 2); } input = new Variant(channelContext.Random.GetRandomByteString(messageLength)); ServiceResultException sre = null; try { responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); } catch (ServiceResultException e) { sre = e; } if (messageLength > testCaseContext.ServerMaxMessageSize) { if (sre == null) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Server did not reject a message that is too large ({0} bytes).", messageLength)); } else { if (sre.StatusCode != StatusCodes.BadRequestTooLarge) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Client do not receive a BadRequestTooLarge exception: {0}", sre.StatusCode)); } } } else { channelContext.Random.Start( (int)(testCase.ResponseSeed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); if (channelContext.Random.GetRandomBoolean()) { messageLength = channelContext.Random.GetInt32Range(1, testCaseContext.ClientMaxMessageSize / 2); } else { messageLength = channelContext.Random.GetInt32Range(testCaseContext.ClientMaxMessageSize, testCaseContext.ClientMaxMessageSize * 2); } if (sre == null) { if (messageLength > testCaseContext.ClientMaxMessageSize) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Client received a message that is too large ({0} bytes).", messageLength)); } expectedOutput = new Variant(channelContext.Random.GetRandomByteString(messageLength)); if (!Compare.CompareVariant(output, expectedOutput)) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("'{0}' is not equal to '{1}'.", output, expectedOutput)); } } else { if (sre.StatusCode != StatusCodes.BadResponseTooLarge) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Client do not receive a BadResponseTooLarge exception: {0}", sre.StatusCode)); } } } } if (!isSetupStep) { channelContext.EventLogger.LogCompleteEvent(testCase, iteration); } }
/// <summary> /// This method executes a scalar values test. /// </summary> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> /// <param name="iteration">This parameter stores the current iteration number.</param> /// <remarks> /// The test parameters required for this test case are of the /// following types: /// <list type="bullet"> /// <item>MinTimeout <see cref="TestCaseContext.MinTimeout"/></item> /// <item>MaxTimeout <see cref="TestCaseContext.MaxTimeout"/></item> /// <item>MaxStringLength <see cref="TestCaseContext.MaxStringLength"/></item> /// <item>MaxTransportDelay <see cref="TestCaseContext.MaxTransportDelay"/></item> /// </list> /// </remarks> private void ExecuteTest_ServerTimout(ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { bool isSetupStep = TestUtils.IsSetupIteration(iteration); if (!isSetupStep) { channelContext.EventLogger.LogStartEvent(testCase, iteration); } isSetupStep = TestUtils.IsSetupIteration(iteration); RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; Variant input; Variant output; if (isSetupStep) { input = Variant.Null; ResponseHeader responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); } else { int serverSleepTime = 0; DateTime startTime = DateTime.UtcNow; try { channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); input = channelContext.Random.GetScalarVariant(false); // Server's sleep time serverSleepTime = channelContext.Random.GetTimeout(); channelContext.ClientSession.OperationTimeout = serverSleepTime - 100; ResponseHeader responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); channelContext.EventLogger.LogErrorEvent(testCase, iteration, new Exception("Test failed. Expected a TimeoutException, but did not occur.")); return; } catch (Exception e) { ServiceResultException sre = e as ServiceResultException; if (e is TimeoutException || (sre != null && sre.StatusCode == StatusCodes.BadRequestTimeout)) { // This indicates that Stack did timeout the request. } else { throw e; } } TimeSpan timeSpent = DateTime.UtcNow.Subtract(startTime); if (timeSpent.TotalMilliseconds > serverSleepTime * 1.10) { channelContext.EventLogger.LogErrorEvent(testCase, iteration, new Exception("Test failed. Timeout took too long.")); return; } } if (!isSetupStep) { channelContext.EventLogger.LogCompleteEvent(testCase, iteration); } }
/// <summary> /// This method executes a Server Fault test. /// </summary> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> /// <param name="iteration">This parameter stores the current iteration number.</param> /// <remarks> /// The test parameters required for this test case are of the /// following types: /// <list type="bullet"> /// <item>MaxStringLength <see cref="TestCaseContext.MaxStringLength"/></item> /// </list> /// </remarks> private void ExecuteTest_ServerFault(ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { bool isSetupStep = isSetupStep = TestUtils.IsSetupIteration(iteration); if (!isSetupStep) { channelContext.EventLogger.LogStartEvent(testCase, iteration); } else { channelContext.ClientSession.OperationTimeout = 30000; } RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; Variant input; Variant output; ResponseHeader responseHeader; if (isSetupStep) { input = Variant.Null; responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); } else { channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); input = channelContext.Random.GetScalarVariant(false); channelContext.Random.Start( (int)(testCase.ResponseSeed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); string expectedExceptionMessage = channelContext.Random.GetRandomString(); try { responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); channelContext.EventLogger.LogErrorEvent(testCase, iteration, new Exception("Test failed. Expected a ServiceResultException.")); } catch (ServiceResultException sre) { if (sre.StatusCode != StatusCodes.BadMethodInvalid || sre.LocalizedText != expectedExceptionMessage) { channelContext.EventLogger.LogErrorEvent(testCase, iteration, sre); } } } if (!isSetupStep) { channelContext.EventLogger.LogCompleteEvent(testCase, iteration); } }
/// <summary> /// This method executes a test using messages that exceed the maximum message size. /// </summary> private void ExecuteTest_LargeMessages( ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { bool isSetupStep = TestUtils.IsSetupIteration(iteration); if (!isSetupStep) { channelContext.EventLogger.LogStartEvent(testCase, iteration); } else { channelContext.ClientSession.OperationTimeout = 30000; } RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; Variant input; Variant output; Variant expectedOutput; ResponseHeader responseHeader; if (isSetupStep) { testCaseContext.ClientMaxMessageSize = channelContext.MessageContext.MaxMessageSize; responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, new Variant(testCaseContext.ClientMaxMessageSize), out output); if (output.Value is int) { testCaseContext.ServerMaxMessageSize = (int)output.Value; } // update the parameters. for (int ii = 0; ii < testCase.Parameter.Length; ii++) { if (testCase.Parameter[ii].Name == TestCases.ServerMaxMessageSize) { testCase.Parameter[ii].Value = Utils.Format("{0}", testCaseContext.ServerMaxMessageSize); continue; } if (testCase.Parameter[ii].Name == TestCases.ClientMaxMessageSize) { testCase.Parameter[ii].Value = Utils.Format("{0}", testCaseContext.ClientMaxMessageSize); continue; } } } else { channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); int messageLength = 0; if (channelContext.Random.GetRandomBoolean()) { messageLength = channelContext.Random.GetInt32Range(1, testCaseContext.ServerMaxMessageSize/2); } else { messageLength = channelContext.Random.GetInt32Range(testCaseContext.ServerMaxMessageSize, testCaseContext.ServerMaxMessageSize*2); } input = new Variant(channelContext.Random.GetRandomByteString(messageLength)); ServiceResultException sre = null; try { responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); } catch (ServiceResultException e) { sre = e; } if (messageLength > testCaseContext.ServerMaxMessageSize) { if (sre == null) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Server did not reject a message that is too large ({0} bytes).", messageLength)); } else { if (sre.StatusCode != StatusCodes.BadRequestTooLarge) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Client do not receive a BadRequestTooLarge exception: {0}", sre.StatusCode)); } } } else { channelContext.Random.Start( (int)(testCase.ResponseSeed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); if (channelContext.Random.GetRandomBoolean()) { messageLength = channelContext.Random.GetInt32Range(1, testCaseContext.ClientMaxMessageSize/2); } else { messageLength = channelContext.Random.GetInt32Range(testCaseContext.ClientMaxMessageSize, testCaseContext.ClientMaxMessageSize*2); } if (sre == null) { if (messageLength > testCaseContext.ClientMaxMessageSize) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Client received a message that is too large ({0} bytes).", messageLength)); } expectedOutput = new Variant(channelContext.Random.GetRandomByteString(messageLength)); if (!Compare.CompareVariant(output, expectedOutput)) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("'{0}' is not equal to '{1}'.", output, expectedOutput)); } } else { if (sre.StatusCode != StatusCodes.BadResponseTooLarge) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("Client do not receive a BadResponseTooLarge exception: {0}", sre.StatusCode)); } } } } if (!isSetupStep) { channelContext.EventLogger.LogCompleteEvent(testCase, iteration); } }
/// <summary> /// This method executes a scalar values test. /// </summary> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> /// <param name="iteration">This parameter stores the current iteration number.</param> /// <remarks> /// The test parameters required for this test case are of the /// following types: /// <list type="bullet"> /// <item>MinTimeout <see cref="TestCaseContext.MinTimeout"/></item> /// <item>MaxTimeout <see cref="TestCaseContext.MaxTimeout"/></item> /// <item>MaxStringLength <see cref="TestCaseContext.MaxStringLength"/></item> /// <item>MaxTransportDelay <see cref="TestCaseContext.MaxTransportDelay"/></item> /// </list> /// </remarks> private void ExecuteTest_ServerTimout(ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { bool isSetupStep = TestUtils.IsSetupIteration(iteration); if (!isSetupStep) { channelContext.EventLogger.LogStartEvent(testCase, iteration); } isSetupStep = TestUtils.IsSetupIteration(iteration); RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; Variant input; Variant output; if (isSetupStep) { input = Variant.Null; ResponseHeader responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); } else { int serverSleepTime = 0; DateTime startTime = DateTime.UtcNow; try { channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); input = channelContext.Random.GetScalarVariant(false); // Server's sleep time serverSleepTime = channelContext.Random.GetTimeout(); channelContext.ClientSession.OperationTimeout = serverSleepTime-100; ResponseHeader responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); channelContext.EventLogger.LogErrorEvent(testCase, iteration, new Exception("Test failed. Expected a TimeoutException, but did not occur.")); return; } catch (Exception e) { ServiceResultException sre = e as ServiceResultException; if (e is TimeoutException || (sre != null && sre.StatusCode == StatusCodes.BadRequestTimeout)) { // This indicates that Stack did timeout the request. } else { throw e; } } TimeSpan timeSpent = DateTime.UtcNow.Subtract(startTime); if (timeSpent.TotalMilliseconds > serverSleepTime*1.10) { channelContext.EventLogger.LogErrorEvent(testCase, iteration, new Exception("Test failed. Timeout took too long.")); return; } } if (!isSetupStep) { channelContext.EventLogger.LogCompleteEvent(testCase, iteration); } }
private void ExecuteTest_AutoReconnect( ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { Variant input; Variant output; // initialize test case. if (iteration == TestCases.TestSetupIteration) { m_fault = null; m_blackouts = new List<BlackoutPeriod>(); channelContext.ClientSession.OperationTimeout = 30000; RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; ResponseHeader responseHeader = channelContext.ClientSession.TestStack( null, testCase.TestId, TestCases.TestSetupIteration, input, out output); return; } if (iteration == TestCases.TestCleanupIteration) { do { lock (m_lock) { if (m_requestCount == 0) { return; } } Thread.Sleep(100); } while (true); } Thread.Sleep(testCaseContext.RequestInterval); // report fault after waiting for all active threads to exit. if (m_sequenceToExecute.HaltOnError) { ServiceResult fault = null; lock (m_lock) { fault = m_fault; } if (fault != null) { do { lock (m_lock) { if (m_requestCount == 0) { throw new ServiceResultException(fault); } } Thread.Sleep(100); } while (true); } } // begin iteration. channelContext.EventLogger.LogStartEvent(testCase, iteration); lock (m_lock) { // set up header. RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; // generate input data. channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); input = channelContext.Random.GetVariant(); // determine processing time in server. int processingTime = channelContext.Random.GetInt32Range(0, testCaseContext.MaxResponseDelay); Utils.Trace("Iteration {0}; Processing Time {1}.", iteration, processingTime); AsyncTestState state = new AsyncTestState(channelContext, testCaseContext, testCase, iteration); state.CallData = (DateTime.UtcNow.AddMilliseconds(processingTime).Ticks/TimeSpan.TicksPerMillisecond); // set timeout to twice the processing time. if (processingTime < testCaseContext.MaxTransportDelay) { processingTime = testCaseContext.MaxTransportDelay; } channelContext.ClientSession.OperationTimeout = processingTime*2; if ((iteration+1)%testCaseContext.StackEventFrequency == 0) { StackAction action = TestUtils.GetStackAction(testCaseContext, channelContext.EndpointDescription); if (action != null) { BlackoutPeriod period = new BlackoutPeriod(); period.Start = (DateTime.UtcNow.Ticks/TimeSpan.TicksPerMillisecond); m_blackouts.Add(period); Utils.Trace("Iteration {0}; Expecting Fault {1}", iteration, action.ActionType); } } try { channelContext.ClientSession.BeginTestStack( requestHeader, testCase.TestId, iteration, input, EndAutoReconnect, state); m_requestCount++; } catch (Exception e) { // check if a fault is expected. bool faultExpected = FaultExpected((long)state.CallData , testCaseContext); if (faultExpected) { Utils.Trace("Iteration {0}; Fault Expected {1}", state.Iteration, e.Message); state.ChannelContext.EventLogger.LogCompleteEvent(testCase, iteration); return; } channelContext.EventLogger.LogErrorEvent(testCase, iteration, e); if (m_sequenceToExecute.HaltOnError) { if (m_fault == null) { m_fault = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Could not send request."); } } } } }
/// <summary> /// This method executes the test case. /// </summary> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> private void ExecuteTestCase(ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase) { try { channelContext.TestCaseComplete.Reset(); channelContext.AsyncTestsComplete.Set(); lock (m_lock) { if (m_cancel) { return; } } try { channelContext.EventLogger.LogStartEvent(testCase, TestCases.TestSetupIteration); ExecuteTest(channelContext, testCaseContext, testCase, TestCases.TestSetupIteration); } catch (Exception e) { channelContext.EventLogger.LogErrorEvent(testCase, TestCases.TestSetupIteration, e); if (m_sequenceToExecute.HaltOnError) { throw; } else { return; } } // start the test at the iteration specified in the test case. for (int ii = (int)testCase.Start; ii < testCase.Count; ii++) { lock (m_lock) { if (m_cancel) { break; } if (m_quickTest && ii > 10) { break; } RaiseEvent(new TestSequenceEventArgs(testCase.TestId, testCase.Name, ii)); } try { ExecuteTest(channelContext, testCaseContext, testCase, ii); } catch (Exception e) { channelContext.EventLogger.LogErrorEvent(testCase, ii, e); if (m_sequenceToExecute.HaltOnError) { throw; } else { continue; } } } try { // Wait till any of the pending test cases to finish before closing the logger channelContext.AsyncTestsComplete.WaitOne(); ExecuteTest(channelContext, testCaseContext, testCase, TestCases.TestCleanupIteration); channelContext.EventLogger.LogCompleteEvent(testCase, TestCases.TestCleanupIteration); } catch (Exception e) { channelContext.EventLogger.LogErrorEvent(testCase, TestCases.TestCleanupIteration, e); if (m_sequenceToExecute.HaltOnError) { throw; } else { return; } } } finally { channelContext.TestCaseComplete.Set(); } }
/// <summary> /// This method executes the test cases for the configured endpoint. /// In case of multiple channel test cases, this endpoint value is ignored and new /// endpoint is used to connect to the server specified in test configuration. /// </summary> /// <param name="endpoint">This parameter stores an endpoint of the server.</param> public void ExecuteTestSequence(ConfiguredEndpoint endpoint) { lock (m_lock) { m_cancel = false; } if (endpoint.UpdateBeforeConnect) { // create the binding factory if it has not been created yet. if (m_bindingFactory == null) { m_bindingFactory = BindingFactory.Create(m_configuration, m_messageContext); } endpoint.UpdateFromServer(m_bindingFactory); } ChannelContext selectedChannelContext = null; selectedChannelContext = InitializeChannel(endpoint, m_logFilePath); try { foreach (TestCase testCase in m_sequenceToExecute.TestCase) { if (testCase.SkipTest || testCase.Name.StartsWith(TestCases.SerializerDirect)) { continue; } try { TestUtils.ValidateTestCase(testCase, (int)testCase.Start); } catch (Exception e) { selectedChannelContext.EventLogger.LogErrorEvent(testCase, (int)testCase.Start, e); if (m_sequenceToExecute.HaltOnError) { throw; } else { continue; } } TestCaseContext testCaseContext = TestUtils.GetExecutionContext(testCase); try { ValidateTestContext(testCaseContext, testCase); } catch (Exception e) { selectedChannelContext.EventLogger.LogErrorEvent(testCase, (int)testCase.Start, e); if (m_sequenceToExecute.HaltOnError) { throw; } else { continue; } } if (testCase.Name != TestCases.MultipleChannels) { ExecuteTestCase(selectedChannelContext, testCaseContext, testCase); } else { Uri defaultUrl = new Uri(endpoint.Description.EndpointUrl); // In case of multiple channel get endpoint urls from the test case file. List <ChannelContext> channelContextList = new List <ChannelContext>(); List <ConfiguredEndpoint> configuredEndpointList = new List <ConfiguredEndpoint>(); for (int serverCnt = 0; serverCnt < testCaseContext.ServerDetails.Count; serverCnt++) { string serverURL = testCaseContext.ServerDetails[serverCnt].Url; serverURL = serverURL.Replace("localhost", defaultUrl.DnsSafeHost); //ConfiguredEndpointCollection endpointCollection = new ConfiguredEndpointCollection () ; //ConfiguredEndpoint serverendpoint = endpointCollection.Create(serverURL); ConfiguredEndpoint serverendpoint = (ConfiguredEndpoint)endpoint.Clone(); // slow systems may not be able to renew tokens fast enough when overloaded with channels. serverendpoint.Configuration.SecurityTokenLifetime = 60000; serverendpoint.Description.EndpointUrl = serverURL; configuredEndpointList.Add(serverendpoint); //For each channel get the log file name as <default file name>_<server name>_<channel index>. for (int channelCnt = 0; channelCnt < testCaseContext.ChannelsPerServer; channelCnt++) { string logFileSuffix = "_" + testCaseContext.ServerDetails[serverCnt].Name + "_" + channelCnt.ToString(); string logFileName = m_logFilePath.Replace(".xml", logFileSuffix) + ".xml"; ChannelContext channelContext = InitializeChannel(configuredEndpointList[serverCnt], logFileName); channelContextList.Add(channelContext); } } try { WaitHandle[] waitHandles = new WaitHandle[channelContextList.Count]; for (int iCtr = 0; iCtr < channelContextList.Count; iCtr++) { waitHandles[iCtr] = channelContextList[iCtr].TestCaseComplete; ThreadPool.QueueUserWorkItem(ExecuteTestCase, new object[] { channelContextList[iCtr], testCaseContext, testCase }); } WaitHandle.WaitAll(waitHandles); } finally { for (int iCtr = 0; iCtr < channelContextList.Count; iCtr++) { WindupChannel(channelContextList[iCtr]); } } } } } finally { WindupChannel(selectedChannelContext); } RaiseEvent(new TestSequenceEventArgs(0, "Done", 0)); }
/// <summary> /// Winds up a channel /// </summary> /// <param name="channelContext">Channel related data.</param> private void WindupChannel(ChannelContext channelContext) { if (m_testLogEventHandler != null) { channelContext.EventLogger.TestLogEvent -= m_testLogEventHandler; } channelContext.EventLogger.Close(); channelContext.EventLogger = null; channelContext.Channel.Close(); channelContext.Channel = null; }
/// <summary> /// Connects to an endpoint of a server and returns its channel context /// </summary> /// <param name="endpoint">This parameter stores an endpoint of the server.</param> /// <param name="logFileName">File name for logging.</param> /// <returns>This object will contain the channel related information.</returns> private ChannelContext InitializeChannel(ConfiguredEndpoint endpoint, string logFileName) { ChannelContext channelContext = new ChannelContext(); channelContext.PendingAsycnTests = 0; channelContext.AsyncTestsComplete = new AutoResetEvent(false); channelContext.TestCaseComplete = new AutoResetEvent(false); // load random number file. channelContext.Random = new PseudoRandom(m_randomFilePath); // create the proxy. channelContext.Channel = SessionChannel.Create( Configuration, endpoint.Description, endpoint.Configuration, m_configuration.SecurityConfiguration.ApplicationCertificate.Find(true), m_messageContext); channelContext.MessageContext = m_messageContext; channelContext.EndpointDescription = endpoint.Description; // wrap the channel. channelContext.ClientSession = new SessionClient(channelContext.Channel); // open log file. channelContext.EventLogger = new Logger(logFileName, (TestLogDetailMasks)m_sequenceToExecute.LogDetailLevel); channelContext.EventLogger.Open(String.Empty, m_testFilePath, channelContext.Random.FilePath); if (m_testLogEventHandler != null) { channelContext.EventLogger.TestLogEvent += m_testLogEventHandler; } return channelContext; }
/// <summary> /// This method executes a test. /// </summary> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> /// <param name="iteration">This parameter stores the current iteration number.</param> private void ExecuteTest(ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { switch (testCase.Name) { #region Serialization Tests case TestCases.ScalarValues: { ExecuteTest_ScalarValues(channelContext, testCaseContext, testCase, iteration); break; } case TestCases.ArrayValues: { ExecuteTest_ArrayValues(channelContext, testCaseContext, testCase, iteration); break; } case TestCases.ExtensionObjectValues: { ExecuteTest_ExtensionObjectValues(channelContext, testCaseContext, testCase, iteration); break; } case TestCases.BuiltInTypes: { ExecuteTest_BuiltInTypes(channelContext, testCaseContext, testCase, iteration); break; } case TestCases.LargeMessages: { ExecuteTest_LargeMessages(channelContext, testCaseContext, testCase, iteration); break; } #endregion #region Protocol Tests case TestCases.MultipleChannels: { ExecuteTest_MultipleChannels(channelContext, testCaseContext, testCase, iteration); break; } case TestCases.AutoReconnect: { ExecuteTest_AutoReconnect(channelContext, testCaseContext, testCase, iteration); break; } #endregion #region Fault Tests case TestCases.ServerFault: { ExecuteTest_ServerFault(channelContext, testCaseContext, testCase, iteration); break; } case TestCases.ServerTimeout: { ExecuteTest_ServerTimout(channelContext, testCaseContext, testCase, iteration); break; } #endregion default: { throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Unsupported test case : " + testCase.Name); } } }
private void ExecuteTest_AutoReconnect( ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { Variant input; Variant output; // initialize test case. if (iteration == TestCases.TestSetupIteration) { m_fault = null; m_blackouts = new List <BlackoutPeriod>(); channelContext.ClientSession.OperationTimeout = 30000; RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; ResponseHeader responseHeader = channelContext.ClientSession.TestStack( null, testCase.TestId, TestCases.TestSetupIteration, input, out output); return; } if (iteration == TestCases.TestCleanupIteration) { do { lock (m_lock) { if (m_requestCount == 0) { return; } } Thread.Sleep(100); }while (true); } Thread.Sleep(testCaseContext.RequestInterval); // report fault after waiting for all active threads to exit. if (m_sequenceToExecute.HaltOnError) { ServiceResult fault = null; lock (m_lock) { fault = m_fault; } if (fault != null) { do { lock (m_lock) { if (m_requestCount == 0) { throw new ServiceResultException(fault); } } Thread.Sleep(100); }while (true); } } // begin iteration. channelContext.EventLogger.LogStartEvent(testCase, iteration); lock (m_lock) { // set up header. RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; // generate input data. channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); input = channelContext.Random.GetVariant(); // determine processing time in server. int processingTime = channelContext.Random.GetInt32Range(0, testCaseContext.MaxResponseDelay); Utils.Trace("Iteration {0}; Processing Time {1}.", iteration, processingTime); AsyncTestState state = new AsyncTestState(channelContext, testCaseContext, testCase, iteration); state.CallData = (DateTime.UtcNow.AddMilliseconds(processingTime).Ticks / TimeSpan.TicksPerMillisecond); // set timeout to twice the processing time. if (processingTime < testCaseContext.MaxTransportDelay) { processingTime = testCaseContext.MaxTransportDelay; } channelContext.ClientSession.OperationTimeout = processingTime * 2; if ((iteration + 1) % testCaseContext.StackEventFrequency == 0) { StackAction action = TestUtils.GetStackAction(testCaseContext, channelContext.EndpointDescription); if (action != null) { BlackoutPeriod period = new BlackoutPeriod(); period.Start = (DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond); m_blackouts.Add(period); Utils.Trace("Iteration {0}; Expecting Fault {1}", iteration, action.ActionType); } } try { channelContext.ClientSession.BeginTestStack( requestHeader, testCase.TestId, iteration, input, EndAutoReconnect, state); m_requestCount++; } catch (Exception e) { // check if a fault is expected. bool faultExpected = FaultExpected((long)state.CallData, testCaseContext); if (faultExpected) { Utils.Trace("Iteration {0}; Fault Expected {1}", state.Iteration, e.Message); state.ChannelContext.EventLogger.LogCompleteEvent(testCase, iteration); return; } channelContext.EventLogger.LogErrorEvent(testCase, iteration, e); if (m_sequenceToExecute.HaltOnError) { if (m_fault == null) { m_fault = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Could not send request."); } } } } }
/// <summary> /// This method executes a multi channel test. /// <see cref="ExecuteTest"/> /// </summary> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> /// <param name="iteration">This parameter stores the current iteration number.</param> /// <remarks> /// The test parameters required for this test case are of the /// following types: /// <list type="bullet"> /// <item>MaxStringLength <see cref="TestCaseContext.MaxStringLength"/></item> /// <item>ChannelsPerServer <see cref="TestCaseContext.ChannelsPerServer"/></item> /// <item>ServerDetails <see cref="TestCaseContext.ServerDetails"/></item> /// </list> /// </remarks> private void ExecuteTest_MultipleChannels(ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { bool isSetupStep = TestUtils.IsSetupIteration(iteration); if (!isSetupStep) { channelContext.EventLogger.LogStartEvent(testCase, iteration); } else { channelContext.ClientSession.OperationTimeout = 30000; } RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; Variant input; Variant output; Variant expectedOutput; ResponseHeader responseHeader; if (isSetupStep) { input = Variant.Null; responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); } else { channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); input = channelContext.Random.GetScalarVariant(false); responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); channelContext.Random.Start( (int)(testCase.ResponseSeed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); expectedOutput = channelContext.Random.GetScalarVariant(false); if (!Compare.CompareVariant(output, expectedOutput)) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("'{0}' is not equal to '{1}'.", output, expectedOutput)); } } if (!isSetupStep) { channelContext.EventLogger.LogCompleteEvent(testCase, iteration); } }
/// <summary> /// This method executes an extension object values test. /// </summary> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> /// <param name="iteration">This parameter stores the current iteration number.</param> /// <remarks> /// The test parameters required for this test case are of the /// following types: /// <list type="bullet"> /// <item>MaxStringLength <see cref="TestCaseContext.MaxStringLength"/></item> /// <item>MaxArrayLength <see cref="TestCaseContext.MaxArrayLength"/></item> /// <item>MaxDepth <see cref="TestCaseContext.MaxDepth"/></item> /// </list> /// </remarks> private void ExecuteTest_ExtensionObjectValues(ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { bool isSetupStep = TestUtils.IsSetupIteration(iteration); if (!isSetupStep) { channelContext.EventLogger.LogStartEvent(testCase, iteration); } else { channelContext.ClientSession.OperationTimeout = 30000; } RequestHeader requestHeader = new RequestHeader(); requestHeader.Timestamp = DateTime.UtcNow; requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; Variant input; Variant output; Variant expectedOutput; if (isSetupStep) { input = new ExtensionObject(); ResponseHeader responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); } else { channelContext.Random.Start( (int)(testCase.Seed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); input = channelContext.Random.GetExtensionObject(); ResponseHeader responseHeader = channelContext.ClientSession.TestStack( requestHeader, testCase.TestId, iteration, input, out output); channelContext.Random.Start( (int)(testCase.ResponseSeed + iteration), (int)m_sequenceToExecute.RandomDataStepSize, testCaseContext); expectedOutput = channelContext.Random.GetExtensionObject(); if (!Compare.CompareVariant(output, expectedOutput)) { throw new ServiceResultException( StatusCodes.BadInvalidState, Utils.Format("'{0}' is not equal to '{1}'.", output, expectedOutput)); } } if (!isSetupStep) { channelContext.EventLogger.LogCompleteEvent(testCase, iteration); } }
/// <summary /> /// <param name="channelContext">This parameter stores the channel related data.</param> /// <param name="testCaseContext">This parameter stores the test case parameter values.</param> /// <param name="testCase">This parameter stores the test case related data.</param> /// <param name="iteration">This parameter stores the current iteration number.</param> public AsyncTestState( ChannelContext channelContext, TestCaseContext testCaseContext, TestCase testCase, int iteration) { ChannelContext = channelContext; TestCaseContext = testCaseContext; Testcase = testCase; Iteration = iteration; }