mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-10 15:20:48 -05:00
actually fix the session score concurrency issue
fix rare bug with shared guid kicker plugin allow hiding of the connection lost notification
This commit is contained in:
37
Tests/ApplicationTests/DepedencyInjectionExtensions.cs
Normal file
37
Tests/ApplicationTests/DepedencyInjectionExtensions.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using ApplicationTests.Fixtures;
|
||||
using FakeItEasy;
|
||||
using IW4MAdmin;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Services;
|
||||
|
||||
namespace ApplicationTests
|
||||
{
|
||||
static class DepedencyInjectionExtensions
|
||||
{
|
||||
public static IServiceCollection BuildBase(this IServiceCollection serviceCollection)
|
||||
{
|
||||
var manager = A.Fake<IManager>();
|
||||
var logger = A.Fake<ILogger>();
|
||||
A.CallTo(() => manager.GetLogger(A<long>.Ignored))
|
||||
.Returns(logger);
|
||||
|
||||
serviceCollection.AddSingleton(logger)
|
||||
.AddSingleton(manager)
|
||||
.AddSingleton(A.Fake<IRConConnectionFactory>())
|
||||
.AddSingleton(A.Fake<IRConConnection>())
|
||||
.AddSingleton(A.Fake<ITranslationLookup>())
|
||||
.AddSingleton(A.Fake<IRConParser>())
|
||||
.AddSingleton(A.Fake<IParserRegexFactory>())
|
||||
.AddSingleton(A.Fake<ClientService>());
|
||||
|
||||
serviceCollection.AddSingleton(_sp => new IW4MServer(_sp.GetRequiredService<IManager>(), ConfigurationGenerators.CreateServerConfiguration(),
|
||||
_sp.GetRequiredService<ITranslationLookup>(), _sp.GetRequiredService<IRConConnectionFactory>())
|
||||
{
|
||||
RconParser = _sp.GetRequiredService<IRConParser>()
|
||||
});
|
||||
|
||||
return serviceCollection;
|
||||
}
|
||||
}
|
||||
}
|
@ -8,17 +8,35 @@ namespace ApplicationTests.Fixtures
|
||||
{
|
||||
public class ClientGenerators
|
||||
{
|
||||
public static EFClient CreateBasicClient(Server currentServer, bool isIngame = true) => new EFClient()
|
||||
public static EFClient CreateBasicClient(Server currentServer, bool isIngame = true, bool hasIp = true, EFClient.ClientState clientState = EFClient.ClientState.Connected) => new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
CurrentAlias = new EFAlias()
|
||||
{
|
||||
Name = "BasicClient",
|
||||
IPAddress = "127.0.0.1".ConvertToIP(),
|
||||
IPAddress = hasIp ? "127.0.0.1".ConvertToIP() : null,
|
||||
},
|
||||
Level = EFClient.Permission.User,
|
||||
ClientNumber = isIngame ? 0 : -1,
|
||||
CurrentServer = currentServer
|
||||
};
|
||||
|
||||
public static EFClient CreateDatabaseClient(bool hasIp = true) => new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
ClientNumber = -1,
|
||||
AliasLinkId = 1,
|
||||
Level = EFClient.Permission.User,
|
||||
Connections = 1,
|
||||
FirstConnection = DateTime.UtcNow.AddDays(-1),
|
||||
LastConnection = DateTime.UtcNow,
|
||||
NetworkId = 1,
|
||||
TotalConnectionTime = 100,
|
||||
CurrentAlias = new EFAlias()
|
||||
{
|
||||
Name = "BasicDatabaseClient",
|
||||
IPAddress = hasIp ? "127.0.0.1".ConvertToIP() : null,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ using SharedLibraryCore.Database.Models;
|
||||
using System.Threading.Tasks;
|
||||
using ApplicationTests.Mocks;
|
||||
using System.Linq;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using SharedLibraryCore.Configuration;
|
||||
|
||||
namespace ApplicationTests
|
||||
{
|
||||
@ -27,29 +30,28 @@ namespace ApplicationTests
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
fakeLogger = A.Fake<ILogger>();
|
||||
fakeManager = A.Fake<IManager>();
|
||||
fakeRConConnection = A.Fake<IRConConnection>();
|
||||
var rconConnectionFactory = A.Fake<IRConConnectionFactory>();
|
||||
serviceProvider = new ServiceCollection().BuildBase().BuildServiceProvider();
|
||||
|
||||
fakeLogger = serviceProvider.GetRequiredService<ILogger>();
|
||||
fakeManager = serviceProvider.GetRequiredService<IManager>();
|
||||
fakeRConConnection = serviceProvider.GetRequiredService<IRConConnection>();
|
||||
fakeRConParser = serviceProvider.GetRequiredService<IRConParser>();
|
||||
|
||||
var rconConnectionFactory = serviceProvider.GetRequiredService<IRConConnectionFactory>();
|
||||
|
||||
A.CallTo(() => rconConnectionFactory.CreateConnection(A<string>.Ignored, A<int>.Ignored, A<string>.Ignored))
|
||||
.Returns(fakeRConConnection);
|
||||
var fakeTranslationLookup = A.Fake<ITranslationLookup>();
|
||||
fakeRConParser = A.Fake<IRConParser>();
|
||||
|
||||
A.CallTo(() => fakeRConParser.Configuration)
|
||||
.Returns(ConfigurationGenerators.CreateRConParserConfiguration(A.Fake<IParserRegexFactory>()));
|
||||
.Returns(ConfigurationGenerators.CreateRConParserConfiguration(serviceProvider.GetRequiredService<IParserRegexFactory>()));
|
||||
|
||||
|
||||
mockEventHandler = new MockEventHandler();
|
||||
A.CallTo(() => fakeManager.GetEventHandler())
|
||||
.Returns(mockEventHandler);
|
||||
|
||||
serviceProvider = new ServiceCollection()
|
||||
.AddSingleton(new IW4MServer(fakeManager, ConfigurationGenerators.CreateServerConfiguration(), fakeTranslationLookup, rconConnectionFactory)
|
||||
{
|
||||
RconParser = fakeRConParser
|
||||
})
|
||||
.BuildServiceProvider();
|
||||
}
|
||||
|
||||
#region LOG
|
||||
[Test]
|
||||
public void Test_GenerateLogPath_Basic()
|
||||
{
|
||||
@ -176,6 +178,7 @@ namespace ApplicationTests
|
||||
|
||||
Assert.AreEqual(expected, generated);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BAN
|
||||
[Test]
|
||||
@ -508,5 +511,65 @@ namespace ApplicationTests
|
||||
.MustHaveHappened();
|
||||
}
|
||||
#endregion
|
||||
|
||||
[Test]
|
||||
public async Task Test_ConnectionLostNotificationDisabled()
|
||||
{
|
||||
var server = serviceProvider.GetService<IW4MServer>();
|
||||
var fakeConfigHandler = A.Fake<IConfigurationHandler<ApplicationConfiguration>>();
|
||||
|
||||
A.CallTo(() => fakeManager.GetApplicationSettings())
|
||||
.Returns(fakeConfigHandler);
|
||||
|
||||
A.CallTo(() => fakeConfigHandler.Configuration())
|
||||
.Returns(new ApplicationConfiguration() { IgnoreServerConnectionLost = true });
|
||||
|
||||
A.CallTo(() => fakeRConParser.GetStatusAsync(A<IRConConnection>.Ignored))
|
||||
.ThrowsAsync(new NetworkException("err"));
|
||||
|
||||
// simulate failed connection attempts
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
await server.ProcessUpdatesAsync(new System.Threading.CancellationToken());
|
||||
}
|
||||
|
||||
A.CallTo(() => fakeLogger.WriteError(A<string>.Ignored))
|
||||
.MustNotHaveHappened();
|
||||
Assert.IsEmpty(mockEventHandler.Events);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_ConnectionLostNotificationEnabled()
|
||||
{
|
||||
var server = serviceProvider.GetService<IW4MServer>();
|
||||
var fakeConfigHandler = A.Fake<IConfigurationHandler<ApplicationConfiguration>>();
|
||||
|
||||
A.CallTo(() => fakeManager.GetApplicationSettings())
|
||||
.Returns(fakeConfigHandler);
|
||||
|
||||
A.CallTo(() => fakeConfigHandler.Configuration())
|
||||
.Returns(new ApplicationConfiguration() { IgnoreServerConnectionLost = false });
|
||||
|
||||
A.CallTo(() => fakeRConParser.GetStatusAsync(A<IRConConnection>.Ignored))
|
||||
.ThrowsAsync(new NetworkException("err"));
|
||||
|
||||
// simulate failed connection attempts
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
await server.ProcessUpdatesAsync(new System.Threading.CancellationToken());
|
||||
}
|
||||
|
||||
// execute the connection lost event
|
||||
foreach(var e in mockEventHandler.Events.ToList())
|
||||
{
|
||||
await server.ExecuteEvent(e);
|
||||
}
|
||||
|
||||
A.CallTo(() => fakeLogger.WriteError(A<string>.Ignored))
|
||||
.MustHaveHappenedOnceExactly();
|
||||
|
||||
Assert.IsNotEmpty(mockEventHandler.Events);
|
||||
Assert.AreEqual("err", (mockEventHandler.Events[0].Extra as NetworkException).Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
86
Tests/ApplicationTests/PluginTests.cs
Normal file
86
Tests/ApplicationTests/PluginTests.cs
Normal file
@ -0,0 +1,86 @@
|
||||
using ApplicationTests.Fixtures;
|
||||
using ApplicationTests.Mocks;
|
||||
using FakeItEasy;
|
||||
using IW4MAdmin;
|
||||
using IW4MAdmin.Application.Misc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NUnit.Framework;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ApplicationTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class PluginTests
|
||||
{
|
||||
private static string PLUGIN_DIR = @"X:\IW4MAdmin\Plugins\ScriptPlugins";
|
||||
private IServiceProvider serviceProvider;
|
||||
private IManager fakeManager;
|
||||
private MockEventHandler mockEventHandler;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
serviceProvider = new ServiceCollection().BuildBase().BuildServiceProvider();
|
||||
fakeManager = serviceProvider.GetRequiredService<IManager>();
|
||||
mockEventHandler = new MockEventHandler();
|
||||
A.CallTo(() => fakeManager.GetEventHandler())
|
||||
.Returns(mockEventHandler);
|
||||
|
||||
var rconConnectionFactory = serviceProvider.GetRequiredService<IRConConnectionFactory>();
|
||||
|
||||
A.CallTo(() => rconConnectionFactory.CreateConnection(A<string>.Ignored, A<int>.Ignored, A<string>.Ignored))
|
||||
.Returns(serviceProvider.GetRequiredService<IRConConnection>());
|
||||
|
||||
A.CallTo(() => serviceProvider.GetRequiredService<IRConParser>().Configuration)
|
||||
.Returns(ConfigurationGenerators.CreateRConParserConfiguration(serviceProvider.GetRequiredService<IParserRegexFactory>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_GenericGuidClientIsKicked()
|
||||
{
|
||||
var plugin = new ScriptPlugin(Path.Join(PLUGIN_DIR, "SharedGUIDKick.js"), PLUGIN_DIR);
|
||||
var server = serviceProvider.GetRequiredService<IW4MServer>();
|
||||
server.GameName = Server.Game.IW4;
|
||||
var client = ClientGenerators.CreateBasicClient(server, hasIp: false, clientState: EFClient.ClientState.Connecting);
|
||||
client.NetworkId = -1168897558496584395;
|
||||
var databaseClient = ClientGenerators.CreateDatabaseClient(hasIp: false);
|
||||
databaseClient.NetworkId = client.NetworkId;
|
||||
|
||||
var fakeClientService = serviceProvider.GetRequiredService<ClientService>();
|
||||
A.CallTo(() => fakeClientService.GetUnique(A<long>.Ignored))
|
||||
.Returns(Task.FromResult(databaseClient));
|
||||
A.CallTo(() => fakeManager.GetClientService())
|
||||
.Returns(fakeClientService);
|
||||
|
||||
await plugin.Initialize(serviceProvider.GetRequiredService<IManager>());
|
||||
|
||||
var gameEvent = new GameEvent()
|
||||
{
|
||||
Origin = client,
|
||||
Owner = server,
|
||||
Type = GameEvent.EventType.PreConnect,
|
||||
IsBlocking = true
|
||||
};
|
||||
|
||||
await server.ExecuteEvent(gameEvent);
|
||||
|
||||
// connect
|
||||
var e = mockEventHandler.Events[0];
|
||||
await server.ExecuteEvent(e);
|
||||
await plugin.OnEventAsync(e, server);
|
||||
|
||||
// kick
|
||||
e = mockEventHandler.Events[1];
|
||||
await server.ExecuteEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user