Implemented IPC system with minimal testing.

Large naming refactoring.

Added some more tests.
This commit is contained in:
2021-04-08 21:36:08 -05:00
parent 56259ac419
commit dfc54fdc00
64 changed files with 2231 additions and 1437 deletions

View File

@@ -15,7 +15,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\GameServiceWarden.Core\GameServiceWarden.Core.csproj" />
<ProjectReference Include="..\..\src\GameServiceWarden.ModuleAPI\GameServiceWarden.ModuleAPI.csproj" />
<ProjectReference Include="..\..\src\GameServiceWarden.API.Module\GameServiceWarden.API.Module.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using GameServiceWarden.ModuleAPI;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
public class FakeGameService : IGameService
{
public IReadOnlyCollection<IGameConfigurable> Configurables { get; set; }
public event EventHandler<ServiceState> StateChangeEvent;
public ServiceState CurrentState { get; private set; } = ServiceState.Stopped;
private TextWriter consoleStream;
public FakeGameService(params IGameConfigurable[] configurables)
{
HashSet<IGameConfigurable> modifiable = new HashSet<IGameConfigurable>();
foreach (IGameConfigurable configurable in configurables)
{
modifiable.Add(configurable);
}
this.Configurables = modifiable;
}
public void ElegantShutdown()
{
CurrentState = ServiceState.Stopped;
StateChangeEvent?.Invoke(this, CurrentState);
}
public void ExecuteCommand(string command)
{
consoleStream.WriteLine(command);
consoleStream.Flush();
}
public void InitializeService(TextWriter stream)
{
CurrentState = ServiceState.Running;
StateChangeEvent?.Invoke(this, CurrentState);
this.consoleStream = stream;
}
}
}

View File

@@ -36,7 +36,7 @@ namespace GameServiceWarden.Core.Tests.Modules
backing.Add(item);
}
public void Add(string key, GameServiceInfo value)
public void Add(string key, ServiceDescriptor value)
{
throw new System.NotImplementedException();
}

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using GameServiceWarden.API.Module;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
public class FakeService : IService
{
public IReadOnlyCollection<IServiceConfigurable> Configurables { get; set; }
public event EventHandler<bool> StateChangeEvent;
public ServiceState CurrentState { get; private set; } = ServiceState.Stopped;
private StreamWriter consoleWriter;
private Stack<Task> taskStack = new Stack<Task>();
public FakeService(params IServiceConfigurable[] configurables)
{
HashSet<IServiceConfigurable> modifiable = new HashSet<IServiceConfigurable>();
foreach (IServiceConfigurable configurable in configurables)
{
modifiable.Add(configurable);
}
this.Configurables = modifiable;
}
public void ElegantShutdown()
{
CurrentState = ServiceState.Stopped;
StateChangeEvent?.Invoke(this, false);
Task task;
while(taskStack.TryPop(out task)) {
if (task.IsCompleted) {
task.Wait();
} else {
throw new InvalidOperationException("A task was not completed.");
}
}
}
public void ExecuteCommand(string command)
{
taskStack.Push(consoleWriter.WriteLineAsync(command));
taskStack.Push(consoleWriter.FlushAsync());
}
public void InitializeService(Stream stream)
{
CurrentState = ServiceState.Running;
this.consoleWriter = new StreamWriter(stream);
StateChangeEvent?.Invoke(this, true);
}
}
}

View File

@@ -1,13 +1,13 @@
using GameServiceWarden.ModuleAPI;
using GameServiceWarden.API.Module;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
public class FakeGameConfigurable : IGameConfigurable
public class FakeServiceConfigurable : IServiceConfigurable
{
private string value;
public string OptionName { get; private set; }
public FakeGameConfigurable(string optionName)
public FakeServiceConfigurable(string optionName)
{
this.OptionName = optionName;
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using GameServiceWarden.API.Games;
using GameServiceWarden.Core.Games;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
public class FakeServiceManagerMonitor : IServiceManagerMonitor
{
public List<ServiceManagerState> states = new List<ServiceManagerState>();
public ServiceManagerState this[int i]
{
get
{
return states[i];
}
}
public void Present(ServiceManagerState state)
{
states.Add(state);
}
public ServiceManagerState GetLastState()
{
return states[states.Count - 1];
}
}
}

View File

@@ -1,25 +1,25 @@
using System.Collections.Generic;
using GameServiceWarden.ModuleAPI;
using GameServiceWarden.API.Module;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
public class FakeGameServiceModule : IGameServiceModule
public class FakeServiceModule : IServiceModule
{
public string Name => "FakeModule";
public string Description => "A fake module for testing.";
private IGameConfigurable[] configurables;
public FakeGameServiceModule(params IGameConfigurable[] configurables)
private IServiceConfigurable[] configurables;
public FakeServiceModule(params IServiceConfigurable[] configurables)
{
this.configurables = configurables;
}
public IEnumerable<string> Authors { get; private set; } = new string[] { "FakeAuthor", "FakeAuthor2" };
public IGameService InstantiateGameService(string workspace, bool clean)
public IService InstantiateService(string workspace, bool clean)
{
return new FakeGameService(configurables);
return new FakeService(configurables);
}
}
}

