SEBWIN-219: Introduced OperationResult to be able to determine cause of operation procedure failures.

This commit is contained in:
dbuechel 2018-02-28 15:49:06 +01:00
parent f5ef7fa859
commit 40fd49126f
31 changed files with 419 additions and 306 deletions

View file

@ -6,7 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Client.Behaviour;
@ -33,139 +32,145 @@ namespace SafeExamBrowser.Client.UnitTests
private ClientController sut;
[TestInitialize]
public void Initialize()
{
displayMonitorMock = new Mock<IDisplayMonitor>();
loggerMock = new Mock<ILogger>();
processMonitorMock = new Mock<IProcessMonitor>();
operationSequenceMock = new Mock<IOperationSequence>();
runtimeProxyMock = new Mock<IRuntimeProxy>();
taskbarMock = new Mock<ITaskbar>();
uiFactoryMock = new Mock<IUserInterfaceFactory>();
windowMonitorMock= new Mock<IWindowMonitor>();
operationSequenceMock.Setup(o => o.TryPerform()).Returns(true);
sut = new ClientController(
displayMonitorMock.Object,
loggerMock.Object,
operationSequenceMock.Object,
processMonitorMock.Object,
runtimeProxyMock.Object,
new Action(() => { }),
taskbarMock.Object,
uiFactoryMock.Object,
windowMonitorMock.Object);
sut.TryStart();
}
[TestMethod]
public void MustHandleDisplayChangeCorrectly()
public void TODO()
{
var order = 0;
var workingArea = 0;
var taskbar = 0;
displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order);
taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order);
displayMonitorMock.Raise(d => d.DisplayChanged += null);
displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once);
taskbarMock.Verify(t => t.InitializeBounds(), Times.Once);
Assert.IsTrue(workingArea == 1);
Assert.IsTrue(taskbar == 2);
Assert.Fail();
}
[TestMethod]
public void MustHandleExplorerStartCorrectly()
{
var order = 0;
var processManager = 0;
var workingArea = 0;
var taskbar = 0;
//[TestInitialize]
//public void Initialize()
//{
// displayMonitorMock = new Mock<IDisplayMonitor>();
// loggerMock = new Mock<ILogger>();
// processMonitorMock = new Mock<IProcessMonitor>();
// operationSequenceMock = new Mock<IOperationSequence>();
// runtimeProxyMock = new Mock<IRuntimeProxy>();
// taskbarMock = new Mock<ITaskbar>();
// uiFactoryMock = new Mock<IUserInterfaceFactory>();
// windowMonitorMock= new Mock<IWindowMonitor>();
processMonitorMock.Setup(p => p.CloseExplorerShell()).Callback(() => processManager = ++order);
displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order);
taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order);
// operationSequenceMock.Setup(o => o.TryPerform()).Returns(true);
processMonitorMock.Raise(p => p.ExplorerStarted += null);
// sut = new ClientController(
// displayMonitorMock.Object,
// loggerMock.Object,
// operationSequenceMock.Object,
// processMonitorMock.Object,
// runtimeProxyMock.Object,
// new Action(() => { }),
// taskbarMock.Object,
// uiFactoryMock.Object,
// windowMonitorMock.Object);
processMonitorMock.Verify(p => p.CloseExplorerShell(), Times.Once);
displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once);
taskbarMock.Verify(t => t.InitializeBounds(), Times.Once);
// sut.TryStart();
//}
Assert.IsTrue(processManager == 1);
Assert.IsTrue(workingArea == 2);
Assert.IsTrue(taskbar == 3);
}
//[TestMethod]
//public void MustHandleDisplayChangeCorrectly()
//{
// var order = 0;
// var workingArea = 0;
// var taskbar = 0;
[TestMethod]
public void MustHandleAllowedWindowChangeCorrectly()
{
var window = new IntPtr(12345);
// displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order);
// taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order);
processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(true);
// displayMonitorMock.Raise(d => d.DisplayChanged += null);
windowMonitorMock.Raise(w => w.WindowChanged += null, window);
// displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once);
// taskbarMock.Verify(t => t.InitializeBounds(), Times.Once);
processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once);
windowMonitorMock.Verify(w => w.Hide(window), Times.Never);
windowMonitorMock.Verify(w => w.Close(window), Times.Never);
}
// Assert.IsTrue(workingArea == 1);
// Assert.IsTrue(taskbar == 2);
//}
[TestMethod]
public void MustHandleUnallowedWindowHideCorrectly()
{
var order = 0;
var belongs = 0;
var hide = 0;
var window = new IntPtr(12345);
//[TestMethod]
//public void MustHandleExplorerStartCorrectly()
//{
// var order = 0;
// var processManager = 0;
// var workingArea = 0;
// var taskbar = 0;
processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order);
windowMonitorMock.Setup(w => w.Hide(window)).Returns(true).Callback(() => hide = ++order);
// processMonitorMock.Setup(p => p.CloseExplorerShell()).Callback(() => processManager = ++order);
// displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order);
// taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order);
windowMonitorMock.Raise(w => w.WindowChanged += null, window);
// processMonitorMock.Raise(p => p.ExplorerStarted += null);
processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once);
windowMonitorMock.Verify(w => w.Hide(window), Times.Once);
windowMonitorMock.Verify(w => w.Close(window), Times.Never);
// processMonitorMock.Verify(p => p.CloseExplorerShell(), Times.Once);
// displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once);
// taskbarMock.Verify(t => t.InitializeBounds(), Times.Once);
Assert.IsTrue(belongs == 1);
Assert.IsTrue(hide == 2);
}
// Assert.IsTrue(processManager == 1);
// Assert.IsTrue(workingArea == 2);
// Assert.IsTrue(taskbar == 3);
//}
[TestMethod]
public void MustHandleUnallowedWindowCloseCorrectly()
{
var order = 0;
var belongs = 0;
var hide = 0;
var close = 0;
var window = new IntPtr(12345);
//[TestMethod]
//public void MustHandleAllowedWindowChangeCorrectly()
//{
// var window = new IntPtr(12345);
processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order);
windowMonitorMock.Setup(w => w.Hide(window)).Returns(false).Callback(() => hide = ++order);
windowMonitorMock.Setup(w => w.Close(window)).Callback(() => close = ++order);
// processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(true);
windowMonitorMock.Raise(w => w.WindowChanged += null, window);
// windowMonitorMock.Raise(w => w.WindowChanged += null, window);
processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once);
windowMonitorMock.Verify(w => w.Hide(window), Times.Once);
windowMonitorMock.Verify(w => w.Close(window), Times.Once);
// processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once);
// windowMonitorMock.Verify(w => w.Hide(window), Times.Never);
// windowMonitorMock.Verify(w => w.Close(window), Times.Never);
//}
Assert.IsTrue(belongs == 1);
Assert.IsTrue(hide == 2);
Assert.IsTrue(close == 3);
}
//[TestMethod]
//public void MustHandleUnallowedWindowHideCorrectly()
//{
// var order = 0;
// var belongs = 0;
// var hide = 0;
// var window = new IntPtr(12345);
[TestCleanup]
public void Cleanup()
{
// TODO sut.Stop();
}
// processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order);
// windowMonitorMock.Setup(w => w.Hide(window)).Returns(true).Callback(() => hide = ++order);
// windowMonitorMock.Raise(w => w.WindowChanged += null, window);
// processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once);
// windowMonitorMock.Verify(w => w.Hide(window), Times.Once);
// windowMonitorMock.Verify(w => w.Close(window), Times.Never);
// Assert.IsTrue(belongs == 1);
// Assert.IsTrue(hide == 2);
//}
//[TestMethod]
//public void MustHandleUnallowedWindowCloseCorrectly()
//{
// var order = 0;
// var belongs = 0;
// var hide = 0;
// var close = 0;
// var window = new IntPtr(12345);
// processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order);
// windowMonitorMock.Setup(w => w.Hide(window)).Returns(false).Callback(() => hide = ++order);
// windowMonitorMock.Setup(w => w.Close(window)).Callback(() => close = ++order);
// windowMonitorMock.Raise(w => w.WindowChanged += null, window);
// processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once);
// windowMonitorMock.Verify(w => w.Hide(window), Times.Once);
// windowMonitorMock.Verify(w => w.Close(window), Times.Once);
// Assert.IsTrue(belongs == 1);
// Assert.IsTrue(hide == 2);
// Assert.IsTrue(close == 3);
//}
//[TestCleanup]
//public void Cleanup()
//{
// // TODO sut.Stop();
//}
}
}

