Index: Ringtoets/Common/test/Ringtoets.Common.Service.Test/Structures/StructuresCalculationServiceBaseTest.cs =================================================================== diff -u -r19f983eab8eac43d27e39f6eb9de019bad677652 -re6e0f3a201a644070997b531763b63f19d44df0e --- Ringtoets/Common/test/Ringtoets.Common.Service.Test/Structures/StructuresCalculationServiceBaseTest.cs (.../StructuresCalculationServiceBaseTest.cs) (revision 19f983eab8eac43d27e39f6eb9de019bad677652) +++ Ringtoets/Common/test/Ringtoets.Common.Service.Test/Structures/StructuresCalculationServiceBaseTest.cs (.../StructuresCalculationServiceBaseTest.cs) (revision e6e0f3a201a644070997b531763b63f19d44df0e) @@ -24,21 +24,25 @@ using System.Linq; using Core.Common.Base.Geometry; using Core.Common.TestUtil; +using log4net.Core; using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; +using Ringtoets.Common.Data.Exceptions; using Ringtoets.Common.Data.FailureMechanism; using Ringtoets.Common.Data.Structures; using Ringtoets.Common.Data.TestUtil; using Ringtoets.Common.Service.MessageProviders; using Ringtoets.Common.Service.Structures; using Ringtoets.Common.Service.TestUtil; +using Ringtoets.HydraRing.Calculation.Calculator; using Ringtoets.HydraRing.Calculation.Calculator.Factory; using Ringtoets.HydraRing.Calculation.Data; using Ringtoets.HydraRing.Calculation.Data.Input; using Ringtoets.HydraRing.Calculation.Exceptions; using Ringtoets.HydraRing.Calculation.TestUtil; using Ringtoets.HydraRing.Calculation.TestUtil.Calculator; +using Ringtoets.HydraRing.Calculation.TestUtil.IllustrationPoints; namespace Ringtoets.Common.Service.Test.Structures { @@ -335,92 +339,235 @@ [Test] public void Calculate_CalculationNull_ThrowArgumentNullException() { + // Setup + var mocks = new MockRepository(); + var messageProvider = mocks.Stub(); + mocks.ReplayAll(); + // Call - TestDelegate test = () => new TestStructuresCalculationService() + TestDelegate test = () => new TestStructuresCalculationService(messageProvider) .Calculate(null, new GeneralTestInput(), 0, 1, 1, string.Empty); // Assert var exception = Assert.Throws(test); Assert.AreEqual("calculation", exception.ParamName); + mocks.VerifyAll(); } [Test] public void Calculate_GeneralInputNull_ThrowArgumentNullException() { // Setup + var mocks = new MockRepository(); + var messageProvider = mocks.Stub(); + mocks.ReplayAll(); + var calculation = new TestStructuresCalculation(); // Call - TestDelegate test = () => new TestStructuresCalculationService() + TestDelegate test = () => new TestStructuresCalculationService(messageProvider) .Calculate(calculation, null, 0, 1, 1, string.Empty); // Assert var exception = Assert.Throws(test); Assert.AreEqual("generalInput", exception.ParamName); + mocks.VerifyAll(); } [Test] - public void Calculate_ValidInput_InputPropertiesCorrectlySentToCalculator() + [TestCase(true)] + [TestCase(false)] + public void Calculate_ValidInput_InputPropertiesCorrectlySentToCalculatorAndLogs(bool readIllustrationPoints) { // Setup var mocks = new MockRepository(); - var calculator = new TestStructuresCalculator(); + var calculator = new TestStructuresCalculator + { + OutputDirectory = validFilePath, + IllustrationPointsResult = new TestGeneralResult() + }; var calculatorFactory = mocks.StrictMock(); calculatorFactory.Expect(cf => cf.CreateStructuresCalculator(testDataPath)) .Return(calculator); + + const string performedCalculationMessage = "Calculation succesful"; + var messageProvider = mocks.StrictMock(); + messageProvider.Expect(mp => mp.GetCalculationPerformedMessage(validFilePath)).Return(performedCalculationMessage); mocks.ReplayAll(); var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); var calculation = new TestStructuresCalculation { InputParameters = { - HydraulicBoundaryLocation = hydraulicBoundaryLocation + HydraulicBoundaryLocation = hydraulicBoundaryLocation, + ShouldIllustrationPointsBeCalculated = readIllustrationPoints } }; using (new HydraRingCalculatorFactoryConfig(calculatorFactory)) { - var service = new TestStructuresCalculationService(); + var service = new TestStructuresCalculationService(messageProvider); // Call - service.Calculate(calculation, new GeneralTestInput(), 1, 1, 1, validFilePath); + Action call = () => service.Calculate(calculation, new GeneralTestInput(), 1, 1, 1, validFilePath); // Assert + TestHelper.AssertLogMessages(call, messages => + { + string[] msgs = messages.ToArray(); + Assert.AreEqual(3, msgs.Length); + CalculationServiceTestHelper.AssertCalculationStartMessage(msgs[0]); + Assert.AreEqual(performedCalculationMessage, msgs[1]); + CalculationServiceTestHelper.AssertCalculationEndMessage(msgs[2]); + }); + ExceedanceProbabilityCalculationInput[] calculationInputs = calculator.ReceivedInputs.ToArray(); Assert.AreEqual(1, calculationInputs.Length); var expectedInput = new TestExceedanceProbabilityCalculationInput(hydraulicBoundaryLocation.Id); ExceedanceProbabilityCalculationInput actualInput = calculationInputs[0]; HydraRingDataEqualityHelper.AreEqual(expectedInput, actualInput); + Assert.IsNotNull(calculation.Output); Assert.IsFalse(calculator.IsCanceled); + Assert.AreEqual(readIllustrationPoints, calculation.Output.HasIllustrationPoints); } mocks.VerifyAll(); } [Test] - public void Calculate_CancelCalculationWithValidInput_CancelsCalculatorAndHasNullOutput() + public void Calculate_ValidInputButIllustrationPointsNull_IllustrationPointsNotSet() { // Setup var mocks = new MockRepository(); - var calculator = new TestStructuresCalculator(); + var calculator = new TestStructuresCalculator + { + OutputDirectory = validFilePath + }; var calculatorFactory = mocks.StrictMock(); calculatorFactory.Expect(cf => cf.CreateStructuresCalculator(testDataPath)) .Return(calculator); + + const string performedCalculationMessage = "Calculation succesful"; + var messageProvider = mocks.StrictMock(); + messageProvider.Expect(mp => mp.GetCalculationPerformedMessage(validFilePath)).Return(performedCalculationMessage); mocks.ReplayAll(); var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); var calculation = new TestStructuresCalculation { InputParameters = { + HydraulicBoundaryLocation = hydraulicBoundaryLocation, + ShouldIllustrationPointsBeCalculated = true + } + }; + + using (new HydraRingCalculatorFactoryConfig(calculatorFactory)) + { + var service = new TestStructuresCalculationService(messageProvider); + + // Call + Action call = () => service.Calculate(calculation, new GeneralTestInput(), 1, 1, 1, validFilePath); + + // Assert + TestHelper.AssertLogMessages(call, messages => + { + string[] msgs = messages.ToArray(); + Assert.AreEqual(3, msgs.Length); + + CalculationServiceTestHelper.AssertCalculationStartMessage(msgs[0]); + Assert.AreEqual(performedCalculationMessage, msgs[1]); + CalculationServiceTestHelper.AssertCalculationEndMessage(msgs[2]); + }); + Assert.IsNotNull(calculation.Output); + Assert.IsFalse(calculation.Output.HasIllustrationPoints); + } + mocks.VerifyAll(); + } + + [Test] + public void Calculate_ValidInputButIllustrationPointResultsInvalid_IllustrationPointsNotSetAndLogsWarning() + { + // Setup + var mocks = new MockRepository(); + var calculator = new TestStructuresCalculator + { + OutputDirectory = validFilePath, + IllustrationPointsResult = TestGeneralResult.CreateGeneralResultWithSubMechanismIllustrationPoints() + }; + var calculatorFactory = mocks.StrictMock(); + calculatorFactory.Expect(cf => cf.CreateStructuresCalculator(testDataPath)) + .Return(calculator); + + const string performedCalculationMessage = "Calculation succesful"; + var messageProvider = mocks.StrictMock(); + messageProvider.Expect(mp => mp.GetCalculationPerformedMessage(validFilePath)).Return(performedCalculationMessage); + mocks.ReplayAll(); + + var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); + var calculation = new TestStructuresCalculation + { + InputParameters = + { + HydraulicBoundaryLocation = hydraulicBoundaryLocation, + ShouldIllustrationPointsBeCalculated = true + } + }; + + using (new HydraRingCalculatorFactoryConfig(calculatorFactory)) + { + var service = new TestStructuresCalculationService(messageProvider); + + // Call + Action call = () => service.Calculate(calculation, new GeneralTestInput(), 1, 1, 1, validFilePath); + + // Assert + TestHelper.AssertLogMessagesAndLoggedExceptions(call, messages => + { + Tuple[] tupleArray = messages.ToArray(); + + string[] msgs = tupleArray.Select(tuple => tuple.Item1).ToArray(); + Assert.AreEqual(4, msgs.Length); + + CalculationServiceTestHelper.AssertCalculationStartMessage(msgs[0]); + Assert.AreEqual("Het uitlezen van illustratiepunten is mislukt.", msgs[1]); + Assert.AreEqual(performedCalculationMessage, msgs[2]); + CalculationServiceTestHelper.AssertCalculationEndMessage(msgs[3]); + + Assert.IsInstanceOf(tupleArray[1].Item3); + }); + Assert.IsNotNull(calculation.Output); + Assert.IsFalse(calculation.Output.HasIllustrationPoints); + } + mocks.VerifyAll(); + } + + [Test] + public void Calculate_CancelCalculationWithValidInput_CancelsCalculatorAndHasNullOutput() + { + // Setup + var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); + var calculation = new TestStructuresCalculation + { + InputParameters = + { HydraulicBoundaryLocation = hydraulicBoundaryLocation } }; + var mocks = new MockRepository(); + var calculator = new TestStructuresCalculator(); + var calculatorFactory = mocks.StrictMock(); + calculatorFactory.Expect(cf => cf.CreateStructuresCalculator(testDataPath)) + .Return(calculator); + + var messageProvider = mocks.Stub(); + mocks.ReplayAll(); + using (new HydraRingCalculatorFactoryConfig(calculatorFactory)) { - var service = new TestStructuresCalculationService(); + var service = new TestStructuresCalculationService(messageProvider); calculator.CalculationFinishedHandler += (s, e) => service.Cancel(); // Call @@ -435,14 +582,23 @@ [Test] [TestCaseSource(typeof(HydraRingCalculatorTestCaseProvider), nameof(HydraRingCalculatorTestCaseProvider.GetCalculatorFailingConditionsWithReportDetails), new object[] - { - nameof(Calculate_CalculationFailed_ThrowsHydraRingCalculationExceptionAndLogError) - })] + { + nameof(Calculate_CalculationFailed_ThrowsHydraRingCalculationExceptionAndLogError) + })] public void Calculate_CalculationFailed_ThrowsHydraRingCalculationExceptionAndLogError(bool endInFailure, string lastErrorFileContent, string detailedReport) { // Setup + var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); + var calculation = new TestStructuresCalculation + { + InputParameters = + { + HydraulicBoundaryLocation = hydraulicBoundaryLocation + } + }; + var mocks = new MockRepository(); var calculator = new TestStructuresCalculator { @@ -452,27 +608,39 @@ var calculatorFactory = mocks.StrictMock(); calculatorFactory.Expect(cf => cf.CreateStructuresCalculator(testDataPath)) .Return(calculator); - mocks.ReplayAll(); - var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(); - var calculation = new TestStructuresCalculation + const string calculationFailedMessage = "Calculation failed"; + const string calculationPerformedMessage = "Calculation performed"; + var messageProvider = mocks.StrictMock(); + + + // TODO: WTI-1308 remove if statement when it's clear what needs to be done + if (endInFailure && string.IsNullOrEmpty(lastErrorFileContent)) { - InputParameters = - { - HydraulicBoundaryLocation = hydraulicBoundaryLocation - } - }; + messageProvider.Expect(mp => mp.GetCalculationFailedMessage(calculation.Name)).Return(calculationFailedMessage); + } + else + { + messageProvider.Expect(mp => mp.GetCalculationFailedWithErrorReportMessage(calculation.Name, + endInFailure && string.IsNullOrEmpty(lastErrorFileContent) + ? calculator.HydraRingCalculationException.Message + : lastErrorFileContent + )).Return(calculationFailedMessage); + } + messageProvider.Expect(mp => mp.GetCalculationPerformedMessage(calculator.OutputDirectory)).Return(calculationPerformedMessage); + mocks.ReplayAll(); using (new HydraRingCalculatorFactoryConfig(calculatorFactory)) { var exceptionThrown = false; + var structuresCalculationService = new TestStructuresCalculationService(messageProvider); // Call Action call = () => { try { - new TestStructuresCalculationService().Calculate(calculation, new GeneralTestInput(), 0, 0.5, 1, validFilePath); + structuresCalculationService.Calculate(calculation, new GeneralTestInput(), 0, 0.5, 1, validFilePath); } catch (HydraRingCalculationException) { @@ -481,14 +649,21 @@ }; // Assert - TestHelper.AssertLogMessages(call, messages => + TestHelper.AssertLogMessagesAndLoggedExceptions(call, messages => { - string[] msgs = messages.ToArray(); + Tuple[] generatedMessages = messages.ToArray(); + + string[] msgs = generatedMessages.Select(msg => msg.Item1).ToArray(); Assert.AreEqual(4, msgs.Length); CalculationServiceTestHelper.AssertCalculationStartMessage(msgs[0]); - Assert.AreEqual($"Calculation '{calculation.Name}' failed. {detailedReport}", msgs[1]); - Assert.AreEqual("Calculation performed in directory ''.", msgs[2]); + Assert.AreEqual(calculationFailedMessage, msgs[1]); + Assert.AreEqual(calculationPerformedMessage, msgs[2]); CalculationServiceTestHelper.AssertCalculationEndMessage(msgs[3]); + + if (!endInFailure && string.IsNullOrEmpty(lastErrorFileContent)) + { + Assert.IsInstanceOf(generatedMessages[1].Item3); + } }); Assert.IsTrue(exceptionThrown); Assert.IsNull(calculation.Output); @@ -499,8 +674,6 @@ private class TestStructuresCalculationService : StructuresCalculationServiceBase { - public TestStructuresCalculationService() : this(new TestMessageProvider()) {} - public TestStructuresCalculationService(IStructuresCalculationMessageProvider messageProvider) : base(messageProvider) {} protected override ExceedanceProbabilityCalculationInput CreateInput(TestStructuresInput structureInput, @@ -528,24 +701,6 @@ } } - private class TestMessageProvider : IStructuresCalculationMessageProvider - { - public string GetCalculationFailedMessage(string calculationSubject) - { - return $"Calculation '{calculationSubject}' failed. Er is geen foutrapport beschikbaar."; - } - - public string GetCalculationFailedWithErrorReportMessage(string calculationSubject, string errorReport) - { - return $"Calculation '{calculationSubject}' failed. Bekijk het foutrapport door op details te klikken.{Environment.NewLine}{errorReport}"; - } - - public string GetCalculationPerformedMessage(string outputDirectory) - { - return $"Calculation performed in directory '{outputDirectory}'."; - } - } - private class GeneralTestInput { public double N