View File

@@ -1,155 +0,0 @@
using System.Collections.Generic;
using System.IO;
using GameServiceWarden.Core.Games;
using GameServiceWarden.ModuleAPI;
using Xunit;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
// Testing convention from: https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
// fakes are generic test objects,
// mocks are the objects being asserted upon,
// stubs are objects used as part of the test.
public class GameServiceInfoTest
{
//MethodTested_ScenarioTested_ExpectedBehavior
[Fact]
public void Start_FromStopped_StateIsRunning()
{
//Arrange, Act, Assert
IGameService stubGameService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubGameService, "FakeModule", "FakeAssembly");
serviceInfo.Start();
Assert.Equal(ServiceState.Running, serviceInfo.GetServiceState());
serviceInfo.Dispose();
}
[Fact]
public void Stop_FromStart_Stopped()
{
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
serviceInfo.Start();
serviceInfo.Stop();
Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState());
serviceInfo.Dispose();
}
[Fact]
public void GetConfigurableOptions_ServiceStopped_ReturnsConfigurables()
{
//Given
FakeGameService stubService = new FakeGameService();
FakeGameConfigurable stubConfigurable = new FakeGameConfigurable("Option");
HashSet<IGameConfigurable> configurables = new HashSet<IGameConfigurable>();
configurables.Add(stubConfigurable);
stubService.Configurables = configurables;
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//Then
Assert.Contains<string>(stubConfigurable.OptionName, serviceInfo.GetConfigurableOptions());
serviceInfo.Dispose();
}
[Fact]
public void SetAndGetConfigurationValue_ServiceStopped_AppropriateValueReturned()
{
//Given
FakeGameService stubService = new FakeGameService();
FakeGameConfigurable stubConfigurable = new FakeGameConfigurable("Option");
HashSet<IGameConfigurable> configurables = new HashSet<IGameConfigurable>();
configurables.Add(stubConfigurable);
stubService.Configurables = configurables;
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//When
serviceInfo.SetConfigurableValue(stubConfigurable.OptionName, "success");
//Then
Assert.True("success".Equals(serviceInfo.GetConfigurableValue(stubConfigurable.OptionName)));
}
[Fact]
public void GetServiceState_ServiceNotStarted_ReturnsStoppedState()
{
//Given
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//Then
Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState());
serviceInfo.Dispose();
}
[Fact]
public void GetServiceState_ServiceStarted_ReturnsRunningState()
{
//Given
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//When
serviceInfo.Start();
//Then
Assert.Equal(ServiceState.Running, serviceInfo.GetServiceState());
serviceInfo.Dispose();
}
[Fact]
public void GetModuleName_ServiceNotStarted_ReturnsSetName()
{
//Given
const string MODULE_NAME = "FakeModule";
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, MODULE_NAME, "FakeAssembly");
//Then
Assert.Equal(MODULE_NAME, serviceInfo.ModuleName);
serviceInfo.Dispose();
}
[Fact]
public void GetAssemblyName_ServiceNotStarted_ReturnsSetAssemblyName()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", ASSEMBLY_NAME);
//Then
Assert.Equal(ASSEMBLY_NAME, serviceInfo.GetAssemblyName());
serviceInfo.Dispose();
}
[Fact]
public void SetAndGetServiceName_ServiceNotStartedSingleThread_ServiceNameUpdated()
{
//Given
const string SERVICE_NAME = "Service";
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssemblyName");
//When
serviceInfo.ServiceName = SERVICE_NAME;
//Then
Assert.True(SERVICE_NAME.Equals(serviceInfo.ServiceName));
serviceInfo.Dispose();
}
[Fact]
public void ServiceConsoleStream_ServiceNotStarted_NullReturned()
{
//Given
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//Then
Assert.Null(serviceInfo.ServiceConsoleStream);
serviceInfo.Dispose();
}
[Fact]
public void ServiceConsoleStream_ServiceStarted_StreamReturned()
{
//Given
IGameService stubService = new FakeGameService();
GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//When
serviceInfo.Start();
//Then
Assert.IsAssignableFrom<Stream>(serviceInfo.ServiceConsoleStream);
serviceInfo.Dispose();
}
}
}

View File