View file

@ -80,7 +80,7 @@ namespace SafeExamBrowser.Client.Behaviour
splashScreen = uiFactory.CreateSplashScreen();
operations.ProgressIndicator = splashScreen;
var success = operations.TryPerform();
var success = operations.TryPerform() == OperationResult.Success;
if (success)
{

View file

@ -24,7 +24,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private ITaskbar taskbar;
private IUserInterfaceFactory uiFactory;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public BrowserOperation(
@ -41,7 +40,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.uiFactory = uiFactory;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing browser...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeBrowser, true);
@ -52,11 +51,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
browserController.RegisterApplicationButton(browserButton);
taskbar.AddApplication(browserButton);
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -19,7 +19,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private ILogger logger;
private INativeMethods nativeMethods;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public ClipboardOperation(ILogger logger, INativeMethods nativeMethods)
@ -28,14 +27,16 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.nativeMethods = nativeMethods;
}
public void Perform()
public OperationResult Perform()
{
EmptyClipboard();
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -22,7 +22,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private ILogger logger;
private IRuntimeProxy runtime;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public ConfigurationOperation(ClientConfiguration configuration, ILogger logger, IRuntimeProxy runtime)
@ -32,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.runtime = runtime;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing application configuration...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeConfiguration);
@ -50,12 +49,16 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
catch (Exception e)
{
logger.Error("An unexpected error occurred while trying to retrieve the application configuration!", e);
return OperationResult.Failed;
}
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -21,7 +21,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private ILogger logger;
private ITaskbar taskbar;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar)
@ -31,7 +30,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.taskbar = taskbar;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing working area...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeWorkingArea);
@ -39,11 +38,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
displayMonitor.PreventSleepMode();
displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight());
displayMonitor.StartMonitoringDisplayChanges();
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -21,7 +21,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private ILogger logger;
private INativeMethods nativeMethods;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public KeyboardInterceptorOperation(
@ -34,17 +33,19 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.nativeMethods = nativeMethods;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Starting keyboard interception...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartKeyboardInterception);
nativeMethods.RegisterKeyboardHook(keyboardInterceptor);
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -21,7 +21,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private IMouseInterceptor mouseInterceptor;
private INativeMethods nativeMethods;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public MouseInterceptorOperation(
@ -34,17 +33,19 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.nativeMethods = nativeMethods;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Starting mouse interception...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartMouseInterception);
nativeMethods.RegisterMouseHook(mouseInterceptor);
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -19,7 +19,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private ILogger logger;
private IProcessMonitor processMonitor;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor)
@ -28,7 +27,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.processMonitor = processMonitor;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing process monitoring...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_WaitExplorerTermination, true);
@ -39,11 +38,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeProcessMonitoring);
// TODO: Implement process monitoring...
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -22,7 +22,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private IRuntimeProxy runtime;
private Guid token;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public RuntimeConnectionOperation(ILogger logger, IRuntimeProxy runtime, Guid token)
@ -32,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.token = token;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing runtime connection...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeRuntimeConnection);
@ -46,20 +45,21 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
logger.Error("An unexpected error occurred while trying to connect to the runtime!", e);
}
if (connected)
if (!connected)
{
logger.Info("Successfully connected to the runtime.");
}
else
{
Abort = true;
logger.Error("Failed to connect to the runtime. Aborting startup...");
return OperationResult.Failed;
}
logger.Info("Successfully connected to the runtime.");
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -32,7 +32,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private IUserInterfaceFactory uiFactory;
private IText text;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public TaskbarOperation(
@ -61,7 +60,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.wirelessNetwork = wirelessNetwork;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing taskbar...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeTaskbar);
@ -85,11 +84,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
{
AddWirelessNetworkControl();
}
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -19,7 +19,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
private ILogger logger;
private IWindowMonitor windowMonitor;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor)
@ -28,18 +27,20 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
this.windowMonitor = windowMonitor;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing window monitoring...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeWindowMonitoring);
windowMonitor.HideAllWindows();
windowMonitor.StartMonitoringWindows();
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -12,11 +12,6 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations
{
public interface IOperation
{
/// <summary>
/// Determines whether the procedure to which this operation belongs to should be aborted.
/// </summary>
bool Abort { get; }
/// <summary>
/// The progress indicator to be used to show status information to the user. Will be ignored if <c>null</c>.
/// </summary>
@ -25,15 +20,15 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations
/// <summary>
/// Performs the operation.
/// </summary>
void Perform();
OperationResult Perform();
/// <summary>
/// Repeats the operation.
/// </summary>
void Repeat();
OperationResult Repeat();
/// <summary>
/// Reverts all changes which were made when performing the operation.
/// Reverts all changes which were made when executing the operation.
/// </summary>
void Revert();
}

View file

@ -13,22 +13,23 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations
public interface IOperationSequence
{
/// <summary>
/// The progress indicator to be used when performing any action. Will be ignored if <c>null</c>.
/// The progress indicator to be used when executing an operation. Will be ignored if <c>null</c>.
/// </summary>
IProgressIndicator ProgressIndicator { set; }
/// <summary>
/// Tries to perform the operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
/// Tries to perform the operations of this sequence.
/// </summary>
bool TryPerform();
OperationResult TryPerform();
/// <summary>
/// Tries to repeat the operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
/// Tries to repeat the operations of this sequence.
/// </summary>
bool TryRepeat();
OperationResult TryRepeat();
/// <summary>
/// Tries to revert the operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
/// Tries to revert the operations of this sequence. Returns <c>true</c> if all operations were reverted without errors,
/// otherwise <c>false</c>.
/// </summary>
bool TryRevert();
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018 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/.
*/
namespace SafeExamBrowser.Contracts.Behaviour.Operations
{
public enum OperationResult
{
/// <summary>
/// Indicates that the operation has been aborted due to an expected condition, e.g. as result of a user decision.
/// </summary>
Aborted,
/// <summary>
/// Indicates that the operation has failed due to an invalid or unexpected condition.
/// </summary>
Failed,
/// <summary>
/// Indicates that the operation has been executed successfully.
/// </summary>
Success
}
}

View file

@ -56,6 +56,7 @@
<Compile Include="Behaviour\IApplicationController.cs" />
<Compile Include="Behaviour\IRuntimeController.cs" />
<Compile Include="Behaviour\Operations\IOperationSequence.cs" />
<Compile Include="Behaviour\Operations\OperationResult.cs" />
<Compile Include="Communication\IClientHost.cs" />
<Compile Include="Communication\ICommunication.cs" />
<Compile Include="Communication\IClientProxy.cs" />

View file

@ -36,6 +36,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationC.Setup(o => o.Perform()).Returns(OperationResult.Success);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
@ -61,14 +65,15 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationB.SetupGet(o => o.Abort).Returns(true);
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Aborted);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryPerform();
var result = sut.TryPerform();
operationA.Verify(o => o.Perform(), Times.Once);
operationA.Verify(o => o.Revert(), Times.Once);
@ -77,7 +82,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operationC.Verify(o => o.Perform(), Times.Never);
operationC.Verify(o => o.Revert(), Times.Never);
Assert.IsFalse(success);
Assert.AreEqual(OperationResult.Aborted, result);
}
[TestMethod]
@ -88,12 +93,16 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationC.Setup(o => o.Perform()).Returns(OperationResult.Success);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryPerform();
var result = sut.TryPerform();
operationA.Verify(o => o.Perform(), Times.Once);
operationA.Verify(o => o.Revert(), Times.Never);
@ -102,7 +111,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operationC.Verify(o => o.Perform(), Times.Once);
operationC.Verify(o => o.Revert(), Times.Never);
Assert.IsTrue(success);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
@ -114,18 +123,18 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Callback(() => a = ++current);
operationB.Setup(o => o.Perform()).Callback(() => b = ++current);
operationC.Setup(o => o.Perform()).Callback(() => c = ++current);
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success).Callback(() => a = ++current);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success).Callback(() => b = ++current);
operationC.Setup(o => o.Perform()).Returns(OperationResult.Success).Callback(() => c = ++current);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryPerform();
var result = sut.TryPerform();
Assert.IsTrue(success);
Assert.AreEqual(OperationResult.Success, result);
Assert.IsTrue(a == 1);
Assert.IsTrue(b == 2);
Assert.IsTrue(c == 3);
@ -140,6 +149,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationD = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationC.Setup(o => o.Perform()).Throws<Exception>();
operations.Enqueue(operationA.Object);
@ -148,7 +159,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operations.Enqueue(operationD.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryPerform();
var result = sut.TryPerform();
operationA.Verify(o => o.Perform(), Times.Once);
operationA.Verify(o => o.Revert(), Times.Once);
@ -159,7 +170,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operationD.Verify(o => o.Perform(), Times.Never);
operationD.Verify(o => o.Revert(), Times.Never);
Assert.IsFalse(success);
Assert.AreEqual(OperationResult.Failed, result);
}
[TestMethod]
@ -172,10 +183,12 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationD = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationA.Setup(o => o.Revert()).Callback(() => a = ++current);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Revert()).Callback(() => b = ++current);
operationC.Setup(o => o.Revert()).Callback(() => c = ++current);
operationC.Setup(o => o.Perform()).Throws<Exception>();
operationC.Setup(o => o.Revert()).Callback(() => c = ++current);
operationD.Setup(o => o.Revert()).Callback(() => d = ++current);
operations.Enqueue(operationA.Object);
@ -184,9 +197,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operations.Enqueue(operationD.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryPerform();
var result = sut.TryPerform();
Assert.IsFalse(success);
Assert.AreEqual(OperationResult.Failed, result);
Assert.IsTrue(d == 0);
Assert.IsTrue(c == 1);
Assert.IsTrue(b == 2);
@ -201,7 +214,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationC.Setup(o => o.Perform()).Throws<Exception>();
operationC.Setup(o => o.Revert()).Throws<Exception>();
operationB.Setup(o => o.Revert()).Throws<Exception>();
operationA.Setup(o => o.Revert()).Throws<Exception>();
@ -225,9 +241,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
public void MustSucceedWithEmptyQueue()
{
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
var success = sut.TryPerform();
var result = sut.TryPerform();
Assert.IsTrue(success);
Assert.AreEqual(OperationResult.Success, result);
}
@ -240,9 +256,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
indicatorMock.Setup(i => i.SetMaxValue(It.IsAny<int>())).Throws<Exception>();
sut.ProgressIndicator = indicatorMock.Object;
var success = sut.TryPerform();
var result = sut.TryPerform();
Assert.IsFalse(success);
Assert.AreEqual(OperationResult.Failed, result);
}
#endregion
@ -257,14 +273,15 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationB.SetupGet(o => o.Abort).Returns(true);
operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationB.Setup(o => o.Repeat()).Returns(OperationResult.Aborted);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryRepeat();
var result = sut.TryRepeat();
operationA.Verify(o => o.Repeat(), Times.Once);
operationA.Verify(o => o.Revert(), Times.Never);
@ -273,7 +290,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operationC.Verify(o => o.Repeat(), Times.Never);
operationC.Verify(o => o.Revert(), Times.Never);
Assert.IsFalse(success);
Assert.AreEqual(OperationResult.Aborted, result);
}
[TestMethod]
@ -284,12 +301,16 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationC.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryRepeat();
var result = sut.TryRepeat();
operationA.Verify(o => o.Perform(), Times.Never);
operationA.Verify(o => o.Repeat(), Times.Once);
@ -301,7 +322,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operationC.Verify(o => o.Repeat(), Times.Once);
operationC.Verify(o => o.Revert(), Times.Never);
Assert.IsTrue(success);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
@ -313,18 +334,18 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Repeat()).Callback(() => a = ++current);
operationB.Setup(o => o.Repeat()).Callback(() => b = ++current);
operationC.Setup(o => o.Repeat()).Callback(() => c = ++current);
operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success).Callback(() => a = ++current);
operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success).Callback(() => b = ++current);
operationC.Setup(o => o.Repeat()).Returns(OperationResult.Success).Callback(() => c = ++current);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryRepeat();
var result = sut.TryRepeat();
Assert.IsTrue(success);
Assert.AreEqual(OperationResult.Success, result);
Assert.IsTrue(a == 1);
Assert.IsTrue(b == 2);
Assert.IsTrue(c == 3);
@ -339,6 +360,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationD = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationC.Setup(o => o.Repeat()).Throws<Exception>();
operations.Enqueue(operationA.Object);
@ -347,7 +370,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operations.Enqueue(operationD.Object);
var sut = new OperationSequence(loggerMock.Object, operations);
var success = sut.TryRepeat();
var result = sut.TryRepeat();
operationA.Verify(o => o.Repeat(), Times.Once);
operationA.Verify(o => o.Revert(), Times.Never);
@ -358,25 +381,25 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
operationD.Verify(o => o.Repeat(), Times.Never);
operationD.Verify(o => o.Revert(), Times.Never);
Assert.IsFalse(success);
Assert.AreEqual(OperationResult.Failed, result);
}
[TestMethod]
public void MustSucceedRepeatingWithEmptyQueue()
{
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
var success = sut.TryRepeat();
var result = sut.TryRepeat();
Assert.IsTrue(success);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
public void MustSucceedRepeatingWithoutCallingPerform()
{
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
var success = sut.TryRepeat();
var result = sut.TryRepeat();
Assert.IsTrue(success);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
@ -388,9 +411,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
indicatorMock.Setup(i => i.SetMaxValue(It.IsAny<int>())).Throws<Exception>();
sut.ProgressIndicator = indicatorMock.Object;
var success = sut.TryRepeat();
var result = sut.TryRepeat();
Assert.IsFalse(success);
Assert.AreEqual(OperationResult.Failed, result);
}
#endregion
@ -405,6 +428,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationC.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationC.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);
operations.Enqueue(operationC.Object);
@ -431,6 +461,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationC.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationA.Setup(o => o.Revert()).Callback(() => a = ++current);
operationB.Setup(o => o.Revert()).Callback(() => b = ++current);
operationC.Setup(o => o.Revert()).Callback(() => c = ++current);
@ -459,6 +493,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationC.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationA.Setup(o => o.Revert()).Throws<Exception>();
operationB.Setup(o => o.Revert()).Throws<Exception>();
operationC.Setup(o => o.Revert()).Throws<Exception>();
@ -488,7 +526,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
var operationC = new Mock<IOperation>();
var operations = new Queue<IOperation>();
operationB.SetupGet(o => o.Abort).Returns(true);
operationA.Setup(o => o.Perform()).Returns(OperationResult.Success);
operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operationB.Setup(o => o.Perform()).Returns(OperationResult.Aborted);
operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success);
operations.Enqueue(operationA.Object);
operations.Enqueue(operationB.Object);

