예제 #1
0
        public bool TryDeleteFiles(IEnumerable <string> files, bool deleteFiles)
        {
            var filesListed   = files.ToList();
            var filteredFiled = filesListed.Where(f => !_fileProvider.IsFileLocked(f)).ToList();

            if (filteredFiled.Count != filesListed.Count)
            {
                _log.Info($"Some files where locked. Amount: {filesListed.Count - filteredFiled.Count}");
            }

            foreach (var file in filteredFiled)
            {
                try
                {
                    _fileProvider.DeleteFile(file, deleteFiles);
                }
                catch (Exception e)
                {
                    _log.Error(e);
                    retryCount++;
                    _log.Error($"Exception occured while deleting filePath: {file}. Retry {retryCount} out of {retryMaxCount}");
                    if (retryCount <= retryMaxCount)
                    {
                        _threadProvider.Sleep(waitBeforeRetryMs);
                        return(TryDeleteFiles(filteredFiled, deleteFiles));
                    }
                }
            }

            var filesDeleted = filteredFiled.All(f => !_fileProvider.Exists(f));

            _log.Info(filesDeleted ? $"Files were successfully deleted" : $"Some files were not deleted");

            return(filesDeleted);
        }
예제 #2
0
        public string DecideArchiveName(Archive archive, DateTime time)
        {
            var machinename  = _environmentProvider.MachineName;
            var archiveName  = $"{machinename}_{archive.ArchiveName}_{time:yyMMdd}.7z";
            var originalPath = Path.Combine(archive.ArchivePath, archiveName);

            if (!_fileProvider.Exists(originalPath))
            {
                Log.Info($"ArchivePath selected. path: {originalPath}");
                return(originalPath);
            }
            Log.Warn($"Archive already exists for path: {originalPath}");

            //already exists, getting new name
            var iteration       = 0;
            var alternativePath = string.Empty;

            do
            {
                var alternatveArchiveName = $"{machinename}_{archive.ArchiveName}_{time:yyMMdd}_{++iteration}.7z";
                alternativePath = Path.Combine(archive.ArchivePath, alternatveArchiveName);

                if (iteration > 1000)
                {
                    throw new Exception("Failed to establish archive name.");
                }
            } while (_fileProvider.Exists(alternativePath));
            Log.Info($"AlternativePath selected. path: {alternativePath}");
            return(alternativePath);
        }
예제 #3
0
        public static async Task <BITSUploadSession> Create(IFileProvider fileProvider, string fileName, long fragmentSizeLimit)
        {
            BITSUploadSession session = new BITSUploadSession(fileProvider, fileName, fragmentSizeLimit);

            if (await fileProvider.Exists(fileName))          // case the file already exists
            {
                if (await fileProvider.IsDirectory(fileName)) // case the file is actually a directory
                {
                    session._status_code = HttpStatusCode.Forbidden;
                }
                else if (SimpleBITSRequestHandler.Sessions.Any(_ => _.Value.FileName == fileName)) // case the file is being uploaded in another active session
                {
                    session._status_code = HttpStatusCode.Conflict;
                }
                else // case file exists on server - we overwrite the file with the new upload
                {
                    await session.OpenFile();
                }
            }
            else // case file does not exist but its parent folder does exist - we create the file
            {
                await session.OpenFile();
            }

            /*else // case file does not exist nor its parent folder - we don't create the directory tree
             *  session._status_code = HttpStatusCode.Forbidden;*/

            return(session);
        }
        private void InitializeRoutes()
        {
            var          routesContent  = new EmbeddedFileProvider().GetContentsForFile("Commands.InitContent.routes.json");
            const string fileName       = "routes.json";
            var          routesFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);

            if (_fileProvider.Exists(routesFilePath))
            {
                _logger.Info($"{fileName} file already exists.");
            }
            else
            {
                File.WriteAllText(routesFilePath, routesContent);
                _logger.Info($"{fileName} file created.");
            }
        }
