public static void RegisterServer(SocketMessageLayer socketMessageLayer) { socketMessageLayer.AddPacketHandler<DownloadFileQuery>( async (packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read); var data = new byte[stream.Length]; await stream.ReadAsync(data, 0, data.Length); stream.Dispose(); socketMessageLayer.Send(new DownloadFileAnswer { StreamId = packet.StreamId, Data = data }); }); socketMessageLayer.AddPacketHandler<UploadFilePacket>( async (packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write); await stream.WriteAsync(packet.Data, 0, packet.Data.Length); stream.Dispose(); }); socketMessageLayer.AddPacketHandler<FileExistsQuery>( async (packet) => { var fileExists = await VirtualFileSystem.FileExistsAsync(packet.Url); socketMessageLayer.Send(new FileExistsAnswer { StreamId = packet.StreamId, FileExists = fileExists }); }); }
public void KeyPress(Keys key, TimeSpan timeDown) { socketMessageLayer.Send(new KeySimulationRequest { Down = true, Key = key }).Wait(); Console.WriteLine(@"Simulating key down {0}.", key); Thread.Sleep(timeDown); socketMessageLayer.Send(new KeySimulationRequest { Down = false, Key = key }).Wait(); Console.WriteLine(@"Simulating key up {0}.", key); }
private static async Task ShaderCompilerRequestHandler(SocketMessageLayer socketMessageLayer, EffectCompiler effectCompiler, RemoteEffectCompilerEffectRequest remoteEffectCompilerEffectRequest) { // Yield so that this socket can continue its message loop to answer to shader file request // TODO: maybe not necessary anymore with RouterServiceServer? await Task.Yield(); Console.WriteLine($"Compiling shader: {remoteEffectCompilerEffectRequest.MixinTree.Name}"); // A shader has been requested, compile it (asynchronously)! var precompiledEffectShaderPass = await effectCompiler.Compile(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters, null).AwaitResult(); // Send compiled shader await socketMessageLayer.Send(new RemoteEffectCompilerEffectAnswer { StreamId = remoteEffectCompilerEffectRequest.StreamId, EffectBytecode = precompiledEffectShaderPass.Bytecode }); }
private static async Task ShaderCompilerRequestHandler(SocketMessageLayer socketMessageLayer, EffectLogStore recordedEffectCompile, EffectCompiler effectCompiler, RemoteEffectCompilerEffectRequest remoteEffectCompilerEffectRequest) { // Yield so that this socket can continue its message loop to answer to shader file request // TODO: maybe not necessary anymore with RouterServiceServer? await Task.Yield(); Console.WriteLine("Compiling shader"); // Restore MixinTree.UsedParameters (since it is DataMemberIgnore) remoteEffectCompilerEffectRequest.MixinTree.UsedParameters = remoteEffectCompilerEffectRequest.UsedParameters; // A shader has been requested, compile it (asynchronously)! var precompiledEffectShaderPass = await effectCompiler.Compile(remoteEffectCompilerEffectRequest.MixinTree, null).AwaitResult(); // Record compilation to asset file (only if parent) recordedEffectCompile[new EffectCompileRequest(remoteEffectCompilerEffectRequest.MixinTree.Name, remoteEffectCompilerEffectRequest.MixinTree.UsedParameters)] = true; // Send compiled shader socketMessageLayer.Send(new RemoteEffectCompilerEffectAnswer { StreamId = remoteEffectCompilerEffectRequest.StreamId, EffectBytecode = precompiledEffectShaderPass.Bytecode }); }
private void SaveTexture(Texture texture, string filename) { using (var image = texture.GetDataAsImage()) { //Send to server and store to disk var imageData = new TestResultImage { CurrentVersion = "1.0", Frame = "0", Image = image, TestName = "" }; var payload = new ScreenShotPayload { FileName = filename }; var resultFileStream = new MemoryStream(); var writer = new BinaryWriter(resultFileStream); imageData.Write(writer); Task.Run(() => { payload.Data = resultFileStream.ToArray(); payload.Size = payload.Data.Length; socketMessageLayer.Send(payload).Wait(); resultFileStream.Dispose(); }); } }
public GameTestingClient(string gamePath, PlatformType platform) { GameTestingSystem.Initialized = true; //prevent time-outs from test side!! if (gamePath == null) { throw new ArgumentNullException(nameof(gamePath)); } xenkoDir = Environment.GetEnvironmentVariable("SiliconStudioXenkoDir"); if (xenkoDir.IsNullOrEmpty()) { throw new NullReferenceException("Could not find SiliconStudioXenkoDir, make sure the environment variable is set."); } gameName = Path.GetFileNameWithoutExtension(gamePath); switch (platform) { case PlatformType.Windows: platformName = "Windows"; break; case PlatformType.Android: platformName = "Android"; break; case PlatformType.iOS: platformName = "iOS"; break; case PlatformType.UWP: platformName = "UWP"; break; default: platformName = ""; break; } var url = $"/service/{XenkoVersion.CurrentAsText}/SiliconStudio.Xenko.SamplesTestServer.exe"; var socketContext = RouterClient.RequestServer(url).Result; var success = false; var message = ""; var ev = new AutoResetEvent(false); socketMessageLayer = new SocketMessageLayer(socketContext, false); socketMessageLayer.AddPacketHandler <StatusMessageRequest>(request => { success = !request.Error; message = request.Message; ev.Set(); }); socketMessageLayer.AddPacketHandler <LogRequest>(request => { Console.WriteLine(request.Message); }); socketMessageLayer.AddPacketHandler <ScreenshotStored>(request => { screenshotEvent.Set(); }); var runTask = Task.Run(() => socketMessageLayer.MessageLoop()); var cmd = platform == PlatformType.Windows ? xenkoDir + "\\" + gamePath : ""; socketMessageLayer.Send(new TestRegistrationRequest { Platform = (int)platform, Tester = true, Cmd = cmd, GameAssembly = gameName }).Wait(); var waitMs = 10000; switch (platform) { case PlatformType.Android: waitMs = 20000; break; case PlatformType.iOS: waitMs = 40000; break; } if (!ev.WaitOne(waitMs)) { socketMessageLayer.Send(new TestAbortedRequest()).Wait(); throw new Exception("Time out while launching the game"); } if (!success) { throw new Exception("Failed: " + message); } Console.WriteLine(@"Game started. (message: " + message + @")"); }
public override async void Initialize() { var game = (Game)Game; var url = $"/service/Stride.SamplesTestServer/{StrideVersion.NuGetVersion}/Stride.SamplesTestServer.exe"; var socketContext = await RouterClient.RequestServer(url); socketMessageLayer = new SocketMessageLayer(socketContext, false); socketMessageLayer.AddPacketHandler <KeySimulationRequest>(request => { drawActions.Enqueue(() => { if (request.Down) { keyboardSimulated.SimulateDown(request.Key); } else { keyboardSimulated.SimulateUp(request.Key); } }); }); socketMessageLayer.AddPacketHandler <TapSimulationRequest>(request => { drawActions.Enqueue(() => { mouseSimulated.SimulatePointer(request.EventType, request.Coords); }); }); socketMessageLayer.AddPacketHandler <ScreenshotRequest>(request => { drawActions.Enqueue(() => { SaveTexture(game.GraphicsDevice.Presenter.BackBuffer, request.Filename); }); }); socketMessageLayer.AddPacketHandler <TestEndedRequest>(request => { socketMessageLayer.Context.Dispose(); game.Exit(); Quit(); }); var t = Task.Run(() => socketMessageLayer.MessageLoop()); drawActions.Enqueue(async() => { await socketMessageLayer.Send(new TestRegistrationRequest { GameAssembly = game.Settings.PackageName, Tester = false, Platform = (int)Platform.Type }); }); Initialized = true; Console.WriteLine(@"Test initialized, waiting to start..."); }
protected override async void HandleClient(SimpleSocket clientSocket, string url) { await AcceptConnection(clientSocket); var socketMessageLayer = new SocketMessageLayer(clientSocket, true); socketMessageLayer.AddPacketHandler<TestRegistrationRequest>(request => { if (request.Tester) { switch (request.Platform) { case (int)PlatformType.Windows: { Process process = null; var debugInfo = ""; try { var workingDir = Path.GetDirectoryName(request.Cmd); if (workingDir != null) { var start = new ProcessStartInfo { WorkingDirectory = workingDir, FileName = request.Cmd }; start.EnvironmentVariables["SiliconStudioXenkoDir"] = Environment.GetEnvironmentVariable("SiliconStudioXenkoDir"); start.UseShellExecute = false; start.RedirectStandardError = true; start.RedirectStandardOutput = true; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; socketMessageLayer.Send(new LogRequest { Message = debugInfo }).Wait(); process = Process.Start(start); } } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { process.OutputDataReceived += (sender, args) => { try { socketMessageLayer.Send(new LogRequest { Message = $"STDIO: {args.Data}" }).Wait(); } catch { } }; process.ErrorDataReceived += (sender, args) => { try { socketMessageLayer.Send(new LogRequest { Message = $"STDERR: {args.Data}" }).Wait(); } catch { } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.Android: { Process process = null; try { process = Process.Start("cmd.exe", $"/C adb shell monkey -p {request.GameAssembly}.{request.GameAssembly} -c android.intent.category.LAUNCHER 1"); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process." }).Wait(); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process, TestEndAction = () => { // force stop - only works for Android 3.0 and above. Process.Start("cmd.exe", $"/C adb shell am force-stop {request.GameAssembly}.{request.GameAssembly}"); } }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.iOS: { Process process = null; var debugInfo = ""; try { Thread.Sleep(5000); //ios processes might be slow to close, we must make sure that we start clean var start = new ProcessStartInfo { WorkingDirectory = $"{Environment.GetEnvironmentVariable("SiliconStudioXenkoDir")}\\Bin\\Windows-Direct3D11\\", FileName = $"{Environment.GetEnvironmentVariable("SiliconStudioXenkoDir")}\\Bin\\Windows-Direct3D11\\idevicedebug.exe", Arguments = $"run com.your-company.{request.GameAssembly}", UseShellExecute = false }; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; process = Process.Start(start); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = $"Launch exception: {ex.Message} info: {debugInfo}" }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } } } else //Game process { TestPair pair; if (!processes.TryGetValue(request.GameAssembly, out pair)) return; pair.GameSocket = socketMessageLayer; testerToGame[pair.TesterSocket] = pair; gameToTester[pair.GameSocket] = pair; pair.TesterSocket.Send(new StatusMessageRequest { Error = false, Message = "Start" }).Wait(); Console.WriteLine($"Starting test {request.GameAssembly}"); } }); socketMessageLayer.AddPacketHandler<KeySimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TapSimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<ScreenshotRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TestEndedRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); testerToGame.Remove(socketMessageLayer); gameToTester.Remove(game.GameSocket); processes.Remove(game.GameName); socketMessageLayer.Context.Dispose(); game.GameSocket.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } game.TestEndAction?.Invoke(); Console.WriteLine($"Finished test {game.GameName}"); }); socketMessageLayer.AddPacketHandler<TestAbortedRequest>(request => { var game = testerToGame[socketMessageLayer]; testerToGame.Remove(socketMessageLayer); processes.Remove(game.GameName); socketMessageLayer.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } game.TestEndAction?.Invoke(); Console.WriteLine($"Aborted test {game.GameName}"); }); socketMessageLayer.AddPacketHandler<ScreenShotPayload>(request => { var tester = gameToTester[socketMessageLayer]; var imageData = new TestResultImage(); var stream = new MemoryStream(request.Data); imageData.Read(new BinaryReader(stream)); stream.Dispose(); var resultFileStream = File.OpenWrite(request.FileName); imageData.Image.Save(resultFileStream, ImageFileType.Png); resultFileStream.Dispose(); tester.TesterSocket.Send(new ScreenshotStored()).Wait(); }); Task.Run(async () => { try { await socketMessageLayer.MessageLoop(); } catch { } }); }
public override async void Initialize() { var game = (Game)Game; var url = $"/service/{XenkoVersion.CurrentAsText}/SiliconStudio.Xenko.SamplesTestServer.exe"; var socketContext = await RouterClient.RequestServer(url); socketMessageLayer = new SocketMessageLayer(socketContext, false); socketMessageLayer.AddPacketHandler<KeySimulationRequest>(request => { if (request.Down) { game.Input.SimulateKeyDown(request.Key); } else { game.Input.SimulateKeyUp(request.Key); } }); socketMessageLayer.AddPacketHandler<TapSimulationRequest>(request => { switch (request.State) { case PointerState.Down: game.Input.SimulateTapDown(request.Coords); break; case PointerState.Up: game.Input.SimulateTapUp(request.Coords, request.CoordsDelta, request.Delta); break; case PointerState.Move: game.Input.SimulateTapMove(request.Coords, request.CoordsDelta, request.Delta); break; } }); socketMessageLayer.AddPacketHandler<ScreenshotRequest>(request => { drawActions.Enqueue(() => { SaveTexture(game.GraphicsDevice.BackBuffer, request.Filename); }); }); socketMessageLayer.AddPacketHandler<TestEndedRequest>(request => { socketMessageLayer.Context.Dispose(); game.Exit(); Quit(); }); Task.Run(() => socketMessageLayer.MessageLoop()); drawActions.Enqueue(async () => { await socketMessageLayer.Send(new TestRegistrationRequest { GameAssembly = game.Settings.PackageName, Tester = false, Platform = (int)Platform.Type }); }); Initialized = true; #if SILICONSTUDIO_PLATFORM_IOS || SILICONSTUDIO_PLATFORM_ANDROID || SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP Console.WriteLine(@"Test initialized, waiting to start..."); #endif }
public GameTestingClient(string gamePath, PlatformType platform) { GameTestingSystem.Initialized = true; //prevent time-outs from test side!! this.gamePath = gamePath ?? throw new ArgumentNullException(nameof(gamePath)); gameName = Path.GetFileName(gamePath); switch (platform) { case PlatformType.Windows: platformName = "Windows"; break; case PlatformType.Android: platformName = "Android"; break; case PlatformType.iOS: platformName = "iOS"; break; case PlatformType.UWP: platformName = "UWP"; break; default: platformName = ""; break; } var url = $"/service/Stride.SamplesTestServer/{StrideVersion.NuGetVersion}/Stride.SamplesTestServer.exe"; var socketContext = RouterClient.RequestServer(url).Result; var success = false; var message = ""; var ev = new AutoResetEvent(false); socketMessageLayer = new SocketMessageLayer(socketContext, false); socketMessageLayer.AddPacketHandler <StatusMessageRequest>(request => { success = !request.Error; message = request.Message; ev.Set(); }); socketMessageLayer.AddPacketHandler <LogRequest>(request => { Console.WriteLine(request.Message); }); socketMessageLayer.AddPacketHandler <ScreenshotStored>(request => { screenshotEvent.Set(); }); var runTask = Task.Run(() => socketMessageLayer.MessageLoop()); var cmd = platform == PlatformType.Windows ? Path.Combine(Environment.CurrentDirectory, gamePath, "Bin\\Windows\\Debug", gameName + ".Windows.exe") : ""; socketMessageLayer.Send(new TestRegistrationRequest { Platform = (int)platform, Tester = true, Cmd = cmd, GameAssembly = gameName + ".Game" }).Wait(); // Wait up to one minute var waitMs = 60 * 1000; switch (platform) { case PlatformType.Android: waitMs *= 2; break; case PlatformType.iOS: waitMs *= 2; break; } if (!ev.WaitOne(waitMs)) { socketMessageLayer.Send(new TestAbortedRequest()).Wait(); throw new Exception("Time out while launching the game"); } if (!success) { throw new Exception("Failed: " + message); } Console.WriteLine(@"Game started. (message: " + message + @")"); }
public SamplesTestServer() : base($"/service/{XenkoVersion.CurrentAsText}/SiliconStudio.Xenko.SamplesTestServer.exe") { //start logging the iOS device if we have the proper tools avail if (IosTracker.CanProxy()) { var loggerProcess = Process.Start(new ProcessStartInfo($"{ Environment.GetEnvironmentVariable("SiliconStudioXenkoDir") }\\Bin\\Windows-Direct3D11\\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 { //clear the log first ShellHelper.RunProcessAndGetOutput("cmd.exe", "/C adb logcat -c"); //start logger var loggerProcess = Process.Start(new ProcessStartInfo("cmd.exe", "/C adb 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); } } }
protected override async void HandleClient(SimpleSocket clientSocket, string url) { await AcceptConnection(clientSocket); var socketMessageLayer = new SocketMessageLayer(clientSocket, true); socketMessageLayer.AddPacketHandler<TestRegistrationRequest>(request => { if (request.Tester) { switch (request.Platform) { case (int)PlatformType.Windows: { Process process = null; var debugInfo = ""; try { var start = new ProcessStartInfo { WorkingDirectory = Path.GetDirectoryName(request.Cmd), FileName = request.Cmd, }; start.EnvironmentVariables["SiliconStudioXenkoDir"] = Environment.GetEnvironmentVariable("SiliconStudioXenkoDir"); start.UseShellExecute = false; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; socketMessageLayer.Send(new LogRequest { Message = debugInfo }).Wait(); process = Process.Start(start); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { processes[request.GameAssembly] = new TestProcess { Process = process, TesterSocket = socketMessageLayer }; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.Android: { Process process = null; var debugInfo = ""; try { process = Process.Start("cmd.exe", $"/C adb shell monkey -p {request.GameAssembly}.{request.GameAssembly} -c android.intent.category.LAUNCHER 1"); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { processes[request.GameAssembly] = new TestProcess { Process = process, TesterSocket = socketMessageLayer }; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } } } else //Game process { TestProcess process; if (processes.TryGetValue(request.GameAssembly, out process)) { process.GameSocket = socketMessageLayer; testerToGame[process.TesterSocket] = process.GameSocket; gameToTester[process.GameSocket] = process.TesterSocket; process.TesterSocket.Send(new StatusMessageRequest { Error = false, Message = "Start" }).Wait(); } } }); socketMessageLayer.AddPacketHandler<KeySimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TapSimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<ScreenshotRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TestEndedRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); testerToGame.Remove(socketMessageLayer); }); socketMessageLayer.AddPacketHandler<ScreenShotPayload>(request => { var tester = gameToTester[socketMessageLayer]; var imageData = new TestResultImage(); var stream = new MemoryStream(request.Data); imageData.Read(new BinaryReader(stream)); stream.Dispose(); var resultFileStream = File.OpenWrite(request.FileName); imageData.Image.Save(resultFileStream, ImageFileType.Png); resultFileStream.Dispose(); tester.Send(new ScreenshotStored()).Wait(); }); Task.Run(() => socketMessageLayer.MessageLoop()); }
protected override async void HandleClient(SimpleSocket clientSocket, string url) { await AcceptConnection(clientSocket); var socketMessageLayer = new SocketMessageLayer(clientSocket, true); socketMessageLayer.AddPacketHandler <TestRegistrationRequest>(async request => { if (request.Tester) { switch (request.Platform) { case (int)PlatformType.Windows: { Process process = null; var debugInfo = ""; try { var workingDir = Path.GetDirectoryName(request.Cmd); if (workingDir != null) { var start = new ProcessStartInfo { WorkingDirectory = workingDir, FileName = request.Cmd }; start.UseShellExecute = false; start.RedirectStandardError = true; start.RedirectStandardOutput = true; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; await socketMessageLayer.Send(new LogRequest { Message = debugInfo }); process = Process.Start(start); } } catch (Exception ex) { await socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }); } if (process == null) { await socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }); } else { process.OutputDataReceived += async(sender, args) => { try { if (args.Data != null) { await socketMessageLayer.Send(new LogRequest { Message = $"STDIO: {args.Data}" }); } } catch { } }; process.ErrorDataReceived += async(sender, args) => { try { if (args.Data != null) { await socketMessageLayer.Send(new LogRequest { Message = $"STDERR: {args.Data}" }); } } catch { } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; lock (processes) { processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; } await socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }); } break; } case (int)PlatformType.Android: { Process process = null; try { process = Process.Start("cmd.exe", $"/C adb shell monkey -p {request.GameAssembly}.{request.GameAssembly} -c android.intent.category.LAUNCHER 1"); } catch (Exception ex) { await socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }); } if (process == null) { await socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process." }); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process, TestEndAction = () => { // force stop - only works for Android 3.0 and above. Process.Start("cmd.exe", $"/C adb shell am force-stop {request.GameAssembly}.{request.GameAssembly}"); } }; lock (processes) { processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; } await socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }); } break; } case (int)PlatformType.iOS: { Process process = null; var debugInfo = ""; try { Thread.Sleep(5000); //ios processes might be slow to close, we must make sure that we start clean var start = new ProcessStartInfo { FileName = $"idevicedebug.exe", Arguments = $"run com.your-company.{request.GameAssembly}", UseShellExecute = false }; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; process = Process.Start(start); } catch (Exception ex) { await socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = $"Launch exception: {ex.Message} info: {debugInfo}" }); } if (process == null) { await socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; lock (processes) { processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; } await socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }); } break; } } } else //Game process { TestPair pair; lock (processes) { if (!processes.TryGetValue(request.GameAssembly, out pair)) { return; } pair.GameSocket = socketMessageLayer; testerToGame[pair.TesterSocket] = pair; gameToTester[pair.GameSocket] = pair; } await pair.TesterSocket.Send(new StatusMessageRequest { Error = false, Message = "Start" }); Console.WriteLine($"Starting test {request.GameAssembly}"); } }); socketMessageLayer.AddPacketHandler <KeySimulationRequest>(async request => { TestPair game; lock (processes) { game = testerToGame[socketMessageLayer]; } await game.GameSocket.Send(request); }); socketMessageLayer.AddPacketHandler <TapSimulationRequest>(async request => { TestPair game; lock (processes) { game = testerToGame[socketMessageLayer]; } await game.GameSocket.Send(request); }); socketMessageLayer.AddPacketHandler <ScreenshotRequest>(async request => { TestPair game; lock (processes) { game = testerToGame[socketMessageLayer]; } await game.GameSocket.Send(request); }); socketMessageLayer.AddPacketHandler <TestEndedRequest>(async request => { TestPair game; lock (processes) { game = testerToGame[socketMessageLayer]; } await game.GameSocket.Send(request); lock (processes) { testerToGame.Remove(socketMessageLayer); gameToTester.Remove(game.GameSocket); processes.Remove(game.GameName); } socketMessageLayer.Context.Dispose(); game.GameSocket.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } game.TestEndAction?.Invoke(); Console.WriteLine($"Finished test {game.GameName}"); }); socketMessageLayer.AddPacketHandler <TestAbortedRequest>(request => { TestPair game; lock (processes) { game = testerToGame[socketMessageLayer]; testerToGame.Remove(socketMessageLayer); processes.Remove(game.GameName); } socketMessageLayer.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } game.TestEndAction?.Invoke(); Console.WriteLine($"Aborted test {game.GameName}"); }); socketMessageLayer.AddPacketHandler <ScreenShotPayload>(async request => { TestPair tester; lock (processes) { tester = gameToTester[socketMessageLayer]; } var imageData = new TestResultImage(); var stream = new MemoryStream(request.Data); imageData.Read(new BinaryReader(stream)); stream.Dispose(); // Ensure directory exists Directory.CreateDirectory(Path.GetDirectoryName(request.FileName)); var resultFileStream = File.OpenWrite(request.FileName); imageData.Image.Save(resultFileStream, ImageFileType.Png); resultFileStream.Dispose(); await tester.TesterSocket.Send(new ScreenshotStored()); }); Task.Run(async() => { try { await socketMessageLayer.MessageLoop(); } catch { } }); }
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 override async void Initialize() { var game = (Game)Game; //Quit after 1 minute anyway! Task.Run(async () => { await Task.Delay(60000); Quit(game); }); var url = $"/service/{XenkoVersion.CurrentAsText}/SiliconStudio.Xenko.SamplesTestServer.exe"; var socketContext = await RouterClient.RequestServer(url); socketMessageLayer = new SocketMessageLayer(socketContext, false); socketMessageLayer.AddPacketHandler<KeySimulationRequest>(request => { if (request.Down) { game.Input.SimulateKeyDown(request.Key); } else { game.Input.SimulateKeyUp(request.Key); } }); socketMessageLayer.AddPacketHandler<TapSimulationRequest>(request => { switch (request.State) { case PointerState.Down: game.Input.SimulateTapDown(request.Coords); break; case PointerState.Up: game.Input.SimulateTapUp(request.Coords, request.CoordsDelta, request.Delta); break; case PointerState.Move: game.Input.SimulateTapMove(request.Coords, request.CoordsDelta, request.Delta); break; } }); socketMessageLayer.AddPacketHandler<ScreenshotRequest>(request => { drawActions.Enqueue(() => { SaveTexture(game.GraphicsDevice.BackBuffer, request.Filename); }); }); socketMessageLayer.AddPacketHandler<TestEndedRequest>(request => { Quit(game); }); Task.Run(() => socketMessageLayer.MessageLoop()); drawActions.Enqueue(async () => { await socketMessageLayer.Send(new TestRegistrationRequest { GameAssembly = game.Settings.PackageName, Tester = false, Platform = (int)Platform.Type }); }); }
public override async void Initialize() { var game = (Game)Game; var url = $"/service/{XenkoVersion.CurrentAsText}/SiliconStudio.Xenko.SamplesTestServer.exe"; var socketContext = await RouterClient.RequestServer(url); socketMessageLayer = new SocketMessageLayer(socketContext, false); socketMessageLayer.AddPacketHandler <KeySimulationRequest>(request => { if (request.Down) { game.Input.SimulateKeyDown(request.Key); } else { game.Input.SimulateKeyUp(request.Key); } }); socketMessageLayer.AddPacketHandler <TapSimulationRequest>(request => { switch (request.State) { case PointerState.Down: game.Input.SimulateTapDown(request.Coords); break; case PointerState.Up: game.Input.SimulateTapUp(request.Coords, request.CoordsDelta, request.Delta); break; case PointerState.Move: game.Input.SimulateTapMove(request.Coords, request.CoordsDelta, request.Delta); break; } }); socketMessageLayer.AddPacketHandler <ScreenshotRequest>(request => { drawActions.Enqueue(() => { SaveTexture(game.GraphicsDevice.BackBuffer, request.Filename); }); }); socketMessageLayer.AddPacketHandler <TestEndedRequest>(request => { socketMessageLayer.Context.Dispose(); game.Exit(); Quit(); }); Task.Run(() => socketMessageLayer.MessageLoop()); drawActions.Enqueue(async() => { await socketMessageLayer.Send(new TestRegistrationRequest { GameAssembly = game.Settings.PackageName, Tester = false, Platform = (int)Platform.Type }); }); Initialized = true; #if SILICONSTUDIO_PLATFORM_IOS || SILICONSTUDIO_PLATFORM_ANDROID || SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP Console.WriteLine(@"Test initialized, waiting to start..."); #endif }
public GameTestingClient(string gamePath, PlatformType platform) { if(gamePath == null) throw new ArgumentNullException(nameof(gamePath)); xenkoDir = Environment.GetEnvironmentVariable("SiliconStudioXenkoDir"); if(xenkoDir.IsNullOrEmpty()) throw new NullReferenceException("Could not find SiliconStudioXenkoDir, make sure the environment variable is set."); gameName = Path.GetFileNameWithoutExtension(gamePath); switch (platform) { case PlatformType.Windows: platformName = "Windows"; break; case PlatformType.WindowsPhone: platformName = "WindowsPhone"; break; case PlatformType.WindowsStore: platformName = "WindowsStore"; break; case PlatformType.Android: platformName = "Android"; break; case PlatformType.iOS: platformName = "iOS"; break; case PlatformType.Windows10: platformName = "Windows10"; break; default: platformName = ""; break; } var url = $"/service/{XenkoVersion.CurrentAsText}/SiliconStudio.Xenko.SamplesTestServer.exe"; var socketContext = RouterClient.RequestServer(url).Result; var success = false; var message = ""; var ev = new AutoResetEvent(false); socketMessageLayer = new SocketMessageLayer(socketContext, false); socketMessageLayer.AddPacketHandler<StatusMessageRequest>(request => { success = !request.Error; message = request.Message; ev.Set(); }); socketMessageLayer.AddPacketHandler<LogRequest>(request => { Console.WriteLine(request.Message); }); socketMessageLayer.AddPacketHandler<ScreenshotStored>(request => { screenshotEvent.Set(); }); var runTask = Task.Run(() => socketMessageLayer.MessageLoop()); var cmd = platform == PlatformType.Windows ? xenkoDir + "\\" + gamePath : ""; socketMessageLayer.Send(new TestRegistrationRequest { Platform = (int)platform, Tester = true, Cmd = cmd, GameAssembly = gameName }).Wait(); if (!ev.WaitOne(platform == PlatformType.Windows ? 10000 : 20000)) { throw new Exception("Time out while launching the game"); } if (!success) { throw new Exception("Failed: " + message); } Console.WriteLine(@"Game started. (message: " + message + @")"); }