diff --git a/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs b/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs index d0c5ff47..49b40fa1 100644 --- a/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs @@ -40,7 +40,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication hostObjectFactory.Setup(f => f.CreateObject(It.IsAny(), It.IsAny())).Returns(hostObject.Object); - sut = new ClientHost("net:pipe://some/address", hostObjectFactory.Object, logger.Object, PROCESS_ID); + sut = new ClientHost("net:pipe://some/address", hostObjectFactory.Object, logger.Object, PROCESS_ID, 0); } [TestMethod] diff --git a/SafeExamBrowser.Client.UnitTests/Operations/ClientHostDisconnectionOperationTests.cs b/SafeExamBrowser.Client.UnitTests/Operations/ClientHostDisconnectionOperationTests.cs index ae2f7211..6f26e940 100644 --- a/SafeExamBrowser.Client.UnitTests/Operations/ClientHostDisconnectionOperationTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Operations/ClientHostDisconnectionOperationTests.cs @@ -72,7 +72,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations clientHost.VerifyNoOtherCalls(); Assert.IsFalse(stopWatch.IsRunning); - Assert.IsTrue(stopWatch.ElapsedMilliseconds > timeout_ms); + Assert.IsTrue(stopWatch.ElapsedMilliseconds >= timeout_ms); } [TestMethod] diff --git a/SafeExamBrowser.Client/Communication/ClientHost.cs b/SafeExamBrowser.Client/Communication/ClientHost.cs index 680a8275..c32b869c 100644 --- a/SafeExamBrowser.Client/Communication/ClientHost.cs +++ b/SafeExamBrowser.Client/Communication/ClientHost.cs @@ -28,7 +28,12 @@ namespace SafeExamBrowser.Client.Communication public event CommunicationEventHandler RuntimeDisconnected; public event CommunicationEventHandler Shutdown; - public ClientHost(string address, IHostObjectFactory factory, ILogger logger, int processId) : base(address, factory, logger) + public ClientHost( + string address, + IHostObjectFactory factory, + ILogger logger, + int processId, + int timeout_ms) : base(address, factory, logger, timeout_ms) { this.processId = processId; } diff --git a/SafeExamBrowser.Client/CompositionRoot.cs b/SafeExamBrowser.Client/CompositionRoot.cs index 961ea5cf..2095b6e1 100644 --- a/SafeExamBrowser.Client/CompositionRoot.cs +++ b/SafeExamBrowser.Client/CompositionRoot.cs @@ -180,9 +180,10 @@ namespace SafeExamBrowser.Client private IOperation BuildClientHostOperation() { + const int FIVE_SECONDS = 5000; var processId = Process.GetCurrentProcess().Id; var factory = new HostObjectFactory(); - var host = new ClientHost(configuration.AppConfig.ClientAddress, factory, new ModuleLogger(logger, nameof(ClientHost)), processId); + var host = new ClientHost(configuration.AppConfig.ClientAddress, factory, new ModuleLogger(logger, nameof(ClientHost)), processId, FIVE_SECONDS); var operation = new CommunicationHostOperation(host, logger); clientHost = host; diff --git a/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostStub.cs b/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostStub.cs index 3cabe727..993228ec 100644 --- a/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostStub.cs +++ b/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostStub.cs @@ -21,7 +21,7 @@ namespace SafeExamBrowser.Communication.UnitTests.Hosts public Func OnReceiveStub { get; set; } public Func OnReceiveSimpleMessageStub { get; set; } - public BaseHostStub(string address, IHostObjectFactory factory, ILogger logger) : base(address, factory, logger) + public BaseHostStub(string address, IHostObjectFactory factory, ILogger logger, int timeout_ms) : base(address, factory, logger, timeout_ms) { } diff --git a/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs b/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs index 20c58198..59067b66 100644 --- a/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs +++ b/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs @@ -35,7 +35,7 @@ namespace SafeExamBrowser.Communication.UnitTests.Hosts hostObjectFactory.Setup(f => f.CreateObject(It.IsAny(), It.IsAny())).Returns(hostObject.Object); - sut = new BaseHostStub("net.pipe://some/address/here", hostObjectFactory.Object, logger.Object); + sut = new BaseHostStub("net.pipe://some/address/here", hostObjectFactory.Object, logger.Object, 10); } [TestMethod] @@ -56,7 +56,6 @@ namespace SafeExamBrowser.Communication.UnitTests.Hosts [ExpectedException(typeof(CommunicationException))] public void MustCorrectlyHandleStartupException() { - // TODO: Takes waaay too long, extract timeout (move to constructor like in ClientOperation)! hostObject.Setup(h => h.Open()).Throws(); sut.Start(); diff --git a/SafeExamBrowser.Communication/Hosts/BaseHost.cs b/SafeExamBrowser.Communication/Hosts/BaseHost.cs index fe4531e0..f7eec248 100644 --- a/SafeExamBrowser.Communication/Hosts/BaseHost.cs +++ b/SafeExamBrowser.Communication/Hosts/BaseHost.cs @@ -22,13 +22,13 @@ namespace SafeExamBrowser.Communication.Hosts [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)] public abstract class BaseHost : ICommunication, ICommunicationHost { - private const int FIVE_SECONDS = 5000; private readonly object @lock = new object(); private string address; private IHostObject host; private IHostObjectFactory factory; private Thread hostThread; + private int timeout_ms; protected Guid? CommunicationToken { get; private set; } protected ILogger Logger { get; private set; } @@ -44,11 +44,12 @@ namespace SafeExamBrowser.Communication.Hosts } } - public BaseHost(string address, IHostObjectFactory factory, ILogger logger) + public BaseHost(string address, IHostObjectFactory factory, ILogger logger, int timeout_ms) { this.address = address; this.factory = factory; this.Logger = logger; + this.timeout_ms = timeout_ms; } protected abstract bool OnConnect(Guid? token); @@ -137,11 +138,11 @@ namespace SafeExamBrowser.Communication.Hosts hostThread.IsBackground = true; hostThread.Start(); - var success = startedEvent.WaitOne(FIVE_SECONDS); + var success = startedEvent.WaitOne(timeout_ms); if (!success) { - throw new CommunicationException($"Failed to start communication host for endpoint '{address}' within {FIVE_SECONDS / 1000} seconds!", exception); + throw new CommunicationException($"Failed to start communication host for endpoint '{address}' within {timeout_ms / 1000} seconds!", exception); } } } @@ -202,7 +203,7 @@ namespace SafeExamBrowser.Communication.Hosts try { host?.Close(); - success = hostThread?.Join(FIVE_SECONDS) == true; + success = hostThread?.Join(timeout_ms) == true; } catch (Exception e) { diff --git a/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs b/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs index ce3a2ea7..bbb79517 100644 --- a/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs +++ b/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs @@ -37,7 +37,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication hostObjectFactory.Setup(f => f.CreateObject(It.IsAny(), It.IsAny())).Returns(hostObject.Object); - sut = new RuntimeHost("net:pipe://some/address", configuration.Object, hostObjectFactory.Object, logger.Object); + sut = new RuntimeHost("net:pipe://some/address", configuration.Object, hostObjectFactory.Object, logger.Object, 0); } [TestMethod] diff --git a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs index fecdd5e1..9616a776 100644 --- a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs +++ b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs @@ -7,12 +7,12 @@ */ using System; +using SafeExamBrowser.Communication.Hosts; 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.Communication.Hosts; namespace SafeExamBrowser.Runtime.Communication { @@ -29,7 +29,12 @@ namespace SafeExamBrowser.Runtime.Communication public event CommunicationEventHandler ReconfigurationRequested; public event CommunicationEventHandler ShutdownRequested; - public RuntimeHost(string address, IConfigurationRepository configuration, IHostObjectFactory factory, ILogger logger) : base(address, factory, logger) + public RuntimeHost( + string address, + IConfigurationRepository configuration, + IHostObjectFactory factory, + ILogger logger, + int timeout_ms) : base(address, factory, logger, timeout_ms) { this.configuration = configuration; } diff --git a/SafeExamBrowser.Runtime/CompositionRoot.cs b/SafeExamBrowser.Runtime/CompositionRoot.cs index e40ad90d..6b491450 100644 --- a/SafeExamBrowser.Runtime/CompositionRoot.cs +++ b/SafeExamBrowser.Runtime/CompositionRoot.cs @@ -41,7 +41,8 @@ namespace SafeExamBrowser.Runtime internal void BuildObjectGraph(Action shutdown) { - const int STARTUP_TIMEOUT_MS = 15000; + const int FIVE_SECONDS = 5000; + const int FIFTEEN_SECONDS = 15000; var args = Environment.GetCommandLineArgs(); var configuration = BuildConfigurationRepository(); @@ -60,7 +61,7 @@ namespace SafeExamBrowser.Runtime var processFactory = new ProcessFactory(new ModuleLogger(logger, nameof(ProcessFactory))); var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger); var resourceLoader = new ResourceLoader(); - var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, nameof(RuntimeHost))); + var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, nameof(RuntimeHost)), FIVE_SECONDS); var serviceProxy = new ServiceProxy(appConfig.ServiceAddress, new ProxyObjectFactory(), new ModuleLogger(logger, nameof(ServiceProxy))); var uiFactory = new UserInterfaceFactory(text); @@ -73,9 +74,9 @@ namespace SafeExamBrowser.Runtime sessionOperations.Enqueue(new ConfigurationOperation(appConfig, configuration, logger, messageBox, resourceLoader, runtimeHost, text, uiFactory, args)); sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost)); sessionOperations.Enqueue(new ServiceOperation(configuration, logger, serviceProxy, text)); - sessionOperations.Enqueue(new ClientTerminationOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, STARTUP_TIMEOUT_MS)); + sessionOperations.Enqueue(new ClientTerminationOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, FIFTEEN_SECONDS)); sessionOperations.Enqueue(new KioskModeOperation(configuration, desktopFactory, explorerShell, logger, processFactory)); - sessionOperations.Enqueue(new ClientOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, STARTUP_TIMEOUT_MS)); + sessionOperations.Enqueue(new ClientOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, FIFTEEN_SECONDS)); var bootstrapSequence = new OperationSequence(logger, bootstrapOperations); var sessionSequence = new OperationSequence(logger, sessionOperations);