View file

@ -19,7 +19,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
private ICommunicationHost host;
private ILogger logger;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public CommunicationOperation(ICommunicationHost host, ILogger logger)
@ -28,15 +27,17 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
this.logger = logger;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Starting communication host...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartCommunicationHost);
host.Start();
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
if (!host.IsRunning)
{
@ -46,6 +47,8 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
host.Stop();
host.Start();
}
return OperationResult.Success;
}
public void Revert()

View file

@ -17,7 +17,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
private Func<IOperation> initialize;
private IOperation operation;
public bool Abort { get; set; }
public IProgressIndicator ProgressIndicator { get; set; }
public DelayedInitializationOperation(Func<IOperation> initialize)
@ -25,21 +24,19 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
this.initialize = initialize;
}
public void Perform()
public OperationResult Perform()
{
operation = initialize.Invoke();
operation.ProgressIndicator = ProgressIndicator;
operation.Perform();
Abort = operation.Abort;
return operation.Perform();
}
public void Repeat()
public OperationResult Repeat()
{
operation.ProgressIndicator = ProgressIndicator;
operation.Repeat();
Abort = operation.Abort;
return operation.Repeat();
}
public void Revert()

View file

@ -18,7 +18,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
private Action repeat;
private Action revert;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public DelegateOperation(Action perform, Action repeat = null, Action revert = null)
@ -28,14 +27,18 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
this.revert = revert;
}
public void Perform()
public OperationResult Perform()
{
perform?.Invoke();
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
repeat?.Invoke();
return OperationResult.Success;
}
public void Revert()

