Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix android uninstall command and add validations #55431

Merged
merged 1 commit into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 95 additions & 59 deletions src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,99 +8,135 @@ namespace CoreclrTestLib
{
public class MobileAppHandler
{
public void InstallMobileApp(string platform, string category, string testBinaryBase, string reportBase)
public int InstallMobileApp(string platform, string category, string testBinaryBase, string reportBase)
{
HandleMobileApp("install", platform, category, testBinaryBase, reportBase);
return HandleMobileApp("install", platform, category, testBinaryBase, reportBase);
}

public void UninstallMobileApp(string platform, string category, string testBinaryBase, string reportBase)
public int UninstallMobileApp(string platform, string category, string testBinaryBase, string reportBase)
{
HandleMobileApp("uninstall", platform, category, testBinaryBase, reportBase);
return HandleMobileApp("uninstall", platform, category, testBinaryBase, reportBase);
}

private static void HandleMobileApp(string action, string platform, string category, string testBinaryBase, string reportBase)
private static int HandleMobileApp(string action, string platform, string category, string testBinaryBase, string reportBase)
{
//install or uninstall mobile app
int exitCode = -100;
string outputFile = Path.Combine(reportBase, action, $"{category}_{action}.output.txt");
string errorFile = Path.Combine(reportBase, action, $"{category}_{action}.error.txt");
string dotnetCmd_raw = System.Environment.GetEnvironmentVariable("__TestDotNetCmd");
string xharnessCmd_raw = System.Environment.GetEnvironmentVariable("XHARNESS_CLI_PATH");
int timeout = 600000; // Set timeout to 4 mins, because the installation on Android arm64/32 devices could take up to 10 mins on CI

string dotnetCmd = string.IsNullOrEmpty(dotnetCmd_raw) ? "dotnet" : dotnetCmd_raw;
string xharnessCmd = string.IsNullOrEmpty(xharnessCmd_raw) ? "xharness" : $"exec {xharnessCmd_raw}";
string appExtension = platform == "android" ? "apk" : "app";
string cmdStr = $"{dotnetCmd} {xharnessCmd} {platform} {action} --output-directory={reportBase}/{action}";

if (action == "install")
{
cmdStr += $" --app={testBinaryBase}/{category}.{appExtension}";
}
else if (platform != "android")
{
cmdStr += $" --app=net.dot.{category}";
}

if (platform == "android")
{
cmdStr += $" --package-name=net.dot.{category}";
}
bool platformValueFlag = true;
bool actionValueFlag = true;

Directory.CreateDirectory(Path.Combine(reportBase, action));
var outputStream = new FileStream(outputFile, FileMode.Create);
var errorStream = new FileStream(errorFile, FileMode.Create);

using (var outputWriter = new StreamWriter(outputStream))
using (var errorWriter = new StreamWriter(errorStream))
using (Process process = new Process())
{
if (OperatingSystem.IsWindows())
//Validate inputs
if ((platform != "android") && (platform != "apple"))
{
process.StartInfo.FileName = "cmd.exe";
outputWriter.WriteLine($"Incorrect value of platform. Provided {platform}. Valid strings are android and apple.");
platformValueFlag = false;
}
else

if ((action != "install") && (action != "uninstall"))
{
process.StartInfo.FileName = "/bin/bash";
outputWriter.WriteLine($"Incorrect value of action. Provided {action}. Valid strings are install and uninstall.");
actionValueFlag = false;
}

process.StartInfo.Arguments = ConvertCmd2Arg(cmdStr);
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
if (platformValueFlag && actionValueFlag)
{
int timeout = 240000; // Set timeout to 4 mins, because the installation on Android arm64/32 devices could take up to 10 mins on CI
string dotnetCmd_raw = System.Environment.GetEnvironmentVariable("__TestDotNetCmd");
string xharnessCmd_raw = System.Environment.GetEnvironmentVariable("XHARNESS_CLI_PATH");
string dotnetCmd = string.IsNullOrEmpty(dotnetCmd_raw) ? "dotnet" : dotnetCmd_raw;
string xharnessCmd = string.IsNullOrEmpty(xharnessCmd_raw) ? "xharness" : $"exec {xharnessCmd_raw}";
string appExtension = platform == "android" ? "apk" : "app";

DateTime startTime = DateTime.Now;
process.Start();
string cmdStr = $"{dotnetCmd} {xharnessCmd} {platform} {action}";

var cts = new CancellationTokenSource();
Task copyOutput = process.StandardOutput.BaseStream.CopyToAsync(outputStream, 4096, cts.Token);
Task copyError = process.StandardError.BaseStream.CopyToAsync(errorStream, 4096, cts.Token);
if (platform == "android")
{
cmdStr += $" --package-name=net.dot.{category}";

if (process.WaitForExit(timeout))
{
Task.WaitAll(copyOutput, copyError);
}
else
{
//Time out
DateTime endTime = DateTime.Now;
if (action == "install")
{
cmdStr += $" --app={testBinaryBase}/{category}.{appExtension} --output-directory={reportBase}/{action}";
}
}
else // platform is apple
{
cmdStr += $" --output-directory={reportBase}/{action} --target=ios-simulator-64"; //To Do: target should be either emulator or device

if (action == "install")
{
cmdStr += $" --app={testBinaryBase}/{category}.{appExtension}";
}
else // action is uninstall
{
cmdStr += $" --app=net.dot.{category}";
}
}

try
using (Process process = new Process())
{
cts.Cancel();
if (OperatingSystem.IsWindows())
{
process.StartInfo.FileName = "cmd.exe";
}
else
{
process.StartInfo.FileName = "/bin/bash";
}

process.StartInfo.Arguments = ConvertCmd2Arg(cmdStr);
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;

DateTime startTime = DateTime.Now;
process.Start();

var cts = new CancellationTokenSource();
Task copyOutput = process.StandardOutput.BaseStream.CopyToAsync(outputStream, 4096, cts.Token);
Task copyError = process.StandardError.BaseStream.CopyToAsync(errorStream, 4096, cts.Token);

if (process.WaitForExit(timeout))
{
// Process completed.
exitCode = process.ExitCode;
Task.WaitAll(copyOutput, copyError);
}
else
{
//Time out.
DateTime endTime = DateTime.Now;

try
{
cts.Cancel();
}
catch {}

outputWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}, start: {2}, end: {3})",
cmdStr, timeout, startTime.ToString(), endTime.ToString());
errorWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}, start: {2}, end: {3})",
cmdStr, timeout, startTime.ToString(), endTime.ToString());

process.Kill(entireProcessTree: true);
}
}
catch {}

outputWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}, start: {2}, end: {3})",
cmdStr, timeout, startTime.ToString(), endTime.ToString());
errorWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}, start: {2}, end: {3})",
cmdStr, timeout, startTime.ToString(), endTime.ToString());

process.Kill(entireProcessTree: true);
}

outputWriter.WriteLine("xharness exitcode is : " + exitCode.ToString());
outputWriter.Flush();
errorWriter.Flush();
}

return exitCode;
}

private static string ConvertCmd2Arg(string cmd)
Expand Down
9 changes: 7 additions & 2 deletions src/tests/run.proj
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").
coreRoot = Environment.GetEnvironmentVariable(%22CORE_ROOT%22)%3B
category = "$([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").Replace("-","_"))"%3B
helixUploadRoot = Environment.GetEnvironmentVariable(%22HELIX_WORKITEM_UPLOAD_ROOT%22)%3B
int retCode = -100%3B

if (!String.IsNullOrEmpty(helixUploadRoot)) {
reportBase = Path.Combine(Path.GetFullPath(helixUploadRoot), "Reports")%3B
}
Expand All @@ -293,12 +295,15 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").
string operatingSystem = Environment.GetEnvironmentVariable("OS")%3B
runningInWindows = (operatingSystem != null && operatingSystem.StartsWith("Windows"))%3B

handler.InstallMobileApp(%22$(MobilePlatform)%22, category, testBinaryBase, reportBase)%3B
retCode = handler.InstallMobileApp(%22$(MobilePlatform)%22, category, testBinaryBase, reportBase)%3B
Assert.True(retCode == 0, "Failed to install mobile app.")%3B
}

public void Dispose()
{
handler.UninstallMobileApp(%22$(MobilePlatform)%22, category, testBinaryBase, reportBase)%3B
int retCode = -100%3B
retCode = handler.UninstallMobileApp(%22$(MobilePlatform)%22, category, testBinaryBase, reportBase)%3B
Assert.True(retCode == 0, "Failed to uninstall mobile app.")%3B
}
}

Expand Down