SEBWIN-301: Added unit tests for basic service functionality.

This commit is contained in:
dbuechel 2019-06-19 15:40:21 +02:00
parent 3589b92b9d
commit ac28eec94a
10 changed files with 520 additions and 28 deletions

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Communication;
using SafeExamBrowser.Contracts.Communication.Data;
using SafeExamBrowser.Contracts.Communication.Events;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Service.Communication;
namespace SafeExamBrowser.Service.UnitTests.Communication
{
[TestClass]
public class ServiceHostTests
{
private Mock<IHostObject> hostObject;
private Mock<IHostObjectFactory> hostObjectFactory;
private Mock<ILogger> logger;
private ServiceHost sut;
[TestInitialize]
public void Initialize()
{
hostObject = new Mock<IHostObject>();
hostObjectFactory = new Mock<IHostObjectFactory>();
logger = new Mock<ILogger>();
hostObjectFactory.Setup(f => f.CreateObject(It.IsAny<string>(), It.IsAny<ICommunication>())).Returns(hostObject.Object);
sut = new ServiceHost("net:pipe://some/address", hostObjectFactory.Object, logger.Object, 0);
}
[TestMethod]
public void Connect_MustAllowFirstConnnectionAndDenyFurtherRequests()
{
var response = sut.Connect();
var response2 = sut.Connect();
var response3 = sut.Connect();
Assert.IsTrue(response.ConnectionEstablished);
Assert.IsFalse(sut.AllowConnection);
Assert.IsFalse(response2.ConnectionEstablished);
Assert.IsFalse(response3.ConnectionEstablished);
}
[TestMethod]
public void Disconnect_MustDisconnectAndThenAllowNewConnection()
{
var connect = sut.Connect();
var disconnect = sut.Disconnect(new DisconnectionMessage { CommunicationToken = connect.CommunicationToken.Value, Interlocutor = Interlocutor.Runtime });
Assert.IsTrue(sut.AllowConnection);
Assert.IsTrue(disconnect.ConnectionTerminated);
var connect2 = sut.Connect();
Assert.IsFalse(sut.AllowConnection);
Assert.IsTrue(connect2.ConnectionEstablished);
}
[TestMethod]
public void Send_MustHandleSessionStartRequest()
{
var args = default(SessionStartEventArgs);
var sync = new AutoResetEvent(false);
var configuration = new ServiceConfiguration { SessionId = Guid.NewGuid() };
var sessionStartRequested = false;
sut.SessionStartRequested += (a) => { args = a; sessionStartRequested = true; sync.Set(); };
var token = sut.Connect().CommunicationToken.Value;
var message = new SessionStartMessage(configuration) { CommunicationToken = token };
var response = sut.Send(message);
sync.WaitOne();
Assert.IsTrue(sessionStartRequested);
Assert.IsNotNull(args);
Assert.IsNotNull(response);
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
Assert.AreEqual(configuration.SessionId, args.Configuration.SessionId);
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
}
[TestMethod]
public void Send_MustHandleSessionStopRequest()
{
var args = default(SessionStopEventArgs);
var sync = new AutoResetEvent(false);
var sessionId = Guid.NewGuid();
var sessionStopRequested = false;
sut.SessionStopRequested += (a) => { args = a; sessionStopRequested = true; sync.Set(); };
var token = sut.Connect().CommunicationToken.Value;
var message = new SessionStopMessage(sessionId) { CommunicationToken = token };
var response = sut.Send(message);
sync.WaitOne();
Assert.IsTrue(sessionStopRequested);
Assert.IsNotNull(args);
Assert.IsNotNull(response);
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
Assert.AreEqual(sessionId, args.SessionId);
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
}
[TestMethod]
public void Send_MustReturnUnknownMessageAsDefault()
{
var token = sut.Connect().CommunicationToken.Value;
var message = new TestMessage { CommunicationToken = token } as Message;
var response = sut.Send(message);
Assert.IsNotNull(response);
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
Assert.AreEqual(SimpleResponsePurport.UnknownMessage, (response as SimpleResponse)?.Purport);
message = new SimpleMessage(default(SimpleMessagePurport)) { CommunicationToken = token };
response = sut.Send(message);
Assert.IsNotNull(response);
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
Assert.AreEqual(SimpleResponsePurport.UnknownMessage, (response as SimpleResponse)?.Purport);
}
private class TestMessage : Message { };
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System.Threading;
namespace SafeExamBrowser.Service.UnitTests.Operations
{
internal class EventStub : EventWaitHandle
{
public bool IsClosed { get; set; }
public EventStub() : base(false, EventResetMode.AutoReset)
{
}
public override void Close()
{
IsClosed = true;
}
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Service.Operations;
namespace SafeExamBrowser.Service.UnitTests.Operations
{
[TestClass]
public class ServiceEventCleanupOperationTests
{
private Mock<ILogger> logger;
private SessionContext sessionContext;
private ServiceEventCleanupOperation sut;
[TestInitialize]
public void Initialize()
{
logger = new Mock<ILogger>();
sessionContext = new SessionContext();
sut = new ServiceEventCleanupOperation(logger.Object, sessionContext);
}
[TestMethod]
public void Perform_MustDoNothing()
{
var serviceEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
sessionContext.ServiceEvent = serviceEvent;
var result = sut.Perform();
Assert.AreEqual(OperationResult.Success, result);
Assert.AreSame(serviceEvent, sessionContext.ServiceEvent);
}
[TestMethod]
public void Revert_MustCloseEvent()
{
var serviceEvent = new EventStub();
sessionContext.ServiceEvent = serviceEvent;
var result = sut.Revert();
Assert.AreEqual(OperationResult.Success, result);
Assert.IsTrue(serviceEvent.IsClosed);
}
[TestMethod]
public void Revert_MustNotFailIfEventNull()
{
var result = sut.Revert();
Assert.AreEqual(OperationResult.Success, result);
}
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Service.Operations;
namespace SafeExamBrowser.Service.UnitTests.Operations
{
[TestClass]
public class SessionActivationOperationTests
{
private Mock<ILogger> logger;
private SessionContext sessionContext;
private SessionActivationOperation sut;
[TestInitialize]
public void Initialize()
{
logger = new Mock<ILogger>();
sessionContext = new SessionContext();
sut = new SessionActivationOperation(logger.Object, sessionContext);
}
[TestMethod]
public void Perform_MustSetServiceEvent()
{
sessionContext.ServiceEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
var wasSet = false;
var task = Task.Run(() => wasSet = sessionContext.ServiceEvent.WaitOne(1000));
var result = sut.Perform();
task.Wait();
Assert.AreEqual(OperationResult.Success, result);
Assert.IsTrue(wasSet);
}
[TestMethod]
public void Revert_MustDoNothing()
{
var result = sut.Revert();
Assert.AreEqual(OperationResult.Success, result);
}
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Service.Operations;
namespace SafeExamBrowser.Service.UnitTests.Operations
{
[TestClass]
public class SessionInitializationOperationTests
{
private Mock<ILogger> logger;
private Mock<Func<string, ILogObserver>> logWriterFactory;
private Mock<IServiceHost> serviceHost;
private Mock<Func<string, EventWaitHandle>> serviceEventFactory;
private SessionContext sessionContext;
private SessionInitializationOperation sut;
[TestInitialize]
public void Initialize()
{
logger = new Mock<ILogger>();
logWriterFactory = new Mock<Func<string, ILogObserver>>();
serviceHost = new Mock<IServiceHost>();
serviceEventFactory = new Mock<Func<string, EventWaitHandle>>();
sessionContext = new SessionContext();
logWriterFactory.Setup(f => f.Invoke(It.IsAny<string>())).Returns(new Mock<ILogObserver>().Object);
serviceEventFactory.Setup(f => f.Invoke(It.IsAny<string>())).Returns(new EventStub());
sessionContext.Configuration = new ServiceConfiguration
{
AppConfig = new AppConfig { ServiceEventName = $"{nameof(SafeExamBrowser)}-{nameof(SessionInitializationOperationTests)}" }
};
sut = new SessionInitializationOperation(logger.Object, logWriterFactory.Object, serviceEventFactory.Object, serviceHost.Object, sessionContext);
}
[TestMethod]
public void Perform_MustDisableNewConnections()
{
var result = sut.Perform();
serviceHost.VerifySet(h => h.AllowConnection = false, Times.Once);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
public void Perform_MustInitializeServiceEvent()
{
var result = sut.Perform();
Assert.AreEqual(OperationResult.Success, result);
Assert.IsInstanceOfType(sessionContext.ServiceEvent, typeof(EventWaitHandle));
}
[TestMethod]
public void Revert_MustSetServiceEvent()
{
sessionContext.ServiceEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
var wasSet = false;
var task = Task.Run(() => wasSet = sessionContext.ServiceEvent.WaitOne(1000));
var result = sut.Revert();
task.Wait();
Assert.AreEqual(OperationResult.Success, result);
Assert.IsTrue(wasSet);
}
[TestMethod]
public void Revert_MustDeleteConfiguration()
{
sessionContext.Configuration = new ServiceConfiguration();
sessionContext.ServiceEvent = new EventStub();
var result = sut.Revert();
Assert.AreEqual(OperationResult.Success, result);
Assert.IsNull(sessionContext.Configuration);
}
[TestMethod]
public void Revert_MustEnableNewConnections()
{
sessionContext.ServiceEvent = new EventStub();
var result = sut.Revert();
serviceHost.VerifySet(h => h.AllowConnection = true, Times.Once);
Assert.AreEqual(OperationResult.Success, result);
}
}
}

View file

@ -80,6 +80,11 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Communication\ServiceHostTests.cs" />
<Compile Include="Operations\EventStub.cs" />
<Compile Include="Operations\ServiceEventCleanupOperationTests.cs" />
<Compile Include="Operations\SessionActivationOperationTests.cs" />
<Compile Include="Operations\SessionInitializationOperationTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceControllerTests.cs" />
</ItemGroup>
@ -87,6 +92,10 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Communication\SafeExamBrowser.Communication.csproj">
<Project>{c9416a62-0623-4d38-96aa-92516b32f02f}</Project>
<Name>SafeExamBrowser.Communication</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
<Project>{47da5933-bef8-4729-94e6-abde2db12262}</Project>
<Name>SafeExamBrowser.Contracts</Name>
@ -96,10 +105,7 @@
<Name>SafeExamBrowser.Service</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Communication\" />
<Folder Include="Operations\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View file

@ -6,8 +6,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Communication.Events;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Core.OperationModel;
@ -21,7 +23,7 @@ namespace SafeExamBrowser.Service.UnitTests
private Mock<ILogger> logger;
private Mock<IOperationSequence> bootstrapSequence;
private SessionContext sessionContext;
private Mock<IRepeatableOperationSequence> sessionSequence;
private Mock<IOperationSequence> sessionSequence;
private Mock<IServiceHost> serviceHost;
private ServiceController sut;
@ -31,12 +33,86 @@ namespace SafeExamBrowser.Service.UnitTests
logger = new Mock<ILogger>();
bootstrapSequence = new Mock<IOperationSequence>();
sessionContext = new SessionContext();
sessionSequence = new Mock<IRepeatableOperationSequence>();
sessionSequence = new Mock<IOperationSequence>();
serviceHost = new Mock<IServiceHost>();
sut = new ServiceController(logger.Object, bootstrapSequence.Object, sessionSequence.Object, serviceHost.Object, sessionContext);
}
[TestMethod]
public void Communication_MustStartNewSessionUponRequest()
{
var args = new SessionStartEventArgs { Configuration = new ServiceConfiguration { SessionId = Guid.NewGuid() } };
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sut.TryStart();
serviceHost.Raise(h => h.SessionStartRequested += null, args);
sessionSequence.Verify(s => s.TryPerform(), Times.Once);
Assert.IsNotNull(sessionContext.Configuration);
Assert.AreEqual(args.Configuration.SessionId, sessionContext.Configuration.SessionId);
}
[TestMethod]
public void Communication_MustNotAllowNewSessionDuringActiveSession()
{
var args = new SessionStartEventArgs { Configuration = new ServiceConfiguration { SessionId = Guid.NewGuid() } };
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sessionContext.Configuration = new ServiceConfiguration { SessionId = Guid.NewGuid() };
sut.TryStart();
serviceHost.Raise(h => h.SessionStartRequested += null, args);
sessionSequence.Verify(s => s.TryPerform(), Times.Never);
Assert.AreNotEqual(args.Configuration.SessionId, sessionContext.Configuration.SessionId);
}
[TestMethod]
public void Communication_MustStopActiveSessionUponRequest()
{
var args = new SessionStopEventArgs { SessionId = Guid.NewGuid() };
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sessionContext.Configuration = new ServiceConfiguration { SessionId = args.SessionId };
sut.TryStart();
serviceHost.Raise(h => h.SessionStopRequested += null, args);
sessionSequence.Verify(s => s.TryRevert(), Times.Once);
}
[TestMethod]
public void Communication_MustNotStopSessionWithWrongId()
{
var args = new SessionStopEventArgs { SessionId = Guid.NewGuid() };
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sessionContext.Configuration = new ServiceConfiguration { SessionId = Guid.NewGuid() };
sut.TryStart();
serviceHost.Raise(h => h.SessionStopRequested += null, args);
sessionSequence.Verify(s => s.TryRevert(), Times.Never);
}
[TestMethod]
public void Communication_MustNotStopSessionWithoutActiveSession()
{
var args = new SessionStopEventArgs { SessionId = Guid.NewGuid() };
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sut.TryStart();
serviceHost.Raise(h => h.SessionStopRequested += null, args);
sessionSequence.Verify(s => s.TryRevert(), Times.Never);
}
[TestMethod]
public void Start_MustOnlyPerformBootstrapSequence()
{
@ -49,7 +125,6 @@ namespace SafeExamBrowser.Service.UnitTests
bootstrapSequence.Verify(b => b.TryPerform(), Times.Once);
bootstrapSequence.Verify(b => b.TryRevert(), Times.Never);
sessionSequence.Verify(b => b.TryPerform(), Times.Never);
sessionSequence.Verify(b => b.TryRepeat(), Times.Never);
sessionSequence.Verify(b => b.TryRevert(), Times.Never);
Assert.IsTrue(success);
@ -76,7 +151,6 @@ namespace SafeExamBrowser.Service.UnitTests
bootstrapSequence.Verify(b => b.TryPerform(), Times.Never);
bootstrapSequence.Verify(b => b.TryRevert(), Times.Once);
sessionSequence.Verify(b => b.TryPerform(), Times.Never);
sessionSequence.Verify(b => b.TryRepeat(), Times.Never);
sessionSequence.Verify(b => b.TryRevert(), Times.Once);
Assert.AreEqual(1, session);
@ -104,7 +178,6 @@ namespace SafeExamBrowser.Service.UnitTests
bootstrapSequence.Verify(b => b.TryPerform(), Times.Never);
bootstrapSequence.Verify(b => b.TryRevert(), Times.Once);
sessionSequence.Verify(b => b.TryPerform(), Times.Never);
sessionSequence.Verify(b => b.TryRepeat(), Times.Never);
sessionSequence.Verify(b => b.TryRevert(), Times.Never);
Assert.AreEqual(0, session);

View file

@ -9,6 +9,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using SafeExamBrowser.Communication.Hosts;
using SafeExamBrowser.Communication.Proxies;
using SafeExamBrowser.Contracts.Core.OperationModel;
@ -42,13 +45,10 @@ namespace SafeExamBrowser.Service
var bootstrapOperations = new Queue<IOperation>();
var sessionOperations = new Queue<IOperation>();
// TODO: bootstrapOperations.Enqueue(new RestoreOperation());
bootstrapOperations.Enqueue(new CommunicationHostOperation(serviceHost, logger));
bootstrapOperations.Enqueue(new ServiceEventCleanupOperation(logger, sessionContext));
sessionOperations.Enqueue(new SessionInitializationOperation(logger, CreateLogWriter, serviceHost, sessionContext));
// TODO: sessionOperations.Enqueue(new RegistryOperation());
// sessionOperations.Enqueue(new WindowsUpdateOperation());
sessionOperations.Enqueue(new SessionInitializationOperation(logger, LogWriterFactory, ServiceEventFactory, serviceHost, sessionContext));
sessionOperations.Enqueue(new SessionActivationOperation(logger, sessionContext));
var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
@ -82,7 +82,7 @@ namespace SafeExamBrowser.Service
logFileWriter.Initialize();
}
private ILogObserver CreateLogWriter(string filePath)
private ILogObserver LogWriterFactory(string filePath)
{
var writer = new LogFileWriter(new DefaultLogFormatter(), filePath);
@ -90,5 +90,16 @@ namespace SafeExamBrowser.Service
return writer;
}
private EventWaitHandle ServiceEventFactory(string eventName)
{
var securityIdentifier = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
var accessRule = new EventWaitHandleAccessRule(securityIdentifier, EventWaitHandleRights.Synchronize, AccessControlType.Allow);
var security = new EventWaitHandleSecurity();
security.AddAccessRule(accessRule);
return new EventWaitHandle(false, EventResetMode.AutoReset, eventName, out _, security);
}
}
}

View file

@ -7,8 +7,6 @@
*/
using System;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Core.OperationModel;
@ -19,18 +17,21 @@ namespace SafeExamBrowser.Service.Operations
internal class SessionInitializationOperation : SessionOperation
{
private ILogger logger;
private Func<string, ILogObserver> createLogWriter;
private Func<string, ILogObserver> logWriterFactory;
private Func<string, EventWaitHandle> serviceEventFactory;
private IServiceHost serviceHost;
private ILogObserver sessionWriter;
public SessionInitializationOperation(
ILogger logger,
Func<string, ILogObserver> createLogWriter,
Func<string, ILogObserver> logWriterFactory,
Func<string, EventWaitHandle> serviceEventFactory,
IServiceHost serviceHost,
SessionContext sessionContext) : base(sessionContext)
{
this.logger = logger;
this.createLogWriter = createLogWriter;
this.logWriterFactory = logWriterFactory;
this.serviceEventFactory = serviceEventFactory;
this.serviceHost = serviceHost;
}
@ -80,12 +81,6 @@ namespace SafeExamBrowser.Service.Operations
private void InitializeServiceEvent()
{
var securityIdentifier = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
var accessRule = new EventWaitHandleAccessRule(securityIdentifier, EventWaitHandleRights.Synchronize, AccessControlType.Allow);
var security = new EventWaitHandleSecurity();
security.AddAccessRule(accessRule);
if (Context.ServiceEvent != null)
{
logger.Info("Closing service event from previous session...");
@ -94,13 +89,13 @@ namespace SafeExamBrowser.Service.Operations
}
logger.Info("Attempting to create new service event...");
Context.ServiceEvent = new EventWaitHandle(false, EventResetMode.AutoReset, Context.Configuration.AppConfig.ServiceEventName, out _, security);
Context.ServiceEvent = serviceEventFactory.Invoke(Context.Configuration.AppConfig.ServiceEventName);
logger.Info("Service event successfully created.");
}
private void InitializeSessionWriter()
{
sessionWriter = createLogWriter.Invoke(Context.Configuration.AppConfig.ServiceLogFilePath);
sessionWriter = logWriterFactory.Invoke(Context.Configuration.AppConfig.ServiceLogFilePath);
logger.Subscribe(sessionWriter);
}
}

View file

@ -160,7 +160,14 @@ namespace SafeExamBrowser.Service
{
if (SessionIsRunning)
{
StopSession();
if (Session.SessionId == args.SessionId)
{
StopSession();
}
else
{
logger.Warn("Received session stop request with wrong session ID!");
}
}
else
{