Last active
June 28, 2016 11:43
-
-
Save roubachof/824a83bd7a9cf1680d8e741164bf7efa to your computer and use it in GitHub Desktop.
Script and tcp server listening to log results with NUnit.Xamarin 3 with TcpWriterParameters option (https://github.com/nunit/nunit.xamarin)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Notes: | |
# | |
# - 10/06/16 | |
# - the script attempts to connect to the first active Android emulator | |
# found in the list returned by the "adb devices" command, and launches it, if this list is empty. | |
# In this case, the AVD launched is the first .ini file found in the directory. | |
# | |
# paramètres (exemple): | |
# .\launch-emulator.ps1 | |
# -tcpListenerPath .\Stago.Mhp.Instr.Pocm.UnitTests.Droid.Server.exe | |
# -tcpListenerIp 127.0.0.1 | |
# -tcpListenerPort 13000 | |
# -packageName Stago.Mhp.Instr.Pocm.UnitTests.Droid | |
# -activityName stago.mhp.instr.pocm.unitTests.droid.mainActivity | |
# [option] -avdName Nexus-S-API22-ARM | |
# [option] -outXmlReportPath ..\..\artifacts\DroidTestResults.xml | |
# [option] -logServerTimeoutInSeconds 1200 | |
# [option] -apkName xxxx-Signed.pak | |
# powershell.exe -noprofile -executionpolicy bypass -file .\launch-emulator.ps1 -tcpListenerPath .\Stago.Mhp.Instr.Pocm.UnitTests.Droid.Server.exe -tcpListenerIp 127.0.0.1 -tcpListenerPort 13000 -packageName Stago.Mhp.Instr.Pocm.UnitTests.Droid -activityName stago.mhp.instr.pocm.unitTests.droid.mainActivity -outXmlReportPath ..\..\artifacts\DroidTestResults.xml -logServerTimeoutInSeconds 1200 | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory=$True)] | |
[string]$tcpListenerPath, | |
[Parameter(Mandatory=$True)] | |
[string]$tcpListenerIp, | |
[Parameter(Mandatory=$True)] | |
[int]$tcpListenerPort, | |
[Parameter(Mandatory=$True)] | |
[string]$packageName, | |
[Parameter(Mandatory=$True)] | |
[string]$activityName, | |
[string]$avdName, | |
[string]$apkName, | |
[string]$outXmlReportPath, | |
[int]$logServerTimeoutInSeconds | |
) | |
try | |
{ | |
#region --- try | |
Write-Host "Version=1.0.503" | |
Write-Host "" | |
# | |
# IMPORTANT: cleanup des process 'adb', 'emulator', ... | |
# | |
Write-Host "Get-Process emulator*, adb*(0)" | |
Get-Process emulator*, adb* | |
Write-Host "-------------------------------" | |
Get-Process emulator*, adb* | Stop-Process | |
Write-Host "Get-Process emulator*, adb*(1)" | |
Get-Process emulator*, adb* | |
Write-Host "-------------------------------" | |
#region --- Prepare environment | |
# Add needed pathes | |
Write-Host "Adding the needed paths to the process environment path" | |
$VerifiedPathsToAdd = $Null | |
$PathToAdd = @( | |
"C:\Users\AgentTeamcity\AppData\Local\Android\android-sdk\platform-tools", | |
"C:\Users\AgentTeamcity\AppData\Local\Android\android-sdk\tools") | |
Foreach ($Path in $PathToAdd) | |
{ | |
if ($env:Path -like "*$Path*") | |
{ | |
Write-Host "$Path already exists in Path statement" | |
} | |
else | |
{ | |
$VerifiedPathsToAdd += ";$Path" | |
Write-Host "`$Path will be added to the environment path" | |
} | |
} | |
if($VerifiedPathsToAdd -ne $null) | |
{ | |
Write-Host "Adding $VerifiedPathsToAdd to Path statement now..." | |
[Environment]::SetEnvironmentVariable("Path",$env:Path + $VerifiedPathsToAdd,"Process") # replace 'Process' with [EnvironmentVariableTarget]::Machine, if you want to make this persistent | |
} | |
Write-Host "--------------------------------------------------------------------" | |
#endregion | |
#region --- Find or starts an emulator | |
# Find the emulator name is one is already running | |
Write-Host "adb devices" | |
adb devices | |
Write-Host "-------------------------------" | |
$aDevice = adb devices | |
foreach ($device in $aDevice) | |
{ | |
$position0 = $device.IndexOf("emulator") | |
if ($position0 -lt 0) | |
{ | |
continue | |
} | |
$emulator = $device.Substring($position0) | |
$position1 = $emulator.IndexOf(0x09) | |
if ($position1 -gt 0) | |
{ | |
$emulator = $emulator.Substring(0, $position1); | |
} | |
break | |
} | |
Write-Host "emulator='"$emulator"'" | |
# A running emulator wasn't found lookup in .ini file | |
if (!$emulator) | |
{ | |
#region --- Choose the AVD from .ini file | |
$avdDir = "C:\Users\AgentTeamcity\.android\avd" | |
Write-Host "Value of the avdName parameter="$avdName | |
Write-Host "----------------------------------------" | |
if (!$avdName) | |
{ | |
Write-Host "Looking for the first .ini file in the avdDir="$avdDir" directory" | |
Write-Host "--------------------------------------------------------------------" | |
$List = get-childitem $avdDir | where {$_.extension -eq ".ini"} | |
if (!$List) | |
{ | |
throw "EXIT: NO .ini file was found in the directory avdDir=" + $avdDir | |
} | |
foreach ($item in $List) | |
{ | |
$avdName = $item.BaseName | |
break | |
} | |
} | |
if (!$avdName) | |
{ | |
throw "EXIT: No AVD was found" | |
} | |
Write-Host "Effective value of the avdName="$avdName | |
Write-Host "----------------------------------------" | |
#endregion | |
#region --- Starts the emulator | |
Try | |
{ | |
Write-Host "Start-Process(-) -PassThru -FilePath emulator.exe -ArgumentList -no-boot-anim -no-window -avd="$avdName | |
$process_emulator = Start-Process -PassThru -FilePath emulator.exe -ArgumentList "-no-boot-anim -no-window -avd $avdName" | |
Write-Host "Start-Process(+) process_emulator="$process_emulator | |
} | |
Catch | |
{ | |
$ErrorMessage = $_.Exception.Message | |
$FailedItem = $_.Exception.ItemName | |
Write-Host "Start-Process(EXCEPTION) ErrorMessage="$ErrorMessage | |
} | |
if (!$process_emulator) | |
{ | |
throw "EXIT: no emulator could be launched." | |
} | |
#endregion | |
Write-Host "adb wait-for-device" | |
adb wait-for-device | |
Write-Host "--------------------------------------" | |
#region --- wait for end of boot | |
Write-Host "Waiting for the end of the boot sequence" | |
$timeout = 400 | |
for ($attempts = 0; $attempts -lt $timeout; $attempts++) | |
{ | |
$result = adb shell getprop sys.boot_completed | |
Write-Host "adb shell getprop sys.boot_completed -> " $result | |
if ($result -match "invalid|error|fail") | |
{ | |
throw "EXIT: failed to communicate with the emulator: $result" | |
} | |
Sleep 1 | |
if ($result -like "1*") | |
{ | |
"Boot sequence ended" | |
break; | |
} | |
} | |
Write-Host "--------------------------------" | |
if ($attempts -ge $timeout) | |
{ | |
throw "Timeout reached while waiting for the end of the boot sequence ($attempts attempts with a 1 second delay)" | |
} | |
#endregion | |
#region --- Get emulator name | |
Write-Host "adb devices" | |
adb devices | |
Write-Host "-------------------------------" | |
$aDevice = adb devices | |
foreach ($device in $aDevice) | |
{ | |
$position0 = $device.IndexOf("emulator") | |
if ($position0 -lt 0) | |
{ | |
continue | |
} | |
$emulator = $device.Substring($position0) | |
$position1 = $emulator.IndexOf(0x09) | |
if ($position1 -gt 0) | |
{ | |
$emulator = $emulator.Substring(0, $position1); | |
} | |
break | |
} | |
Write-Host "emulator=<<"$emulator">>" | |
#endregion | |
#endregion | |
} | |
#endregion | |
#region --- Launch log server | |
# $tcpListenerPath_name <- $tcpListenerPath, 'nettoyage' | |
$tcpListenerPath_name=$tcpListenerPath.ToUpper() | |
while ($true) | |
{ | |
if ($tcpListenerPath_name.StartsWith(".")) | |
{ | |
$tcpListenerPath_name = $tcpListenerPath_name.Substring(1) | |
continue | |
} | |
if ($tcpListenerPath_name.StartsWith("\")) | |
{ | |
$tcpListenerPath_name = $tcpListenerPath_name.Substring(1) | |
continue | |
} | |
break | |
} | |
if ($tcpListenerPath_name.EndsWith(".EXE")) | |
{ | |
$tcpListenerPath_name = $tcpListenerPath_name.Substring(0, $tcpListenerPath_name.Length - 4) | |
} | |
Write-Host "tcpListenerPath_name="$tcpListenerPath_name | |
# kill old server log process | |
$aProcess = Get-Process | |
foreach ($process in $aProcess) | |
{ | |
$processName = $process.Name.ToUpper() | |
if ($processName.Equals($tcpListenerPath_name)) | |
{ | |
Write-Host "process.Kill()="$process | |
$process.Kill() | |
} | |
} | |
Write-Host "-------------------------------" | |
Try | |
{ | |
Write-Host "Start-Process(-) -PassThru -FilePath tcpListenerPath="$tcpListenerPath | |
$process_tcpListenerPath = Start-Process -PassThru -FilePath $tcpListenerPath -ArgumentList "-hostname=$tcpListenerIp -port=$tcpListenerPort -output=$outXmlReportPath" | |
Write-Host "Start-Process(+) process_tcpListenerPath="$process_tcpListenerPath | |
} | |
Catch | |
{ | |
$ErrorMessage = $_.Exception.Message | |
$FailedItem = $_.Exception.ItemName | |
Write-Host "Start-Process(EXCEPTION) ErrorMessage="$ErrorMessage | |
} | |
if (!$process_tcpListenerPath) | |
{ | |
throw "EXIT: process_tcpListenerPath='" + $process_tcpListenerPath + "' could not be launched" | |
} | |
#endregion | |
#region --- Starting the APK | |
Write-Host "apkName(-)="$apkName | |
if (-Not $apkName) | |
{ | |
$apkName = "$packageName-Signed.apk" | |
} | |
Write-Host "apkName(+)="$apkName | |
Write-Host "-------------------------" | |
Write-Host "Unlocking the emulator screen" | |
Write-Host "adb -s $emulator shell input keyevent 82" | |
adb -s $emulator shell input keyevent 82 | |
Write-Host "-------------------------" | |
Write-Host "Trying to uninstall the package previous version" | |
Write-Host "adb -s $emulator uninstall $packageName" | |
adb -s $emulator uninstall $packageName | |
Write-Host "-------------------------" | |
Write-Host "Installing the APK" | |
Write-Host "adb -s $emulator install -r $apkName" | |
$result = adb -s $emulator install -r "$apkName" | |
if ($result -match "invalid|error|fail") | |
{ | |
throw "APK installation failed: $result" | |
} | |
Write-Host "-------------------------" | |
Write-Host "Removing the existing xml results" | |
Write-Host "adb -s $emulator shell run-as $packageName rm -fr files/NUnitTestsOutput" | |
adb -s $emulator shell run-as $packageName rm -fr files/NUnitTestsOutput | |
Write-Host "-------------------------" | |
Write-Host "Launching the test Activity" | |
"adb -s $emulator shell am start $packageName/$activityName" | |
Sleep 5 | |
$result = adb -s $emulator shell am start "$packageName/$activityName" | |
if ($result -match "invalid|error|fail") | |
{ | |
throw "Error while launching main activity: $result" | |
} | |
Write-Host "-------------------------" | |
$logServerTimeoutInSeconds = if ($logServerTimeoutInSeconds -eq 0) { 5 * 60 } else { $logServerTimeoutInSeconds } | |
Write-Host "Waiting for process $logServerProcess with timeout of $logServerTimeoutInSeconds seconds" | |
if (-Not $process_tcpListenerPath -Or -Not $process_tcpListenerPath.WaitForExit($logServerTimeoutInSeconds * 1000)) | |
{ | |
throw "The log server hasn't received any log in $logServerTimeoutInSeconds seconds: a timeout is detected" | |
} | |
Write-Host "-------------------------" | |
#endregion | |
#endregion | |
} | |
finally | |
{ | |
# | |
# IMPORTANT: cleanup processes 'adb', 'emulator', ... | |
# | |
Write-Host "Get-Process emulator*, adb*(0)" | |
Get-Process emulator*, adb* | |
Write-Host "-------------------------------" | |
Get-Process emulator*, adb* | Stop-Process | |
Write-Host "Get-Process emulator*, adb*(1)" | |
Get-Process emulator*, adb* | |
Write-Host "-------------------------------" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using Mono.Options; | |
namespace Company.Whatever.UnitTests.Droid.Server | |
{ | |
public class MyTcpListener | |
{ | |
public static void Main(string[] args) | |
{ | |
TcpListener server = null; | |
try | |
{ | |
// Set the TcpListener on port 13000. | |
int port = 13000; | |
var localAddr = IPAddress.Parse("127.0.0.1"); | |
string outputPath = @".\output.xml"; | |
var options = new OptionSet | |
{ | |
{ | |
"h|hostname=", "the host dns name or IP address.", | |
host => localAddr = IPAddress.Parse(host) | |
}, | |
{ | |
"p|port=", "the port number to listen to.\n" + "this must be an integer.", | |
(int p) => port = p | |
}, | |
{ | |
"o|output=", "the path of the output result.", | |
o => outputPath = o | |
} | |
}; | |
options.Parse(args); | |
// TcpListener server = new TcpListener(port); | |
server = new TcpListener(localAddr, port); | |
// Start listening for client requests. | |
server.Start(); | |
// Buffer for reading data | |
var bytes = new byte[256]; | |
// Enter the listening loop. | |
//while (true) | |
{ | |
Console.Write($"Waiting for a connection on {localAddr}:{port}, will drop output to {outputPath}"); | |
// Perform a blocking call to accept requests. | |
// You could also user server.AcceptSocket() here. | |
TcpClient client = server.AcceptTcpClient(); | |
Console.WriteLine("Connected!"); | |
// Get a stream object for reading and writing | |
NetworkStream stream = client.GetStream(); | |
int i; | |
StringBuilder builder = new StringBuilder(); | |
// Loop to receive all the data sent by the client. | |
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) | |
{ | |
// Translate data bytes to a ASCII string. | |
var data = Encoding.UTF8.GetString(bytes, 0, i); | |
builder.Append(data); | |
Console.WriteLine("Received: {0}", data); | |
} | |
// Shutdown and end connection | |
client.Close(); | |
// Create a file to write to. | |
File.WriteAllText(outputPath, builder.ToString()); | |
} | |
} | |
catch (SocketException e) | |
{ | |
Console.WriteLine("SocketException: {0}", e); | |
} | |
finally | |
{ | |
// Stop listening for new clients. | |
server?.Stop(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment