Skip to content

Commit

Permalink
Merge pull request #101 from cake-build/feature/omnisharp-mono-integr…
Browse files Browse the repository at this point in the history
…ation-tests

Use OmniSharp's embedded Mono version for integration tests.
  • Loading branch information
bjorkstromm authored May 30, 2018
2 parents e124c00 + e7ae351 commit d222586
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,5 @@ tools/**
!tools/packages.config
BuildArtifacts/
tests/integration/tools/
tests/integration/mono/
.dotnet/
61 changes: 59 additions & 2 deletions setup.cake
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ ToolSettings.SetToolSettings(context: Context,

var binArtifactPath = BuildParameters.Paths.Directories.PublishedApplications.Combine("Cake.Bakery/net461");
var zipArtifactsPath = BuildParameters.Paths.Directories.Build.Combine("Packages/Zip");
var omnisharpBaseDownloadURL = "https://omnisharpdownload.blob.core.windows.net/ext";
var omnisharpMonoRuntimeMacOS = $"{omnisharpBaseDownloadURL}/mono.osx-5.12.0.226.zip";
var omnisharpMonoRuntimeLinux32= $"{omnisharpBaseDownloadURL}/mono.linux-x86-5.12.0.226.zip";
var omnisharpMonoRuntimeLinux64= $"{omnisharpBaseDownloadURL}/mono.linux-x86_64-5.12.0.226.zip";
var omnisharpMonoFramework = $"{omnisharpBaseDownloadURL}/framework-5.12.0.226.zip";

Task("Copy-License")
.IsDependentOn("DotNetCore-Build")
Expand Down Expand Up @@ -155,19 +160,71 @@ Task("Init-Integration-Tests")
"./tests/integration/packages");
});

Task("Download-Mono-Assets")
.WithCriteria(() => !BuildParameters.IsRunningOnWindows)
.Does(() =>
{
CleanDirectories(new [] {
"./tests/integration/mono",
"./tests/integration/mono/framework"
});
string downloadUrl = null;
switch(Context.Environment.Platform.Family)
{
case PlatformFamily.OSX:
downloadUrl = omnisharpMonoRuntimeMacOS;
break;
case PlatformFamily.Linux:
downloadUrl = Context.Environment.Platform.Is64Bit ?
omnisharpMonoRuntimeLinux64 :
omnisharpMonoRuntimeLinux32;
break;
default:
break;
}
if (string.IsNullOrEmpty(downloadUrl))
{
return;
}
var zipFile = DownloadFile(downloadUrl);
Unzip(zipFile, "./tests/integration/mono");
zipFile = DownloadFile(omnisharpMonoFramework);
Unzip(zipFile, "./tests/integration/mono/framework");
StartProcess("chmod", "u+x ./tests/integration/mono/run");
var monoExec = GetFiles("./tests/integration/mono/bin/mono.*").First().FullPath;
StartProcess("chmod", $"u+x {monoExec}");
});

Task("Run-Bakery-Integration-Tests")
.IsDependentOn("Init-Integration-Tests")
.IsDependentOn("Download-Mono-Assets")
.IsDependeeOf("AppVeyor")
.IsDependeeOf("Default")
.Does(() =>
{
CakeExecuteScript("./tests/integration/tests.cake", new CakeSettings {
var settings = new CakeSettings {
Verbosity = Context.Log.Verbosity,
WorkingDirectory = "./tests/integration/",
Arguments = new Dictionary<string, string> {
{ "NuGet_Source", MakeAbsolute(new DirectoryPath("./tests/integration/packages")).FullPath }
}
});
};
CakeExecuteScript("./tests/integration/tests.cake", settings);
// If not running on Windows, also run with OmniSharp Mono.
if (!BuildParameters.IsRunningOnWindows)
{
settings.ArgumentCustomization = args => args.Prepend($"--no-omnisharp {MakeAbsolute(Context.Environment.ApplicationRoot).CombineWithFilePath("Cake.exe")}");
settings.ToolPath = "./tests/integration/mono/run";
CakeExecuteScript("./tests/integration/tests.cake", settings);
}
});

Task("Sign-Binaries")
Expand Down
119 changes: 115 additions & 4 deletions tests/integration/tests.cake
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,112 @@ using Cake.Scripting.Transport.Tcp.Client;
using Microsoft.Extensions.Logging;
using Xunit;
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
if (args.Name.StartsWith("System.Runtime.InteropServices.RuntimeInformation"))
{
return System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"));
}
return null;
};
class MonoScriptGenerationProcess : IScriptGenerationProcess
{
private readonly ILogger _logger;
private Process _process;
public MonoScriptGenerationProcess(string serverExecutablePath, ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger(typeof(MonoScriptGenerationProcess));
ServerExecutablePath = serverExecutablePath;
}
public void Dispose()
{
_process?.Kill();
_process?.WaitForExit();
_process?.Dispose();
}
public void Start(int port, string workingDirectory)
{
var (fileName, arguments) = GetMonoRuntime();
if (fileName == null)
{
// Something went wrong figurint out mono runtime,
// try executing exe and let mono handle it.
fileName = ServerExecutablePath;
}
else
{
// Else set exe as argument
arguments += $"\"{ServerExecutablePath}\"";
}
arguments += $" --port={port}";
if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
{
arguments += " --verbose";
}
var startInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
WorkingDirectory = workingDirectory,
};
_logger.LogDebug("Starting \"{fileName}\" with arguments \"{arguments}\"", startInfo.FileName, startInfo.Arguments);
_process = Process.Start(startInfo);
_process.ErrorDataReceived += (s, e) =>
{
if (e.Data != null)
{
_logger.LogError(e.Data);
}
};
_process.BeginErrorReadLine();
_process.OutputDataReceived += (s, e) =>
{
if (e.Data != null)
{
_logger.LogDebug(e.Data);
}
};
_process.BeginOutputReadLine();
}

private (string, string) GetMonoRuntime()
{
// Check using ps how process was started.
var startInfo = new ProcessStartInfo
{
FileName = "sh",
Arguments = $"-c \"ps -fp {Process.GetCurrentProcess().Id} | tail -n1 | awk '{{print $8}}'\"",
RedirectStandardOutput = true,
UseShellExecute = false,
};
var process = Process.Start(startInfo);
var runtime = process.StandardOutput.ReadToEnd().TrimEnd('\n');
process.WaitForExit();

// If OmniSharp bundled Mono runtime, use bootstrap script.
var script = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(runtime), "../run");
if (System.IO.File.Exists(script))
{
return (script, "--no-omnisharp ");
}

// Else use mono directly.
return (runtime, string.Empty);
}

public string ServerExecutablePath { get; set; }
}

// Globals
IScriptGenerationService service;
const string CakeHelloWorldFile = "helloworld.cake";
Expand Down Expand Up @@ -52,10 +158,15 @@ Setup((context) => {
var loggerFactory = new LoggerFactory()
.AddConsole(Microsoft.Extensions.Logging.LogLevel.Debug);
service = new ScriptGenerationClient(
MakeAbsolute(context.Tools.Resolve("Cake.Bakery.exe")).FullPath,
MakeAbsolute(context.Environment.WorkingDirectory).FullPath,
loggerFactory);
service = Context.IsRunningOnUnix() ?
new ScriptGenerationClient(
new MonoScriptGenerationProcess(MakeAbsolute(context.Tools.Resolve("Cake.Bakery.exe")).FullPath, loggerFactory),
MakeAbsolute(context.Environment.WorkingDirectory).FullPath,
loggerFactory) :
new ScriptGenerationClient(
MakeAbsolute(context.Tools.Resolve("Cake.Bakery.exe")).FullPath,
MakeAbsolute(context.Environment.WorkingDirectory).FullPath,
loggerFactory);
});

Task("Should-Generate-From-File")
Expand Down

0 comments on commit d222586

Please sign in to comment.