View file

@ -22,7 +22,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
private ILogger logger;
private IText text;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public I18nOperation(ILogger logger, IText text)
@ -31,7 +30,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
this.text = text;
}
public void Perform()
public OperationResult Perform()
{
logger.Info($"Loading default text data (the currently active culture is '{CultureInfo.CurrentCulture.Name}')...");
@ -40,11 +39,13 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
var textResource = new XmlTextResource(path);
text.Initialize(textResource);
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// Nothing to do here...
return OperationResult.Success;
}
public void Revert()

View file

@ -29,16 +29,16 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
this.operations = new Queue<IOperation>(operations);
}
public bool TryPerform()
public OperationResult TryPerform()
{
var success = false;
var result = OperationResult.Failed;
try
{
Initialize();
success = Perform();
result = Perform();
if (!success)
if (result != OperationResult.Success)
{
Revert(true);
}
@ -48,24 +48,24 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
logger.Error("Failed to perform operations!", e);
}
return success;
return result;
}
public bool TryRepeat()
public OperationResult TryRepeat()
{
var success = false;
var result = OperationResult.Failed;
try
{
Initialize();
success = Repeat();
result = Repeat();
}
catch (Exception e)
{
logger.Error("Failed to repeat operations!", e);
}
return success;
return result;
}
public bool TryRevert()
@ -98,60 +98,60 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
}
}
private bool Perform()
private OperationResult Perform()
{
foreach (var operation in operations)
{
var result = OperationResult.Failed;
stack.Push(operation);
try
{
operation.ProgressIndicator = ProgressIndicator;
operation.Perform();
result = operation.Perform();
}
catch (Exception e)
{
logger.Error($"Failed to perform operation '{operation.GetType().Name}'!", e);
return false;
logger.Error($"Caught unexpected exception while performing operation '{operation.GetType().Name}'!", e);
}
if (operation.Abort)
if (result != OperationResult.Success)
{
return false;
return result;
}
ProgressIndicator?.Progress();
}
return true;
return OperationResult.Success;
}
private bool Repeat()
private OperationResult Repeat()
{
foreach (var operation in operations)
{
var result = OperationResult.Failed;
try
{
operation.ProgressIndicator = ProgressIndicator;
operation.Repeat();
result = operation.Repeat();
}
catch (Exception e)
{
logger.Error($"Failed to repeat operation '{operation.GetType().Name}'!", e);
return false;
logger.Error($"Caught unexpected exception while repeating operation '{operation.GetType().Name}'!", e);
}
if (operation.Abort)
if (result != OperationResult.Success)
{
return false;
return result;
}
ProgressIndicator?.Progress();
}
return true;
return OperationResult.Success;
}
private bool Revert(bool regress = false)

