提交 4a835e11 编写于 作者: B Balaji Soundrarajan

Merge pull request #11020 from basoundr/perfTypesFinal1

Move Perf helpers into binary 
......@@ -4,7 +4,7 @@ call "%~dp0..\..\..\Restore.cmd"
set MSBuild=%ProgramFiles%\MSBuild\14.0\bin\msbuild.exe
if not exist "%MSBuild%" set MSBuild=%ProgramFiles(x86)%\MSBuild\14.0\bin\msbuild.exe
"%MSBuild%" "%~dp0..\..\Interactive\csi\csi.csproj" /p:Configuration=Release /p:OutDir="%~dp0infra\bin\\"
"%MSBuild%" "%~dp0..\..\..\src\Interactive\csi\csi.csproj" /p:Configuration=Release /p:OutDir="%~dp0infra\bin\\"
if "%USERDNSDOMAIN%" == "REDMOND.CORP.MICROSOFT.COM" (
if exist "%SYSTEMDRIVE%/CPC" ( rd /s /q "%SYSTEMDRIVE%/CPC" )
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#r "./../../Roslyn.Test.Performance.Utilities.dll"
// IsVerbose()
#load "../util/test_util.csx"
// RunFile()
#load "../util/runner_util.csx"
#load "../util/Download_util.csx"
using Roslyn.Test.Performance.Utilities;
var directoryUtil = new RelativeDirectory();
var logger = new ConsoleAndFileLogger();
TestUtilities.InitUtilities();
// Update the repository
string branch = StdoutFrom("git", "rev-parse --abbrev-ref HEAD");
ShellOutVital("git", $"pull origin {branch}");
ShellOutVital(Path.Combine(directoryUtil.RoslynDirectory, "Restore.cmd"), "", workingDirectory: directoryUtil.RoslynDirectory);
string branch = TestUtilities.StdoutFrom("git", IsVerbose(), logger, "rev-parse --abbrev-ref HEAD");
TestUtilities.ShellOutVital("git", $"pull origin {branch}", IsVerbose(), logger);
TestUtilities.ShellOutVital(Path.Combine(directoryUtil.RoslynDirectory, "Restore.cmd"), "", IsVerbose(), logger, workingDirectory: directoryUtil.RoslynDirectory);
// Build Roslyn in Release Mode
ShellOutVital("msbuild", "./Roslyn.sln /p:Configuration=Release", workingDirectory: directoryUtil.RoslynDirectory);
TestUtilities.ShellOutVital("msbuild", "./Roslyn.sln /p:Configuration=Release", IsVerbose(), logger, workingDirectory: directoryUtil.RoslynDirectory);
// Install the Vsixes to RoslynPerf hive
await RunFile(Path.Combine(directoryUtil.MyWorkingDirectory, "install_vsixes.csx"));
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// IsVerbose()
#load "../util/test_util.csx"
using System.IO;
// TODO: Use actual command line argument parser so we can have help text, etc...
var branch = Args.Length == 1 ? Args[0] : "master";
var repoFolder = Args.Lenth == 2 ? Args[1] : @"C:\Roslyn";
var branch = Args.Count() == 2 ? Args[0] : "master";
var repoFolder = Args.Count() == 2 ? Args[1] : @"C:\Roslyn";
Directory.Delete(repoFolder, recursive: true);
......@@ -17,13 +19,13 @@ Directory.Delete(repoFolder, recursive: true);
// consume the OptProf data via nuget (https://github.com/dotnet/roslyn/issues/5283).
var repo = "https://github.com/dotnet/roslyn";
var result = ShellOut("git", $"clone {repo} master {repoFolder}");
var result = ShellOut("git", $"clone {repo} master {repoFolder}", "");
if (!result.Succeeded)
{
return result.Code;
}
result = ShellOut("msbuild", $"/m /t:rebuild /p:Configuration=Release /p:RealSignBuild=true /p:DelaySignBuild=false {Path.Combine(repoFolder, "Roslyn.sln")}");
result = ShellOut("msbuild", $"/m /t:rebuild /p:Configuration=Release /p:RealSignBuild=true /p:DelaySignBuild=false {Path.Combine(repoFolder, "Roslyn.sln")}", "");
if (!result.Succeeded)
{
return result.Code;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Log()
#load "../util/test_util.csx"
#load "../util/tools_util.csx"
using System;
......@@ -7,8 +10,8 @@ using System.Linq;
using System.Xml;
// TODO: Use actual command line argument parser so we can have help text, etc...
var branch = Args.Length == 2 ? Args[0] : "master";
var destinationFolder = Args.Length == 2 ? Args[1] : @"C:\Roslyn\Binaries\Release";
var branch = Args.Count() == 2 ? Args[0] : "master";
var destinationFolder = Args.Count() == 2 ? Args[1] : @"C:\Roslyn\Binaries\Release";
var sourceFolder = $@"\\cpvsbuild\drops\Roslyn\Roslyn-{branch}-Signed-Release";
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#r "./../../Roslyn.Test.Performance.Utilities.dll"
// IsVerbose()
#load "../util/test_util.csx"
#load "./assemblies.csx"
#load "./ngen.csx"
using System;
using System.Diagnostics;
using System.IO;
using Roslyn.Test.Performance.Utilities;
using static Roslyn.Test.Performance.Utilities.TestUtilities;
InitUtilities();
TestUtilities.InitUtilities();
// If we're being #load'ed by uninstall.csx, set the "uninstall" flag.
var uninstall = Environment.GetCommandLineArgs()[1] == "uninstall.csx";
......@@ -26,7 +32,9 @@ foreach (var processName in new[] { "devenv", "msbuild", "VBCSCompiler"})
}
}
Log($"\n{message} Roslyn binaries to VS folder.");
var logger = new ConsoleAndFileLogger();
logger.Log($"\n{message} Roslyn binaries to VS folder.");
var devenvFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Microsoft Visual Studio 14.0\Common7\IDE");
var destinationFolder = Path.Combine(devenvFolder, "PrivateAssemblies");
var filesToNGen = new List<string>();
......@@ -47,11 +55,11 @@ foreach (var file in filesToNGen)
}
var devenv = Path.Combine(devenvFolder, "devenv.exe");
ShellOutVital(devenv, "/clearcache");
ShellOutVital(devenv, "/updateconfiguration");
ShellOutVital(devenv, $"/resetsettingsfull {Path.Combine(sourceFolder, "Default.vssettings")} /command \"File.Exit\"");
ShellOutVital(devenv, "/clearcache", IsVerbose(), logger);
ShellOutVital(devenv, "/updateconfiguration", IsVerbose(), logger);
ShellOutVital(devenv, $"/resetsettingsfull {Path.Combine(sourceFolder, "Default.vssettings")} /command \"File.Exit\"", IsVerbose(), logger);
Log($"\n{message} compilers in MSBuild folders.");
logger.Log($"\n{message} compilers in MSBuild folders.");
destinationFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"MSBuild\14.0\Bin");
var destinationFolder64 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"MSBuild\14.0\Bin\amd64");
filesToNGen = new List<string>();
......
#load "test_util.csx"
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#r "./../../Roslyn.Test.Performance.Utilities.dll"
var binariesDirectory = new RelativeDirectory().MyBinaries();
// IsVerbose()
#load "../util/test_util.csx"
using System.IO;
using Roslyn.Test.Performance.Utilities;
TestUtilities.InitUtilities();
var directoryUtil = new RelativeDirectory();
var logger = new ConsoleAndFileLogger();
var binariesDirectory = directoryUtil.MyBinaries();
var vsixes = new[]
{
"Roslyn.VisualStudio.Setup.vsix",
......@@ -16,7 +27,5 @@ var installer = Path.Combine(binariesDirectory, "VSIXExpInstaller.exe");
foreach (var vsix in vsixes)
{
ShellOutVital(installer, $"/rootSuffix:RoslynPerf {vsix}", binariesDirectory, System.Threading.CancellationToken.None);
}
TestUtilities.ShellOutVital(installer, $"/rootSuffix:RoslynPerf {vsix}", IsVerbose(), logger, binariesDirectory);
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// StdoutFrom()
// Log()
#load "../util/test_util.csx"
using System.IO;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#r "./../../Roslyn.Test.Performance.Utilities.dll"
// IsVerbose()
#load "../util/test_util.csx"
// RunFile()
#load "../util/runner_util.csx"
#load "../util/tools_util.csx"
using System.IO;
using Roslyn.Test.Performance.Utilities;
using static Roslyn.Test.Performance.Utilities.Tools;
var directoryUtil = new RelativeDirectory();
var logger = new ConsoleAndFileLogger();
// Gather performance metrics and produce csv files
await RunFile(Path.Combine(directoryUtil.MyWorkingDirectory, "..", "runner.csx"));
// Convert the produced consumptionTempResults.xml file to consumptionTempResults.csv file
var elapsedTimeCsvFilePath = Path.Combine(directoryUtil.CPCDirectoryPath, "consumptionTempResults_ElapsedTime.csv");
var result = ConvertConsumptionToCsv(Path.Combine(directoryUtil.CPCDirectoryPath, "consumptionTempResults.xml"), elapsedTimeCsvFilePath, "Duration_TotalElapsedTime");
var result = ConvertConsumptionToCsv(Path.Combine(directoryUtil.CPCDirectoryPath, "consumptionTempResults.xml"), elapsedTimeCsvFilePath, "Duration_TotalElapsedTime", logger);
if (result)
{
var elapsedTimeViBenchJsonFilePath = GetViBenchJsonFromCsv(elapsedTimeCsvFilePath, null, null);
var elapsedTimeViBenchJsonFilePath = GetViBenchJsonFromCsv(elapsedTimeCsvFilePath, null, null, IsVerbose(), logger);
string jsonFileName = Path.GetFileName(elapsedTimeViBenchJsonFilePath);
// Move the json file to a file-share
......@@ -29,4 +35,4 @@ else
}
// Move the traces to mlangfs1 share
UploadTraces(directoryUtil.CPCDirectoryPath, @"\\mlangfs1\public\basoundr\PerfTraces");
UploadTraces(directoryUtil.CPCDirectoryPath, @"\\mlangfs1\public\basoundr\PerfTraces", logger);
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#load "../util/test_util.csx"
using System.IO;
using System;
var directoryUtil = new RelativeDirectory();
string FirstLine(string input)
{
return input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)[0];
}
string branch = StdoutFrom("git", "rev-parse --abbrev-ref HEAD");
string date = FirstLine(StdoutFrom("git", $"show --format=\"%aI\" {branch} --"));
string hash = FirstLine(StdoutFrom("git", $"show --format=\"%h\" {branch} --"));
string longHash = FirstLine(StdoutFrom("git", $"show --format=\"%H\" {branch} --"));
string username = StdoutFrom("whoami");
string machineName = StdoutFrom("hostname");
string architecture = System.Environment.Is64BitOperatingSystem ? "x86-64" : "x86";
// File locations
string workingDir = Path.Combine(directoryUtil.MyWorkingDirectory, "..", "temp");
string inCompilerTime = Path.Combine(workingDir, "compiler_time.csv");
string inRunTime = Path.Combine(workingDir, "run_time.csv");
string inFileSize = Path.Combine(workingDir, "file_size.csv");
string outJson = Path.Combine(workingDir, $"Roslyn-{longHash}.json");
// ViBenchToJson does not like empty csv files.
string files = "";
if (new FileInfo(inCompilerTime).Length != 0)
{
files += $@"compilertime:""{inCompilerTime}""";
}
if (new FileInfo(inRunTime).Length != 0)
{
files += $@"exectime:""{inRunTime}""";
}
if (new FileInfo(inFileSize).Length != 0)
{
files += $@"filesize:""{inFileSize}""";
}
string arguments = $@"
{files}
jobName:""RoslynPerf-{hash}-{date}""
jobGroupName:""Roslyn-{branch}""
jobTypeName:""official""
buildInfoName:""{date}-{branch}-{hash}""
configName:""Default Configuration""
machinePoolName:""4-core-windows""
architectureName:""{architecture}""
manufacturerName:""unknown-manufacturer""
microarchName:""unknown-microarch""
userName:""{username}""
userAlias:""{username}""
osInfoName:""Windows""
machineName:""{machineName}""
buildNumber:""{date}-{hash}""
/json:""{outJson}""
";
arguments = arguments.Replace("\r\n", " ").Replace("\n", "");
ShellOutVital(@"\\vcuts-server\tools\ViBenchCsvToJson\ViBenchToJson.exe", arguments);
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#r "./../Roslyn.Test.Performance.Utilities.dll"
// RunFile()
// GetAllCsxRecursive()
#load "./util/runner_util.csx"
// Log()
// StdoutFrom()
#load "./util/test_util.csx"
#load "./util/trace_manager_util.csx"
using System.Collections.Generic;
using System.IO;
using System;
using Roslyn.Test.Performance.Utilities;
var directoryInfo = new RelativeDirectory();
var testDirectory = Path.Combine(directoryInfo.MyWorkingDirectory, "tests");
......@@ -16,7 +21,7 @@ Log("Starting Performance Test Run");
Log("hash: " + StdoutFrom("git", "show --format=\"%h\" HEAD --").Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)[0]);
Log("time: " + DateTime.Now.ToString());
var testInstances = new List<dynamic>();
var testInstances = new List<PerfTest>();
// Find all the tests from inside of the csx files.
foreach (var script in GetAllCsxRecursive(testDirectory))
......@@ -24,13 +29,14 @@ foreach (var script in GetAllCsxRecursive(testDirectory))
var scriptName = Path.GetFileNameWithoutExtension(script);
Log($"Collecting tests from {scriptName}");
var state = await RunFile(script);
object[] tests = (object[]) state.GetVariable("resultTests").Value;
var tests = (PerfTest[]) state.GetVariable("resultTests").Value;
testInstances.AddRange(tests);
}
var traceManager = TraceManagerFactory.GetTraceManager();
traceManager.Initialize();
foreach (dynamic test in testInstances)
foreach (var test in testInstances)
{
test.Setup();
traceManager.Setup();
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#r "../../../Roslyn.Test.Performance.Utilities.dll"
// TestThisPlease()
// IsVerbose()
#load "../../util/test_util.csx"
using System.IO;
using System.Collections.Generic;
using Roslyn.Test.Performance.Utilities;
using static Roslyn.Test.Performance.Utilities.TestUtilities;
class CSharpCompilerTest: PerfTest
class CSharpCompilerTest: PerfTest
{
private string _rspFile;
private string _rspFile;
private ILogger _logger;
public CSharpCompilerTest(string rspFile): base() {
_rspFile = rspFile;
_logger = new ConsoleAndFileLogger();
}
public override void Setup()
{
DownloadProject("csharp", version: 1);
DownloadProject("csharp", version: 1, logger: _logger);
}
public override void Test()
......@@ -22,12 +31,13 @@ class CSharpCompilerTest: PerfTest
string keyfileLocation = Path.Combine(MyTempDirectory, "csharp", "keyfile", "35MSSharedLib1024.snk");
string args = $"{responseFile} /keyfile:{keyfileLocation}";
string executeInDirectory = Path.Combine(MyTempDirectory, "csharp");
string workingDirectory = Path.Combine(MyTempDirectory, "csharp");
ShellOutVital(ReleaseCscPath, args, executeInDirectory);
ShellOutVital(Path.Combine(MyBinaries(), "csc.exe"), args, IsVerbose(), _logger, workingDirectory);
_logger.Flush();
}
public override int Iterations => 2;
public override int Iterations => 1;
public override string Name => "csharp " + _rspFile;
public override string MeasuredProc => "csc";
public override bool ProvidesScenarios => false;
......@@ -37,7 +47,8 @@ class CSharpCompilerTest: PerfTest
}
}
TestThisPlease(
TestThisPlease(
new CSharpCompilerTest("CSharpCompiler.rsp"),
new CSharpCompilerTest("CSharpCompilerNoAnalyzer.rsp"),
new CSharpCompilerTest("CSharpCompilerNoAnalyzerNoDeterminism.rsp"));
new CSharpCompilerTest("CSharpCompilerNoAnalyzerNoDeterminism.rsp")
);
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#load "../../util/test_util.csx"
#r "../../../Roslyn.Test.Performance.Utilities.dll"
// TestThisPlease()
// IsVerbose()
#load "./../../util/test_util.csx"
using System.IO;
using Roslyn.Test.Performance.Utilities;
using static Roslyn.Test.Performance.Utilities.TestUtilities;
class HelloWorldTest: PerfTest
class HelloWorldTest : PerfTest
{
private string _pathToHelloWorld;
private string _pathToOutput;
private ILogger _logger;
public HelloWorldTest(): base()
{
_logger = new ConsoleAndFileLogger();
}
public HelloWorldTest(): base() {}
public override void Setup()
{
......@@ -18,7 +30,8 @@ class HelloWorldTest: PerfTest
public override void Test()
{
ShellOutVital(ReleaseCscPath, _pathToHelloWorld + " /out:" + _pathToOutput);
ShellOutVital(ReleaseCscPath, _pathToHelloWorld + " /out:" + _pathToOutput, IsVerbose(), _logger);
_logger.Flush();
}
public override int Iterations => 2;
......
#load "test_util.csx"
#load "tools_util.csx"
using System;
using System.IO;
void DownloadTools()
{
DownloadCPC();
DownloadViBenchToJson();
}
void DownloadCPC()
{
var directoryUtil = new RelativeDirectory();
var cpcDestinationPath = directoryUtil.CPCDirectoryPath;
var cpcSourceBinaryLocation = @"\\mlangfs1\public\basoundr\CpcBinaries";
// Delete the existing CPC folder
if (Directory.Exists(cpcDestinationPath))
{
Directory.Delete(cpcDestinationPath, true);
}
// Copy CPC from the share to cpcDestinationPath
CopyDirectory(cpcSourceBinaryLocation, cpcDestinationPath);
}
void DownloadViBenchToJson()
{
var directoryUtil = new RelativeDirectory();
var destinationFolderPath = directoryUtil.CPCDirectoryPath;
var sourceFile = @"\\mlangfs1\public\basoundr\vibenchcsv2json";
CopyDirectory(sourceFile, destinationFolderPath, @"/s");
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Roslyn.Test.Performance.Utilities
{
public interface ILogger
{
void Log(string v);
void Flush();
}
}
using System;
using System.Diagnostics;
using System.IO;
namespace Roslyn.Test.Performance.Utilities
{
public interface ITraceManager
{
bool HasWarmUpIteration { get; }
void Initialize();
void Cleanup();
void EndEvent();
void EndScenario();
void EndScenarios();
void ResetScenarioGenerator();
void Setup();
void Start();
void StartEvent();
void StartScenario(string scenarioName, string processName);
void StartScenarios();
void Stop();
void WriteScenarios(string[] scenarios);
void WriteScenariosFileToDisk();
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Roslyn.Test.Performance.Utilities
{
public class ConsoleAndFileLogger : ILogger
{
private readonly string _file;
private readonly StringBuilder _buffer = new StringBuilder();
public ConsoleAndFileLogger(string file = "log.txt")
{
_file = file;
}
public void Flush()
{
File.WriteAllText(_file, _buffer.ToString());
}
public void Log(string v)
{
Console.WriteLine(v);
_buffer.AppendLine(v);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Roslyn.Test.Performance.Utilities
{
public class NoOpTraceManager : ITraceManager
{
public NoOpTraceManager()
{
}
public bool HasWarmUpIteration
{
get
{
return false;
}
}
public void Initialize()
{
}
public void Cleanup()
{
}
public void EndEvent()
{
}
public void EndScenario()
{
}
public void EndScenarios()
{
}
public void ResetScenarioGenerator()
{
}
public void Setup()
{
}
public void Start()
{
}
public void StartEvent()
{
}
public void StartScenarios()
{
}
public void StartScenario(string scenarioName, string processName)
{
}
public void Stop()
{
}
public void WriteScenarios(string[] scenarios)
{
}
public void WriteScenariosFileToDisk()
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Roslyn.Test.Performance.Utilities
{
public abstract class PerfTest : RelativeDirectory
{
public PerfTest([CallerFilePath] string workingFile = "") : base(workingFile) { }
public abstract void Setup();
public abstract void Test();
public abstract int Iterations { get; }
public abstract string Name { get; }
public abstract string MeasuredProc { get; }
public abstract bool ProvidesScenarios { get; }
public abstract string[] GetScenarios();
}
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Roslyn.Test.Performance.Utilities
{
public class RelativeDirectory
{
string _workingDir;
public RelativeDirectory([CallerFilePath] string workingFile = "")
{
_workingDir = Directory.GetParent(workingFile).FullName;
}
public string MyWorkingDirectory => _workingDir;
/// Returns the directory that you can put artifacts like
/// etl traces or compiled binaries
public string MyArtifactsDirectory
{
get
{
var path = Path.Combine(MyWorkingDirectory, "artifacts");
Directory.CreateDirectory(path);
return path;
}
}
public string MyTempDirectory
{
get
{
var workingDir = MyWorkingDirectory;
var path = Path.Combine(workingDir, "temp");
Directory.CreateDirectory(path);
return path;
}
}
public string RoslynDirectory
{
get
{
var workingDir = MyWorkingDirectory;
var binaryDebug = Path.Combine("Binaries", "Debug").ToString();
int binaryDebugIndex = workingDir.IndexOf(binaryDebug, StringComparison.OrdinalIgnoreCase);
if (binaryDebugIndex != -1)
{
return workingDir.Substring(0, binaryDebugIndex);
}
var binaryRelease = Path.Combine("Binaries", "Release").ToString();
return workingDir.Substring(0, workingDir.IndexOf(binaryRelease, StringComparison.OrdinalIgnoreCase));
}
}
public string MyBinaries()
{
// The exceptation is that scripts calling this are included
// in a project in the solution and have already been deployed
// to a binaries folder
// Debug?
var debug = "debug";
var debugIndex = _workingDir.IndexOf(debug, StringComparison.CurrentCultureIgnoreCase);
if (debugIndex != -1)
{
return _workingDir.Substring(0, debugIndex + debug.Length);
}
// Release?
var release = "release";
var releaseIndex = _workingDir.IndexOf(release, StringComparison.CurrentCultureIgnoreCase);
if (releaseIndex != -1)
{
return _workingDir.Substring(0, releaseIndex + release.Length);
}
throw new Exception("Couldn't find binaries. Are you running from the binaries directory?");
}
public string PerfDirectory => Path.Combine(RoslynDirectory, "src", "Test", "Perf");
public string BinDirectory => Path.Combine(RoslynDirectory, "Binaries");
public string BinDebugDirectory => Path.Combine(BinDirectory, "Debug");
public string BinReleaseDirectory => Path.Combine(BinDirectory, "Release");
public string DebugCscPath => Path.Combine(BinDebugDirectory, "csc.exe");
public string ReleaseCscPath => Path.Combine(BinReleaseDirectory, "csc.exe");
public string DebugVbcPath => Path.Combine(BinDebugDirectory, "vbc.exe");
public string ReleaseVbcPath => Path.Combine(BinReleaseDirectory, "vbc.exe");
public string CPCDirectoryPath
{
get
{
return Environment.ExpandEnvironmentVariables(@"%SYSTEMDRIVE%\CPC");
}
}
public string GetViBenchToJsonExeFilePath => Path.Combine(CPCDirectoryPath, "ViBenchToJson.exe");
/// Downloads a zip from azure store and extracts it into
/// the ./temp directory.
///
/// If this current version has already been downloaded
/// and extracted, do nothing.
public void DownloadProject(string name, int version, ILogger logger)
{
var zipFileName = $"{name}.{version}.zip";
var zipPath = Path.Combine(MyTempDirectory, zipFileName);
// If we've already downloaded the zip, assume that it
// has been downloaded *and* extracted.
if (File.Exists(zipPath))
{
logger.Log($"Didn't download and extract {zipFileName} because one already exists.");
return;
}
// Remove all .zip files that were downloaded before.
foreach (var path in Directory.EnumerateFiles(MyTempDirectory, $"{name}.*.zip"))
{
logger.Log($"Removing old zip {path}");
File.Delete(path);
}
// Download zip file to temp directory
var downloadTarget = $"https://dotnetci.blob.core.windows.net/roslyn-perf/{zipFileName}";
logger.Log($"Downloading {downloadTarget}");
var client = new WebClient();
client.DownloadFile(downloadTarget, zipPath);
logger.Log($"Done Downloading");
// Extract to temp directory
logger.Log($"Extracting {zipPath} to {MyTempDirectory}");
ZipFile.ExtractToDirectory(zipPath, MyTempDirectory);
logger.Log($"Done Extracting");
}
}
}
using System.Collections.Generic;
using System.IO;
namespace Roslyn.Test.Performance.Utilities
{
public class ScenarioGenerator
{
private const string KernelProviderGuid = @"{9e814aad-3204-11d2-9a82-006008a86939}";
private string _fullPath = "scenarios.xml";
private List<string> _buffer;
public ScenarioGenerator(string scenarioFolderPath = "")
{
if (!string.IsNullOrEmpty(scenarioFolderPath))
{
_fullPath = Path.Combine(scenarioFolderPath, _fullPath);
}
Initialize();
}
public void Initialize()
{
// Delete any existing file
if (File.Exists(_fullPath))
{
File.Delete(_fullPath);
}
_buffer = new List<string>();
}
public void AddScenariosFileStart()
{
WriteToBuffer(@"<?xml version=""1.0"" encoding=""utf-8"" ?>");
WriteToBuffer(@"<scenarios>");
}
public void AddScenariosFileEnd()
{
WriteToBuffer(@"</scenarios>");
}
public void AddStartScenario(string scenarioName, string processName)
{
WriteToBuffer($@"<scenario name=""{scenarioName}"" process=""{processName}"">");
}
public void AddEndScenario()
{
WriteToBuffer(@"</scenario>");
}
public void AddStartEvent(int absoluteInstance)
{
WriteToBuffer($@"<from providerGuid=""{KernelProviderGuid}"" absoluteInstance=""{absoluteInstance}"" process=""csc"" eventName = ""Process/Start""/>");
}
public void AddEndEvent()
{
WriteToBuffer($@"<to providerGuid=""{KernelProviderGuid}"" absoluteInstance=""1"" process=""csc"" eventName=""Process/Stop""/>");
}
public void AddComment(string comment)
{
WriteToBuffer($@"<!-- {comment} -->");
}
public void AddLine(string line)
{
WriteToBuffer(line);
}
public void WriteToDisk()
{
File.WriteAllLines(_fullPath, _buffer);
}
private void WriteToBuffer(string content)
{
_buffer.Add(content);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Roslyn.Test.Performance.Utilities;
namespace Roslyn.Test.Performance.Utilities
{
public class TestUtilities
{
//
// Directory Locating Functions
//
public static string _myWorkingFile = null;
public static void InitUtilities([CallerFilePath] string sourceFilePath = "")
{
_myWorkingFile = sourceFilePath;
}
/// Returns the directory that houses the currenly executing script.
public static string MyWorkingDirectory()
{
if (_myWorkingFile == null)
{
throw new Exception("Tests must call InitUtilities before doing any path-dependent operations.");
}
return Directory.GetParent(_myWorkingFile).FullName;
}
/// Returns the directory that you can put artifacts like
/// etl traces or compiled binaries
public static string MyArtifactsDirectory()
{
var path = Path.Combine(MyWorkingDirectory(), "artifacts");
Directory.CreateDirectory(path);
return path;
}
public static string MyTempDirectory()
{
var workingDir = MyWorkingDirectory();
var path = Path.Combine(workingDir, "temp");
Directory.CreateDirectory(path);
return path;
}
public static string RoslynDirectory()
{
var workingDir = MyWorkingDirectory();
var binaryDebug = Path.Combine("Binaries", "Debug").ToString();
int binaryDebugIndex = workingDir.IndexOf(binaryDebug, StringComparison.OrdinalIgnoreCase);
if (binaryDebugIndex != -1)
{
return workingDir.Substring(0, binaryDebugIndex);
}
var binaryRelease= Path.Combine("Binaries", "Release").ToString();
return workingDir.Substring(0, workingDir.IndexOf(binaryRelease, StringComparison.OrdinalIgnoreCase));
}
public static string CscPath()
{
return Path.Combine(MyBinaries(), "csc.exe");
}
public static string MyBinaries()
{
var workingDir = MyWorkingDirectory();
// We may be a release or debug build
var debug = workingDir.IndexOf("debug", StringComparison.CurrentCultureIgnoreCase);
if (debug != -1)
return workingDir.Substring(0, debug + "debug".Length);
var release = workingDir.IndexOf("release", StringComparison.CurrentCultureIgnoreCase);
if (release != -1)
return workingDir.Substring(0, release + "release".Length);
throw new Exception("You are attempting to run performance test from the src directory. Run it from binaries");
}
public static string PerfDirectory()
{
return Path.Combine(RoslynDirectory(), "src", "Test", "Perf");
}
public static string BinDirectory()
{
return Path.Combine(RoslynDirectory(), "Binaries");
}
public static string BinDebugDirectory()
{
return Path.Combine(BinDirectory(), "Debug");
}
public static string BinReleaseDirectory()
{
return Path.Combine(BinDirectory(), "Release");
}
public static string DebugCscPath()
{
return Path.Combine(BinDebugDirectory(), "csc.exe");
}
public static string ReleaseCscPath()
{
return Path.Combine(BinReleaseDirectory(), "csc.exe");
}
public static string DebugVbcPath()
{
return Path.Combine(BinDebugDirectory(), "vbc.exe");
}
public static string ReleaseVbcPath()
{
return Path.Combine(BinReleaseDirectory(), "vbc.exe");
}
public static string GetCPCDirectoryPath()
{
return Environment.ExpandEnvironmentVariables(@"%SYSTEMDRIVE%\CPC");
}
public static string GetViBenchToJsonExeFilePath()
{
return Path.Combine(GetCPCDirectoryPath(), "ViBenchToJson.exe");
}
//
// Process spawning and error handling.
//
public class ProcessResult
{
public string ExecutablePath { get; set; }
public string Args { get; set; }
public int Code { get; set; }
public string StdOut { get; set; }
public string StdErr { get; set; }
public bool Failed => Code != 0;
public bool Succeeded => !Failed;
}
/// Shells out, and if the process fails, log the error
/// and quit the script.
public static void ShellOutVital(
string file,
string args,
bool verbose,
ILogger logger,
string workingDirectory = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var result = ShellOut(file, args, verbose, logger, workingDirectory, cancellationToken);
if (result.Failed)
{
LogProcessResult(result, logger);
throw new System.Exception("ShellOutVital Failed");
}
}
public static ProcessResult ShellOut(
string file,
string args,
bool verbose,
ILogger logger,
string workingDirectory = null,
CancellationToken cancellationToken = default(CancellationToken))
{
if (workingDirectory == null)
{
workingDirectory = MyWorkingDirectory();
}
var tcs = new TaskCompletionSource<ProcessResult>();
var startInfo = new ProcessStartInfo(file, args);
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.WorkingDirectory = workingDirectory;
var process = new Process
{
StartInfo = startInfo,
EnableRaisingEvents = true,
};
if (cancellationToken != default(CancellationToken))
{
cancellationToken.Register(() => process.Kill());
}
if (verbose)
{
logger.Log($"running \"{file}\" with arguments \"{args}\" from directory {workingDirectory}");
}
process.Start();
var output = new StringWriter();
var error = new StringWriter();
process.OutputDataReceived += (s, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
output.WriteLine(e.Data);
}
};
process.ErrorDataReceived += (s, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
error.WriteLine(e.Data);
}
};
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
return new ProcessResult
{
ExecutablePath = file,
Args = args,
Code = process.ExitCode,
StdOut = output.ToString(),
StdErr = error.ToString(),
};
}
public static string StdoutFrom(string program, bool verbose, ILogger logger, string args = "")
{
var result = ShellOut(program, args, verbose, logger);
if (result.Failed)
{
LogProcessResult(result, logger);
throw new Exception("Shelling out failed");
}
return result.StdOut.Trim();
}
/// Logs a message.
///
/// The actual implementation of this method may change depending on
/// if the script is being run standalone or through the test runner.
public static void Log(string info, string logFile)
{
System.Console.WriteLine(info);
if (logFile != null)
{
File.AppendAllText(logFile, info + System.Environment.NewLine);
}
}
/// Logs the result of a finished process
public static void LogProcessResult(ProcessResult result, ILogger logger)
{
logger.Log(String.Format("The process \"{0}\" {1} with code {2}",
$"{result.ExecutablePath} {result.Args}",
result.Failed ? "failed" : "succeeded",
result.Code));
logger.Log($"Standard Out:\n{result.StdOut}");
logger.Log($"\nStandard Error:\n{result.StdErr}");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Xml;
using static Roslyn.Test.Performance.Utilities.TestUtilities;
namespace Roslyn.Test.Performance.Utilities
{
public class Tools
{
/// Takes a consumptionTempResults file and converts to csv file
/// Each info contains the <ScenarioName, Metric Key, Metric value>
public static bool ConvertConsumptionToCsv(string source, string destination, string requiredMetricKey, ILogger logger)
{
logger.Log("Entering ConvertConsumptionToCsv");
if (!File.Exists(source))
{
logger.Log($"File {source} does not exist");
return false;
}
try
{
var result = new List<string>();
string currentScenarioName = null;
using (XmlReader xmlReader = XmlReader.Create(source))
{
while (xmlReader.Read())
{
if ((xmlReader.NodeType == XmlNodeType.Element))
{
if (xmlReader.Name.Equals("ScenarioResult"))
{
currentScenarioName = xmlReader.GetAttribute("Name");
// These are not test results
if (string.Equals(currentScenarioName, "..TestDiagnostics.."))
{
currentScenarioName = null;
}
}
else if (currentScenarioName != null && xmlReader.Name.Equals("CounterResult"))
{
var metricKey = xmlReader.GetAttribute("Name");
if (string.Equals(metricKey, requiredMetricKey))
{
var metricScale = xmlReader.GetAttribute("Units");
xmlReader.Read();
var metricvalue = xmlReader.Value;
result.Add($"{currentScenarioName}, {metricKey} ({metricScale}), {metricvalue}");
}
}
}
}
}
File.WriteAllLines(destination, result);
}
catch (System.Exception e)
{
System.Console.WriteLine(e.Message);
System.Console.WriteLine(e.StackTrace);
return false;
}
return true;
}
/// Gets a csv file with metrics and converts them to ViBench supported JSON file
public static string GetViBenchJsonFromCsv(string compilerTimeCsvFilePath, string execTimeCsvFilePath, string fileSizeCsvFilePath, bool verbose, ILogger logger)
{
logger.Log("Convert the csv to JSON using ViBench tool");
string branch = StdoutFrom("git", verbose, logger, "rev-parse --abbrev-ref HEAD");
string date = FirstLine(StdoutFrom("git", verbose, logger, $"show --format=\"%aI\" {branch} --"));
string hash = FirstLine(StdoutFrom("git", verbose, logger, $"show --format=\"%h\" {branch} --"));
string longHash = FirstLine(StdoutFrom("git", verbose, logger, $"show --format=\"%H\" {branch} --"));
string username = StdoutFrom("whoami", verbose, logger);
string machineName = StdoutFrom("hostname", verbose, logger);
string architecture = System.Environment.Is64BitOperatingSystem ? "x86-64" : "x86";
// File locations
string outJson = Path.Combine(GetCPCDirectoryPath(), $"Roslyn-{longHash}.json");
// ViBenchToJson does not like empty csv files.
string files = "";
if (compilerTimeCsvFilePath != null && new FileInfo(compilerTimeCsvFilePath).Length != 0)
{
files += $@"compilertime:""{compilerTimeCsvFilePath}""";
}
if (execTimeCsvFilePath != null && new FileInfo(execTimeCsvFilePath).Length != 0)
{
files += $@"exectime:""{execTimeCsvFilePath}""";
}
if (fileSizeCsvFilePath != null && new FileInfo(fileSizeCsvFilePath).Length != 0)
{
files += $@"filesize:""{fileSizeCsvFilePath}""";
}
string arguments = $@"
{files}
jobName:""RoslynPerf-{hash}-{date}""
jobGroupName:""Roslyn-{branch}""
jobTypeName:""official""
buildInfoName:""{date}-{branch}-{hash}""
configName:""Default Configuration""
machinePoolName:""4-core-windows""
architectureName:""{architecture}""
manufacturerName:""unknown-manufacturer""
microarchName:""unknown-microarch""
userName:""{username}""
userAlias:""{username}""
osInfoName:""Windows""
machineName:""{machineName}""
buildNumber:""{date}-{hash}""
/json:""{outJson}""
";
arguments = arguments.Replace("\r\n", " ").Replace("\n", "");
ShellOutVital(Path.Combine(GetCPCDirectoryPath(), "ViBenchToJson.exe"), arguments, verbose, logger);
return outJson;
}
public static string FirstLine(string input)
{
return input.Split(new[] { "\r\n", "\r", "\n" }, System.StringSplitOptions.None)[0];
}
public static void UploadTraces(string sourceFolderPath, string destinationFolderPath, ILogger logger)
{
logger.Log("Uploading traces");
if (Directory.Exists(sourceFolderPath))
{
var directoriesToUpload = new DirectoryInfo(sourceFolderPath).GetDirectories("DataBackup*");
if (directoriesToUpload.Count() == 0)
{
logger.Log($"There are no trace directory starting with DataBackup in {sourceFolderPath}");
return;
}
var perfResultDestinationFolderName = string.Format("PerfResults-{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now);
var destination = Path.Combine(destinationFolderPath, perfResultDestinationFolderName);
foreach (var directoryToUpload in directoriesToUpload)
{
var destinationDataBackupDirectory = Path.Combine(destination, directoryToUpload.Name);
if (Directory.Exists(destinationDataBackupDirectory))
{
Directory.CreateDirectory(destinationDataBackupDirectory);
}
CopyDirectory(directoryToUpload.FullName, logger, destinationDataBackupDirectory);
}
foreach (var file in new DirectoryInfo(sourceFolderPath).GetFiles().Where(f => f.Name.StartsWith("ConsumptionTemp", StringComparison.OrdinalIgnoreCase) || f.Name.StartsWith("Roslyn-", StringComparison.OrdinalIgnoreCase)))
{
File.Copy(file.FullName, Path.Combine(destination, file.Name));
}
}
else
{
logger.Log($"sourceFolderPath: {sourceFolderPath} does not exist");
}
}
public static void CopyDirectory(string source, ILogger logger, string destination, string argument = @"/mir")
{
var result = ShellOut("Robocopy", $"{argument} {source} {destination}", verbose: true, logger: logger);
// Robocopy has a success exit code from 0 - 7
if (result.Code > 7)
{
throw new IOException($"Failed to copy \"{source}\" to \"{destination}\".");
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Roslyn.Test.Performance.Utilities.TestUtilities;
namespace Roslyn.Test.Performance.Utilities
{
public class TraceManager : ITraceManager
{
private readonly ScenarioGenerator _scenarioGenerator;
private readonly string _cpcPath;
private readonly bool _verbose;
private readonly ILogger _logger;
private int _startEventAbsoluteInstance = 1;
private int _stopEventAbsoluteInstance = 1;
public TraceManager(
string cpcPath,
string scenarioPath,
bool verbose,
ILogger logger) : base()
{
_cpcPath = cpcPath;
_scenarioGenerator = new ScenarioGenerator(scenarioPath);
_verbose = verbose;
_logger = logger;
// Since TraceManager.Setup() and few other functions use ShellOutVital,
// which requires the TestUtilities.InitUtilities() to be called
InitUtilities();
}
public bool HasWarmUpIteration
{
get
{
return true;
}
}
// Cleanup the results directory and files before every run
public void Initialize()
{
var consumptionTempResultsPath = Path.Combine(GetCPCDirectoryPath(), "ConsumptionTempResults.xml");
if (File.Exists(consumptionTempResultsPath))
{
File.Delete(consumptionTempResultsPath);
}
if (Directory.Exists(GetCPCDirectoryPath()))
{
var databackDirectories = Directory.GetDirectories(GetCPCDirectoryPath(), "DataBackup*", SearchOption.AllDirectories);
foreach (var databackDirectory in databackDirectories)
{
Directory.Delete(databackDirectory, true);
}
}
}
public void Setup()
{
ShellOutVital(_cpcPath, "/Setup /DisableArchive", _verbose, _logger);
}
public void Start()
{
ShellOutVital(_cpcPath, "/Start /DisableArchive", _verbose, _logger);
}
public void Stop()
{
var scenariosXmlPath = Path.Combine(GetCPCDirectoryPath(), "scenarios.xml");
var consumptionTempResultsPath = Path.Combine(GetCPCDirectoryPath(), "ConsumptionTempResults.xml");
ShellOutVital(_cpcPath, $"/Stop /DisableArchive /ScenarioPath=\"{scenariosXmlPath}\" /ConsumptionTempResultsPath=\"{consumptionTempResultsPath}\"", _verbose, _logger);
}
public void Cleanup()
{
ShellOutVital(_cpcPath, "/Cleanup /DisableArchive", _verbose, _logger);
}
public void StartScenarios()
{
_scenarioGenerator.AddScenariosFileStart();
}
public void StartScenario(string scenarioName, string processName)
{
_scenarioGenerator.AddStartScenario(scenarioName, processName);
}
public void StartEvent()
{
_scenarioGenerator.AddStartEvent(_startEventAbsoluteInstance);
_startEventAbsoluteInstance++;
}
public void EndEvent()
{
_scenarioGenerator.AddEndEvent();
_stopEventAbsoluteInstance++;
}
public void EndScenario()
{
_scenarioGenerator.AddEndScenario();
}
public void EndScenarios()
{
_scenarioGenerator.AddScenariosFileEnd();
}
public void WriteScenarios(string[] scenarios)
{
foreach (var line in scenarios)
{
_scenarioGenerator.AddLine(line);
}
}
public void WriteScenariosFileToDisk()
{
_scenarioGenerator.WriteToDisk();
}
public void ResetScenarioGenerator()
{
_scenarioGenerator.Initialize();
_startEventAbsoluteInstance = 1;
_stopEventAbsoluteInstance = 1;
}
}
}
using System.IO;
namespace Roslyn.Test.Performance.Utilities
{
public class TraceManagerFactory
{
public static ITraceManager GetTraceManager()
{
var cpcFullPath = Path.Combine(TestUtilities.GetCPCDirectoryPath(), "CPC.exe");
var scenarioPath = TestUtilities.GetCPCDirectoryPath();
if (File.Exists(cpcFullPath))
{
return new TraceManager(cpcFullPath, scenarioPath, verbose: false, logger: null);
}
else
{
return new NoOpTraceManager();
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#load "test_util.csx"
#r "../infra/bin/Microsoft.CodeAnalysis.Scripting.dll"
#r "../infra/bin/Microsoft.CodeAnalysis.CSharp.Scripting.dll"
#r "../../Microsoft.CodeAnalysis.Scripting.dll"
#r "../../Microsoft.CodeAnalysis.CSharp.Scripting.dll"
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.CSharp.Scripting;
......
using System.Collections.Generic;
using System.IO;
public class ScenarioGenerator
{
private const string KernelProviderGuid = @"{9e814aad-3204-11d2-9a82-006008a86939}";
private string _fullPath = "scenarios.xml";
private List<string> _buffer;
public ScenarioGenerator(string scenarioFolderPath = "")
{
if (!string.IsNullOrEmpty(scenarioFolderPath))
{
_fullPath = Path.Combine(scenarioFolderPath, _fullPath);
}
Initialize();
}
public void Initialize()
{
// Delete any existing file
if (File.Exists(_fullPath))
{
File.Delete(_fullPath);
}
_buffer = new List<string>();
}
public void AddScenariosFileStart()
{
WriteToBuffer(@"<?xml version=""1.0"" encoding=""utf-8"" ?>");
WriteToBuffer(@"<scenarios>");
}
public void AddScenariosFileEnd()
{
WriteToBuffer(@"</scenarios>");
}
public void AddStartScenario(string scenarioName, string processName)
{
WriteToBuffer($@"<scenario name=""{scenarioName}"" process=""{processName}"">");
}
public void AddEndScenario()
{
WriteToBuffer(@"</scenario>");
}
public void AddStartEvent(int absoluteInstance)
{
WriteToBuffer($@"<from providerGuid=""{KernelProviderGuid}"" absoluteInstance=""{absoluteInstance}"" process=""csc"" eventName=""Process/Start""/>");
}
public void AddEndEvent()
{
WriteToBuffer($@"<to providerGuid=""{KernelProviderGuid}"" absoluteInstance=""1"" process=""csc"" eventName=""Process/Stop""/>");
}
public void AddComment(string comment)
{
WriteToBuffer($@"<!-- {comment} -->");
}
public void AddLine(string line)
{
WriteToBuffer(line);
}
public void WriteToDisk()
{
File.WriteAllLines(_fullPath, _buffer);
}
private void WriteToBuffer(string content)
{
_buffer.Add(content);
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#r "System.IO.Compression.FileSystem"
#r "../../Roslyn.Test.Performance.Utilities.dll"
using System.IO;
using System.IO.Compression;
......@@ -13,168 +14,8 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Net;
using System.Globalization;
using Roslyn.Test.Performance.Utilities;
class RelativeDirectory
{
string _workingDir;
public RelativeDirectory([CallerFilePath] string workingFile = "")
{
_workingDir = Directory.GetParent(workingFile).FullName;
}
public string MyWorkingDirectory => _workingDir;
/// Returns the directory that you can put artifacts like
/// etl traces or compiled binaries
public string MyArtifactsDirectory
{
get
{
var path = Path.Combine(MyWorkingDirectory, "artifacts");
Directory.CreateDirectory(path);
return path;
}
}
public string MyTempDirectory
{
get {
var workingDir = MyWorkingDirectory;
var path = Path.Combine(workingDir, "temp");
Directory.CreateDirectory(path);
return path;
}
}
public string RoslynDirectory
{
get {
// In Windows, our path could be reported as "src/Test/Perf" (as it should),
// or "src/TeSt/PeRf" which is completely insane.
var workingDir = MyWorkingDirectory;
var srcTestPerf = Path.Combine("src", "Test", "Perf").ToString();
CompareInfo inv = CultureInfo.InvariantCulture.CompareInfo;
var idx = inv.IndexOf(workingDir, srcTestPerf, CompareOptions.IgnoreCase);
return workingDir.Substring(0, idx);
}
}
public string MyBinaries()
{
// The exceptation is that scripts calling this are included
// in a project in the solution and have already been deployed
// to a binaries folder
// Debug?
var debug = "debug";
var debugIndex = _workingDir.IndexOf(debug, StringComparison.CurrentCultureIgnoreCase);
if (debugIndex != -1)
{
return _workingDir.Substring(0, debugIndex + debug.Length);
}
// Release?
var release = "release";
var releaseIndex = _workingDir.IndexOf(release, StringComparison.CurrentCultureIgnoreCase);
if (releaseIndex != -1)
{
return _workingDir.Substring(0, releaseIndex + release.Length);
}
throw new Exception("Couldn't find binaries. Are you running from the binaries directory?");
}
public string PerfDirectory => Path.Combine(RoslynDirectory, "src", "Test", "Perf");
public string BinDirectory => Path.Combine(RoslynDirectory, "Binaries");
public string BinDebugDirectory => Path.Combine(BinDirectory, "Debug");
public string BinReleaseDirectory => Path.Combine(BinDirectory, "Release");
public string DebugCscPath => Path.Combine(BinDebugDirectory, "csc.exe");
public string ReleaseCscPath => Path.Combine(BinReleaseDirectory, "csc.exe");
public string DebugVbcPath => Path.Combine(BinDebugDirectory, "vbc.exe");
public string ReleaseVbcPath => Path.Combine(BinReleaseDirectory, "vbc.exe");
public string CPCDirectoryPath
{
get {
return Environment.ExpandEnvironmentVariables(@"%SYSTEMDRIVE%\CPC");
}
}
public string GetViBenchToJsonExeFilePath => Path.Combine(CPCDirectoryPath, "ViBenchToJson.exe");
/// Downloads a zip from azure store and extracts it into
/// the ./temp directory.
///
/// If this current version has already been downloaded
/// and extracted, do nothing.
public void DownloadProject(string name, int version)
{
var zipFileName = $"{name}.{version}.zip";
var zipPath = Path.Combine(MyTempDirectory, zipFileName);
// If we've already downloaded the zip, assume that it
// has been downloaded *and* extracted.
if (File.Exists(zipPath))
{
Log($"Didn't download and extract {zipFileName} because one already exists.");
return;
}
// Remove all .zip files that were downloaded before.
foreach (var path in Directory.EnumerateFiles(MyTempDirectory, $"{name}.*.zip"))
{
Log($"Removing old zip {path}");
File.Delete(path);
}
// Download zip file to temp directory
var downloadTarget = $"https://dotnetci.blob.core.windows.net/roslyn-perf/{zipFileName}";
Log($"Downloading {downloadTarget}");
var client = new WebClient();
client.DownloadFile(downloadTarget, zipPath);
Log($"Done Downloading");
// Extract to temp directory
Log($"Extracting {zipPath} to {MyTempDirectory}");
ZipFile.ExtractToDirectory(zipPath, MyTempDirectory);
Log($"Done Extracting");
}
}
abstract class PerfTest: RelativeDirectory {
private List<Tuple<int, string, object>> _metrics = new List<Tuple<int, string, object>>();
public PerfTest([CallerFilePath] string workingFile = ""): base(workingFile) {}
/// Reports a metric to be recorded in the performance monitor.
protected void Report(ReportKind reportKind, string description, object value)
{
_metrics.Add(Tuple.Create((int) reportKind, description, value));
Log(description + ": " + value.ToString());
}
public abstract bool ProvidesScenarios { get; }
public abstract string[] GetScenarios();
public abstract void Setup();
public abstract void Test();
public abstract int Iterations { get; }
public abstract string Name { get; }
public abstract string MeasuredProc { get; }
}
// This is a workaround for not being able to return
// arbitrary objects from a csi script while not being
// run under the runner script.
static PerfTest[] resultTests = null;
static void TestThisPlease(params PerfTest[] tests)
......@@ -240,22 +81,6 @@ class ProcessResult
public bool Succeeded => !Failed;
}
/// Shells out, and if the process fails, log the error
/// and quit the script.
static void ShellOutVital(
string file,
string args,
string workingDirectory = null,
CancellationToken? cancelationToken = null)
{
var result = ShellOut(file, args, workingDirectory, cancelationToken);
if (result.Failed)
{
LogProcessResult(result);
throw new System.Exception("ShellOutVital Failed");
}
}
static ProcessResult ShellOut(
string file,
string args,
......@@ -334,39 +159,6 @@ string StdoutFrom(string program, string args = "", string workingDirectory = nu
return result.StdOut.Trim();
}
//
// Timing and Testing
//
static long WalltimeMs(Action action)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
action();
return stopwatch.ElapsedMilliseconds;
}
static long WalltimeMs<R>(Func<R> action)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
action();
return stopwatch.ElapsedMilliseconds;
}
//
// Reporting and logging
//
enum ReportKind: int {
CompileTime,
RunTime,
FileSize,
}
/// A list of
static var Metrics = new List<Tuple<int, string, object>>();
/// Logs a message.
///
/// The actual implementation of this method may change depending on
......
// ShellOut()
#load "test_util.csx"
using System;
......@@ -6,165 +7,6 @@ using System.IO;
using System.Linq;
using System.Xml;
/// Takes a consumptionTempResults file and converts to csv file
/// Each info contains the <ScenarioName, Metric Key, Metric value>
bool ConvertConsumptionToCsv(string source, string destination, string requiredMetricKey)
{
Log("Entering ConvertConsumptionToCsv");
if (!File.Exists(source))
{
Log($"File {source} does not exist");
return false;
}
try
{
var result = new List<string>();
string currentScenarioName = null;
using (XmlReader xmlReader = XmlReader.Create(source))
{
while (xmlReader.Read())
{
if ((xmlReader.NodeType == XmlNodeType.Element))
{
if (xmlReader.Name.Equals("ScenarioResult"))
{
currentScenarioName = xmlReader.GetAttribute("Name");
currentScenarioName = new string(currentScenarioName.TakeWhile(c => !Char.IsDigit(c)).ToArray());
// These are not test results
if (string.Equals(currentScenarioName, "..TestDiagnostics.."))
{
currentScenarioName = null;
}
}
else if (currentScenarioName != null && xmlReader.Name.Equals("CounterResult"))
{
var metricKey = xmlReader.GetAttribute("Name");
if (string.Equals(metricKey, requiredMetricKey))
{
var metricScale = xmlReader.GetAttribute("Units");
xmlReader.Read();
var metricvalue = xmlReader.Value;
result.Add($"{currentScenarioName}, {metricKey} ({metricScale}), {metricvalue}");
}
}
}
}
}
File.WriteAllLines(destination, result);
}
catch(System.Exception e)
{
System.Console.WriteLine(e.Message);
System.Console.WriteLine(e.StackTrace);
return false;
}
return true;
}
/// Gets a csv file with metrics and converts them to ViBench supported JSON file
string GetViBenchJsonFromCsv(string compilerTimeCsvFilePath, string execTimeCsvFilePath, string fileSizeCsvFilePath)
{
var directoryUtil = new RelativeDirectory();
Log("Convert the csv to JSON using ViBench tool");
string branch = StdoutFrom("git", "rev-parse --abbrev-ref HEAD");
string date = FirstLine(StdoutFrom("git", $"show --format=\"%aI\" {branch} --"));
string hash = FirstLine(StdoutFrom("git", $"show --format=\"%h\" {branch} --"));
string longHash = FirstLine(StdoutFrom("git", $"show --format=\"%H\" {branch} --"));
string username = StdoutFrom("whoami");
string machineName = StdoutFrom("hostname");
string architecture = System.Environment.Is64BitOperatingSystem ? "x86-64" : "x86";
// File locations
string outJson = Path.Combine(directoryUtil.CPCDirectoryPath, $"Roslyn-{longHash}.json");
// ViBenchToJson does not like empty csv files.
string files = "";
if (compilerTimeCsvFilePath != null && new FileInfo(compilerTimeCsvFilePath).Length != 0)
{
files += $@"compilertime:""{compilerTimeCsvFilePath}""";
}
if (execTimeCsvFilePath != null && new FileInfo(execTimeCsvFilePath).Length != 0)
{
files += $@"exectime:""{execTimeCsvFilePath}""";
}
if (fileSizeCsvFilePath != null && new FileInfo(fileSizeCsvFilePath).Length != 0)
{
files += $@"filesize:""{fileSizeCsvFilePath}""";
}
string arguments = $@"
{files}
jobName:""RoslynPerf-{hash}-{date}""
jobGroupName:""Roslyn-{branch}""
jobTypeName:""official""
buildInfoName:""{date}-{branch}-{hash}""
configName:""Default Configuration""
machinePoolName:""4-core-windows""
architectureName:""{architecture}""
manufacturerName:""unknown-manufacturer""
microarchName:""unknown-microarch""
userName:""{username}""
userAlias:""{username}""
osInfoName:""Windows""
machineName:""{machineName}""
buildNumber:""{date}-{hash}""
/json:""{outJson}""
";
arguments = arguments.Replace("\r\n", " ").Replace("\n", "");
ShellOutVital(Path.Combine(directoryUtil.CPCDirectoryPath, "ViBenchToJson.exe"), arguments);
return outJson;
}
string FirstLine(string input)
{
return input.Split(new[] {"\r\n", "\r", "\n"}, System.StringSplitOptions.None)[0];
}
void UploadTraces(string sourceFolderPath, string destinationFolderPath)
{
Log("Uploading traces");
if (Directory.Exists(sourceFolderPath))
{
var directoriesToUpload = new DirectoryInfo(sourceFolderPath).GetDirectories("DataBackup*");
if (directoriesToUpload.Count() == 0)
{
Log($"There are no trace directory starting with DataBackup in {sourceFolderPath}");
return;
}
var perfResultDestinationFolderName = string.Format("PerfResults-{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now);
var destination = Path.Combine(destinationFolderPath, perfResultDestinationFolderName);
foreach (var directoryToUpload in directoriesToUpload)
{
var destinationDataBackupDirectory = Path.Combine(destination, directoryToUpload.Name);
if (Directory.Exists(destinationDataBackupDirectory))
{
Directory.CreateDirectory(destinationDataBackupDirectory);
}
CopyDirectory(directoryToUpload.FullName, destinationDataBackupDirectory);
}
foreach(var file in new DirectoryInfo(sourceFolderPath).GetFiles().Where(f => f.Name.StartsWith("ConsumptionTemp", StringComparison.OrdinalIgnoreCase) || f.Name.StartsWith("Roslyn-", StringComparison.OrdinalIgnoreCase)))
{
File.Copy(file.FullName, Path.Combine(destination, file.Name));
}
}
else
{
Log($"sourceFolderPath: {sourceFolderPath} does not exist");
}
}
void CopyDirectory(string source, string destination, string argument = @"/mir")
{
var result = ShellOut("Robocopy", $"{argument} {source} {destination}", "");
......
#load "scenario_generator_util.csx"
#load "test_util.csx"
using System;
using System.Diagnostics;
using System.IO;
interface ITraceManager
{
bool HasWarmUpIteration { get; }
void Initialize();
void Cleanup();
void EndEvent();
void EndScenario();
void EndScenarios();
void ResetScenarioGenerator();
void Setup();
void Start();
void StartEvent();
void StartScenario(string scenarioName, string processName);
void StartScenarios();
void Stop();
void WriteScenarios(string[] scenarios);
void WriteScenariosFileToDisk();
}
class TraceManagerFactory
{
public static ITraceManager GetTraceManager()
{
var directoryInfo = new RelativeDirectory();
var cpcFullPath = Path.Combine(directoryInfo.CPCDirectoryPath, "CPC.exe");
var scenarioPath = directoryInfo.CPCDirectoryPath;
if (File.Exists(cpcFullPath))
{
return new TraceManager(cpcFullPath, scenarioPath);
}
else
{
return new NoOpTraceManager();
}
}
}
/// This is the Trace Manager that will be used when there is no CPC found in the machine
/// All operations are NoOp
class NoOpTraceManager : ITraceManager
{
public NoOpTraceManager()
{
}
public bool HasWarmUpIteration
{
get
{
return false;
}
}
public void Initialize()
{
}
public void Cleanup()
{
}
public void EndEvent()
{
}
public void EndScenario()
{
}
public void EndScenarios()
{
}
public void ResetScenarioGenerator()
{
}
public void Setup()
{
}
public void Start()
{
}
public void StartEvent()
{
}
public void StartScenarios()
{
}
public void StartScenario(string scenarioName, string processName)
{
}
public void Stop()
{
}
public void WriteScenarios(string[] scenarios)
{
}
public void WriteScenariosFileToDisk()
{
}
}
class TraceManager: ITraceManager
{
private readonly ScenarioGenerator _scenarioGenerator;
private readonly string _cpcPath;
private RelativeDirectory _directoryInfo = new RelativeDirectory();
private int _startEventAbsoluteInstance = 1;
private int _stopEventAbsoluteInstance = 1;
public TraceManager(
string cpcPath,
string scenarioPath): base()
{
_cpcPath = cpcPath;
_scenarioGenerator = new ScenarioGenerator(scenarioPath);
}
public bool HasWarmUpIteration
{
get
{
return true;
}
}
// Cleanup the results directory and files before every run
public void Initialize()
{
var consumptionTempResultsPath = Path.Combine(_directoryInfo.CPCDirectoryPath, "ConsumptionTempResults.xml");
if (File.Exists(consumptionTempResultsPath))
{
File.Delete(consumptionTempResultsPath);
}
if (Directory.Exists(_directoryInfo.CPCDirectoryPath))
{
var databackDirectories = Directory.GetDirectories(_directoryInfo.CPCDirectoryPath, "DataBackup*", SearchOption.AllDirectories);
foreach (var databackDirectory in databackDirectories)
{
Directory.Delete(databackDirectory, true);
}
}
}
public void Setup()
{
ShellOutVital(_cpcPath, "/Setup /DisableArchive");
}
public void Start()
{
ShellOutVital(_cpcPath, "/Start /DisableArchive");
}
public void Stop()
{
var scenariosXmlPath = Path.Combine(_directoryInfo.CPCDirectoryPath, "scenarios.xml");
var consumptionTempResultsPath = Path.Combine(_directoryInfo.CPCDirectoryPath, "ConsumptionTempResults.xml");
ShellOutVital(_cpcPath, $"/Stop /DisableArchive /ScenarioPath=\"{scenariosXmlPath}\" /ConsumptionTempResultsPath=\"{consumptionTempResultsPath}\"");
}
public void Cleanup()
{
ShellOutVital(_cpcPath, "/Cleanup /DisableArchive");
}
public void StartScenarios()
{
_scenarioGenerator.AddScenariosFileStart();
}
public void StartScenario(string scenarioName, string processName)
{
_scenarioGenerator.AddStartScenario(scenarioName, processName);
}
public void StartEvent()
{
_scenarioGenerator.AddStartEvent(_startEventAbsoluteInstance);
_startEventAbsoluteInstance++;
}
public void EndEvent()
{
_scenarioGenerator.AddEndEvent();
_stopEventAbsoluteInstance++;
}
public void EndScenario()
{
_scenarioGenerator.AddEndScenario();
}
public void EndScenarios()
{
_scenarioGenerator.AddScenariosFileEnd();
}
public void WriteScenarios(string[] scenarios)
{
foreach (var line in scenarios)
{
_scenarioGenerator.AddLine(line);
}
}
public void WriteScenariosFileToDisk()
{
_scenarioGenerator.WriteToDisk();
}
public void ResetScenarioGenerator()
{
_scenarioGenerator.Initialize();
_startEventAbsoluteInstance = 1;
_stopEventAbsoluteInstance = 1;
}
}
......@@ -9,8 +9,8 @@
<ProjectGuid>{DA0D2A70-A2F9-4654-A99A-3227EDF54FF1}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PerformanceTesting</RootNamespace>
<AssemblyName>PerformanceTesting</AssemblyName>
<RootNamespace>Roslyn.Test.Performance</RootNamespace>
<AssemblyName>Roslyn.Test.Performance.Utilities</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
......@@ -24,7 +24,8 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>CS2008</NoWarn>
<NoWarn>
</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
......@@ -41,6 +42,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
......@@ -49,11 +51,13 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Folder Include="Perf\projects\csharp\" />
<Folder Include="Perf\temp\cpc\" />
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<Compile Include="Perf\util\Logger.cs" />
<Compile Include="Perf\util\PerfTestBase.cs" />
<Compile Include="Perf\util\RelativeDirectory.cs" />
<Compile Include="Perf\util\Tools.cs" />
<None Include="Perf\.gitignore" />
<Content Include="Perf\bootstrap.bat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
......@@ -82,9 +86,6 @@
<Content Include="Perf\infra\run_and_report.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\infra\transform_csv.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\infra\uninstall.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
......@@ -94,33 +95,21 @@
<Content Include="Perf\runner.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="Perf\temp\compiler_time.csv" />
<None Include="Perf\temp\file_size.csv" />
<None Include="Perf\temp\run_time.csv" />
<Content Include="Perf\tests\csharp\csharp_compiler.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\tests\helloworld\hello_world.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\util\Download_util.csx">
<None Include="Perf\tests\csharp\csharp_compiler.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</None>
<Content Include="Perf\util\runner_util.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\util\scenario_generator_util.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\util\test_util.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\util\tools_util.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\util\trace_manager_util.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Perf\infra\install_vsixes.csx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
......@@ -130,6 +119,15 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Include="Perf\util\ILogger.cs" />
<Compile Include="Perf\util\ITraceManager.cs" />
<Compile Include="Perf\util\NoOpTraceManager.cs" />
<Compile Include="Perf\util\ScenarioGenerator.cs"/>
<Compile Include="Perf\util\TestUtilities.cs" />
<Compile Include="Perf\util\TraceManager.cs" />
<Compile Include="Perf\util\TraceManagerFactory.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
......
......@@ -27,12 +27,6 @@
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonCoreClrRuntime\CommonCoreClrRuntime.csproj">
<Project>{1b665337-9d6a-451a-aeac-f7bf1af95ffb}</Project>
<Name>CommonCoreClrRuntime</Name>
</ProjectReference>
</ItemGroup>
<ImportGroup Label="Targets">
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
......
......@@ -151,9 +151,11 @@
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleSet />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleSet />
</PropertyGroup>
<PropertyGroup>
<StartAction>Program</StartAction>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册