using NUnit.Framework; using Unity.Pipeline.Config; using Unity.Pipeline.Models; using UnityEngine; namespace Unity.Pipeline.Tests.Editor { /// /// Tests for RuntimePipelineManager component functionality. /// Validates the unified runtime approach and port range separation. /// /// /// Excluded from the default (dogfood) run: these tests start a real RuntimePipelineManager / /// runtime server and mutate global command discovery, which destabilizes the live editor /// server agents drive over HTTP. Run them deliberately from the Test Runner window. /// [Explicit("Starts a real RuntimePipelineManager/server and mutates global state; would destabilize the live server. Run manually from the Test Runner window.")] [Category("ServerLifecycle")] public class RuntimePipelineManagerTests { private GameObject m_TestGameObject; private RuntimePipelineManager m_Manager; [SetUp] public void SetUp() { // Create test GameObject with RuntimePipelineManager m_TestGameObject = new GameObject("TestRuntimePipelineManager"); m_Manager = m_TestGameObject.AddComponent(); } [TearDown] public void TearDown() { // Clean up if (m_Manager != null && m_Manager.IsServerRunning) { m_Manager.StopServer(); } if (m_TestGameObject != null) { Object.DestroyImmediate(m_TestGameObject); } } [Test] public void ComponentCreation_DefaultValues_AreSecure() { // Assert default security configuration Assert.IsFalse(m_Manager.enableInBuilds, "enableInBuilds should default to false for security"); Assert.AreEqual(0, m_Manager.port, "Port should default to 0 for auto-assignment"); Assert.IsTrue(m_Manager.autoStart, "Should default to auto-start"); Assert.AreEqual(10, m_Manager.maxWorkItemsPerFrame, "Should have reasonable default for work items per frame"); } [Test] public void ServerLifecycle_EnabledInBuilds_CanStartAndStop() { // Arrange m_Manager.enableInBuilds = true; // Act - Start server m_Manager.StartServer(); // Assert - Server started Assert.IsTrue(m_Manager.IsServerRunning, "Server should be running"); Assert.Greater(m_Manager.ActualPort, 0, "Should have assigned port"); Assert.NotNull(m_Manager.Server, "Server instance should exist"); // Act - Stop server m_Manager.StopServer(); // Assert - Server stopped Assert.IsFalse(m_Manager.IsServerRunning, "Server should be stopped"); } // Runtime port-range separation is covered by RuntimePipelineServerTests // (RuntimeServer_PortRange_UsesDifferentRangeFromEditor and friends). [Test] public void Configuration_ValidSettings_PassesValidation() { // Arrange - Valid configuration m_Manager.enableInBuilds = true; // Act var result = m_Manager.ValidateConfiguration(); // Assert Assert.IsTrue(result.IsValid, $"Should pass validation: {result.Message}"); } [Test] public void Token_AutoGenerated_IsSecure() { // Arrange var config = ScriptableObject.CreateInstance(); // Act var descriptor = RuntimeInstanceDescriptor.CreateCurrent(7900, config); // Assert Assert.IsNotEmpty(descriptor.EvalToken, "Token should not be empty"); Assert.GreaterOrEqual(descriptor.EvalToken.Length, 32, "Token should be at least 32 characters for security"); Object.DestroyImmediate(config); } [Test] public void ServerStart_DisabledInBuilds_DoesNotStart() { // Arrange m_Manager.enableInBuilds = false; // Act m_Manager.StartServer(); // Assert Assert.IsFalse(m_Manager.IsServerRunning, "Server should not start when disabled"); } [Test] public void ServerStart_AlreadyStarted_DoesNotStartAgain() { // Arrange m_Manager.enableInBuilds = true; m_Manager.StartServer(); var firstPort = m_Manager.ActualPort; // Act - Try to start again m_Manager.StartServer(); // Assert Assert.AreEqual(firstPort, m_Manager.ActualPort, "Port should not change when starting already started server"); } } }