private static int BuildAndRunAndroidTests(List <string> commandArgs, bool reinstall, string resultPath) { if (commandArgs.Count == 0) { throw new OptionException("One APK should be provided", "apk"); } // get build number int buildNumber; if (!Int32.TryParse(Environment.GetEnvironmentVariable("XENKO_BUILD_NUMBER"), out buildNumber)) { buildNumber = -1; } // get branch name var branchName = Environment.GetEnvironmentVariable("XENKO_BRANCH_NAME"); var exitCode = 0; foreach (var packageFile in commandArgs) { if (!packageFile.EndsWith("-Signed.apk")) { throw new OptionException("APK should end up with \"-Signed.apk\"", "apk"); } // Remove -Signed.apk suffix var packageName = Path.GetFileName(packageFile); packageName = packageName.Replace("-Signed.apk", string.Empty); var androidDevices = AndroidDeviceEnumerator.ListAndroidDevices(); if (androidDevices.Length == 0) { throw new InvalidOperationException("Could not find any Android device connected."); } foreach (var device in androidDevices) { var testServerHost = new TestServerHost(buildNumber, branchName); Directory.CreateDirectory(resultPath); var deviceResultFile = Path.Combine(resultPath, "TestResult_" + packageName + "_Android_" + device.Name + "_" + device.Serial + ".xml"); var currentExitCode = testServerHost.RunAndroidTest( new TestServerHost.ConnectedDevice { Name = device.Name, Serial = device.Serial, Platform = TestPlatform.Android, }, reinstall, packageName, packageFile, deviceResultFile); if (currentExitCode != 0) { exitCode = currentExitCode; } } } return(exitCode); }
/// <summary> /// Run the test on Android through a bat file. /// </summary> private void RunAndroidTestOnBamboo(string serial) { try { // force stop - only works for Android 3.0 and above. var o0 = ShellHelper.RunProcessAndGetOutput(AndroidDeviceEnumerator.GetAdbPath(), @"-s " + serial + @" am shell force-stop " + assemblyNameForAndroid); // install var o1 = ShellHelper.RunProcessAndGetOutput(AndroidDeviceEnumerator.GetAdbPath(), @"-s " + serial + @" -d install -r ..\..\Bin\Android-OpenGLES\" + assemblyNameForAndroid + "-Signed.apk"); // run var parameters = new StringBuilder(); parameters.Append("-s "); parameters.Append(serial); parameters.Append(@" shell am start -a android.intent.action.MAIN -n " + assemblyNameForAndroid + "/siliconstudio.paradox.graphicstests.GraphicsTestRunner"); AddAndroidParameter(parameters, TestRunner.ParadoxServerIp, serverAddresses); AddAndroidParameter(parameters, TestRunner.ParadoxServerPort, serverPort.ToString()); AddAndroidParameter(parameters, TestRunner.ParadoxBuildNumber, buildNumber.ToString()); AddAndroidParameter(parameters, TestRunner.ParadoxDeviceSerial, serial); AddAndroidParameter(parameters, TestRunner.ParadoxTestName, this.GetType().Name); Console.WriteLine(parameters.ToString()); ShellHelper.RunProcess(AndroidDeviceEnumerator.GetAdbPath(), parameters.ToString()); } catch { Console.WriteLine(@"An error was thrown when running the test on Android."); dataReceivedEvent.Set(); } }
/// <summary> /// Lists all the Android devices accessible from the computer. /// </summary> /// <returns>The list of all the available Android devices.</returns> public ConnectedDevice[] ListAndroidDevices() { var devices = new List <ConnectedDevice>(); var devicesOutputs = ShellHelper.RunProcessAndGetOutput(AndroidDeviceEnumerator.GetAdbPath(), @"devices"); var whitespace = new[] { ' ', '\t' }; for (var i = 1; i < devicesOutputs.OutputLines.Count; ++i) // from the second line { var line = devicesOutputs.OutputLines[i]; if (line != null) { var res = line.Split(whitespace); if (res.Length == 2) { ConnectedDevice device; device.Serial = res[0]; device.Name = res[1]; device.Platform = TestPlatform.Android; devices.Add(device); } } } // Set the real name of the Android device. for (var i = 0; i < devices.Count; ++i) { var device = devices[i]; //TODO: doing a grep instead will be better var deviceNameOutputs = ShellHelper.RunProcessAndGetOutput(AndroidDeviceEnumerator.GetAdbPath(), @"-s " + device.Serial + @" shell cat /system/build.prop"); foreach (var line in deviceNameOutputs.OutputLines) { if (line != null && line.StartsWith(@"ro.product.model")) // correct line { var parts = line.Split('='); if (parts.Length > 1) { device.Name = parts[1]; devices[i] = device; } break; // no need to search further } } } // get the name of the base device. foreach (var device in devices) { if (device.Name.Equals(AndroidReferenceName)) { //device = device.Serial; break; } } return(devices.ToArray()); }
public SamplesTestServer() : base($"/service/Stride.SamplesTestServer/{StrideVersion.NuGetVersion}/Stride.SamplesTestServer.exe") { GameTestingSystem.Initialized = true; //start logging the iOS device if we have the proper tools avail if (IosTracker.CanProxy()) { var loggerProcess = Process.Start(new ProcessStartInfo($"idevicesyslog.exe", "-d") { UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardOutput = true, }); if (loggerProcess != null) { loggerProcess.OutputDataReceived += (sender, args) => { try { lock (loggerLock) { currentTester?.Send(new LogRequest { Message = $"STDIO: {args.Data}" }).Wait(); } } catch { } }; loggerProcess.ErrorDataReceived += (sender, args) => { try { lock (loggerLock) { currentTester?.Send(new LogRequest { Message = $"STDERR: {args.Data}" }).Wait(); } } catch { } }; loggerProcess.BeginOutputReadLine(); loggerProcess.BeginErrorReadLine(); new AttachedChildProcessJob(loggerProcess); } } //Start also adb in case of android device var adbPath = AndroidDeviceEnumerator.GetAdbPath(); if (!string.IsNullOrEmpty(adbPath) && AndroidDeviceEnumerator.ListAndroidDevices().Length > 0) { //clear the log first ShellHelper.RunProcessAndGetOutput("cmd.exe", $"/C {adbPath} logcat -c"); //start logger var loggerProcess = Process.Start(new ProcessStartInfo("cmd.exe", $"/C {adbPath} logcat") { UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardOutput = true, }); if (loggerProcess != null) { loggerProcess.OutputDataReceived += (sender, args) => { try { currentTester?.Send(new LogRequest { Message = $"STDIO: {args.Data}" }).Wait(); } catch { } }; loggerProcess.ErrorDataReceived += (sender, args) => { try { currentTester?.Send(new LogRequest { Message = $"STDERR: {args.Data}" }).Wait(); } catch { } }; loggerProcess.BeginOutputReadLine(); loggerProcess.BeginErrorReadLine(); new AttachedChildProcessJob(loggerProcess); } } }
public static void TrackDevices(Router router) { var currentAndroidDevices = new Dictionary <string, ConnectedDevice>(); // Start new devices int startLocalPort = 51153; // Use ports in the dynamic port range // Check if ADB is on the path var adbPath = AndroidDeviceEnumerator.GetAdbPath(); if (adbPath == null) { return; } // Wait and process android device changes events while (true) { // Fill list of android devices var newAndroidDevices = new Dictionary <string, string>(); foreach (var device in AndroidDeviceEnumerator.ListAndroidDevices()) { newAndroidDevices.Add(device.Serial, string.Format("{0} ({1})", device.Name, device.Serial)); } DeviceHelper.UpdateDevices(Log, newAndroidDevices, currentAndroidDevices, (connectedDevice) => { // First, try adb reverse port mapping (supported on newest adb+device) // This is the best solution, as nothing specific needs to be done. // NOTE: disabled for now, as it's difficult to know what to try first from the device itself. //var output = ShellHelper.RunProcessAndGetOutput(AndroidDeviceEnumerator.GetAdbPath(), string.Format(@"-s {0} reverse tcp:{1} tcp:{2}", newAndroidDevice, LocalPort, LocalPort)); //if (output.ExitCode == 0) // continue; // Setup adb port forward (tries up to 5 times for open ports) int localPort = 0; int firstTestedLocalPort = startLocalPort; for (int i = 0; i < 4; ++i) { int testedLocalPort = startLocalPort++; if (startLocalPort >= 65536) // Make sure we stay in the range of dynamic ports: 49152-65535 { startLocalPort = 49152; } var output = ShellHelper.RunProcessAndGetOutput(adbPath, string.Format(@"-s {0} forward tcp:{1} tcp:{2}", connectedDevice.Key, testedLocalPort, RouterClient.DefaultListenPort)); if (output.ExitCode == 0) { localPort = testedLocalPort; Log.Info($"Android Device connected: {connectedDevice.Name}; successfully mapped port {testedLocalPort}:{RouterClient.DefaultListenPort}"); break; } } if (localPort == 0) { int lastTestedLocalPort = startLocalPort; Log.Info($"Android Device connected: {connectedDevice.Name}; error when mapping port [{firstTestedLocalPort}-{lastTestedLocalPort - 1}]:{RouterClient.DefaultListenPort}"); return; } // Launch a client thread that will automatically tries to connect to this port Task.Run(() => DeviceHelper.LaunchPersistentClient(connectedDevice, router, "localhost", localPort)); }); Thread.Sleep(1000); // Detect new devices every 1000 msec } }
public int RunAndroidTest(ConnectedDevice device, bool reinstall, string packageName, string packageFile, string resultFilename) { resultFile = resultFilename; try { ProcessOutputs adbOutputs; var adbPath = AndroidDeviceEnumerator.GetAdbPath(); if (adbPath == null) { throw new InvalidOperationException("Can't find adb"); } // force stop - only works for Android 3.0 and above. ShellHelper.RunProcessAndGetOutput(adbPath, $@"-s {device.Serial} shell am force-stop {packageName}"); if (reinstall) { // uninstall ShellHelper.RunProcessAndGetOutput(adbPath, $@"-s {device.Serial} uninstall {packageName}"); // install adbOutputs = ShellHelper.RunProcessAndGetOutput(adbPath, $@"-s {device.Serial} install {packageFile}"); Console.WriteLine("adb install: exitcode {0}\nOutput: {1}\nErrors: {2}", adbOutputs.ExitCode, adbOutputs.OutputAsString, adbOutputs.ErrorsAsString); if (adbOutputs.ExitCode != 0) { throw new InvalidOperationException("Invalid error code from adb install.\n Shell log: {0}"); } } // run var parameters = new StringBuilder(); parameters.Append("-s "); parameters.Append(device.Serial); parameters.Append(@" shell am start -a android.intent.action.MAIN -n " + packageName + "/nunitlite.tests.MainActivity"); AddAndroidParameter(parameters, Graphics.Regression.TestRunner.StrideVersion, StrideVersion.NuGetVersion); AddAndroidParameter(parameters, Graphics.Regression.TestRunner.StrideBuildNumber, buildNumber.ToString()); if (!IsNullOrEmpty(branchName)) { AddAndroidParameter(parameters, Graphics.Regression.TestRunner.StrideBranchName, branchName); } Console.WriteLine(parameters.ToString()); adbOutputs = ShellHelper.RunProcessAndGetOutput(adbPath, parameters.ToString()); Console.WriteLine("adb shell am start: exitcode {0}\nOutput: {1}\nErrors: {2}", adbOutputs.ExitCode, adbOutputs.OutputAsString, adbOutputs.ErrorsAsString); if (adbOutputs.ExitCode != 0) { throw new InvalidOperationException("Invalid error code from adb shell am start."); } if (!clientResultsEvent.WaitOne(TimeSpan.FromSeconds(300))) //wait 30 seconds for client connection { Console.WriteLine(@"Device failed to connect."); return(-1); } Console.WriteLine(@"Device client connected, waiting for test results..."); // if we receive no events during more than 5 minutes, something is wrong // we also check that test session is not finished as well while (clientResultsEvent.WaitOne(TimeSpan.FromMinutes(5)) && !testFinished) { } return(testFailed ? -1 : 0); } catch (Exception e) { Console.WriteLine(@"An error was thrown when running the test on Android: {0}", e); return(-1); } }
public int RunAndroidTest(ConnectedDevice device, bool reinstall, string packageName, string packageFile, string resultFile) { try { server = StartServer(); ProcessOutputs adbOutputs; var adbPath = AndroidDeviceEnumerator.GetAdbPath(); if (adbPath == null) { throw new InvalidOperationException("Can't find adb"); } var logStack = new List <string>(); if (reinstall) { // force stop - only works for Android 3.0 and above. adbOutputs = ShellHelper.RunProcessAndGetOutput(adbPath, string.Format(@"-s {0} shell am force-stop {1}", device.Serial, packageName)); // uninstall adbOutputs = ShellHelper.RunProcessAndGetOutput(adbPath, string.Format(@"-s {0} uninstall {1}", device.Serial, packageName)); // install adbOutputs = ShellHelper.RunProcessAndGetOutput(adbPath, string.Format(@"-s {0} install {1}", device.Serial, packageFile)); Console.WriteLine("adb install: exitcode {0}\nOutput: {1}\nErrors: {2}", adbOutputs.ExitCode, adbOutputs.OutputAsString, adbOutputs.ErrorsAsString); if (adbOutputs.ExitCode != 0) { throw new InvalidOperationException("Invalid error code from adb install.\n Shell log: {0}"); } } // run var parameters = new StringBuilder(); parameters.Append("-s "); parameters.Append(device.Serial); parameters.Append(@" shell am start -a android.intent.action.MAIN -n " + packageName + "/nunitlite.tests.MainActivity"); AddAndroidParameter(parameters, TestRunner.ParadoxServerIp, serverAddresses); AddAndroidParameter(parameters, TestRunner.ParadoxServerPort, ((IPEndPoint)server.Server.LocalEndPoint).Port.ToString()); AddAndroidParameter(parameters, TestRunner.ParadoxBuildNumber, buildNumber.ToString()); if (!String.IsNullOrEmpty(branchName)) { AddAndroidParameter(parameters, TestRunner.ParadoxBranchName, branchName); } Console.WriteLine(parameters.ToString()); adbOutputs = ShellHelper.RunProcessAndGetOutput(adbPath, parameters.ToString()); Console.WriteLine("adb shell am start: exitcode {0}\nOutput: {1}\nErrors: {2}", adbOutputs.ExitCode, adbOutputs.OutputAsString, adbOutputs.ErrorsAsString); if (adbOutputs.ExitCode != 0) { throw new InvalidOperationException("Invalid error code from adb shell am start."); } // Wait for client to connect const int WaitingTime = 30; for (int i = 0; i < WaitingTime; i++) { if (server.Pending()) { break; } Thread.Sleep(1000); } if (!server.Pending()) { throw new InvalidOperationException("The client (the remote test application) failed to establish the connection."); } var client = server.AcceptTcpClient(); Console.WriteLine("Device connected, wait for results..."); var clientStream = client.GetStream(); var binaryReader = new BinaryReader(clientStream); // Read output var output = binaryReader.ReadString(); Console.WriteLine(output); // Read XML result var result = binaryReader.ReadString(); Console.WriteLine(result); // Write XML result to disk File.WriteAllText(resultFile, result); return(0); } catch (Exception e) { Console.WriteLine(@"An error was thrown when running the test on Android: {0}", e); return(-1); } }