From 8692d7fdb0e491d3741df1415ff71cc04dbdc534 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Wed, 27 Jul 2016 13:02:00 +0200 Subject: [PATCH] add the simulation mode to the validation context certain validations are only done in declaration mode (e.g. gross vehicle weight) --- .../Simulation/Impl/SimulatorFactory.cs | 2 +- .../Data/SimulationComponentData.cs | 8 ++ .../SimulationComponent/Data/VehicleData.cs | 7 +- VectoCore/VectoCore/Utils/Validation.cs | 24 +++- .../Models/SimulationComponent/GearboxTest.cs | 4 +- .../SimulationComponentData/ValidationTest.cs | 132 ++++++++++++++++-- 6 files changed, 161 insertions(+), 16 deletions(-) diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index 9e59a781d6..96478896ff 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -151,7 +151,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl throw new ArgumentOutOfRangeException("CycleType unknown:" + data.Cycle.CycleType); } - var validationErrors = run.Validate(); + var validationErrors = run.Validate(_mode); if (validationErrors.Any()) { throw new VectoException("Validation of Run-Data Failed: " + "\n".Join(validationErrors.Select(r => r.ErrorMessage))); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs index a6dc7f1a4e..558791d936 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs @@ -29,8 +29,10 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.ComponentModel.DataAnnotations; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Data { @@ -50,5 +52,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public string DigestValue { get; internal set; } public IntegrityStatus IntegrityStatus { get; internal set; } + + protected static ExecutionMode GetExecutionMode(ValidationContext context) + { + var modeService = context.GetService(typeof(ExecutionMode)) as ExecutionModeServiceContainer; + return modeService == null ? ExecutionMode.Declaration : modeService.Mode; + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs index aca8f710a0..0e8d1b5829 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs @@ -140,6 +140,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public static ValidationResult ValidateVehicleData(VehicleData vehicleData, ValidationContext validationContext) { + var mode = SimulationComponentData.GetExecutionMode(validationContext); + var weightShareSum = vehicleData.AxleData.Sum(axle => axle.AxleWeightShare); if (!weightShareSum.IsEqual(1.0, 1E-10)) { return new ValidationResult( @@ -147,12 +149,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data weightShareSum, 1 - weightShareSum)); } + if (mode != ExecutionMode.Declaration) { + return ValidationResult.Success; + } + if (vehicleData.TotalVehicleWeight() > vehicleData.GrossVehicleMassRating) { return new ValidationResult( string.Format("Total Vehicle Weight is greater than GrossVehicleMassRating! sum: {0}, GVM: {1}", vehicleData.TotalVehicleWeight(), vehicleData.GrossVehicleMassRating)); } - return ValidationResult.Success; } } diff --git a/VectoCore/VectoCore/Utils/Validation.cs b/VectoCore/VectoCore/Utils/Validation.cs index ade2ded943..313f867036 100644 --- a/VectoCore/VectoCore/Utils/Validation.cs +++ b/VectoCore/VectoCore/Utils/Validation.cs @@ -36,6 +36,7 @@ using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Reflection; +using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; namespace TUGraz.VectoCore.Utils @@ -50,12 +51,14 @@ namespace TUGraz.VectoCore.Utils /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity">The entity.</param> + /// <param name="mode">validate the entity for the given execution mode</param> /// <returns>Null, if the validation was successfull. Otherwise a list of ValidationResults with the ErrorMessages.</returns> - public static IList<ValidationResult> Validate<T>(this T entity) + public static IList<ValidationResult> Validate<T>(this T entity, ExecutionMode mode) { var context = new ValidationContext(entity); + context.ServiceContainer.AddService(typeof(ExecutionMode), new ExecutionModeServiceContainer(mode)); var results = new List<ValidationResult>(); - Validator.TryValidateObject(entity, new ValidationContext(entity), results, true); + Validator.TryValidateObject(entity, context, results, true); const BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | @@ -129,6 +132,16 @@ namespace TUGraz.VectoCore.Utils } } + public class ExecutionModeServiceContainer + { + public ExecutionModeServiceContainer(ExecutionMode mode) + { + Mode = mode; + } + + public ExecutionMode Mode { get; protected set; } + } + /// <summary> /// Determines that the attributed object should be validated recursively. /// </summary> @@ -148,11 +161,14 @@ namespace TUGraz.VectoCore.Utils return ValidationResult.Success; } + var modeService = validationContext.GetService(typeof(ExecutionMode)) as ExecutionModeServiceContainer; + var mode = modeService != null ? modeService.Mode : ExecutionMode.Declaration; + var enumerable = value as IEnumerable; if (enumerable != null) { var i = 0; foreach (var element in enumerable) { - var results = element.Validate(); + var results = element.Validate(mode); if (results.Any()) { return new ValidationResult( string.Format("{1}[{0}] in {1} invalid: {2}", i, validationContext.DisplayName, @@ -161,7 +177,7 @@ namespace TUGraz.VectoCore.Utils i++; } } else { - var results = value.Validate(); + var results = value.Validate(mode); if (!results.Any()) { return ValidationResult.Success; } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs index 2daadd875d..7dadf10e48 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs @@ -136,7 +136,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var vehicle = new VehicleContainer(ExecutionMode.Engineering); var axleGearData = MockSimulationDataFactory.CreateAxleGearDataFromFile(AxleGearValidRangeDataFile); var axleGear = new AxleGear(vehicle, axleGearData); - Assert.AreEqual(0, axleGear.Validate().Count); + Assert.AreEqual(0, axleGear.Validate(ExecutionMode.Declaration).Count); } [TestCase] @@ -145,7 +145,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var vehicle = new VehicleContainer(ExecutionMode.Engineering); var axleGearData = MockSimulationDataFactory.CreateAxleGearDataFromFile(AxleGearInvalidRangeDataFile); var axleGear = new AxleGear(vehicle, axleGearData); - var errors = axleGear.Validate(); + var errors = axleGear.Validate(ExecutionMode.Declaration); Assert.AreEqual(1, errors.Count); } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs index f87c11281f..2b7568cd89 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data; using System.Diagnostics.CodeAnalysis; @@ -38,6 +39,7 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.Reader; using TUGraz.VectoCore.InputData.Reader.DataObjectAdaper; +using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Data; @@ -53,7 +55,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData [TestClass] [SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "UnusedMember.Local")] - public class CombustionEngineDataValidationTestClass + public class ValidationTestClass { /// <summary> /// VECTO-107 Check valid range of input parameters @@ -90,7 +92,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData }; data.FullLoadCurve.EngineData = data; - var results = data.Validate(); + var results = data.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any(), "Validation Failed: " + "; ".Join(results.Select(r => r.ErrorMessage))); Assert.IsTrue(data.IsValid()); } @@ -125,7 +127,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var engineData = dao.CreateEngineData(data); - var results = engineData.Validate(); + var results = engineData.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any(), "Validation failed: " + "; ".Join(results.Select(r => r.ErrorMessage))); Assert.IsTrue(engineData.IsValid()); } @@ -164,11 +166,125 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var engineData = dao.CreateEngineData(data); - var results = engineData.Validate(); + var results = engineData.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any(), "Validation failed: " + "; ".Join(results.Select(r => r.ErrorMessage))); Assert.IsTrue(engineData.IsValid()); } + [TestMethod] + public void ValidationModeVehicleDataTest() + { + var vehicleData = new VehicleData() { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + Creator = "Mr. Test", + CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(CrossWindCorrectionCurveReader.GetNoCorrectionCurve(5.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + CurbWeight = 7500.SI<Kilogram>(), + DynamicTyreRadius = 0.5.SI<Meter>(), + CurbWeigthExtra = 0.SI<Kilogram>(), + Loading = 12000.SI<Kilogram>(), + GrossVehicleMassRating = 16000.SI<Kilogram>() + }; + vehicleData.AxleData = new List<Axle>() { + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.4, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.6, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + }; + var result = vehicleData.Validate(ExecutionMode.Engineering); + Assert.IsTrue(!result.Any()); + + result = vehicleData.Validate(ExecutionMode.Declaration); + Assert.IsTrue(result.Any(), "validation should have failed, but succeeded"); + } + + /// <summary> + /// VECTO-107 Check valid range of input parameters + /// </summary> + [TestMethod] + public void ValidationModeVectoRunDataTest() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var data = new DistanceRun(container); + var engineData = new CombustionEngineData + { + FullLoadCurve = EngineFullLoadCurve.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld"), + IdleSpeed = 560.RPMtoRad() + }; + + var gearboxData = new GearboxData(); + gearboxData.Gears[1] = new GearData + { + LossMap = TransmissionLossMap.ReadFromFile(@"TestData\Components\Direct Gear.vtlm", 1, "1"), + Ratio = 1 + }; + + var axleGearData = new AxleGearData + { + AxleGear = new GearData + { + Ratio = 1, + LossMap = TransmissionLossMap.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), + } + }; + var vehicleData = new VehicleData() + { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + Creator = "Mr. Test", + CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(CrossWindCorrectionCurveReader.GetNoCorrectionCurve(5.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + CurbWeight = 7500.SI<Kilogram>(), + DynamicTyreRadius = 0.5.SI<Meter>(), + CurbWeigthExtra = 0.SI<Kilogram>(), + Loading = 12000.SI<Kilogram>(), + GrossVehicleMassRating = 16000.SI<Kilogram>() + }; + vehicleData.AxleData = new List<Axle>() { + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.4, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.6, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + }; + + container.RunData = new VectoRunData + { + VehicleData = vehicleData, + GearboxData = gearboxData, + EngineData = engineData, + AxleGearData = axleGearData + }; + + var results = data.Validate(ExecutionMode.Declaration); + Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); + + results = vehicleData.Validate(ExecutionMode.Engineering); + Assert.IsTrue(!results.Any()); + } + /// <summary> /// VECTO-107 Check valid range of input parameters /// </summary> @@ -201,7 +317,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData AxleGearData = axleGearData }; - var results = data.Validate(); + var results = data.Validate(ExecutionMode.Declaration); Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); } @@ -211,7 +327,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData [TestMethod] public void Validation_Test() { - var results = new DataObject().Validate(); + var results = new DataObject().Validate(ExecutionMode.Declaration); // every field and property should be tested except private parent fields and properties and // (4*4+1) * 2 = 17*2= 34 - 4 private parent fields (+2 public field and property which are tested twice) = 32 @@ -238,7 +354,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData VectoCSVFile.ReadStream( InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm] ", vgbs))); - var results = shiftPolygon.Validate(); + var results = shiftPolygon.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any()); shiftPolygon = @@ -246,7 +362,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData VectoCSVFile.ReadStream( InputDataHelper.InputDataAsStream("engine torque,upshift rpm [rpm], downshift rpm [rpm] ", vgbs))); - results = shiftPolygon.Validate(); + results = shiftPolygon.Validate(ExecutionMode.Declaration); Assert.IsTrue(results.Any()); } -- GitLab