View file

@ -10,6 +10,7 @@ using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Behaviour.Operations;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.I18n;
@ -136,9 +137,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
sut = new ConfigurationOperation(repository.Object, logger.Object, info, text.Object, uiFactory.Object, null);
sut.Perform();
var result = sut.Perform();
Assert.IsTrue(sut.Abort);
Assert.AreEqual(OperationResult.Aborted, result);
}
[TestMethod]
@ -148,9 +149,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
sut = new ConfigurationOperation(repository.Object, logger.Object, info, text.Object, uiFactory.Object, null);
sut.Perform();
var result = sut.Perform();
Assert.IsFalse(sut.Abort);
Assert.AreEqual(OperationResult.Success, result);
}
}
}

View file

@ -9,6 +9,7 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Behaviour.Operations;
using SafeExamBrowser.Contracts.Communication;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
@ -82,26 +83,27 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
}
[TestMethod]
public void MustAbortIfServiceMandatoryAndNotAvailable()
public void MustFailIfServiceMandatoryAndNotAvailable()
{
service.Setup(s => s.Connect(null)).Returns(false);
configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Mandatory });
sut.Perform();
var result = sut.Perform();
Assert.IsTrue(sut.Abort);
Assert.AreEqual(OperationResult.Failed, result);
}
[TestMethod]
public void MustNotAbortIfServiceOptionalAndNotAvailable()
public void MustNotFailIfServiceOptionalAndNotAvailable()
{
service.Setup(s => s.Connect(null)).Returns(false);
configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Optional });
sut.Perform();
var result = sut.Perform();
service.VerifySet(s => s.Ignore = true);
Assert.IsFalse(sut.Abort);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]