@@ -1,252 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using GameServiceWarden.Core.Games;
using GameServiceWarden.ModuleAPI;
using Xunit;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
public class GameServiceManagerTest
{
[Fact]
public void CreateService_NewManager_NewServiceCreated()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
//Then
Assert.Contains<string>(FAKE_SERVICE_NAME, serviceManager.GetServiceNames());
}
[Fact]
public void CreateService_OneService_ServiceDeleted()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
serviceManager.DeleteService(FAKE_SERVICE_NAME);
//Then
Assert.DoesNotContain<string>(FAKE_SERVICE_NAME, serviceManager.GetServiceNames());
}
[Fact]
public void GetServiceNames_MultipleServices_AllCorrectNames()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_PREFIX = "FakeService_";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
for (int i = 0; i < 100; i++)
{
serviceManager.CreateService(FAKE_SERVICE_PREFIX + i, ASSEMBLY_NAME, stubGameServiceModule.Name);
}
//Then
for (int i = 0; i < 100; i++)
{
Assert.Contains<string>(FAKE_SERVICE_PREFIX + i, serviceManager.GetServiceNames());
}
}
[Fact]
public void GetServiceOptions_ThreeOptionService_CorrectOptions()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(
new FakeGameConfigurable("A"),
new FakeGameConfigurable("B"),
new FakeGameConfigurable("C")
);
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
//Then
Assert.Contains<string>("A", serviceManager.GetServiceOptions(FAKE_SERVICE_NAME));
Assert.Contains<string>("B", serviceManager.GetServiceOptions(FAKE_SERVICE_NAME));
Assert.Contains<string>("C", serviceManager.GetServiceOptions(FAKE_SERVICE_NAME));
}
[Fact]
public void SetandGetServiceOptionValue_OneOption_OptionChanged()
{
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(
new FakeGameConfigurable("A")
);
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
serviceManager.SetServiceOptionValue(FAKE_SERVICE_NAME, "A", "Test");
//Then
Assert.True("Test".Equals(serviceManager.GetServiceOptionValue(FAKE_SERVICE_NAME, "A")));
}
[Fact]
public void GetServiceState_NotRunning_ReturnsNotRunningState()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
//Then
Assert.Equal<ServiceState>(ServiceState.Stopped, serviceManager.GetServiceState(FAKE_SERVICE_NAME));
}
[Fact]
public void GetServiceState_Running_ReturnsNotRunningState()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
//Then
Assert.Equal<ServiceState>(ServiceState.Running, serviceManager.GetServiceState(FAKE_SERVICE_NAME));
}
[Fact]
public void StartService_NotStarted_SuccessfulStart()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
//Then
Assert.Equal<ServiceState>(ServiceState.Running, serviceManager.GetServiceState(FAKE_SERVICE_NAME));
}
[Fact]
public void StopService_Stopped_StateUpdated()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
serviceManager.StopService(FAKE_SERVICE_NAME);
//Then
Assert.Equal<ServiceState>(ServiceState.Stopped, serviceManager.GetServiceState(FAKE_SERVICE_NAME));
}
[Fact]
public void ExecuteCommand_ServiceStarted_CommandLogged()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
serviceManager.ExecuteCommand(FAKE_SERVICE_NAME, "Test");
//Then
Stream stream = serviceManager.GetServiceConsoleStream(FAKE_SERVICE_NAME);
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream))
{
Assert.True("Test".Equals(reader.ReadLine()));
}
}
[Fact]
public void GetServiceConsoleStream_ServiceStopped_ExceptionThrown()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
FakePersistence<GameServiceInfo> stubPersistentServiceDictionary = new FakePersistence<GameServiceInfo>();
GameServiceManager serviceManager = new GameServiceManager(stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IGameServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IGameServiceModule>();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyModulesDictionary.Add(stubGameServiceModule.Name, stubGameServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
//Then
Action action = delegate()
{
serviceManager.GetServiceConsoleStream(FAKE_SERVICE_NAME);
};
Assert.Throws<InvalidOperationException>(action);
}
}
}

View File

