public void RunActionsParallel(int maxConcurrentRunners, IEnumerable<TestRunAction> buildSortedAllActions, CancellationToken token, TextWriterWrapper stdOut, ProgressStats runningTests, Stopwatch totalRuntime, ConcurrentBag<RunStats> testResults) { var sortedAllActions = buildSortedAllActions as TestRunAction[] ?? buildSortedAllActions.ToArray(); if (maxConcurrentRunners <= 0) { maxConcurrentRunners = 12; } //Waiting for complete for (var i = 0; i < sortedAllActions.Count(); i++) { token.ThrowIfCancellationRequested(); CreateThread(sortedAllActions[i], token, stdOut, runningTests, totalRuntime, testResults); //Stop queueing items once reach the limit... really should just always set this to the ThreadPool size... while (_threadCounter >= maxConcurrentRunners) Thread.Sleep(500); } while (_threadCounter > 0) Thread.Sleep(500); }
private async Task LoadDatas() { ProgressStats datas = await _demosService.GetProgressStatsAsync(); DatasWin = datas.Win; DatasDamage = datas.Damage; DatasHeadshot = datas.HeadshotRatio; DatasKill = datas.Kill; CommandManager.InvalidateRequerySuggested(); }
public string BuildProgressDisplay(int width, ProgressStats runningTests, ref int indicatorPos, bool displayFailureSymbols) { var totalCount = runningTests.Count; var displayWidth = Math.Min(width - 4, totalCount); var displayRatio = (double)displayWidth / totalCount; Func<ProgressState, string> getProgressDisplay = x => { var floatWidth = runningTests.GetProgressCount(x) * displayRatio; //Round up decimals to 1 floatWidth = (floatWidth > 0 && floatWidth < 1) ? 1 : floatWidth; return new string(ArrayValueToRunningStatus(x), (int)floatWidth); }; Func<ProgressState, int, string> getProgressDisplayLength = (x, i) => new string(ArrayValueToRunningStatus(x), i); var totalRunning = runningTests.GetProgressCount(ProgressState.Running); var totalFinished = displayFailureSymbols ? runningTests.GetProgressCount(ProgressState.Finished) : runningTests.GetCompletedCount(); var notStarted = runningTests.GetProgressCount(ProgressState.NotStarted); var finishedDisplayChars = (int)Math.Round(totalFinished * displayRatio); var startedDisplayChars = (int)Math.Ceiling(totalRunning * displayRatio); var progressBar = string.Format(displayFailureSymbols ? @"[{0}{1}{2}{3}{4}{5}]" : @"[{2}{3}{4}{5}]", getProgressDisplay(ProgressState.RunFailure), getProgressDisplay(ProgressState.TestFailure), "{0}", getProgressDisplayLength(ProgressState.Running, startedDisplayChars > 0 ? (startedDisplayChars - 1) : 0), startedDisplayChars > 0 ? WorkingIndicator[indicatorPos++ % WorkingIndicator.Length].ToString(CultureInfo.InvariantCulture) : "", "{1}"); var intendedDisplayCharWidth = (finishedDisplayChars) + (progressBar.Length - "[{0}{1}]".Length); var remainingDisplayChars = displayWidth - intendedDisplayCharWidth; if (remainingDisplayChars < 0 || notStarted == 0) { //Trim down finished characters if there are too many characters. finishedDisplayChars += remainingDisplayChars; remainingDisplayChars = 0; } progressBar = string.Format(progressBar, getProgressDisplayLength(ProgressState.Finished, finishedDisplayChars), getProgressDisplayLength(ProgressState.NotStarted, remainingDisplayChars)); return progressBar; }
public void RunActionsParallel(int maxConcurrentRunners, IEnumerable<TestRunAction> buildSortedAllActions, CancellationToken token, TextWriterWrapper stdOut, ProgressStats runningTests, Stopwatch totalRuntime, ConcurrentBag<RunStats> testResults) { var options = new ParallelOptions { MaxDegreeOfParallelism = maxConcurrentRunners > 0 ? maxConcurrentRunners : -1, CancellationToken = token }; var startOrderInt = 0; Parallel.ForEach(buildSortedAllActions, options, action => { //stdOut.Write(string.Format("\r> Starting: {0} \n", action.Name)); token.ThrowIfCancellationRequested(); runningTests.IncrementIndex(action.Index); var startOrder = Interlocked.Increment(ref startOrderInt); var startTime = totalRuntime.Elapsed; var sw = new Stopwatch(); sw.Start(); var exitCode = action.RunTests(); sw.Stop(); testResults.Add(new RunStats { Name = action.Name, StartTime = startTime, RunTime = sw.Elapsed, EndTime = totalRuntime.Elapsed, StartOrder = startOrder, FinishOrder = testResults.Count, ExitCode = exitCode }); runningTests.IncrementIndex(action.Index); if (exitCode != 0) { //Go to TestFailure runningTests.IncrementIndex(action.Index); if (!Console.IsOutputRedirected) stdOut.Write("\r! Test failure: {0} ({1}) \n", action.Name, exitCode); } if (exitCode < 0) { //Go to RunFailure runningTests.IncrementIndex(action.Index); } }); }
ProgressStats BruteLoadProgressStats(int[] data) { var stats = new ProgressStats(data.Length); for (int i = 0; i < data.Length; i++) { for (int j = 0; j < data[i]; j++) { stats.IncrementIndex(i); } } return stats; }
public void CalculateScore() { try { if (Exit.Reference == null) { DefaultDeath(); return; } ResetGameplayStats(); CheckUsedWorldObjectsList(); var score = 0; var alive = true; var prog = new ProgressStats(); for (var i = 0; i < Map.Value.rooms.Length; i++) { var roomData = GetRoomData(i, Map.Value.rooms[i], ref prog); if (roomData.died && alive) { alive = false; DeadScore.Value = score; } score += roomData.score; } FinalScore.Value = score; PlayerDied.Value = !alive; OnScoreCalculated.Trigger(new ScoreData { DeadScore = DeadScore, died = PlayerDied, FinalScore = FinalScore }); } catch { DefaultDeath(); return; } }
private static void CreateThread(TestRunAction action, CancellationToken token, TextWriterWrapper stdOut, ProgressStats runningTests, Stopwatch totalRuntime, ConcurrentBag<RunStats> testResults) { var startOrder = Interlocked.Increment(ref _startOrderInt); var parameters = new MethodParameters { Action = action, RunningTests = runningTests, StartOrderInt = startOrder, StdOut = stdOut, TestResults = testResults, Token = token, TotalRuntime = totalRuntime }; Interlocked.Increment(ref _threadCounter); //Shouldn't really use built-in thread pool for long-running processes... ThreadPool.QueueUserWorkItem(RunTest, parameters); }
private async Task LoadDatas() { IsBusy = true; NotificationMessage = "Loading..."; ProgressStats datas = await _demosService.GetProgressStatsAsync(); DatasWin = datas.Win; DatasDamage = datas.Damage; DatasHeadshot = datas.HeadshotRatio; DatasKill = datas.Kill; VelocityRifle = datas.KillVelocityRifle; VelocityPistol = datas.KillVelocityPistol; VelocitySmg = datas.KillVelocitySmg; VelocitySniper = datas.KillVelocitySniper; VelocityHeavy = datas.KillVelocityHeavy; MaximumVelocity = datas.MaximumVelocity + 10; DatasCrouchKill = datas.CrouchKill; CommandManager.InvalidateRequerySuggested(); IsBusy = false; }
public async Task <ProgressStats> GetProgressStatsAsync() { ProgressStats stats = new ProgressStats(); List <Demo> demos = await _cacheService.GetDemoListAsync(); if (demos.Any()) { List <Demo> demosPlayerList = demos.Where(demo => demo.Players.FirstOrDefault(p => p.SteamId == Settings.Default.SelectedStatsAccountSteamID) != null).ToList(); if (demosPlayerList.Any()) { demosPlayerList.Sort((d1, d2) => d1.Date.CompareTo(d2.Date)); // init the first date int currentMonth = demosPlayerList[0].Date.Month; DateTime initDate = new DateTime(demosPlayerList[0].Date.Year, demosPlayerList[0].Date.Month, 1); stats.Win = new List <WinDateChart> { new WinDateChart { Date = initDate, WinPercentage = 0 } }; stats.HeadshotRatio = new List <HeadshotDateChart> { new HeadshotDateChart { Date = initDate, HeadshotPercentage = 0 } }; stats.Damage = new List <DamageDateChart> { new DamageDateChart { Date = initDate, DamageCount = 0 } }; stats.Kill = new List <KillDateChart> { new KillDateChart { Date = initDate, KillAverage = 0, DeathAverage = 0 } }; int matchCount = 0; int winCount = 0; int headshotCount = 0; int killCount = 0; int deathCount = 0; int damageCount = 0; foreach (Demo demo in demosPlayerList) { matchCount++; if (!Equals(currentMonth, demo.Date.Month)) { matchCount = 1; winCount = 0; headshotCount = 0; killCount = 0; deathCount = 0; damageCount = 0; DateTime newDate = new DateTime(demo.Date.Year, demo.Date.Month, 1); // It's a new month, generate new stats for it stats.Win.Add(new WinDateChart { Date = newDate, WinPercentage = 0 }); stats.HeadshotRatio.Add(new HeadshotDateChart { Date = newDate, HeadshotPercentage = 0 }); stats.Damage.Add(new DamageDateChart { Date = newDate, DamageCount = 0 }); stats.Kill.Add(new KillDateChart { Date = newDate, KillAverage = 0, DeathAverage = 0 }); } if (demo.MatchVerdictSelectedAccountCount == 1) { winCount += demo.MatchVerdictSelectedAccountCount; } if (winCount > 0) { stats.Win.Last().WinPercentage = Math.Round((winCount / (double)matchCount * 100), 2); } headshotCount += demo.HeadshotSelectedAccountCount; killCount += demo.TotalKillSelectedAccountCount; deathCount += demo.DeathSelectedAccountCount; damageCount += demo.TotalDamageHealthSelectedAccountCount + demo.TotalDamageArmorSelectedAccountCount; stats.HeadshotRatio.Last().HeadshotPercentage = Math.Round((headshotCount / (double)killCount * 100), 2); stats.Damage.Last().DamageCount = (double)damageCount / matchCount; stats.Kill.Last().KillAverage = Math.Round((double)killCount / matchCount, 1); stats.Kill.Last().DeathAverage = Math.Round((double)deathCount / matchCount, 1); currentMonth = demo.Date.Month; } } } return(stats); }
private RoomData GetRoomData(int index, Room valueRoom, ref ProgressStats prog) { var rewd = 0; var hasExit = false; var chests = new List <ChestWO>(); var spawners = new List <SpawnerWO>(); var healings = new List <HealingWO>(); var tiles = 0; #region GetBlocks for (var x = valueRoom.Position.X; x < valueRoom.Position.X + valueRoom.roomWidth; x++) { for (var y = valueRoom.Position.Y; y < valueRoom.Position.Y + valueRoom.roomHeight; y++) { ++tiles; var block = GridBlocks.GetBlock(new GridPosition(x, y)); if ((block == null) || !block.HasWorldObject) { continue; } if (UsedWorldObjects.Contains(block.WorldObject)) { continue; } var cWo = block.WorldObject as ChestWO; if (cWo != null) { chests.Add(cWo); UsedWorldObjects.Add(cWo); } var sWo = block.WorldObject as SpawnerWO; if (sWo != null) { spawners.Add(sWo); UsedWorldObjects.Add(sWo); } var hWo = block.WorldObject as HealingWO; if (hWo != null) { healings.Add(hWo); UsedWorldObjects.Add(hWo); } var eWo = block.WorldObject as ExitWO; if (eWo != null) { hasExit = true; UsedWorldObjects.Add(eWo); } } } if (index != 0) { var corridor = Map.Value.corridors[index - 1]; for (var x = corridor.startXPos; x < corridor.startXPos + corridor.EndPositionX; x++) { for (var y = corridor.startYPos; y < corridor.startYPos + corridor.EndPositionY; y++) { ++tiles; var block = GridBlocks.GetBlock(new GridPosition(x, y)); if ((block == null) || !block.HasWorldObject) { continue; } if (UsedWorldObjects.Contains(block.WorldObject)) { continue; } var cWo = block.WorldObject as ChestWO; if (cWo != null) { chests.Add(cWo); UsedWorldObjects.Add(cWo); } var sWo = block.WorldObject as SpawnerWO; if (sWo != null) { spawners.Add(sWo); UsedWorldObjects.Add(sWo); } var hWo = block.WorldObject as HealingWO; if (hWo != null) { healings.Add(hWo); UsedWorldObjects.Add(hWo); } var eWo = block.WorldObject as ExitWO; if (eWo != null) { hasExit = true; UsedWorldObjects.Add(eWo); } } } } #endregion var score = 0; foreach (var spawnerWo in spawners) { var localDiff = LevelProgressionCurve.Evaluate(GetDistance(spawnerWo)); prog.Diff = (prog.Diff + spawnerWo.GetSize()) * localDiff; Health.Value -= spawnerWo.GetDamageDealt(); if (Health.Value <= 0) { prog.Died = false; } } if (Health.Value <= 0) { prog.Died = false; } foreach (var chestWo in chests) { var size = chestWo.GetSize(); score += size; if (hasExit) { rewd += size + size; } else { rewd += (size); } } if (!prog.Died) { foreach (var healingWo in healings) { var localDiff = LevelProgressionCurve.Evaluate(GetDistance(healingWo)); prog.Diff = prog.Diff + localDiff; Health.Value += healingWo.GetHealingAmount(); } Health.Value += HealingPerRoom.Value; Health.Value = Mathf.Min(Mathf.Max(Health.Value, 0), MaxHealth); if (Health.Value <= 0) { prog.Died = false; } } score = score + (int)(prog.Diff * rewd); score = score * 100; if (rewd != 0) { prog.Diff = 0; } if (prog.Died) { return(new RoomData { died = true, score = score }); } return(new RoomData { died = (Health.Value == 0), score = score }); }
public string GetRunResultsAsXml(int maxConcurrentRunners) { if (!_configured) { throw new InvalidOperationException("You must call ConfigureRun first"); } //Keep a reference to standard out var stdOut = new TextWriterWrapper(Console.Out); var totalRuntime = new Stopwatch(); totalRuntime.Start(); var outputPath = _runnerSettings.OutputBasePath; if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } var shouldRunOther = _categoriesToRun.Count == 0 || _categoriesToRun.Contains("all"); //var categoryMessage = "Categories run will be: " + string.Join(", ", runnableCategories); //Debug.WriteLine(categoryMessage); //Console.WriteLine(categoryMessage); stdOut.WriteLine("Starting tests..."); if (maxConcurrentRunners > 0) { stdOut.WriteLine(" Running upto " + maxConcurrentRunners + " concurrently"); } stdOut.WriteLine("(ctrl-c and a few seconds to cancel, '{0}' means running, '{1}' means finished)", _progressDisplayBuilder.ArrayValueToRunningStatusChar(ProgressState.Running), _progressDisplayBuilder.ArrayValueToRunningStatusChar(ProgressState.Finished)); var testFixturesToRun = new List <string>(); if (shouldRunOther) { testFixturesToRun = new List <string>(_otherTestFixtures); } var runnableCategories = _categoriesToRun.Count > 0 ? _categories.Intersect(_categoriesToRun).ToList() : _categories; int totalToRun = runnableCategories.Count(); if (_runnerSettings.RunUncategorizedTestFixturesParallel) { totalToRun += testFixturesToRun.Count; } else if (shouldRunOther && _otherTestFixtures.Any()) { totalToRun += 1; } stdOut.WriteLine(); stdOut.WriteLine("Found {0} categories/fixtures to run", totalToRun); var testResults = new ConcurrentBag <RunStats>(); bool cancelled = false; try { var runningTests = new ProgressStats(totalToRun); int indicatorPos = 0; var buildingDisplay = new object(); var timer = new Timer(x => { if (Console.IsOutputRedirected) { return; } if (!Monitor.TryEnter(buildingDisplay)) { return; } try { int windowWidth = Console.WindowWidth; stdOut.Write("\r"); stdOut.Write(_progressDisplayBuilder.BuildProgressDisplay(windowWidth, runningTests, ref indicatorPos, _runnerSettings.DisplayFailureSymbolsInProgressDisplay)); } catch (Exception exception) { stdOut.Write("display error..."); throw new ApplicationException("Unable to properly build progress display.", exception); } finally { Monitor.Exit(buildingDisplay); } }, null, 0, 250); if (Console.IsOutputRedirected) { timer.Change(Timeout.Infinite, Timeout.Infinite); } //Setup ability to catch ctrl-c Console.CancelKeyPress += (sender, args) => { timer.Change(Timeout.Infinite, Timeout.Infinite); args.Cancel = true; _cancelTokenSource.Cancel(); //stdOut.WriteLine(); //stdOut.WriteLine("CANCEL KEY PUSHED"); //Stop any running ones... maybe don't do this until pressed twice? Process.GetProcesses() .Where(p => p.ProcessName == "nunit-console" || p.ProcessName == "nunit-agent") .Each(x => x.Kill()); }; var startOrderInt = 0; var token = _cancelTokenSource.Token; var buildSortedAllActions = BuildSortedAllActions(testFixturesToRun, runnableCategories) .ToArray(); RunActionsOnThreads(maxConcurrentRunners, buildSortedAllActions, token, stdOut, runningTests, startOrderInt, totalRuntime, testResults); timer.Change(0, Timeout.Infinite); //Tacky way to fix line printing problem Thread.Sleep(100); stdOut.WriteLine(); } catch (OperationCanceledException) { cancelled = true; stdOut.WriteLine(); stdOut.WriteLine("== Cancelled =="); } totalRuntime.Stop(); stdOut.WriteLine("= Total runtime: " + TimeSpanFormat(totalRuntime.Elapsed)); stdOut.WriteLine("Finished with tests, merging results"); var SkippedTests = _categories.Except(testResults.Select(a => a.Name)).ToList(); _resultsStatsWriter.OutputRunStats(totalRuntime.Elapsed, testResults, SkippedTests); var outputResultsXmlPath = _runnerSettings.ResultsXmlFilepath; var outputResultsReportPath = _runnerSettings.ResultsHtmlReportFilepath; var xmlOutput = _resultsWriter.MergeResultsProcess(outputPath, outputResultsXmlPath, outputResultsReportPath); if (cancelled) { Environment.ExitCode = -9; } if (testResults.Any(x => x.ExitCode != 0)) { stdOut.WriteLine("ERROR: Test process exited with error!"); Environment.ExitCode = -1; } //Do we really need to return this? if so we should have the writing happen elsewhere... return(xmlOutput); }
private static void CreateThread(TestRunAction action, CancellationToken token, TextWriterWrapper stdOut, ProgressStats runningTests, int startOrderInt, Stopwatch totalRuntime, ConcurrentBag <RunStats> testResults) { var parameters = new MethodParameters { Action = action, RunningTests = runningTests, StartOrderInt = startOrderInt, StdOut = stdOut, TestResults = testResults, Token = token, TotalRuntime = totalRuntime }; Interlocked.Increment(ref _threadCounter); ThreadPool.QueueUserWorkItem(RunTest, parameters); }
private static void RunActionsOnThreads(int maxConcurrentRunners, IEnumerable <TestRunAction> buildSortedAllActions, CancellationToken token, TextWriterWrapper stdOut, ProgressStats runningTests, int startOrderInt, Stopwatch totalRuntime, ConcurrentBag <RunStats> testResults) { var sortedAllActions = buildSortedAllActions as TestRunAction[] ?? buildSortedAllActions.ToArray(); ThreadPool.SetMaxThreads(maxConcurrentRunners, maxConcurrentRunners); for (var i = 0; i < sortedAllActions.Count(); i++) { CreateThread(sortedAllActions[i], token, stdOut, runningTests, startOrderInt, totalRuntime, testResults); } StopProcessing(); }