Skip to content

Commit 7dced90

Browse files
Add create test suite command to gc infra. (#4803)
* upload ReliabilityFrameworkTestCreateSuite.yaml * AddCreateTestSuiteCommandToGCInfra * AddCreateTestSuiteCommandToGCInfra * Optimize CopyFilesRecursively for Linux * PR feedback --------- Co-authored-by: Shiming Ge <[email protected]>
1 parent ade73e0 commit 7dced90

File tree

13 files changed

+775
-6
lines changed

13 files changed

+775
-6
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
OutputFolder: Q:\output-data_sync_checkin
2+
3+
EnableStressMode: false
4+
5+
CoreRoot: Q:\runtime\artifacts\tests\coreclr\windows.x64.Checked\Tests\Core_Root
6+
ReliabilityFrameworkDll: Q:\runtime\artifacts\tests\coreclr\windows.x64.Release\GC\Stress\Framework\ReliabilityFramework\ReliabilityFramework.dll
7+
GCPerfSimDll: Q:\performance\artifacts\bin\GCPerfSim\Release\net7.0\GCPerfSim.dll
8+
TestFolder: Q:\runtime\artifacts\tests\coreclr\windows.x64.Release\GC\Stress\Framework\ReliabilityFramework\Tests
9+
10+
11+
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
using System.Xml.Linq;
2+
3+
namespace GC.Infrastructure.Core.Configurations
4+
{
5+
public static class ReliabilityFrameworkTestSuiteCreator
6+
{
7+
public static void CreateTestingAssets(string ReliabilityFrameworkDll,
8+
string GCPerfSimDll,
9+
string outputFolder,
10+
string TestFolder)
11+
{
12+
try
13+
{
14+
Console.WriteLine($"====== Copy ReliabilityFramework.dll and Tests to `outputFolder` ======");
15+
Utilities.CopyFile(ReliabilityFrameworkDll, outputFolder);
16+
DirectoryInfo testDir = Directory.CreateDirectory(Path.Combine(outputFolder, "Tests"));
17+
string testfolderPath = testDir.FullName;
18+
Utilities.CopyFilesRecursively(TestFolder, testfolderPath);
19+
20+
Console.WriteLine($"====== Copy gcperfsim.dll to Tests ======");
21+
string destTestsFolder = Path.Combine(outputFolder, "Tests");
22+
Utilities.CopyFile(GCPerfSimDll, destTestsFolder);
23+
}
24+
catch (Exception ex)
25+
{
26+
throw new Exception($"{nameof(ReliabilityFrameworkTestSuiteCreator)}: Fail to generate test assets: {ex}");
27+
}
28+
}
29+
30+
public static void GenerateTestScript(string rid,
31+
string baseSuiteFolder,
32+
string coreRoot,
33+
string configPath,
34+
string gcMode,
35+
string outputRoot,
36+
string scriptPath)
37+
{
38+
string scriptFoler = Path.GetDirectoryName(scriptPath);
39+
string osName = rid.Split("-")
40+
.FirstOrDefault("");
41+
42+
string configName = Path.GetFileName(configPath).Split("-")
43+
.FirstOrDefault("");
44+
45+
(string DOTNET_gcServer, string DOTNET_GCDynamicAdaptationMode) =
46+
gcMode switch
47+
{
48+
"Datas" => ("1", "1"),
49+
"Server" => ("1", "0"),
50+
"Workstation" => ("0", "0"),
51+
_ => throw new Exception($"{nameof(ReliabilityFrameworkTestSuiteCreator)}: Unknow GC mode: {gcMode}")
52+
};
53+
54+
string scriptSettingSegment;
55+
string scriptBaseContent;
56+
57+
if (osName == "win")
58+
{
59+
scriptSettingSegment =
60+
$"""
61+
########## setting start ##########
62+
$Env:DOTNET_gcServer={DOTNET_gcServer}
63+
$Env:DOTNET_GCDynamicAdaptationMode={DOTNET_GCDynamicAdaptationMode}
64+
65+
$OutputRoot="{outputRoot}"
66+
$CORE_ROOT="{coreRoot}"
67+
68+
# set config path
69+
$config_path=Join-Path -Path $PSScriptRoot -ChildPath "{Path.GetRelativePath(scriptFoler, configPath)}"
70+
71+
# set test folder
72+
$test_folder=Join-Path -Path $OutputRoot -ChildPath "Tests"
73+
74+
# set ReliabilityFramework.dll path
75+
$reliability_framework_dll=Join-Path -Path $OutputRoot -ChildPath "ReliabilityFramework.dll"
76+
77+
# set output folder
78+
$output_folder=$PSScriptRoot
79+
########## setting end ##########
80+
""";
81+
string baseScriptPath = Path.Combine(baseSuiteFolder, "TestingScript.ps1.txt");
82+
scriptBaseContent = File.ReadAllText(baseScriptPath);
83+
}
84+
else
85+
{
86+
scriptSettingSegment =
87+
$"""
88+
#!/bin/bash
89+
90+
script_root=$(dirname $(realpath $0))
91+
########## setting start ##########
92+
# set gc mode
93+
export DOTNET_gcServer={DOTNET_gcServer}
94+
export DOTNET_GCDynamicAdaptationMode={DOTNET_GCDynamicAdaptationMode}
95+
96+
# set core_root
97+
Output_Root={outputRoot}
98+
CORE_ROOT={coreRoot}
99+
100+
# set config path
101+
config_path=$script_root/{Path.GetRelativePath(scriptFoler, configPath)}
102+
103+
# set test folder
104+
test_folder=$Output_Root/Tests
105+
106+
# set ReliabilityFramework.dll path
107+
reliability_framework_dll=$Output_Root/ReliabilityFramework.dll
108+
109+
# set output folder
110+
output_folder=$script_root
111+
112+
########## setting end ##########
113+
""";
114+
string baseScriptPath = Path.Combine(baseSuiteFolder, "TestingScript.sh.txt");
115+
scriptBaseContent = File.ReadAllText(baseScriptPath);
116+
}
117+
118+
string content = $"{scriptSettingSegment}\n\n{scriptBaseContent}";
119+
File.WriteAllText(scriptPath, content);
120+
}
121+
122+
public static void GenerateTestConfig(string rid, string baseSuiteFolder, string configName, bool enableStress, string gcMode, string configPath)
123+
{
124+
try
125+
{
126+
string osName = rid.Split("-")
127+
.FirstOrDefault("");
128+
129+
string maximumWaitTime =
130+
(osName, enableStress) switch
131+
{
132+
("win", false) => Windows[configName][gcMode],
133+
("win", true) => WindowsStress[configName][gcMode],
134+
("linux", false) => Linux[configName][gcMode],
135+
("linux", true) => LinuxStress[configName][gcMode],
136+
_ => throw new Exception($"{nameof(ReliabilityFrameworkTestSuiteCreator)}: Unknown OS {osName}")
137+
};
138+
139+
string baseConfigPath = Path.Combine(baseSuiteFolder, $"{configName}.config");
140+
string baseConfigContent = File.ReadAllText(baseConfigPath);
141+
XElement config = XElement.Parse(baseConfigContent);
142+
config.SetAttributeValue("maximumWaitTime", maximumWaitTime);
143+
config.SetAttributeValue("maximumExecutionTime", "24:00:00");
144+
config.SetAttributeValue("maximumTestRuns", "-1");
145+
146+
config.Save(configPath, SaveOptions.OmitDuplicateNamespaces);
147+
}
148+
catch (Exception e)
149+
{
150+
throw new Exception($"{nameof(ReliabilityFrameworkTestSuiteCreator)}: Fail to generate test config: {e.Message}");
151+
}
152+
}
153+
154+
private static Dictionary<string, Dictionary<string, string>> Windows { get; } = new()
155+
{
156+
{ "loh", new() { { "Server", "00:10:00"}, { "Workstation", "01:45:00"}, { "Datas", "00:10:00"} } },
157+
{ "poh", new() { { "Server", "00:05:00"}, { "Workstation", "00:50:00" }, { "Datas", "00:05:00" } } },
158+
{ "non_induced", new() { { "Server", "00:30:00"}, { "Workstation", "03:30:00"}, { "Datas", "00:20:00"} } },
159+
{ "finalization", new() { { "Server", "00:05:00"}, { "Workstation", "00:50:00"}, { "Datas", "00:15:00" } } }
160+
};
161+
private static Dictionary<string, Dictionary<string, string>> WindowsStress { get; } = new()
162+
{
163+
{ "loh", new() { { "Server", "00:02:00"}, { "Workstation", "00:10:00"}, { "Datas", "00:05:00"} } },
164+
{ "poh", new() { { "Server", "00:02:00"}, { "Workstation", "00:10:00" }, { "Datas", "00:05:00" } } },
165+
{ "non_induced", new() { { "Server", "00:25:00"}, { "Workstation", "04:00:00"}, { "Datas", "00:35:00"} } },
166+
{ "finalization", new() { { "Server", "00:05:00"}, { "Workstation", "00:40:00"}, { "Datas", "01:40:00" } } }
167+
};
168+
private static Dictionary<string, Dictionary<string, string>> Linux { get; } = new()
169+
{
170+
{ "loh", new() { { "Server", "00:25:00"}, { "Workstation", "00:20:00"}, { "Datas", "00:20:00"} } },
171+
{ "poh", new() { { "Server", "00:10:00"}, { "Workstation", "00:10:00" }, { "Datas", "00:10:00" } } },
172+
{ "non_induced", new() { { "Server", "00:25:00"}, { "Workstation", "00:55:00"}, { "Datas", "00:15:00"} } },
173+
{ "finalization", new() { { "Server", "00:20:00"}, { "Workstation", "01:30:00"}, { "Datas", "00:25:00" } } }
174+
};
175+
private static Dictionary<string, Dictionary<string, string>> LinuxStress { get; } = new()
176+
{
177+
{ "loh", new() { { "Server", "00:10:00"}, { "Workstation", "00:25:00"}, { "Datas", "00:08:00"} } },
178+
{ "poh", new() { { "Server", "00:05:00"}, { "Workstation", "00:15:00" }, { "Datas", "00:05:00" } } },
179+
{ "non_induced", new() { { "Server", "00:25:00"}, { "Workstation", "01:10:00"}, { "Datas", "00:30:00"} } },
180+
{ "finalization", new() { { "Server", "00:20:00"}, { "Workstation", "00:50:00"}, { "Datas", "04:00:00" } } }
181+
};
182+
}
183+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using YamlDotNet.Serialization;
2+
3+
namespace GC.Infrastructure.Core.Configurations
4+
{
5+
public sealed class ReliabilityFrameworkTestCreateTestSuiteConfiguration
6+
{
7+
public string OutputFolder { get; set; }
8+
public string CoreRoot { get; set; }
9+
public string ReliabilityFrameworkDll { get; set; }
10+
public bool EnableStressMode { get; set; }
11+
public string GCPerfSimDll { get; set; }
12+
public string TestFolder { get; set; }
13+
}
14+
15+
public static class ReliabilityFrameworkTestCreateTestSuiteConfigurationParser
16+
{
17+
private static readonly IDeserializer _deserializer =
18+
new DeserializerBuilder().IgnoreUnmatchedProperties().Build();
19+
20+
public static ReliabilityFrameworkTestCreateTestSuiteConfiguration Parse(string path)
21+
{
22+
// Preconditions.
23+
ConfigurationChecker.VerifyFile(path, nameof(ReliabilityFrameworkTestCreateTestSuiteConfigurationParser));
24+
25+
string serializedConfiguration = File.ReadAllText(path);
26+
ReliabilityFrameworkTestCreateTestSuiteConfiguration? configuration = null;
27+
28+
// This try catch is here because the exception from the YamlDotNet isn't helpful and must be imbued with more details.
29+
try
30+
{
31+
configuration = _deserializer.Deserialize<ReliabilityFrameworkTestCreateTestSuiteConfiguration>(serializedConfiguration);
32+
}
33+
34+
catch (Exception ex)
35+
{
36+
throw new ArgumentException($"{nameof(ReliabilityFrameworkTestCreateTestSuiteConfiguration)}: Unable to parse the yaml file because of an error in the syntax. Exception: {ex.Message} \n Call Stack: {ex.StackTrace}");
37+
}
38+
39+
if (string.IsNullOrEmpty(configuration.OutputFolder))
40+
{
41+
throw new ArgumentException($"{nameof(ReliabilityFrameworkTestCreateTestSuiteConfiguration)}: Please specify output folder");
42+
}
43+
44+
if (string.IsNullOrEmpty(configuration.ReliabilityFrameworkDll) )
45+
{
46+
throw new ArgumentException($"{nameof(ReliabilityFrameworkTestCreateTestSuiteConfiguration)}: Please specify ReliabilityFrameworkDll");
47+
}
48+
49+
if (!Path.Exists(configuration.CoreRoot))
50+
{
51+
throw new ArgumentException($"{nameof(ReliabilityFrameworkTestCreateTestSuiteConfiguration)}: Given CoreRoot path is not valid");
52+
}
53+
54+
if (string.IsNullOrEmpty(configuration.GCPerfSimDll))
55+
{
56+
throw new ArgumentException($"{nameof(ReliabilityFrameworkTestCreateTestSuiteConfiguration)}: Please specify GCPerfSimDll");
57+
}
58+
59+
if (!Path.Exists(configuration.TestFolder))
60+
{
61+
throw new ArgumentException($"{nameof(ReliabilityFrameworkTestCreateTestSuiteConfiguration)}: Given TestFolder path is not valid");
62+
}
63+
64+
return configuration;
65+
}
66+
}
67+
}

src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/Utilities.cs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,24 @@ public static class Utilities
44
{
55
public static void CopyFilesRecursively(string sourcePath, string targetPath)
66
{
7-
string targetPathAsDirectory = targetPath + "\\";
7+
sourcePath = Path.GetFullPath(sourcePath).TrimEnd(Path.DirectorySeparatorChar);
8+
targetPath = Path.GetFullPath(targetPath).TrimEnd(Path.DirectorySeparatorChar);
9+
10+
Directory.CreateDirectory(targetPath);
11+
812
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
913
{
10-
Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPathAsDirectory));
14+
string relativePath = Path.GetRelativePath(sourcePath, dirPath);
15+
string newDirPath = Path.Combine(targetPath, relativePath);
16+
Directory.CreateDirectory(newDirPath);
1117
}
1218

13-
foreach (string newPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
19+
foreach (string filePath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
1420
{
15-
File.Copy(newPath, newPath.Replace(sourcePath, targetPathAsDirectory), true);
21+
string relativePath = Path.GetRelativePath(sourcePath, filePath);
22+
string newFilePath = Path.Combine(targetPath, relativePath);
23+
Directory.CreateDirectory(Path.GetDirectoryName(newFilePath));
24+
File.Copy(filePath, newFilePath, true);
1625
}
1726
}
1827

@@ -49,5 +58,22 @@ public static bool TryCopyFile(string sourcePath, string destinationPath)
4958
return false;
5059
}
5160
}
61+
62+
public static void CopyFile(string srcPath, string dstPath)
63+
{
64+
string realDestPath = String.Empty;
65+
if (Directory.Exists(dstPath))
66+
{
67+
// Copy file to a directory
68+
string fileName = Path.GetFileName(srcPath);
69+
realDestPath = Path.Combine(dstPath, fileName);
70+
}
71+
else
72+
{
73+
realDestPath = dstPath;
74+
}
75+
76+
File.Copy(srcPath, realDestPath);
77+
}
5278
}
5379
}

0 commit comments

Comments
 (0)