@@ -0,0 +1,170 @@
using System.Collections.Generic;
using System.IO;
using GameServiceWarden.Core.Games;
using GameServiceWarden.Core.Logging;
using GameServiceWarden.API.Module;
using Xunit;
using Xunit.Abstractions;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
// Testing convention from: https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
// fakes are generic test objects,
// mocks are the objects being asserted upon,
// stubs are objects used as part of the test.
[CollectionDefinition("Service", DisableParallelization = true)]
public class ServiceDescriptorTest
{
private readonly ITestOutputHelper output;
private readonly XUnitLogger logger;
public ServiceDescriptorTest(ITestOutputHelper output)
{
this.output = output;
logger = new XUnitLogger(output);
Logger.AddLogListener(logger);
}
//MethodTested_ScenarioTested_ExpectedBehavior
[Fact]
public void Start_FromStopped_StateIsRunning()
{
//Arrange, Act, Assert
const string SERVICE_NAME = "Start_FromStopped_StateIsRunning";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
serviceInfo.Start();
Assert.Equal(true, serviceInfo.GetServiceState());
serviceInfo.Stop();
}
[Fact]
public void Stop_FromStart_Stopped()
{
const string SERVICE_NAME = "Stop_FromStart_Stopped";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
serviceInfo.Start();
serviceInfo.Stop();
Assert.Equal(false, serviceInfo.GetServiceState());
}
[Fact]
public void GetConfigurableOptions_ServiceStopped_ReturnsConfigurables()
{
//Given
const string SERVICE_NAME = "GetConfigurableOptions_ServiceStopped_ReturnsConfigurables";
FakeService stubService = new FakeService();
FakeServiceConfigurable stubConfigurable = new FakeServiceConfigurable("Option");
HashSet<IServiceConfigurable> configurables = new HashSet<IServiceConfigurable>();
configurables.Add(stubConfigurable);
stubService.Configurables = configurables;
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
//Then
Assert.Contains<string>(stubConfigurable.OptionName, serviceInfo.GetConfigurableOptions());
}
[Fact]
public void SetAndGetConfigurationValue_ServiceStopped_AppropriateValueReturned()
{
//Given
const string SERVICE_NAME = "SetAndGetConfigurationValue_ServiceStopped_AppropriateValueReturned";
FakeService stubService = new FakeService();
FakeServiceConfigurable stubConfigurable = new FakeServiceConfigurable("Option");
HashSet<IServiceConfigurable> configurables = new HashSet<IServiceConfigurable>();
configurables.Add(stubConfigurable);
stubService.Configurables = configurables;
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
//When
serviceInfo.SetConfigurableValue(stubConfigurable.OptionName, "success");
//Then
Assert.True("success".Equals(serviceInfo.GetConfigurableValue(stubConfigurable.OptionName)));
}
[Fact]
public void GetServiceState_ServiceNotStarted_ReturnsStoppedState()
{
//Given
const string SERVICE_NAME = "GetServiceState_ServiceNotStarted_ReturnsStoppedState";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
//Then
Assert.Equal(false, serviceInfo.GetServiceState());
}
[Fact]
public void GetServiceState_ServiceStarted_ReturnsRunningState()
{
//Given
const string SERVICE_NAME = "GetServiceState_ServiceStarted_ReturnsRunningState";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
//When
serviceInfo.Start();
//Then
Assert.Equal(true, serviceInfo.GetServiceState());
serviceInfo.Stop();
}
[Fact]
public void GetModuleName_ServiceNotStarted_ReturnsSetName()
{
//Given
const string SERVICE_NAME = "GetModuleName_ServiceNotStarted_ReturnsSetName";
const string MODULE_NAME = "FakeModule";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, MODULE_NAME, "FakeAssembly");
//Then
Assert.Equal(MODULE_NAME, serviceInfo.GetModuleName());
}
[Fact]
public void GetAssemblyName_ServiceNotStarted_ReturnsSetAssemblyName()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "GetAssemblyName_ServiceNotStarted_ReturnsSetAssemblyName";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", ASSEMBLY_NAME);
//Then
Assert.Equal(ASSEMBLY_NAME, serviceInfo.GetAssemblyName());
}
[Fact]
public void GetServiceName_ServiceNotStartedSingleThread_ServiceNameReturned()
{
//Given
const string SERVICE_NAME = "GetServiceName_ServiceNotStartedSingleThread_ServiceNameReturned";
IService stubService = new FakeService();
//When
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssemblyName");
//Then
Assert.True(SERVICE_NAME.Equals(serviceInfo.ServiceName));
}
[Fact]
public void ServiceLogPipeName_ServiceNotStarted_NullReturned()
{
//Given
const string SERVICE_NAME = "ServiceLogPipeName_ServiceNotStarted_NullReturned";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
//Then
Assert.NotNull(serviceInfo.ServiceLogPipeName);
}
[Fact]
public void ServiceLogPipeName_ServiceStarted_StreamReturned()
{
//Given
const string SERVICE_NAME = "ServiceLogPipeName_ServiceStarted_StreamReturned";
IService stubService = new FakeService();
ServiceDescriptor serviceInfo = new ServiceDescriptor(stubService, SERVICE_NAME, "FakeModule", "FakeAssembly");
//When
serviceInfo.Start();
//Then
Assert.NotNull(serviceInfo.ServiceLogPipeName);
serviceInfo.Stop();
}
}
}

View File