예제 #5
0
        public ICollection <TItem> Get <TItem>() where TItem : class
        {
            var path = GetFilePath(typeof(TItem));

            if (!_fileProvider.Exists(path))
            {
                return(Enumerable.Empty <TItem>().ToList());
            }

            var instantiator = GetInstantiationFunc(typeof(TItem));

            return(_fileProvider.GetFile(path)
                   .GetLines().Skip(1)
                   .Select(l => instantiator(Split(l)) as TItem)
                   .ToList());
        }
예제 #6
0
        /// <summary>
        /// Returns true if the file exists.
        /// </summary>
        /// <returns>True if the file exists</returns>
        internal bool Exist()
        {
            var fileName      = Path.GetFileName(_filePath);
            var directoryEnum = _filePath.StartsWith(_fileProvider.UploadedFilesDirectory.TrimEnd('/', '\\')) ? DirectoryEnum.Uploaded : DirectoryEnum.Published;

            return(_fileProvider.Exists(fileName, directoryEnum).GetAwaiter().GetResult());
        }
예제 #7
0
        public void Save(string filePath, IFileProvider fileProvider)
        {
            if (this.Config == null || !this.Config.HasData)
            {
                // empty config, removing file
                if (fileProvider.Exists(filePath))
                {
                    fileProvider.Delete(filePath);
                }
            }
            else
            {
                XmlSerializer serialiser = new XmlSerializer(typeof(RepoFolderXmlConfig));

                using (XmlTextWriter stream = new XmlTextWriter(
                           fileProvider.Open(filePath, FileMode.Create, FileAccess.Write)
                           , Encoding.UTF8))
                {
                    stream.Indentation = 1;
                    stream.IndentChar  = '\t';
                    stream.Formatting  = Formatting.Indented;
                    serialiser.Serialize(stream, this);
                }
            }
        }
예제 #8
0
        public bool Exist()
        {
            var fileName      = System.IO.Path.GetFileName(Path);
            var directoryEnum = Path.StartsWith(_fileProvider.UploadedFilesDirectory) ? DirectoryEnum.Uploaded : DirectoryEnum.Published;

            return(_fileProvider.Exists(fileName, directoryEnum).GetAwaiter().GetResult());
        }
예제 #9
0
 public static bool Exists(string path)
 {
     if (_provider == null)
     {
         return(File.Exists(path));
     }
     return(_provider.Exists(path));
 }
예제 #10
0
        private string GetConnectionString()
        {
            var fullFilePath = _configuration["ConnectionStrings:FullFilePath"];

            if (!_fileProvider.Exists(fullFilePath))
            {
                throw new FilePathNotFoundException($"file not found {fullFilePath}");
            }
            return(fullFilePath);
        }
예제 #11
0
        public Task Add(string path)
        {
            if (!_fileProvider.Exists(path))
            {
                throw new FileNotFoundException(path);
            }

            var repositoryTask = _eventStore.CreateRepository(path);

            _watcher.Monitor(path);
            return(repositoryTask);
        }
예제 #12
0
        public string GetContentsFor(string templateKey, IDictionary <string, object> parameters)
        {
            var templatePath = Path.Combine(_filePath, templateKey);

            if (_fileProvider.Exists(templatePath))
            {
                return(_fileProvider.ReadAllText(templatePath));
            }

            _logger.Error(TemplateDoesNotExistFormat, templatePath);
            return(string.Empty);
        }
예제 #13
0
        public async Task <HttpResponseMessage> Head(string fileName, string folder = "Published")
        {
            try
            {
                DirectoryEnum directory = folder == "Uploaded" ? DirectoryEnum.Uploaded : DirectoryEnum.Published;
                if (!await _fileProvider.Exists(fileName, directory))
                {
                    return(new HttpResponseMessage(HttpStatusCode.NotFound));
                }
                long fileLength = await _fileProvider.GetLengthAsync(fileName, directory);

                ContentInfo contentInfo = GetContentInfoFromRequest(Request, fileLength);
                if (contentInfo == null)
                {
                    return(new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable));
                }

                var response = new HttpResponseMessage
                {
                    Content = new ByteArrayContent(new byte[0])
                };
                SetResponseHeaders(response, contentInfo, fileLength, fileName);
                return(response);
            }
            catch (Exception e)
            {
                var errorResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent(e.ToString())
                };
                return(errorResponse);
            }
        }
