231 lines
7.3 KiB
C#
231 lines
7.3 KiB
C#
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Moq;
|
|
using RobotNet10.ScriptEngine;
|
|
using RobotNet10.ScriptEngine.Enums;
|
|
using RobotNet10.ScriptEngine.Helpers;
|
|
using RobotNet10.ScriptEngine.Hubs;
|
|
using RobotNet10.ScriptEngine.Models;
|
|
using RobotNet10.ScriptEngine.Shared;
|
|
using RobotNet10.ScriptEngine.Test.Helpers;
|
|
using RobotNet10.Shared;
|
|
|
|
namespace RobotNet10.ScriptEngine.Test;
|
|
|
|
[TestFixture]
|
|
public class ScriptEngineTests
|
|
{
|
|
private ScriptEngine _scriptEngine = null!;
|
|
private Mock<IScriptEngineResource> _mockResource = null!;
|
|
private FileManager _fileManager = null!;
|
|
private VariableManager _variableManager = null!;
|
|
private TaskManager _taskManager = null!;
|
|
private MissionManager _missionManager = null!;
|
|
private Mock<ILogger<ScriptEngine>> _mockLogger = null!;
|
|
private Mock<IConfiguration> _mockConfiguration = null!;
|
|
private Mock<IHubContext<ScriptManagerHub>> _mockHubContext = null!;
|
|
private string _testScriptPath = null!;
|
|
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
_testScriptPath = Path.Combine(Path.GetTempPath(), "ScriptEngineTest", Guid.NewGuid().ToString());
|
|
Directory.CreateDirectory(_testScriptPath);
|
|
|
|
_mockResource = TestHelpers.CreateMockScriptResource();
|
|
_mockLogger = new Mock<ILogger<ScriptEngine>>();
|
|
_mockConfiguration = new Mock<IConfiguration>();
|
|
_mockHubContext = TestHelpers.CreateMockHubContext();
|
|
|
|
var mockConsoleHubContext = TestHelpers.CreateMockConsoleHubContext();
|
|
var mockLoggerGlobals = TestHelpers.CreateMockLogger();
|
|
var configuration = TestHelpers.CreateMockConfiguration();
|
|
var mockScopeFactory = Mock.Of<IServiceScopeFactory>();
|
|
|
|
_variableManager = new VariableManager();
|
|
_fileManager = new FileManager();
|
|
_fileManager.RootPath = _testScriptPath;
|
|
_taskManager = new TaskManager(
|
|
_variableManager,
|
|
_mockResource.Object,
|
|
mockLoggerGlobals.Object,
|
|
mockScopeFactory,
|
|
mockConsoleHubContext.Object,
|
|
configuration);
|
|
_missionManager = new MissionManager(
|
|
mockScopeFactory,
|
|
_variableManager,
|
|
_mockResource.Object,
|
|
mockLoggerGlobals.Object,
|
|
mockConsoleHubContext.Object,
|
|
configuration);
|
|
|
|
_scriptEngine = new ScriptEngine(
|
|
_mockResource.Object,
|
|
_mockConfiguration.Object,
|
|
_fileManager,
|
|
_variableManager,
|
|
_taskManager,
|
|
_missionManager,
|
|
_mockLogger.Object,
|
|
_mockHubContext.Object,
|
|
mockConsoleHubContext.Object);
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
_scriptEngine?.Dispose();
|
|
_taskManager?.Dispose();
|
|
_missionManager?.Dispose();
|
|
|
|
if (Directory.Exists(_testScriptPath))
|
|
{
|
|
Directory.Delete(_testScriptPath, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Constructor_ShouldInitializeToIdleState()
|
|
{
|
|
// Assert
|
|
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Idle));
|
|
}
|
|
|
|
[Test]
|
|
public void Build_WithValidScript_ShouldTransitionToReady()
|
|
{
|
|
// Arrange
|
|
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
|
File.WriteAllText(scriptFile, @"
|
|
using RobotNet10.Script;
|
|
|
|
public class DummyClass
|
|
{
|
|
[Variable]
|
|
public int TestVar = 42;
|
|
}
|
|
");
|
|
|
|
// Act
|
|
var result = _scriptEngine.Build();
|
|
|
|
// Assert
|
|
Assert.That(result.IsSuccess, Is.True);
|
|
// Wait a bit for async build to complete
|
|
Thread.Sleep(500);
|
|
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Ready).Or.EqualTo(ScriptEngineState.Building));
|
|
}
|
|
|
|
[Test]
|
|
public void Build_WithInvalidScript_ShouldTransitionToBuildError()
|
|
{
|
|
// Arrange
|
|
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
|
File.WriteAllText(scriptFile, "invalid syntax here");
|
|
|
|
// Act
|
|
var result = _scriptEngine.Build();
|
|
|
|
// Assert
|
|
Assert.That(result.IsSuccess, Is.True); // Build initiation succeeds
|
|
// Wait a bit for async build to complete
|
|
Thread.Sleep(500);
|
|
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.BuildError).Or.EqualTo(ScriptEngineState.Building));
|
|
}
|
|
|
|
[Test]
|
|
public void Build_WhenNotIdle_ShouldFail()
|
|
{
|
|
// Arrange
|
|
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
|
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
|
_scriptEngine.Build();
|
|
Thread.Sleep(500); // Wait for build to complete
|
|
_scriptEngine.Start();
|
|
Thread.Sleep(500); // Wait for start to complete
|
|
|
|
// Act
|
|
var result = _scriptEngine.Build();
|
|
|
|
// Assert
|
|
Assert.That(result.IsSuccess, Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void Start_WhenReady_ShouldTransitionToRunning()
|
|
{
|
|
// Arrange
|
|
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
|
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
|
_scriptEngine.Build();
|
|
Thread.Sleep(1000); // Wait for build to complete
|
|
|
|
// Act
|
|
var result = _scriptEngine.Start();
|
|
|
|
// Assert
|
|
Assert.That(result.IsSuccess, Is.True);
|
|
Thread.Sleep(500);
|
|
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Running).Or.EqualTo(ScriptEngineState.Starting));
|
|
}
|
|
|
|
[Test]
|
|
public void Start_WhenNotReady_ShouldFail()
|
|
{
|
|
// Act
|
|
var result = _scriptEngine.Start();
|
|
|
|
// Assert
|
|
Assert.That(result.IsSuccess, Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void Stop_WhenRunning_ShouldTransitionToReady()
|
|
{
|
|
// Arrange
|
|
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
|
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
|
_scriptEngine.Build();
|
|
Thread.Sleep(1000);
|
|
_scriptEngine.Start();
|
|
Thread.Sleep(1000);
|
|
|
|
// Act
|
|
var result = _scriptEngine.Stop();
|
|
|
|
// Assert
|
|
Assert.That(result.IsSuccess, Is.True);
|
|
Thread.Sleep(2000); // Wait for stop to complete
|
|
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Ready).Or.EqualTo(ScriptEngineState.Stopping));
|
|
}
|
|
|
|
[Test]
|
|
public void Reset_ShouldTransitionToIdle()
|
|
{
|
|
// Arrange
|
|
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
|
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
|
_scriptEngine.Build();
|
|
Thread.Sleep(1000);
|
|
|
|
// Act
|
|
var result = _scriptEngine.Reset();
|
|
|
|
// Assert
|
|
Assert.That(result.IsSuccess, Is.True);
|
|
Thread.Sleep(500);
|
|
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Idle).Or.EqualTo(ScriptEngineState.Resetting));
|
|
}
|
|
|
|
[Test]
|
|
public void Dispose_ShouldCleanupResources()
|
|
{
|
|
// Act & Assert
|
|
Assert.DoesNotThrow(() => _scriptEngine.Dispose());
|
|
}
|
|
}
|
|
|