View file

@ -26,7 +26,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
private IUserInterfaceFactory uiFactory;
private string[] commandLineArgs;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public ConfigurationOperation(
@ -45,7 +44,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
this.uiFactory = uiFactory;
}
public void Perform()
public OperationResult Perform()
{
logger.Info("Initializing application configuration...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeConfiguration);
@ -60,8 +59,14 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient)
{
Abort = IsConfigurationSufficient();
logger.Info($"The user chose to {(Abort ? "abort" : "continue")} the application startup after successful client configuration.");
var abort = IsConfigurationSufficient();
logger.Info($"The user chose to {(abort ? "abort" : "continue")} after successful client configuration.");
if (abort)
{
return OperationResult.Aborted;
}
}
}
else
@ -69,13 +74,17 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
logger.Info("No valid settings file specified nor found in PROGRAMDATA or APPDATA - loading default settings...");
settings = repository.LoadDefaultSettings();
}
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// TODO: How will the new settings be retrieved? Uri passed to the repository? If yes, how does the Uri get here?!
// -> IDEA: Use configuration repository as container?
// -> IDEA: Introduce IRepeatParams or alike?
return OperationResult.Success;
}
public void Revert()

View file

@ -21,7 +21,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
private IConfigurationRepository configuration;
private KioskMode kioskMode;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public KioskModeOperation(ILogger logger, IConfigurationRepository configuration)
@ -30,7 +29,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
this.configuration = configuration;
}
public void Perform()
public OperationResult Perform()
{
kioskMode = configuration.CurrentSettings.KioskMode;
@ -46,11 +45,15 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
DisableExplorerShell();
break;
}
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// TODO: Depends on new kiosk mode!
return OperationResult.Success;
}
public void Revert()