예제 #14
0
        private string GenerateDataUri(Match match, string path)
        {
            var uri = match.Groups[2].Value;

            if (!_fileProvider.Exists(path))
            {
                return(uri);
            }

            var imageBytes = _fileProvider.ReadAllBytes(path);
            var dataUrl    = string.Format("data:image/png;base64,{0}", Convert.ToBase64String(imageBytes));

            return(match.ToString().Replace(uri, dataUrl));
        }
예제 #15
0
        public async Task CreateRepository(string path)
        {
            var eventsPath = $"{path}.events";

            _repositories[path] = eventsPath;

            if (!_fileProvider.Exists(eventsPath))
            {
                await _repository.Create(eventsPath);
            }

            if (await _repository.IsEmpty(eventsPath))
            {
                await Initialise(path);
            }
        }
예제 #16
0
        public async Task LoadTestCaseHistoryCollectionAsync()
        {
            try
            {
                var testCaseHistoryDtoCollection = new List <TestCaseHistoryDto>();

                var testCasesHistoryFilePath   = GetTestCasesHistoryFileNamePath();
                var testCaseHistoryFileContent = string.Empty;
                if (_fileProvider.Exists(testCasesHistoryFilePath))
                {
                    testCaseHistoryFileContent = await _fileProvider.ReadAllTextAsync(testCasesHistoryFilePath).ConfigureAwait(false);
                }

                if (!string.IsNullOrEmpty(testCaseHistoryFileContent))
                {
                    testCaseHistoryDtoCollection = _jsonSerializer.Deserialize <List <TestCaseHistoryDto> >(testCaseHistoryFileContent);
                }

                if (testCaseHistoryDtoCollection.Any())
                {
                    foreach (var testCaseHistoryDto in testCaseHistoryDtoCollection)
                    {
                        var testCaseHistory        = Mapper.Map <TestCaseHistory>(testCaseHistoryDto);
                        var createdTestCaseHistory = await _meissaRepository.InsertWithSaveAsync(testCaseHistory).ConfigureAwait(false);

                        if (testCaseHistoryDto.Durations.Any())
                        {
                            foreach (var currentDuration in testCaseHistoryDto.Durations)
                            {
                                var testCaseHistoryEntry = new TestCaseHistoryEntry
                                {
                                    TestCaseHistoryId = createdTestCaseHistory.TestCaseHistoryId,
                                    AvgDuration       = currentDuration,
                                };

                                await _meissaRepository.InsertWithSaveAsync(testCaseHistoryEntry).ConfigureAwait(false);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
        }
        public List <Route> GetRoutes()
        {
            if (_cachedRoutes == null)
            {
                if (_fileProvider.Exists(_routeConfigPath))
                {
                    var json = _fileProvider.ReadAllText(_routeConfigPath);
                    _cachedRoutes = JsonConvert.DeserializeObject <List <Route> >(json);
                }
                else
                {
                    _logger.Warn(RoutesFileDoesNotExistMessage);
                }
            }

            _cachedRoutes = _cachedRoutes ?? new List <Route>();
            return(_cachedRoutes);
        }
예제 #18
0
        /// <summary>
        ///		Load folder configuration from config file
        /// </summary>
        /// <param name="filePath">
        ///		Configuration file full path
        /// </param>
        /// <returns>
        ///		null if file does not exist
        /// </returns>
        public static RepoFolderXmlConfig Load(string filePath, IFileProvider fileProvider)
        {
            RepoFolderXmlConfig retval;

            if (fileProvider.Exists(filePath))
            {
                XmlSerializer serialiser = new XmlSerializer(typeof(RepoFolderXmlConfig));
                using (FileStream stream = fileProvider.Open(filePath, FileMode.Open, FileAccess.Read))
                {
                    retval = (RepoFolderXmlConfig)serialiser.Deserialize(stream);
                }
            }
            else
            {
                // empty config
                retval = new RepoFolderXmlConfig();
            }
            return(retval);
        }
예제 #19
0
        public async Task LoadTestCaseHistoryCollectionAsync()
        {
            var testCaseHistoryCollection = new List <TestCaseHistoryDto>();

            var testCasesHistoryFilePath   = GetTestCasesHistoryFileNamePath();
            var testCaseHistoryFileContent = string.Empty;

            if (_fileProvider.Exists(testCasesHistoryFilePath))
            {
                testCaseHistoryFileContent = await _fileProvider.ReadAllTextAsync(testCasesHistoryFilePath).ConfigureAwait(false);
            }

            if (!string.IsNullOrEmpty(testCaseHistoryFileContent))
            {
                testCaseHistoryCollection = _jsonSerializer.Deserialize <List <TestCaseHistoryDto> >(testCaseHistoryFileContent);
            }

            if (testCaseHistoryCollection.Any())
            {
                foreach (var testCaseHistory in testCaseHistoryCollection)
                {
                    var createdTestCaseHistory = await _testCaseHistoryRepository.CreateAsync(testCaseHistory).ConfigureAwait(false);

                    if (testCaseHistory.Durations.Any())
                    {
                        foreach (var currentDuration in testCaseHistory.Durations)
                        {
                            var testCaseHistoryEntry = new TestCaseHistoryEntryDto
                            {
                                TestCaseHistoryId = createdTestCaseHistory.TestCaseHistoryId,
                                AvgDuration       = currentDuration,
                            };

                            await _testCaseHistoryEntryRepository.CreateAsync(testCaseHistoryEntry).ConfigureAwait(false);
                        }
                    }
                }
            }
        }
예제 #20
0
        private void Mount()
        {
            if (!_fileProvider.Exists(IsoFilePath))
            {
                throw new Exception($"File '{IsoFilePath}' doesn't exists or don't have access.");
            }

            _processProvider.Start(VcdMountPath, $"/l={UnitLetter} \"{IsoFilePath}\"");

            var i = 0;

            while (!_driveInfo.IsReady && i < TriesBeforeError)
            {
                Thread.Sleep(WaitTime);
                i++;
            }

            if (i >= TriesBeforeError)
            {
                throw new Exception(string.Format(Resources.Messages.ErrorMountingFile, UnitLetter));
            }
        }
예제 #21
0
        private async Task <string> ExecuteTestsWithNativeRunnerAsync(
            string workingDir,
            string testsLibraryPath,
            string assemblyName,
            bool runInParallel,
            int maxParallelProcessesCount,
            string nativeArguments,
            int testAgentRunTimeout,
            bool isTimeBasedBalance,
            bool sameMachineByClass,
            List <TestCase> distributedTestCases,
            CancellationTokenSource outerCancellationTokenSource)
        {
            var outputFilesDir = _pathProvider.GetDirectoryName(testsLibraryPath);
            var availableCores = runInParallel ? maxParallelProcessesCount : 1;

            // Merge logic of CreateRunFilterArgument here. remove inner foreach
            var listOfDistributedTestCases = _nativeTestsRunner.SplitTestCases(availableCores, sameMachineByClass, distributedTestCases);
            var testRunsToBeMerged         = new List <object>();
            var testRunProcesses           = new List <Process>();
            var resultsFiles = new List <string>();

            var processCreationTime = _dateTimeProvider.GetCurrentTime();

            foreach (var distributedTestCasesList in listOfDistributedTestCases)
            {
                var currentTestResultsFilePath = _pathProvider.GetTempFileName();
                resultsFiles.Add(currentTestResultsFilePath);
                var arguments = _nativeTestsRunner.BuildNativeRunnerArguments(
                    assemblyName,
                    testsLibraryPath,
                    distributedTestCasesList,
                    currentTestResultsFilePath,
                    outputFilesDir,
                    nativeArguments);

                var currentProcess = _processStarter.InitializeProcess(
                    _nativeTestsRunner.RunnerFile,
                    workingDir,
                    arguments,
                    LogStandardOutput,
                    LogErrorOutput);
                testRunProcesses.Add(currentProcess);
            }

            var innerCancellationTokenSource = new CancellationTokenSource();

            var waitForNativeRunnerProcessesToFinishTask = _taskProvider.StartNewLongRunning(
                (c) =>
            {
                var ranProcesses = new List <int>();
                do
                {
                    var coresCount = availableCores;
                    if (runInParallel)
                    {
                        foreach (var process in testRunProcesses)
                        {
                            if (coresCount == 0)
                            {
                                break;
                            }

                            if (!ranProcesses.Contains(process.GetHashCode()))
                            {
                                _processStarter.StartProcess(process, LogStandardOutput, LogErrorOutput);
                                Thread.Sleep(500);
                                ranProcesses.Add(process.GetHashCode());
                                coresCount--;
                            }
                        }
                    }

                    foreach (var process in testRunProcesses)
                    {
                        if (outerCancellationTokenSource.Token.IsCancellationRequested)
                        {
                            return;
                        }

                        if (!runInParallel)
                        {
                            // Start processes one by one, otherwise they are started all upfront.
                            _processStarter.StartProcess(process, LogStandardOutput, LogErrorOutput);
                            ranProcesses.Add(process.GetHashCode());
                        }

                        if (ranProcesses.Contains(process.GetHashCode()))
                        {
                            _processStarter.WaitForProcessToFinish(testAgentRunTimeout, process);
                        }
                    }
                }while (ranProcesses.Count != testRunProcesses.Count);
            },
                innerCancellationTokenSource);

            var checkCancellationRequestsTask = _taskProvider.StartNewLongRunningRepeating(
                innerCancellationTokenSource,
                () =>
            {
                if (waitForNativeRunnerProcessesToFinishTask.IsCompleted || waitForNativeRunnerProcessesToFinishTask.IsFaulted)
                {
                    if (waitForNativeRunnerProcessesToFinishTask.IsFaulted)
                    {
                        _testRunLogService.CreateTestRunLogAsync($"waitForNativeRunnerProcessesToFinishTask FAULTED- {waitForNativeRunnerProcessesToFinishTask.Exception}", _currentTestRunId).Wait();
                    }

                    innerCancellationTokenSource.Cancel();
                }
                else if (outerCancellationTokenSource.Token.IsCancellationRequested)
                {
                    foreach (var processName in _nativeTestsRunner.RunnerProcessesNamesToKill)
                    {
                        var processes = Process.GetProcessesByName(processName);
                        foreach (var process in processes)
                        {
                            try
                            {
                                if (process.StartTime > processCreationTime)
                                {
                                    process.Kill();
                                    process.WaitForExit();
                                }
                            }
                            catch (Exception e)
                            {
                                _consoleProvider.WriteLine(e.ToString());
                            }
                        }
                    }
                }
            },
                500);

            checkCancellationRequestsTask.Wait();

            string result = null;

            if (!outerCancellationTokenSource.Token.IsCancellationRequested)
            {
                foreach (var testResultFile in resultsFiles)
                {
                    if (_fileProvider.Exists(testResultFile))
                    {
                        var testTestResults = _fileProvider.ReadAllText(testResultFile);
                        var currentTestRun  = _nativeTestsRunner.DeserializeTestResults(testTestResults);
                        testRunsToBeMerged.Add(currentTestRun);
                    }
                    else if (_directoryProvider.Exists(testResultFile))
                    {
                        // TODO: Added this because of the Protractor Plugin, since it produces folder instead of file.
                        // Fix it later with something more generic solution. Maybe, we have to save the test results to plugin folder and
                        // add a plugin method for deleting them at the end.
                        var files = _directoryProvider.GetFiles(testResultFile);
                        if (!files.Any())
                        {
                            throw new Exception("No test results' file was produced for test run");
                        }

                        var firstFile       = _directoryProvider.GetFiles(testResultFile).First();
                        var testTestResults = _fileProvider.ReadAllText(firstFile);
                        var currentTestRun  = _nativeTestsRunner.DeserializeTestResults(testTestResults);
                        testRunsToBeMerged.Add(currentTestRun);
                    }
                    else
                    {
                        throw new Exception("No test results' file was produced for test run");
                    }
                }

                var mergedTestRun = _nativeTestsRunner.MergeTestResults(testRunsToBeMerged);
                if (isTimeBasedBalance)
                {
                    var testCaseRuns = _nativeTestsRunner.UpdateTestCasesHistory(mergedTestRun, assemblyName);
                    await _testCasesHistoryService.UpdateTestCaseExecutionHistoryAsync(testCaseRuns).ConfigureAwait(false);
                }

                try
                {
                    _nativeTestsRunner.ExecutePostRunActions();
                }
                catch (Exception ex)
                {
                    _testRunLogService.CreateTestRunLogAsync($"There was a problem executing ExecutePostRunActions on {Environment.MachineName}. Exception: {ex}", _currentTestRunId).Wait();
                }

                result = mergedTestRun;
            }

            return(result);
        }
예제 #22
0
        private async Task <string> ExecuteTestsWithNativeRunnerAsync(
            string workingDir,
            string testsLibraryPath,
            string assemblyName,
            bool runInParallel,
            int maxParallelProcessesCount,
            string nativeArguments,
            int testAgentRunTimeout,
            bool isTimeBasedBalance,
            List <TestCase> distributedTestCases,
            CancellationTokenSource outerCancellationTokenSource)
        {
            string outputFilesDir = _pathProvider.GetDirectoryName(testsLibraryPath);
            ////var updatedMaxParallelProcessesCount = maxParallelProcessesCount > 1 ? maxParallelProcessesCount - 1 : maxParallelProcessesCount;
            int availableCores = runInParallel ? maxParallelProcessesCount : 1;

            // Merge logic of CreateRunFilterArgument here. remove inner foreach
            var listOfDistributedTestCases = _nativeTestsRunner.SplitTestCases(distributedTestCases, availableCores);
            var testRunsToBeMerged         = new List <object>();

            var testRunProcesses = new List <Process>();
            var resultsFiles     = new List <string>();

            DateTime processCreationTime = _dateTimeProvider.GetCurrentTime();

            // DEBUG:
            ////await _testRunLogService.CreateTestRunLogAsync($"Number of tests to be executed- {distributedTestCases.Count}", _currentTestRunId);

            // DEBUG:
            ////await _testRunLogService.CreateTestRunLogAsync($"Number of listOfDistributedTestCases- {listOfDistributedTestCases.Count()}", _currentTestRunId);
            int index = 1;

            foreach (var distributedTestCasesList in listOfDistributedTestCases)
            {
                // DEBUG:
                ////await _testRunLogService.CreateTestRunLogAsync($"{index++} distributedTestCasesList items- {distributedTestCasesList.Count()}", _currentTestRunId);
                var currentTestResultsFilePath = _pathProvider.GetTempFileName();
                resultsFiles.Add(currentTestResultsFilePath);
                var arguments = _nativeTestsRunner.BuildNativeRunnerArguments(
                    assemblyName,
                    testsLibraryPath,
                    distributedTestCasesList,
                    currentTestResultsFilePath,
                    outputFilesDir,
                    nativeArguments);

                var currentProcess = _processStarter.InitializeProcess(
                    _nativeTestsRunner.RunnerFile,
                    workingDir,
                    arguments,
                    LogStandardOutput,
                    LogErrorOutput);
                testRunProcesses.Add(currentProcess);
            }

            var innerCancellationTokenSource = new CancellationTokenSource();

            // DEBUG:
            ////await _testRunLogService.CreateTestRunLogAsync($"The native runs will be executed in parallel- {runInParallel}. Available core on machine {Environment.MachineName}- {availableCores}", _currentTestRunId);
            ////await _testRunLogService.CreateTestRunLogAsync($"Number of native test runner process to be run- {testRunProcesses.Count}", _currentTestRunId);
            var waitForNativeRunnerProcessesToFinishTask = _taskProvider.StartNewLongRunning(
                (c) =>
            {
                var ranProcesses = new List <int>();
                do
                {
                    var coresCount = availableCores;
                    if (runInParallel)
                    {
                        foreach (var process in testRunProcesses)
                        {
                            if (coresCount == 0)
                            {
                                break;
                            }

                            if (!ranProcesses.Contains(process.GetHashCode()))
                            {
                                _processStarter.StartProcess(process, LogStandardOutput, LogErrorOutput);
                                Thread.Sleep(1000);
                                ranProcesses.Add(process.GetHashCode());
                                coresCount--;
                            }
                        }
                    }

                    // Do not start all processes upfront
                    // if parallel here start all of them?
                    // run in task and pass cancelation token. If is canceled kill all processes. DO IT for NUNIT TOO
                    foreach (var process in testRunProcesses)
                    {
                        if (outerCancellationTokenSource.Token.IsCancellationRequested)
                        {
                            return;
                        }

                        if (!runInParallel)
                        {
                            // Start processes one by one, otherwise they are started all upfront.
                            _processStarter.StartProcess(process, LogStandardOutput, LogErrorOutput);
                            ranProcesses.Add(process.GetHashCode());
                        }

                        if (ranProcesses.Contains(process.GetHashCode()))
                        {
                            _processStarter.WaitForProcessToFinish(testAgentRunTimeout, process);
                        }
                    }

                    // DEBUG:
                    ////_testRunLogService.CreateTestRunLogAsync($"ranProcesses.Count {ranProcesses.Count} testRunProcesses.Count {testRunProcesses.Count} {_dateTimeProvider.GetCurrentTime()}", _currentTestRunId).Wait();
                }while (ranProcesses.Count != testRunProcesses.Count);
            },
                innerCancellationTokenSource);

            var checkCancellationRequestsTask = _taskProvider.StartNewLongRunningRepeating(
                innerCancellationTokenSource,
                () =>
            {
                if (waitForNativeRunnerProcessesToFinishTask.IsCompleted || waitForNativeRunnerProcessesToFinishTask.IsFaulted)
                {
                    if (waitForNativeRunnerProcessesToFinishTask.IsFaulted)
                    {
                        _testRunLogService.CreateTestRunLogAsync($"waitForNativeRunnerProcessesToFinishTask FAULTED- {waitForNativeRunnerProcessesToFinishTask.Exception}", _currentTestRunId).Wait();
                    }

                    innerCancellationTokenSource.Cancel();
                    return;
                }
                else if (outerCancellationTokenSource.Token.IsCancellationRequested)
                {
                    foreach (var processName in _nativeTestsRunner.RunnerProcessesNamesToKill)
                    {
                        var processes = Process.GetProcessesByName(processName);
                        foreach (var process in processes)
                        {
                            try
                            {
                                if (process.StartTime > processCreationTime)
                                {
                                    process.Kill();
                                    process.WaitForExit();
                                }
                            }
                            catch (Exception e)
                            {
                                _consoleProvider.WriteLine(e.ToString());
                            }
                        }
                    }

                    return;
                }
            },
                5000);

            checkCancellationRequestsTask.Wait();

            string result = null;

            if (!outerCancellationTokenSource.Token.IsCancellationRequested)
            {
                // DEBUG:
                _testRunLogService.CreateTestRunLogAsync($"START MERGING RESULTS- on machine {Environment.MachineName}", _currentTestRunId).Wait();
                foreach (var testResultFile in resultsFiles)
                {
                    if (_fileProvider.Exists(testResultFile))
                    {
                        var testTestResults = _fileProvider.ReadAllText(testResultFile);
                        var currentTestRun  = _nativeTestsRunner.DeserializeTestResults(testTestResults);
                        testRunsToBeMerged.Add(currentTestRun);
                    }
                    else
                    {
                        throw new Exception("No test results' file was produced for test run");
                    }
                }

                var mergedTestRun = _nativeTestsRunner.MergeTestResults(testRunsToBeMerged);
                if (isTimeBasedBalance)
                {
                    // DEBUG:
                    var startTime = _dateTimeProvider.GetCurrentTime();
                    _testRunLogService.CreateTestRunLogAsync($"START updating test case history- on machine {Environment.MachineName}", _currentTestRunId).Wait();
                    var testCaseRuns = _nativeTestsRunner.UpdateTestCasesHistory(mergedTestRun, assemblyName);
                    await _testCasesHistoryService.UpdateTestCaseExecutionHistoryAsync(testCaseRuns);

                    // DEBUG:
                    var endTime = _dateTimeProvider.GetCurrentTime();
                    _testRunLogService.CreateTestRunLogAsync($"END updating test case history- on machine {Environment.MachineName} for {(endTime - startTime).Seconds} seconds", _currentTestRunId).Wait();
                }

                result = mergedTestRun;
            }

            return(result);
        }