@@ -0,0 +1,337 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
using GameServiceWarden.Core.Games;
using GameServiceWarden.Core.Logging;
using GameServiceWarden.API.Module;
using Xunit;
using Xunit.Abstractions;
namespace GameServiceWarden.Core.Tests.Modules.Games
{
[CollectionDefinition("Service")]
public class ServiceManagerTest
{
private readonly ITestOutputHelper output;
private readonly XUnitLogger logger;
public ServiceManagerTest(ITestOutputHelper output)
{
this.output = output;
logger = new XUnitLogger(output);
Logger.AddLogListener(logger);
}
[Fact]
public void CreateService_NewManager_NewServiceCreated()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "CreateService_NewManager_NewServiceCreated";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
//Then
Assert.Contains<string>(FAKE_SERVICE_NAME, stubMonitor.GetLastState().services);
}
[Fact]
public void CreateService_OneService_ServiceDeleted()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "CreateService_OneService_ServiceDeleted";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.DeleteService(FAKE_SERVICE_NAME);
//Then
Assert.True(stubMonitor.GetLastState().delta);
Assert.True(stubMonitor.GetLastState().subtract);
Assert.Contains(FAKE_SERVICE_NAME, stubMonitor.GetLastState().services);
}
[Fact]
public void GetServiceNames_MultipleServices_AllCorrectNames()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_PREFIX = "GetServiceNames_MultipleServices_AllCorrectNames_";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
for (int i = 0; i < 100; i++)
{
serviceManager.CreateService(FAKE_SERVICE_PREFIX + i, ASSEMBLY_NAME, stubServiceModule.Name);
}
//Then
for (int i = 0; i < 100; i++)
{
Assert.Contains<string>(FAKE_SERVICE_PREFIX + i, serviceManager.GetServiceNames());
}
}
[Fact]
public void GetServiceOptions_ThreeOptionService_CorrectOptions()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "GetServiceOptions_ThreeOptionService_CorrectOptions";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule(
new FakeServiceConfigurable("A"),
new FakeServiceConfigurable("B"),
new FakeServiceConfigurable("C")
);
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
//Then
Assert.Contains<string>("A", serviceManager.GetOptions()[FAKE_SERVICE_NAME].Keys);
Assert.Contains<string>("B", serviceManager.GetOptions()[FAKE_SERVICE_NAME].Keys);
Assert.Contains<string>("C", serviceManager.GetOptions()[FAKE_SERVICE_NAME].Keys);
}
[Fact]
public void SetandGetServiceOptionValue_OneOption_OptionChanged()
{
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "SetandGetServiceOptionValue_OneOption_OptionChanged";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule(
new FakeServiceConfigurable("A")
);
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.SetServiceOptionValue(FAKE_SERVICE_NAME, "A", "Test");
//Then
Assert.True("Test".Equals(serviceManager.GetOptions()[FAKE_SERVICE_NAME]["A"]));
}
[Fact]
public void GetServiceState_NotRunning_ReturnsNotRunningState()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "GetServiceState_NotRunning_ReturnsNotRunningState";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
//Then
Assert.DoesNotContain(FAKE_SERVICE_NAME, serviceManager.GetRunningServiceNames());
}
[Fact]
public void StartService_NotStarted_SuccessfulStart()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "StartService_NotStarted_SuccessfulStart";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
//Then
Assert.Contains(FAKE_SERVICE_NAME, serviceManager.GetRunningServiceNames());
serviceManager.StopService(FAKE_SERVICE_NAME);
}
[Fact]
public void StopService_Stopped_StateUpdated()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "StopService_Stopped_StateUpdated";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
serviceManager.StopService(FAKE_SERVICE_NAME);
//Then
Assert.DoesNotContain(FAKE_SERVICE_NAME, serviceManager.GetRunningServiceNames());
}
[Fact]
public void ExecuteCommand_CommandExecutedBeforeConnected_CommandLogged()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "ExecuteCommand_CommandExecutedBeforeConnected_CommandLogged";
const string COMMAND = "TEST";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
string pipeName = serviceManager.GetLogPipeNames()[FAKE_SERVICE_NAME];
NamedPipeClientStream clientStream = new NamedPipeClientStream(".", pipeName, PipeDirection.In);
serviceManager.ExecuteCommand(FAKE_SERVICE_NAME, COMMAND);
clientStream.Connect(1000);
Thread.Sleep(1000);
//Then
byte[] buffer = new byte[1024 * 8];
CancellationTokenSource cancelToken = new CancellationTokenSource();
ValueTask<int> task = clientStream.ReadAsync(buffer, cancelToken.Token);
Assert.False(task.AsTask().Wait(1000));
serviceManager.StopService(FAKE_SERVICE_NAME);
}
[Fact]
public void ExecuteCommand_CommandExecutedAfterConnected_CommandLogged()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "ExecuteCommand_CommandExecutedAfterConnected_CommandLogged";
const string COMMAND = "TEST";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
string pipeName = serviceManager.GetLogPipeNames()[FAKE_SERVICE_NAME];
NamedPipeClientStream clientStream = new NamedPipeClientStream(".", pipeName, PipeDirection.In);
clientStream.Connect(1000);
Thread.Sleep(1000);
serviceManager.ExecuteCommand(FAKE_SERVICE_NAME, COMMAND);
//Then
using (StreamReader reader = new StreamReader(clientStream))
{
CancellationTokenSource cancelToken = new CancellationTokenSource();
string message = null;
Task task = Task.Run(() => message = reader.ReadLine(), cancelToken.Token);
Assert.True(task.Wait(1000));
Assert.True(COMMAND.Equals(message), $"Received message \"{message}\" when expecting \"{COMMAND}\"");
}
serviceManager.StopService(FAKE_SERVICE_NAME);
}
[Fact]
public void ExecuteCommand_CommandExecutedAfterMultipleLogListenersConnected_CommandLogged()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "ExecuteCommand_CommandExecutedAfterMultipleLogListenersConnected_CommandLogged";
const string COMMAND = "TEST";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.StartService(FAKE_SERVICE_NAME);
string pipeName = serviceManager.GetLogPipeNames()[FAKE_SERVICE_NAME];
NamedPipeClientStream[] clientStreams = new NamedPipeClientStream[5];
for (int i = 0; i < clientStreams.Length; i++)
{
clientStreams[i] = new NamedPipeClientStream(".", pipeName, PipeDirection.In);
clientStreams[i].Connect(1000);
}
Thread.Sleep(1000);
serviceManager.ExecuteCommand(FAKE_SERVICE_NAME, COMMAND);
//Then
for (int i = 0; i < clientStreams.Length; i++)
{
using (StreamReader reader = new StreamReader(clientStreams[i]))
{
CancellationTokenSource cancelToken = new CancellationTokenSource();
string message = null;
Task task = Task.Run(() => message = reader.ReadLine(), cancelToken.Token);
Assert.True(task.Wait(10000));
Assert.True(COMMAND.Equals(message), $"Received message \"{message}\" when expecting \"{COMMAND}\"");
}
}
serviceManager.StopService(FAKE_SERVICE_NAME);
}
[Fact]
public void GetServiceConsoleStream_ServiceStopped_ExceptionThrown()
{
//Given
const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "GetServiceConsoleStream_ServiceStopped_ExceptionThrown";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubPersistentModuleDictionary = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
FakePersistence<ServiceDescriptor> stubPersistentServiceDictionary = new FakePersistence<ServiceDescriptor>();
FakeServiceManagerMonitor stubMonitor = new FakeServiceManagerMonitor();
ServiceManager serviceManager = new ServiceManager(stubMonitor, stubPersistentServiceDictionary, stubPersistentModuleDictionary);
Dictionary<string, IServiceModule> stubAssemblyModulesDictionary = new Dictionary<string, IServiceModule>();
IServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyModulesDictionary.Add(stubServiceModule.Name, stubServiceModule);
stubPersistentModuleDictionary.AddToPersistence(ASSEMBLY_NAME, stubAssemblyModulesDictionary);
//When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
//Then
Assert.Throws<KeyNotFoundException>(() => serviceManager.GetLogPipeNames()[FAKE_SERVICE_NAME]);
}
}
}

