Skip to content

Commit

Permalink
Add initial cross-platform spec support
Browse files Browse the repository at this point in the history
- Change build script for Net Core MNTR, copy node runner net and net core binaries to mntr/runner
  • Loading branch information
Arkatufus committed Aug 1, 2017
1 parent 6dee7d4 commit b8c948b
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 22 deletions.
51 changes: 51 additions & 0 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ Target "Build" (fun _ ->
Project = solution
Configuration = configuration
AdditionalArgs = additionalArgs })

let sourceBasePath = __SOURCE_DIRECTORY__ @@ "src" @@ "core"
let ntrBasePath = sourceBasePath @@ "Akka.NodeTestRunner" @@ "bin" @@ "Release"
let ntrNetPath = ntrBasePath @@ "net452"
let ntrNetCorePath = ntrBasePath @@ "netcoreapp1.1"
let mntrPath = sourceBasePath @@ "Akka.MultiNodeTestRunner" @@ "bin" @@ "Release" @@ "netcoreapp1.1"
let copyNtrNetToMntrTargetPath = mntrPath @@ "runner" @@ "net"
let copyNtrNetCoreToMntrTargetPath = mntrPath @@ "runner" @@ "netcore"

CopyDir (copyNtrNetToMntrTargetPath) (ntrNetPath) allFiles
CopyDir (copyNtrNetCoreToMntrTargetPath) (ntrNetCorePath) allFiles
)

//--------------------------------------------------------------------------------
Expand Down Expand Up @@ -194,6 +205,46 @@ Target "MultiNodeTestsNetCore" (fun _ ->
multiNodeTestAssemblies |> Seq.iter (runMultiNodeSpec)
)

Target "MultiNodeTestsMultiPlatform" (fun _ ->
ActivateFinalTarget "KillCreatedProcesses"
let multiNodeTestPath = findToolInSubPath "Akka.MultiNodeTestRunner.dll" (currentDirectory @@ "src" @@ "core" @@ "Akka.MultiNodeTestRunner" @@ "bin" @@ "Release" @@ "netcoreapp1.1")

let multiNodeTestAssemblies =
match getBuildParamOrDefault "incremental" "" with
| "true" -> log "The following test projects would be run under Incremental Test config..."
getIncrementalNetCoreMNTRTests() |> Seq.map (fun x -> printfn "\t%s" x; x)
| "experimental" -> log "The following MNTR specs would be run under Incremental Test config..."
getIncrementalNetCoreMNTRTests() |> Seq.iter log
getAllMntrTestNetCoreAssemblies()
| _ -> log "All test projects will be run"
getAllMntrTestNetCoreAssemblies()

printfn "Using MultiNodeTestRunner: %s" multiNodeTestPath

let runMultiNodeSpec assembly =
match assembly with
| null -> ()
| _ ->
let spec = getBuildParam "spec"

let args = StringBuilder()
|> append multiNodeTestPath
|> append assembly
|> append "-Dmultinode.teamcity=true"
|> append "-Dmultinode.enable-filesink=on"
|> append (sprintf "-Dmultinode.output-directory=\"%s\"" outputMultiNode)
|> append "-Dmultinode.platform=multi"
|> appendIfNotNullOrEmpty spec "-Dmultinode.spec="
|> toText

let result = ExecProcess(fun info ->
info.FileName <- "dotnet"
info.WorkingDirectory <- (Path.GetDirectoryName (FullName multiNodeTestPath))
info.Arguments <- args) (System.TimeSpan.FromMinutes 60.0) (* This is a VERY long running task. *)
if result <> 0 then failwithf "MultiNodeTestRunner failed. %s %s" multiNodeTestPath args

multiNodeTestAssemblies |> Seq.iter (runMultiNodeSpec)
)