View file

@ -25,7 +25,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
private IServiceProxy service;
private IText text;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public ServiceConnectionOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy service, IText text)
@ -36,7 +35,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
this.text = text;
}
public void Perform()
public OperationResult Perform()
{
logger.Info($"Initializing service connection...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeServiceConnection);
@ -53,19 +52,22 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
if (mandatory && !connected)
{
Abort = true;
logger.Error("Aborting startup because the service is mandatory but not available!");
return OperationResult.Failed;
}
else
{
service.Ignore = !connected;
logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "available." : "not available. All service-related operations will be ignored!")}");
}
service.Ignore = !connected;
logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "available." : "not available. All service-related operations will be ignored!")}");
return OperationResult.Success;
}
public void Repeat()
public OperationResult Repeat()
{
// TODO: Re-check if mandatory, if so, try to connect (if not connected) - otherwise, no action required (except maybe logging of status?)
return OperationResult.Success;
}
public void Revert()

View file

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.Contracts.Behaviour.Operations;
using SafeExamBrowser.Contracts.Communication;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Logging;
@ -25,14 +26,14 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
}
public override void Perform()
public override OperationResult Perform()
{
StartSession();
return StartSession();
}
public override void Repeat()
public override OperationResult Repeat()
{
StartSession();
return StartSession();
}
public override void Revert()

