From 18b6908cb933c18fc11559a2619814d4c5b493ed Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 25 Nov 2024 11:54:37 +0100 Subject: [PATCH] working --- .../CodexUnitTestCrusher.csproj | 10 + CodexUnitTestCrusher/Program.cs | 193 ++++++++++++++++++ cs-codex-dist-testing.sln | 7 + 3 files changed, 210 insertions(+) create mode 100644 CodexUnitTestCrusher/CodexUnitTestCrusher.csproj create mode 100644 CodexUnitTestCrusher/Program.cs diff --git a/CodexUnitTestCrusher/CodexUnitTestCrusher.csproj b/CodexUnitTestCrusher/CodexUnitTestCrusher.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/CodexUnitTestCrusher/CodexUnitTestCrusher.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/CodexUnitTestCrusher/Program.cs b/CodexUnitTestCrusher/Program.cs new file mode 100644 index 0000000..fbd71e2 --- /dev/null +++ b/CodexUnitTestCrusher/Program.cs @@ -0,0 +1,193 @@ +namespace CodexUnitTestCrusher +{ + public class Program + { + public static void Main(string[] args) + { + var p = new Program(); + p.Run(); + } + + private const bool AddRandomSleeps = true; + private const bool GenerateLoopTestRunners = true; + + private readonly string Root = "C:\\Projects\\nim-codex"; + private readonly string[] Exclude = + [ + "vendor" + ]; + + private readonly string Include = "import std/random"; + private readonly string SleepLine = "await sleepAsync(rand(10))"; + private readonly int NumCompiles = 10; + private readonly int NumRuns = 100; + private readonly string[] TestRunner = + [ + "set -e", + "for i in {0..}", + "do", + " echo \"#1\" >> \"\"", + " for j in {0..}", + " do", + " nim c -r \"\"", + " done", + "done", + "rm ", + ]; + + public void Run() + { + TraverseFolder(Root); + } + + private void TraverseFolder(string root) + { + if (Exclude.Any(x => root.Contains(x))) return; + + var folder = Directory.GetDirectories(root); + foreach (var dir in folder) TraverseFolder(dir); + + var files = Directory.GetFiles(root); + foreach (var file in files) ProcessFile(file); + } + + private void ProcessFile(string file) + { + if (!file.EndsWith(".nim")) return; + + if (AddRandomSleeps) AddRandomSleepsToNimFile(file); + if (GenerateLoopTestRunners) GenerateTestRunner(file); + } + + private void GenerateTestRunner(string file) + { + var filename = Path.GetFileName(file); + if (!filename.StartsWith("test")) return; + var path = Path.GetDirectoryName(file); + + var testFile = file; + var scriptFile = filename.Replace(".nim", ".sh"); + WriteScriptFile(path!, testFile, scriptFile); + } + + private void WriteScriptFile(string path, string testFile, string scriptFile) + { + var lines = TestRunner.Select(l => + { + return l + .Replace("", NumCompiles.ToString()) + .Replace("", NumRuns.ToString()) + .Replace("", testFile.ToString()) + .Replace("", scriptFile.ToString()) + ; + + }).ToArray(); + + File.WriteAllLines(Path.Combine(path, scriptFile), lines); + } + + private void AddRandomSleepsToNimFile(string file) + { + Console.WriteLine("Processing file: " + file); + + var lines = File.ReadAllLines(file).ToList(); + if (!lines.Any(l => l == Include)) + { + AddInclude(lines); + } + + var modified = false; + for (int i = 0; i < lines.Count; i++) + { + if (ProcessLine(i, lines[i], lines)) + { + i++; + modified = true; + } + } + + if (modified) File.WriteAllLines(file, lines); + } + + private bool ProcessLine(int i, string line, List lines) + { + if (IsComment(line)) return false; + + if (line.Contains("await ")) + { + if (!line.Contains("sleep")) + { + var previous = GetPreviousLine(i, lines); + if (previous != null) + { + var trim = previous.Trim(); + // previous line was "let" ??? + if (trim == "let") + { + // insert before let. + InsertSleepLine(i - 1, lines); + return true; + } + // previous line was "without =?" ?? + if (trim.StartsWith("without") && trim.EndsWith("=?")) + { + // insert before without. + InsertSleepLine(i - 1, lines); + return true; + } + // previous line was "const" ?? + if (trim == "const") return false; + } + + var indent = GetIndent(line); + if (indent.Length < 3) InsertSleepLine(i, lines); + return true; + } + } + return false; + } + + private void InsertSleepLine(int i, List lines) + { + lines.Insert(i, GetIndent(lines[i]) + SleepLine); + } + + private string? GetPreviousLine(int i, List lines) + { + var idx = i - 1; + if (idx < 0) return null; + return lines[idx]; + } + + private bool IsComment(string line) + { + return line.Trim().StartsWith("#"); + } + + private string GetIndent(string line) + { + var result = ""; + + while (line.StartsWith(" ")) + { + result += " "; + line = line.Substring(1); + } + + return result; + } + + private void AddInclude(List lines) + { + for (var i = 0; i < lines.Count; i++) + { + var line = lines[i]; + if (line.StartsWith("import ")) + { + lines.Insert(i, Include); + return; + } + } + } + } +} diff --git a/cs-codex-dist-testing.sln b/cs-codex-dist-testing.sln index 67f6310..7ca9700 100644 --- a/cs-codex-dist-testing.sln +++ b/cs-codex-dist-testing.sln @@ -78,6 +78,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarketInsights", "Tools\Mar EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsvCombiner", "Tools\CsvCombiner\CsvCombiner.csproj", "{6230347F-5045-4E25-8E7A-13D7221B7444}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodexUnitTestCrusher", "CodexUnitTestCrusher\CodexUnitTestCrusher.csproj", "{E1B15D68-7055-42C9-B3DC-3130CA1CFBBE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -208,6 +210,10 @@ Global {6230347F-5045-4E25-8E7A-13D7221B7444}.Debug|Any CPU.Build.0 = Debug|Any CPU {6230347F-5045-4E25-8E7A-13D7221B7444}.Release|Any CPU.ActiveCfg = Release|Any CPU {6230347F-5045-4E25-8E7A-13D7221B7444}.Release|Any CPU.Build.0 = Release|Any CPU + {E1B15D68-7055-42C9-B3DC-3130CA1CFBBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1B15D68-7055-42C9-B3DC-3130CA1CFBBE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1B15D68-7055-42C9-B3DC-3130CA1CFBBE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1B15D68-7055-42C9-B3DC-3130CA1CFBBE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -244,6 +250,7 @@ Global {C0EEBD32-23CB-45EC-A863-79FB948508C8} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3} {004614DF-1C65-45E3-882D-59AE44282573} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3} {6230347F-5045-4E25-8E7A-13D7221B7444} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3} + {E1B15D68-7055-42C9-B3DC-3130CA1CFBBE} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {237BF0AA-9EC4-4659-AD9A-65DEB974250C}