Target "MultiNodeTests" (fun _ ->
ActivateFinalTarget "KillCreatedProcesses"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,20 @@ protected override void HandleNodeMessageFragment(LogMessageFragmentForNode logM

protected override void HandleNodeSpecPass(NodeCompletedSpecWithSuccess nodeSuccess)
{
Console.ForegroundColor = ConsoleColor.Green;
_teamCityTestWriter?.WriteStdOutput(
$"[NODE{nodeSuccess.NodeIndex}:{nodeSuccess.NodeRole}][{DateTime.UtcNow.ToShortTimeString()}]: SPEC PASSED: {nodeSuccess.Message}");

Console.ResetColor();

base.HandleNodeSpecPass(nodeSuccess);
}

protected override void HandleNodeSpecFail(NodeCompletedSpecWithFail nodeFail)
{
Console.ForegroundColor = ConsoleColor.Red;
_teamCityTestWriter?.WriteFailed(
$"[NODE{nodeFail.NodeIndex}:{nodeFail.NodeRole}][{DateTime.UtcNow.ToShortTimeString()}]: SPEC FAILED: {nodeFail.Message}", "");
Console.ResetColor();

base.HandleNodeSpecFail(nodeFail);
}
Expand Down
94 changes: 75 additions & 19 deletions src/core/Akka.MultiNodeTestRunner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ namespace Akka.MultiNodeTestRunner
/// </summary>
class Program
{
protected static ActorSystem TestRunSystem;
private static HashSet<string> _validNetCorePlatform = new HashSet<string>
{
"net",
"netcore",
"multi"
};

protected static ActorSystem TestRunSystem;
protected static IActorRef SinkCoordinator;

/// <summary>
Expand All @@ -47,6 +53,7 @@ class Program
protected static string OutputDirectory;

protected static bool TeamCityFormattingOn;
protected static bool MultiPlatform;

/// <summary>
/// MultiNodeTestRunner takes the following <see cref="args"/>:
Expand Down Expand Up @@ -128,9 +135,9 @@ static void Main(string[] args)
var platform = CommandLine.GetPropertyOrDefault("multinode.platform", "net");

#if CORECLR
if (platform != "net" && platform != "netcore")
if (!_validNetCorePlatform.Contains(platform))
{
throw new Exception($"Target platform not supported: {platform}. Supported platforms are net and netcore");
throw new Exception($"Target platform not supported: {platform}. Supported platforms are net, netcore and multi");
}
#else
if (platform != "net")
Expand All @@ -146,7 +153,6 @@ static void Main(string[] args)

EnableAllSinks(assemblyPath, platform);
PublishRunnerMessage($"Running MultiNodeTests for {assemblyPath}");

#if CORECLR
// In NetCore, if the assembly file hasn't been touched,
// XunitFrontController would fail loading external assemblies and its dependencies.
Expand All @@ -157,11 +163,19 @@ static void Main(string[] args)
{
try
{
assembly = Assembly.Load(new AssemblyName(asm.FullName));
Assembly.Load(new AssemblyName(asm.FullName));
}
catch (Exception)
{
assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(basePath, asm.Name + ".dll"));
var path = Path.Combine(basePath, asm.Name + ".dll");
try
{
AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
}
catch (Exception e)
{
Console.Out.WriteLine($"Failed to load dll: {path}");
}
}
}
#endif
Expand Down Expand Up @@ -197,11 +211,16 @@ static void Main(string[] args)
PublishRunnerMessage($"Starting test {test.Value.First().MethodName}");

StartNewSpec(test.Value);
#if CORECLR
var ntrBasePath = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "Akka.NodeTestRunner", "bin", "Release"));
var ntrNetPath = Path.Combine(AppContext.BaseDirectory, "runner", "net", "Akka.NodeTestRunner.exe");
var ntrNetCorePath = Path.Combine(AppContext.BaseDirectory, "runner", "netcore", "Akka.NodeTestRunner.dll");
var alternateIndex = 0;
#endif
foreach (var nodeTest in test.Value)
{
//Loop through each test, work out number of nodes to run on and kick off process
var sbArguments = new StringBuilder()
.Append($@"-Dmultinode.test-assembly=""{assemblyPath}"" ")
.Append($@"-Dmultinode.test-class=""{nodeTest.TypeName}"" ")
.Append($@"-Dmultinode.test-method=""{nodeTest.MethodName}"" ")
.Append($@"-Dmultinode.max-nodes={test.Value.Count} ")
Expand All @@ -210,33 +229,65 @@ static void Main(string[] args)
.Append($@"-Dmultinode.index={nodeTest.Node - 1} ")
.Append($@"-Dmultinode.role=""{nodeTest.Role}"" ")
.Append($@"-Dmultinode.listen-address={listenAddress} ")
.Append($@"-Dmultinode.listen-port={listenPort}");
.Append($@"-Dmultinode.listen-port={listenPort} ");

#if CORECLR
string fileName = null;
switch (platform)
{
case "net":
fileName = ntrNetPath;
sbArguments.Insert(0, $@" -Dmultinode.test-assembly=""{assemblyPath}"" ");
break;
case "netcore":
fileName = "dotnet";
sbArguments.Insert(0, $@" -Dmultinode.test-assembly=""{assemblyPath}"" ");
sbArguments.Insert(0, ntrNetCorePath);
break;
case "multi":
if (alternateIndex % 2 == 0)
{
fileName = ntrNetPath;
sbArguments.Insert(0, $@" -Dmultinode.test-assembly=""{ChangeDllPathPlatform(assemblyPath, "net452")}"" ");
}
else
{
fileName = "dotnet";
sbArguments.Insert(0, $@" -Dmultinode.test-assembly=""{ChangeDllPathPlatform(assemblyPath, "netcoreapp1.1")}"" ");
sbArguments.Insert(0, ntrNetCorePath);
}
++alternateIndex;
break;
}
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = fileName,
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = sbArguments.ToString(),
WorkingDirectory = Path.GetDirectoryName(assemblyPath)
}
};
#else
sbArguments.Insert(0, $@"-Dmultinode.test-assembly=""{assemblyPath}"" ");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "Akka.NodeTestRunner.exe",
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = sbArguments.ToString()
}
};
#endif

