private void RunTestsInternal(object state) { TestcaseExecutorTaskInfo taskInfo = (TestcaseExecutorTaskInfo)state; int threadId = Thread.CurrentThread.ManagedThreadId; // create a browser queue with this thread id CommandManager.CreateBrowserQueue(threadId); //notify the page that we just created a browser queue and send the thread id taskInfo.NotifyBrowserQueueCreated(threadId); BrowserCommand command = new BrowserCommand(BrowserCommand.FunctionNames.TestRunStarted); command.Description = "Test Run Started"; command.Handler.RequiresElementFound = false; command.Handler.SetArguments(_testcases.Count); CommandManager.ExecuteCommand(threadId, command, 10); OnTestRunStarted(new EventArgs()); foreach (Testcase testcase in taskInfo.Testcases) { testcase.TestcaseExecuting += new EventHandler <TestcaseExecutionEventArgs>(testcase_TestcaseExecuting); testcase.TestcaseExecuted += new EventHandler <TestcaseExecutionEventArgs>(testcase_TestcaseExecuted); // [05/05/2009] clear the traces that might have been left from a previous test. WebTestConsole.Clear(); try { testcase.Execute(); } catch (TimeoutException) { // Abort the test run if we receive a TimeoutException because // this likely means the browser has been closed and we don't // want the server to keep sending test commands and timing out // for each of them. return; } } command = new BrowserCommand(BrowserCommand.FunctionNames.TestRunFinished); command.Description = "Test Run Finished"; command.Handler.RequiresElementFound = false; BrowserInfo result = CommandManager.ExecuteCommand(threadId, command, 10); // Provide the results of the test run to anyone interested string log = result != null ? result.Data : null; taskInfo.RequestDetails.Add("TestLog", log); OnTestRunFinished(new TestRunFinishedEventArgs(taskInfo.Testcases, taskInfo.RequestDetails)); }
/// <summary> /// Post the result of the last executed command and wait for the next /// command or return no command if /// </summary> /// <param name="threadId">Server thread handling the tests for the browser</param> /// <param name="result">Result of the executing the last command</param> /// <returns>Next command to execute (or null if there are no more commands or we timed out while waiting)</returns> /// <remarks> /// This method works hand in hand with ExecuteCommand. They wait and /// signal each other. /// </remarks> public static BrowserCommand SetResultAndGetNextCommand(int threadId, BrowserInfo result) { SynchronizationEntry entry = null; lock (_syncRoot) { entry = GetEntry(threadId); } lock (entry.SyncRoot) { // Get the next command to execute BrowserCommand command = null; if (!entry.Started) { // If this is the first request, a command has already been queued entry.Started = true; command = entry.Command; } else { // Update the command that was waiting for its result entry.Result = result; Monitor.Pulse(entry.SyncRoot); // Wait for the next command (only if the last command didn't // signal the end of the test run) if (!entry.Finished && Monitor.Wait(entry.SyncRoot, NextCommandTimeout)) { command = entry.Command; } } entry.Command = null; return(command); } }
/// <summary> /// Execute a commmand on the client and wait for its result /// </summary> /// <param name="threadId">Server thread handling the tests for the browser</param> /// <param name="command">Command to execute</param> /// <param name="secondsTimeout">Maximum timeout </param> /// <returns>Result of executing the command on the client</returns> /// <remarks> /// This method works hand in hand with SetResultAndGetNextCommand. /// They wait and signal each other. /// </remarks> public static BrowserInfo ExecuteCommand(int threadId, BrowserCommand command, int secondsTimeout) { if (command == null) { throw new ArgumentNullException("command", "BrowserCommand cannot be null!"); } SynchronizationEntry entry = null; lock (_syncRoot) { entry = GetEntry(threadId); } lock (entry.SyncRoot) { // Set the command and notify anyone waiting for the next command // (also setting whether this command marks the end of a test run) entry.Command = command; if (string.CompareOrdinal(entry.Command.Handler.ClientFunctionName, BrowserCommand.FunctionNames.TestRunFinished) == 0) { entry.Finished = true; } Monitor.Pulse(entry.SyncRoot); // Wait for the command's result if (!Monitor.Wait(entry.SyncRoot, secondsTimeout * 1000)) { // Use null if the command timed out entry.Result = null; } BrowserInfo result = entry.Result; return(result); } }
public static BrowserCommand GetCommand(int threadId, BrowserInfo resultOfLastCommand) { return(CommandManager.SetResultAndGetNextCommand(threadId, resultOfLastCommand)); }