View file

@ -30,7 +30,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
private IServiceProxy service;
private ISession session;
public bool Abort { get; private set; }
public IProgressIndicator ProgressIndicator { private get; set; }
public SessionSequenceOperation(
@ -49,11 +48,11 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
this.service = service;
}
public abstract void Perform();
public abstract void Repeat();
public abstract OperationResult Perform();
public abstract OperationResult Repeat();
public abstract void Revert();
protected void StartSession()
protected OperationResult StartSession()
{
logger.Info("Starting new session...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartSession, true);
@ -66,19 +65,20 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
sessionRunning = TryStartClient();
if (sessionRunning)
if (!sessionRunning)
{
logger.Info($"Successfully started new session with identifier '{session.Id}'.");
}
else
{
Abort = true;
logger.Info($"Failed to start new session! Reverting service session and aborting procedure...");
service.StopSession(session.Id);
return OperationResult.Failed;
}
logger.Info($"Successfully started new session with identifier '{session.Id}'.");
return OperationResult.Success;
}
protected void StopSession()
protected OperationResult StopSession()
{
if (sessionRunning)
{
@ -96,6 +96,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
sessionRunning = false;
logger.Info($"Successfully stopped session with identifier '{session.Id}'.");
}
return OperationResult.Success;
}
private bool TryStartClient()

View file

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.Contracts.Behaviour.Operations;
using SafeExamBrowser.Contracts.Communication;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Logging;
@ -25,14 +26,14 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
}
public override void Perform()
public override OperationResult Perform()
{
// Nothing to do here...
return OperationResult.Success;
}
public override void Repeat()
public override OperationResult Repeat()
{
StopSession();
return StopSession();
}
public override void Revert()

View file

@ -71,7 +71,7 @@ namespace SafeExamBrowser.Runtime.Behaviour
splashScreen.Show();
var initialized = bootstrapSequence.TryPerform();
var initialized = bootstrapSequence.TryPerform() == OperationResult.Success;
if (initialized)
{
@ -101,7 +101,6 @@ namespace SafeExamBrowser.Runtime.Behaviour
if (sessionRunning)
{
DeregisterSessionEvents();
StopSession();
}
@ -141,9 +140,9 @@ namespace SafeExamBrowser.Runtime.Behaviour
DeregisterSessionEvents();
}
sessionRunning = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat();
var result = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat();
if (sessionRunning)
if (result == OperationResult.Success)
{
RegisterSessionEvents();
@ -155,12 +154,17 @@ namespace SafeExamBrowser.Runtime.Behaviour
{
runtimeWindow.Hide();
}
sessionRunning = true;
}
else
{
logger.Info(">>>--- Session procedure was aborted! ---<<<");
// TODO: Not when user chose to terminate after reconfiguration! Probably needs IOperationSequenceResult or alike...
uiFactory.Show(TextKey.MessageBox_SessionStartError, TextKey.MessageBox_SessionStartErrorTitle, icon: MessageBoxIcon.Error);
logger.Info($">>>--- Session procedure {(result == OperationResult.Aborted ? "was aborted." : "has failed!")} ---<<<");
if (result == OperationResult.Failed)
{
uiFactory.Show(TextKey.MessageBox_SessionStartError, TextKey.MessageBox_SessionStartErrorTitle, icon: MessageBoxIcon.Error);
}
if (!initial)
{
@ -176,6 +180,8 @@ namespace SafeExamBrowser.Runtime.Behaviour
runtimeWindow.ShowProgressBar();
logger.Info(">>>--- Reverting session operations ---<<<");
DeregisterSessionEvents();
var success = sessionSequence.TryRevert();
if (success)