private void RunAllByVersion(IEnumerable <SolutionInfoViewModel> testSolutionInfos, StartupConfigurationMode startupConfigurationMode, AnalysisStatus properInitialStatus) { var actualModels = testSolutionInfos.ToList(); var needToRun = Utils.NeedToRun(actualModels, startupConfigurationMode, properInitialStatus); if (!needToRun) { return; } // Сконфигурируем имя директории var currentTestingDir = CreateTestFiles(startupConfigurationMode); var factory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(_concurrentTestRunNumber)); try { Task.WaitAll( actualModels.OrderBy(model => model.TestSolutionInfo.ReadOrder) .Select( solution => factory.StartNew( () => Execute(startupConfigurationMode, properInitialStatus, solution, currentTestingDir))) .ToArray()); } catch (AggregateException aggrEx) { aggrEx.Handle(innerEx => { AppEventLogger.Log( string.Format("{0}: {1}", innerEx.Message, innerEx.StackTrace), EventLogEntryType.Error); return(true); }); } }
private bool IsSelfExit() { var isSelfExit = false; try { var startTime = _upgradeSlnProcess.StartTime; isSelfExit = _upgradeSlnProcess.WaitForExit(HangTimeMilliseconds); var workingTime = (_upgradeSlnProcess.ExitTime - startTime).Duration(); var staleDuration = TimeSpan.FromMilliseconds(HangTimeMilliseconds).Duration(); if (workingTime >= staleDuration) { try { AnalyzerUtilities.GetScreenSnapshot(_snapshot); } catch (Win32Exception win32Ex) { AppEventLogger.Log( string.Format("Message {0}. Error code: {1}", win32Ex.Message, win32Ex.NativeErrorCode), EventLogEntryType.Warning); } } } catch (InvalidOperationException invOpEx) { AppEventLogger.Log(invOpEx.Message, EventLogEntryType.Warning); } return(isSelfExit); }
/// <summary> /// Обновление решения /// </summary> /// <param name="isHangout"> /// true, если время на обновление вышло, а процесс все еще не завершен, false - если процесс /// завершился /// </param> /// <param name="devenvExitCode"></param> /// <returns>true, если обновление прошло успешно, false - в противном случае</returns> public bool Upgrade(out bool isHangout, out int devenvExitCode) { var restoreResult = AnalyzerUtilities.IndividualRestore(_solutionFileName, _selfTesterRootPath, _srcEtalonFolder); if (!restoreResult.Item1) { isHangout = false; devenvExitCode = default(int); AppEventLogger.Log(restoreResult.Item2, EventLogEntryType.Error); return(false); } try { ConfigureUpgradeProcess(); _upgradeSlnProcess.Start(); var isSelfExit = IsSelfExit(); if (!isSelfExit) // Если сам не завершился, значит завис { ProcessUtils.MandatoryKill(_upgradeSlnProcess); isHangout = true; if (_upgradeSlnProcess.HasExited) { devenvExitCode = _upgradeSlnProcess.ExitCode; return(false); } } isHangout = false; devenvExitCode = _upgradeSlnProcess.HasExited ? _upgradeSlnProcess.ExitCode : default(int); return(devenvExitCode == 0); } catch (Exception ex) { AppEventLogger.Log( string.Format("Error message: {0}{1}{2}", ex.Message, Environment.NewLine, ToString()), EventLogEntryType.Error); isHangout = false; devenvExitCode = default(int); return(false); } }
/// <summary> /// Установка логики анализа в "фоне" /// </summary> private void TuneBackgroundWorker() { if (_testWorker != null) { _testWorker.Dispose(); _testWorker = null; } _testWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _testWorker.DoWork += (workerSender, workEventArgs) => { Interlocked.Exchange(ref _isRunningNow, 1); using (var controller = new AnalyzerController(_currentSelectedSolutions)) { controller.AnalysisManagers.CollectionChanged += (ctrlSender, changedEventArgs) => // "Подписываемся" на добавление менеджера анализа { if (changedEventArgs.Action != NotifyCollectionChangedAction.Add) { return; } var newManager = changedEventArgs.NewItems.Cast <AnalysisManager>().FirstOrDefault(); if (newManager == null) { throw new InvalidOperationException("newManager can't be null"); } newManager.AnalysisStatusChanged += (manSender, analysisEventArgs) => // "Подписываемся" на смену статуса анализа для очередного добавленного менеджера { SetNewStatusValue( analysisEventArgs.StartupMode, analysisEventArgs.SolutionInfo, analysisEventArgs.NewStatus); if (_testWorker.IsBusy && _testWorker.CancellationPending) { workEventArgs.Cancel = true; } }; }; controller.CurrentAnalysisDone += (ctrl, currentAnalysisDoneEventArgs) => // "Подписываемся" на завершение анализа для текущего менеджера { var currentFinishedCount = currentAnalysisDoneEventArgs.CurrentFinishedCount; var progress = (int)(currentFinishedCount / (double)_currentTotalCount * 100); _testWorker.ReportProgress(progress); }; controller.RunAll(AnalysisStatus.InPending); } }; _testWorker.RunWorkerCompleted += (sender, completedEventArgs) => { var ex = completedEventArgs.Error; if (ex != null) { AppEventLogger.Log(ex.ToString(), EventLogEntryType.Warning); } if (!completedEventArgs.Cancelled) { SetUiCompletedState(); UiUtils.ResetActiveStatuses(_currentSelectedSolutions); } else { UiUtils.ResetActiveStatuses(_currentSelectedSolutions, true); } ProcessUtils.MandatoryKill(Process.GetCurrentProcess(), false); if (!StartStopButton.IsEnabled) { StartStopButton.IsEnabled = true; } UiUtils.TurnButtonState(ButtonState.Running, StartStopButton, StartStopImage); if (!completedEventArgs.Cancelled && ShutdownCheckBox.IsChecked == true) { AnalyzerUtilities.ShutdownPc(); } }; _testWorker.ProgressChanged += (sender, changedEventArgs) => { TestingProgressBar.Value = changedEventArgs.ProgressPercentage; }; }
/// <summary> /// Анализ решения /// </summary> /// <param name="isHangout"> /// true, если время, отведенное для анализа вышло, а процесс все еще не завершен, false - если /// процесс завершился /// </param> /// <param name="devenvExitCode"></param> /// <returns>true, если процесс анализа прошел успешно, false - в противном случае</returns> public bool ProcessAnalysis(out bool isHangout, out int devenvExitCode) { const string errorDetectedSuffix = ".plog.exception_messages.txt"; try { ConfigureAnalisysProcess(); var start = DateTime.Now; _analyzerProcess.Start(); var runningQuota = TimeSpan.FromMinutes(ApplicationConfigReader.Instance.HangTime).Duration(); var plogPath = Path.GetDirectoryName(_plog); Debug.Assert(plogPath != null, "plogPath != null"); var destinationPlog = Path.GetFileName(_plog); var plogCreatedEvent = new ManualResetEventSlim(); var plogWatcher = new FileSystemWatcher(plogPath, "*.plog") { EnableRaisingEvents = true, IncludeSubdirectories = false, NotifyFilter = NotifyFilters.FileName }; plogWatcher.Created += (sender, args) => { var createdName = args.Name; if (string.Equals(createdName, destinationPlog)) { plogCreatedEvent.Set(); } }; var destinationErrorPlog = string.Format("{0}{1}", Path.GetFileNameWithoutExtension(_plog), errorDetectedSuffix); var errorCreatedEvent = new ManualResetEventSlim(); var errorWatcher = new FileSystemWatcher(plogPath, string.Format("*{0}", errorDetectedSuffix)) { EnableRaisingEvents = true, IncludeSubdirectories = false, NotifyFilter = NotifyFilters.FileName }; errorWatcher.Created += (sender, args) => { var createdName = args.Name; if (string.Equals(destinationErrorPlog, createdName)) { errorCreatedEvent.Set(); } }; var waitingIndex = WaitHandle.WaitAny( new[] { plogCreatedEvent.WaitHandle, errorCreatedEvent.WaitHandle }, TimeSpan.FromMinutes(ApplicationConfigReader.Instance.HangTime)); var plogAppeared = waitingIndex == 0; if (plogAppeared) { plogAppeared = AnalyzerUtilities.WaitForFileReleased(_plog, start, runningQuota); AppEventLogger.Log( string.Format("File {0} is {1}", _plog, (plogAppeared ? "Released" : "Time out")), plogAppeared ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit); } isHangout = !plogAppeared; ProcessUtils.MandatoryKill(_analyzerProcess); devenvExitCode = default(int); return(!isHangout); } catch (Exception ex) { AppEventLogger.Log( string.Format("Error message: {0}. Stack trace: {1}{2}{3}", ex.Message, ex.StackTrace, Environment.NewLine, ToString()), EventLogEntryType.Error); devenvExitCode = default(int); return(isHangout = !File.Exists(_plog)); } }
/// <summary> /// Шаблонный метод завершения анализа /// </summary> /// <returns>Статус завершения</returns> private AnalysisStatus CompareLogs() { var slnFileName = SolutionInfo.TestSolutionInfo.AbsSolutionFileName; var etalonLog = Utils.GetEtalonLog(slnFileName); var totalElapsed = _endTime.Subtract(_startTime).Duration(); AppEventLogger.Log(totalElapsed, StartupMode, SolutionInfo.TestSolutionInfo); var headerLine = GetHeaderLine(slnFileName, etalonLog, totalElapsed); if (!File.Exists(_logFileName)) { Reason = CrashReason.NoResults; var crashMessage = Reason.GetCrashMessage(); FlushHtml(string.Format("{0}{1}<br/><font color='red'><b>{2}</b></font><br/>", headerLine, crashMessage, Reason.ToString().ToUpper())); return(AnalysisStatus.PluginCrashed); } if (!File.Exists(etalonLog)) { Reason = CrashReason.NoEtalon; var crashMessage = CrashReason.None.GetCrashMessage(); FlushHtml( string.Format("{0}{1}<br/><font color='red'><b>{2}</b></font><br/>", headerLine, crashMessage, Reason.ToString().ToUpper())); return(AnalysisStatus.NoSuchEtalon); } var pluginDiff = new PluginDiff(); var fullSet = pluginDiff.GetDiff(etalonLog, _logFileName); var resultStatus = pluginDiff.Output.Succeeded ? AnalysisStatus.OkFinished : AnalysisStatus.DiffFinished; var logCmpBuilder = new StringBuilder(headerLine, 0x400); logCmpBuilder.Append("<i>Logs comparison result:</i> "); if (pluginDiff.Output.Succeeded) { logCmpBuilder.AppendLine("<font color='green'><B>OK</B></font><br/>"); } else { logCmpBuilder .AppendLine("<font color='red'><b>HASDIFF</b></font><br/>") .AppendLine("<i>Comparison function output:</i><br/><br/>") .AppendLine("<font color='red'>"); foreach (DataRow dataRow in pluginDiff.Output.Missings.Rows) { logCmpBuilder.AppendFormat("{0}<br/>", Utils.GenerateOutputWindowMessage(dataRow)); } logCmpBuilder.AppendLine("</font>").AppendLine("<font color='green'>"); foreach (DataRow dataRow in pluginDiff.Output.Additionals.Rows) { logCmpBuilder.AppendFormat("{0}<br/>", Utils.GenerateOutputWindowMessage(dataRow)); } logCmpBuilder.AppendLine("</font>").AppendLine("<font color='blue'>"); foreach (DataRow dataRow in pluginDiff.Output.Modifies.Rows) { logCmpBuilder.AppendFormat("{0}</br>", Utils.GenerateOutputWindowMessage(dataRow)); } logCmpBuilder.AppendLine("</font>"); logCmpBuilder.AppendFormat("<br/><i>The results are saved to:</i></br>{0}_Diffs.plog<br/>", _logFileName); fullSet.WriteXml(string.Format("{0}_Diffs.plog", _logFileName), XmlWriteMode.WriteSchema); fullSet.Tables.Clear(); } var content = logCmpBuilder.ToString(); FlushHtml(content); Reason = CrashReason.None; return(resultStatus); }