View File

@@ -1,95 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using GameServiceWarden.Core.Games;
using GameServiceWarden.Core.Persistence;
using GameServiceWarden.Core.Tests.Modules;
using GameServiceWarden.Core.Tests.Modules.Games;
using GameServiceWarden.ModuleAPI;
using Xunit;
namespace GameServiceWarden.Core.Tests.Persistence
{
public class PersistedGameServiceInfosTest
{
//MethodTested_ScenarioTested_ExpectedBehavior
[Fact]
public void GetPathForKey_PathGen_ExpectedPathResult()
{
//Given
const string TEST_DIR = "services";
const string MODULE_NAME = "fake_module";
const string ASSEMBLY_NAME = "fake_assembly";
const string SERVICE_NAME = "fake_service";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubModulesPersistence = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
Dictionary<string, IGameServiceModule> stubAssemblyDict = new Dictionary<string, IGameServiceModule>();
FakeGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyDict[MODULE_NAME] = stubGameServiceModule;
stubModulesPersistence[ASSEMBLY_NAME] = stubAssemblyDict;
PersistedGameServiceInfos persistedGameServices = new PersistedGameServiceInfos(TEST_DIR, stubModulesPersistence);
//Then
Assert.True(persistedGameServices.GetPathForKey(SERVICE_NAME).Equals(Path.Combine(TEST_DIR, SERVICE_NAME)));
}
[Fact]
public void Save_SavingService_FileCreated()
{
//Given
const string TEST_DIR = "services";
const string MODULE_NAME = "fake_module";
const string ASSEMBLY_NAME = "fake_assembly";
const string SERVICE_NAME = "fake_service";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubModulesPersistence = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
Dictionary<string, IGameServiceModule> stubAssemblyDict = new Dictionary<string, IGameServiceModule>();
FakeGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyDict[MODULE_NAME] = stubGameServiceModule;
stubModulesPersistence[ASSEMBLY_NAME] = stubAssemblyDict;
PersistedGameServiceInfos persistedGameServiceInfos = new PersistedGameServiceInfos(TEST_DIR, stubModulesPersistence);
GameServiceInfo stubGameServiceInfo = new GameServiceInfo(stubModulesPersistence[ASSEMBLY_NAME][MODULE_NAME].InstantiateGameService(persistedGameServiceInfos.GetPathForKey(SERVICE_NAME), true), MODULE_NAME, ASSEMBLY_NAME);
//When
persistedGameServiceInfos[SERVICE_NAME] = stubGameServiceInfo;
//Then
Assert.True(Directory.Exists(TEST_DIR));
Assert.True(Directory.Exists(persistedGameServiceInfos.GetPathForKey(SERVICE_NAME)));
string[] files = Directory.GetFiles(persistedGameServiceInfos.GetPathForKey(SERVICE_NAME));
Assert.True(files.Length == 1);
Assert.StartsWith(SERVICE_NAME, Path.GetFileName(files[0]));
Directory.Delete(TEST_DIR, true);
}
[Fact]
public void Save_ReadingService_MetadataRead()
{
//Given
const string TEST_DIR = "services";
const string MODULE_NAME = "fake_module";
const string ASSEMBLY_NAME = "fake_assembly";
const string SERVICE_NAME = "fake_service";
FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>> stubModulesPersistence = new FakePersistence<IReadOnlyDictionary<string, IGameServiceModule>>();
Dictionary<string, IGameServiceModule> stubAssemblyDict = new Dictionary<string, IGameServiceModule>();
FakeGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
stubAssemblyDict[MODULE_NAME] = stubGameServiceModule;
stubModulesPersistence[ASSEMBLY_NAME] = stubAssemblyDict;
PersistedGameServiceInfos persistedGameServices = new PersistedGameServiceInfos(TEST_DIR, stubModulesPersistence);
GameServiceInfo stubGameServiceInfo = new GameServiceInfo(stubModulesPersistence[ASSEMBLY_NAME][MODULE_NAME].InstantiateGameService(persistedGameServices.GetPathForKey(SERVICE_NAME), true), MODULE_NAME, ASSEMBLY_NAME);
persistedGameServices[SERVICE_NAME] = stubGameServiceInfo;
//When
GameServiceInfo loadedService = persistedGameServices[SERVICE_NAME];
//Then
Assert.True(loadedService.ModuleName.Equals(MODULE_NAME));
Assert.True(loadedService.GetAssemblyName().Equals(ASSEMBLY_NAME));
Directory.Delete(TEST_DIR, true);
}
}
}

