Tests written for service info persistence.
Class names also changed.
This commit is contained in:
parent
44512329fd
commit
56259ac419
@ -0,0 +1,176 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
|
using GameServiceWarden.Core.Games;
|
||||||
|
using GameServiceWarden.ModuleAPI;
|
||||||
|
|
||||||
|
namespace GameServiceWarden.Core.Persistence
|
||||||
|
{
|
||||||
|
public class PersistedGameServiceInfos : IPersistent<GameServiceInfo>
|
||||||
|
{
|
||||||
|
private readonly IReadOnlyPersistent<IReadOnlyDictionary<string, IGameServiceModule>> modules;
|
||||||
|
private readonly string mapDirectory;
|
||||||
|
private const string ASSEMBLY_NAME = "Assembly Name";
|
||||||
|
private const string MODULE_NAME = "Module Name";
|
||||||
|
private const string EXTENSION = ".sin";
|
||||||
|
|
||||||
|
|
||||||
|
public PersistedGameServiceInfos(string mapDirectory, IReadOnlyPersistent<IReadOnlyDictionary<string, IGameServiceModule>> modules)
|
||||||
|
{
|
||||||
|
this.mapDirectory = mapDirectory;
|
||||||
|
this.modules = modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameServiceInfo this[string key]
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
value.ServiceName = key;
|
||||||
|
SaveService(key, value.GetAssemblyName(), value.ModuleName);
|
||||||
|
}
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!ContainsKey(key)) throw new KeyNotFoundException();
|
||||||
|
string assemblyName = GetServiceInfoValue(key, ASSEMBLY_NAME);
|
||||||
|
string moduleName = GetServiceInfoValue(key, MODULE_NAME);
|
||||||
|
IGameService service = modules[assemblyName][moduleName].InstantiateGameService(GetPathForKey(key), false);
|
||||||
|
return new GameServiceInfo(service, moduleName, assemblyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MapDirectory { get { return mapDirectory; } }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Directory.GetFiles(mapDirectory).Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<GameServiceInfo> Values {
|
||||||
|
get {
|
||||||
|
IEnumerable<string> keys = Keys;
|
||||||
|
List<GameServiceInfo> res = new List<GameServiceInfo>();
|
||||||
|
foreach (string key in keys)
|
||||||
|
{
|
||||||
|
res.Add(this[key]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> Keys {
|
||||||
|
get {
|
||||||
|
IEnumerable<string> keys = Directory.EnumerateDirectories(mapDirectory);
|
||||||
|
List<string> res = new List<string>();
|
||||||
|
foreach (string key in keys)
|
||||||
|
{
|
||||||
|
res.Add(Path.GetDirectoryName(key));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToPersistence(string key, GameServiceInfo value)
|
||||||
|
{
|
||||||
|
if (key == null) throw new ArgumentNullException();
|
||||||
|
if (ContainsKey(key)) throw new ArgumentException();
|
||||||
|
this[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
IEnumerable<string> directories = Keys;
|
||||||
|
foreach (string directory in directories)
|
||||||
|
{
|
||||||
|
Directory.Delete(directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ContainsKey(string key)
|
||||||
|
{
|
||||||
|
return Directory.Exists(GetPathForKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<KeyValuePair<string, GameServiceInfo>> GetEnumerator()
|
||||||
|
{
|
||||||
|
IEnumerable<string> keys = Keys;
|
||||||
|
List<KeyValuePair<string, GameServiceInfo>> result = new List<KeyValuePair<string, GameServiceInfo>>();
|
||||||
|
foreach (string key in keys)
|
||||||
|
{
|
||||||
|
result.Add(new KeyValuePair<string, GameServiceInfo>(key, this[key]));
|
||||||
|
}
|
||||||
|
return result.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetPathForKey(string key)
|
||||||
|
{
|
||||||
|
return Path.Combine(mapDirectory, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(string key)
|
||||||
|
{
|
||||||
|
if (!ContainsKey(key)) return false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.Delete(GetPathForKey(key));
|
||||||
|
}
|
||||||
|
catch (System.Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryLoadValue(string key, [MaybeNullWhen(false)] out GameServiceInfo value)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
value = this[key];
|
||||||
|
} catch (KeyNotFoundException) {
|
||||||
|
value = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveService(string key, string assemblyName, string moduleName)
|
||||||
|
{
|
||||||
|
if (key == null) throw new ArgumentNullException("key");
|
||||||
|
if (assemblyName == null) throw new ArgumentNullException("assemblyName");
|
||||||
|
if (moduleName == null) throw new ArgumentNullException("moduleName");
|
||||||
|
string serviceInfoPath = GetPathForKey(key);
|
||||||
|
Directory.CreateDirectory(serviceInfoPath);
|
||||||
|
using (StreamWriter writer = File.CreateText(Path.Combine(serviceInfoPath, key + EXTENSION)))
|
||||||
|
{
|
||||||
|
writer.WriteLine($"{ASSEMBLY_NAME}: {assemblyName}");
|
||||||
|
writer.WriteLine($"{MODULE_NAME}: {moduleName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetServiceInfoValue(string key, string value)
|
||||||
|
{
|
||||||
|
string path = GetPathForKey(key);
|
||||||
|
IEnumerable<string> lines = File.ReadAllLines(Path.Combine(path, key + EXTENSION));
|
||||||
|
foreach (string line in lines)
|
||||||
|
{
|
||||||
|
if (line.StartsWith($"{value}: "))
|
||||||
|
{
|
||||||
|
return line.Substring(value.Length + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new FormatException($"\"{path}\" is corrupted. Could not find value for: {value}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user