processes.Add(process);
var nodeIndex = nodeTest.Node;
var nodeRole = nodeTest.Role;

#if CORECLR
if (platform == "netcore")
{
process.StartInfo.FileName = "dotnet";
var ntrPath = Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "Akka.NodeTestRunner", "bin", "Release", "netcoreapp1.1", "Akka.NodeTestRunner.dll");
process.StartInfo.Arguments = Path.GetFullPath(ntrPath) + " " + process.StartInfo.Arguments;
process.StartInfo.WorkingDirectory = Path.GetDirectoryName(assemblyPath);
}
#endif

//TODO: might need to do some validation here to avoid the 260 character max path error on Windows
var folder = Directory.CreateDirectory(Path.Combine(OutputDirectory, nodeTest.TestName));
var logFilePath = Path.Combine(folder.FullName, $"node{nodeIndex}__{nodeRole}__{platform}.txt");
Expand Down Expand Up @@ -300,7 +351,7 @@ static void Main(string[] args)
}
}
}

CloseAllSinks();

//Block until all Sinks have been terminated.
Expand All @@ -313,6 +364,11 @@ static void Main(string[] args)
Environment.Exit(ExitCodeContainer.ExitCode);
}

static string ChangeDllPathPlatform(string path, string targetPlatform)
{
return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), "..", targetPlatform, Path.GetFileName(path)));
}

static void EnableAllSinks(string assemblyName, string platform)
{
var now = DateTime.UtcNow;
Expand Down
12 changes: 10 additions & 2 deletions src/core/Akka.NodeTestRunner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,19 @@ static int Main(string[] args)
{
try
{
assembly = Assembly.Load(new AssemblyName(asm.FullName));
Assembly.Load(new AssemblyName(asm.FullName));
}
catch (Exception)
{
assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(basePath, asm.Name + ".dll"));
var path = Path.Combine(basePath, asm.Name + ".dll");
try
{
AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
}
catch (Exception e)
{
Console.Out.WriteLine($"Failed to load dll: {path}");
}
}
}
#endif
Expand Down

0 comments on commit b8c948b

Please sign in to comment.