View File

@@ -0,0 +1,95 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using GameServiceWarden.Core.Games;
using GameServiceWarden.Core.Persistence;
using GameServiceWarden.Core.Tests.Modules;
using GameServiceWarden.Core.Tests.Modules.Games;
using GameServiceWarden.API.Module;
using Xunit;
namespace GameServiceWarden.Core.Tests.Persistence
{
public class ServiceDescriptorPersistenceTest
{
//MethodTested_ScenarioTested_ExpectedBehavior
[Fact]
public void GetPathForKey_PathGen_ExpectedPathResult()
{
//Given
const string TEST_DIR = "services";
const string MODULE_NAME = "fake_module";
const string ASSEMBLY_NAME = "fake_assembly";
const string SERVICE_NAME = "fake_service";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubModulesPersistence = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
Dictionary<string, IServiceModule> stubAssemblyDict = new Dictionary<string, IServiceModule>();
FakeServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyDict[MODULE_NAME] = stubServiceModule;
stubModulesPersistence[ASSEMBLY_NAME] = stubAssemblyDict;
ServiceDescriptorPersistence persistedServices = new ServiceDescriptorPersistence(TEST_DIR, stubModulesPersistence);
//Then
Assert.True(persistedServices.GetPathForKey(SERVICE_NAME).Equals(Path.Combine(TEST_DIR, SERVICE_NAME)));
}
[Fact]
public void Save_SavingService_FileCreated()
{
//Given
const string TEST_DIR = "services";
const string MODULE_NAME = "fake_module";
const string ASSEMBLY_NAME = "fake_assembly";
const string SERVICE_NAME = "fake_service";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubModulesPersistence = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
Dictionary<string, IServiceModule> stubAssemblyDict = new Dictionary<string, IServiceModule>();
FakeServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyDict[MODULE_NAME] = stubServiceModule;
stubModulesPersistence[ASSEMBLY_NAME] = stubAssemblyDict;
ServiceDescriptorPersistence persistedServiceInfos = new ServiceDescriptorPersistence(TEST_DIR, stubModulesPersistence);
ServiceDescriptor stubServiceInfo = new ServiceDescriptor(stubModulesPersistence[ASSEMBLY_NAME][MODULE_NAME].InstantiateService(persistedServiceInfos.GetPathForKey(SERVICE_NAME), true), SERVICE_NAME, MODULE_NAME, ASSEMBLY_NAME);
//When
persistedServiceInfos[SERVICE_NAME] = stubServiceInfo;
//Then
Assert.True(Directory.Exists(TEST_DIR));
Assert.True(Directory.Exists(persistedServiceInfos.GetPathForKey(SERVICE_NAME)));
string[] files = Directory.GetFiles(persistedServiceInfos.GetPathForKey(SERVICE_NAME));
Assert.True(files.Length == 1);
Assert.StartsWith(SERVICE_NAME, Path.GetFileName(files[0]));
Directory.Delete(TEST_DIR, true);
}
[Fact]
public void Save_ReadingService_MetadataRead()
{
//Given
const string TEST_DIR = "services";
const string MODULE_NAME = "fake_module";
const string ASSEMBLY_NAME = "fake_assembly";
const string SERVICE_NAME = "fake_service";
FakePersistence<IReadOnlyDictionary<string, IServiceModule>> stubModulesPersistence = new FakePersistence<IReadOnlyDictionary<string, IServiceModule>>();
Dictionary<string, IServiceModule> stubAssemblyDict = new Dictionary<string, IServiceModule>();
FakeServiceModule stubServiceModule = new FakeServiceModule();
stubAssemblyDict[MODULE_NAME] = stubServiceModule;
stubModulesPersistence[ASSEMBLY_NAME] = stubAssemblyDict;
ServiceDescriptorPersistence persistedServices = new ServiceDescriptorPersistence(TEST_DIR, stubModulesPersistence);
ServiceDescriptor stubServiceInfo = new ServiceDescriptor(stubModulesPersistence[ASSEMBLY_NAME][MODULE_NAME].InstantiateService(persistedServices.GetPathForKey(SERVICE_NAME), true), SERVICE_NAME, MODULE_NAME, ASSEMBLY_NAME);
persistedServices[SERVICE_NAME] = stubServiceInfo;
//When
ServiceDescriptor loadedService = persistedServices[SERVICE_NAME];
//Then
Assert.True(loadedService.GetModuleName().Equals(MODULE_NAME));
Assert.True(loadedService.GetAssemblyName().Equals(ASSEMBLY_NAME));
Directory.Delete(TEST_DIR, true);
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using GameServiceWarden.Core.UI;
using Xunit;
namespace GameServiceWarden.Core.Tests.UI
{
public class IPCMediatorTest
{
[Fact]
public void Open_Closed_Opened()
{
//Given
const string NAME = "MEDIATOR";
IPCMediator mediator = new IPCMediator(NAME);
//When
mediator.Open();
//Then
Assert.True(mediator.IsRunning);
}
[Fact]
public void Open_AlreadyOpened_Exception()
{
//Given
const string NAME = "MEDIATOR";
IPCMediator mediator = new IPCMediator(NAME);
//When
mediator.Open();
//Then
Assert.Throws<InvalidOperationException>(() => mediator.Open());
}
[Fact]
public void Close_Opened_Closed()
{
//Given
const string NAME = "MEDIATOR";
IPCMediator mediator = new IPCMediator(NAME);
//When
mediator.Open();
//Then
Assert.True(mediator.IsRunning);
mediator.Close();
Assert.False(mediator.IsRunning);
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using GameServiceWarden.Core.Logging;
using Xunit.Abstractions;
namespace GameServiceWarden.Core.Tests
{
public class XUnitLogger : ILogReceiver
{
public LogLevel Level => LogLevel.DEBUG;
public string Identifier => GetType().Name;
private ITestOutputHelper outputHelper;
public XUnitLogger(ITestOutputHelper output)
{
this.outputHelper = output;
}
public void Flush()
{
}
public void LogMessage(string message, DateTime time, LogLevel level)
{
outputHelper.WriteLine($"[{time.ToShortTimeString()}][{level.ToString()}]: {message}");
}
}
}