using System.Linq; using System.Threading.Tasks; using NUnit.Framework; using Unity.Pipeline.Commands; using Unity.Pipeline.Editor; using Unity.Pipeline.Models; using Newtonsoft.Json.Linq; using UnityEngine; using System.IO; using Unity.Pipeline.Tests.Editor; using Unity.Pipeline.Tests.Runtime; namespace Unity.Pipeline.Tests.Editor.ServerLifecyle { /// /// End-to-end tests demonstrating complete Pipeline workflow. /// These test the full roundtrip: discovery → connection → command execution /// that simulates real CLI usage patterns. /// /// Marked [Explicit]: starts its own EditorPipelineServer (and manages the shared descriptor), /// which conflicts with the live editor server. Excluded from the normal/dogfood run. /// TODO: to rejoin the dogfood run, refactor to drive an isolated TestEditorPipelineServer /// (ports 7850+, WritesDescriptor=false) instead of starting a real server. /// [Explicit("Starts its own server; conflicts with the live editor server. Run deliberately.")] [Category("ServerLifecycle")] public class EndToEndTests { [Test] public async Task CompleteWorkflow_DiscoverConnectExecute_WorksEndToEnd() { // Setup CommandRegistry.SetDiscovery(new TypeCacheCommandDiscovery()); // Step 1: Start Pipeline Server (simulates Editor startup) var server = new EditorPipelineServer(); server.Start(); try { var projectPath = Path.GetDirectoryName(Application.dataPath); // Step 2: CLI Discovery - Find running instances var instances = MockCliDiscovery.DiscoverInstances(new[] { projectPath }); var runningInstances = instances.Where(i => i.IsRunning).ToList(); Assert.Greater(runningInstances.Count, 0, "Should discover at least one running instance"); var targetInstance = runningInstances.First(); // Give server a moment to fully start await Task.Delay(100); // Step 3: CLI Connection Validation var isReachable = await MockCliDiscovery.ValidateConnection(targetInstance.Descriptor); Assert.IsTrue(isReachable, "Discovered instance should be reachable"); // Step 4: CLI Command Discovery - Get available commands using (var client = new PipelineClient(server)) { var commandsResponse = await client.GetAsync("/api/commands"); Assert.IsTrue(commandsResponse.IsSuccess, "Should be able to get commands list"); var commands = commandsResponse.JsonResponse["commands"] as JArray; Assert.Greater(commands.Count, 0, "Should have available commands"); // Step 5: CLI Command Execution - Execute log_editor command var execResponse = await client.ExecuteCommandAsync( "log_editor", new { message = "Hello from end-to-end test!" }); Assert.IsTrue(execResponse.IsSuccess, $"Command execution should succeed. Response: {execResponse.RawResponse}"); var execData = execResponse.JsonResponse; Assert.IsTrue(execData["success"].ToObject(), "Command should execute successfully"); Assert.AreEqual("log_editor", execData["command"]?.ToString()); } } finally { server.Stop(); } } [Test] public async Task RealWorldScenario_MultipleCommands_ExecutesSequentially() { // Setup CommandRegistry.SetDiscovery(new TypeCacheCommandDiscovery()); var server = new EditorPipelineServer(); server.Start(); try { using (var client = new PipelineClient(server)) { // Simulate CLI batch execution of multiple commands var commands = new CommandExecutionRequest[] { new CommandExecutionRequest("log_editor") { Parameters = { ["message"] = "Starting batch execution" } }, new CommandExecutionRequest("test_types") { Parameters = { ["count"] = 5, ["enabled"] = true, ["factor"] = 2.5f } }, new CommandExecutionRequest("log_editor") { Parameters = { ["message"] = "Batch execution completed" } } }; foreach (var cmd in commands) { var response = await client.ExecuteCommandAsync(cmd.Command, cmd.Parameters); Assert.IsTrue(response.IsSuccess, $"Command '{cmd.Command}' should execute successfully. Response: {response.RawResponse}"); Assert.IsTrue(response.JsonResponse["success"].ToObject(), $"Command '{cmd.Command}' should succeed"); } } } finally { server.Stop(); } } } }