diff --git a/bundles/org.palladiosimulator.simulizar.test.commons/src/org/palladiosimulator/simulizar/test/commons/di/components/TestSimuLizarRuntimeComponent.java b/bundles/org.palladiosimulator.simulizar.test.commons/src/org/palladiosimulator/simulizar/test/commons/di/components/TestSimuLizarRuntimeComponent.java new file mode 100644 index 00000000..3990ff4d --- /dev/null +++ b/bundles/org.palladiosimulator.simulizar.test.commons/src/org/palladiosimulator/simulizar/test/commons/di/components/TestSimuLizarRuntimeComponent.java @@ -0,0 +1,35 @@ +package org.palladiosimulator.simulizar.test.commons.di.components; + +import org.palladiosimulator.simulizar.di.component.core.SimuLizarRootComponent; +import org.palladiosimulator.simulizar.di.component.core.SimuLizarRuntimeComponent; +import org.palladiosimulator.simulizar.di.component.dependency.QUALComponent; +import org.palladiosimulator.simulizar.di.component.dependency.SimEngineComponent; +import org.palladiosimulator.simulizar.di.component.dependency.SimuComFrameworkComponent; +import org.palladiosimulator.simulizar.di.modules.component.core.SimuLizarRuntimeModule; +import org.palladiosimulator.simulizar.di.modules.component.extensions.ExtensionComponentsModule; +import org.palladiosimulator.simulizar.di.modules.scoped.runtime.LegacyRuntimeStateAccessorAdapterModule; +import org.palladiosimulator.simulizar.di.modules.stateless.core.RuntimeComponentFactoriesModule; +import org.palladiosimulator.simulizar.scopes.SimulationRuntimeScope; +import org.palladiosimulator.simulizar.test.commons.di.components.TestSimuLizarRuntimeComponent.TestSimulizarRuntimeModule; + +import dagger.Binds; +import dagger.Component; + +@Component(dependencies = { SimuLizarRootComponent.class, SimuComFrameworkComponent.class, QUALComponent.class, + SimEngineComponent.class }, modules = { TestSimulizarRuntimeModule.class }) +@SimulationRuntimeScope +public interface TestSimuLizarRuntimeComponent extends SimuLizarRuntimeComponent { + + + + @Component.Factory + public interface Factory extends SimuLizarRuntimeComponent.Factory { + + } + + @dagger.Module(includes = { SimuLizarRuntimeModule.class, LegacyRuntimeStateAccessorAdapterModule.class }) + public interface TestSimulizarRuntimeModule { + @Binds SimuLizarRuntimeComponent bindRuntimeComponent(TestSimuLizarRuntimeComponent component); + } + +} diff --git a/bundles/org.palladiosimulator.simulizar.test.commons/src/org/palladiosimulator/simulizar/test/commons/util/RunSimuLizarSimulationJobSupplier.java b/bundles/org.palladiosimulator.simulizar.test.commons/src/org/palladiosimulator/simulizar/test/commons/util/RunSimuLizarSimulationJobSupplier.java index f2c487f1..ba8b9efa 100644 --- a/bundles/org.palladiosimulator.simulizar.test.commons/src/org/palladiosimulator/simulizar/test/commons/util/RunSimuLizarSimulationJobSupplier.java +++ b/bundles/org.palladiosimulator.simulizar.test.commons/src/org/palladiosimulator/simulizar/test/commons/util/RunSimuLizarSimulationJobSupplier.java @@ -8,6 +8,7 @@ import java.util.function.Supplier; import org.junit.jupiter.api.extension.ExtensionContext; +import org.palladiosimulator.simulizar.di.component.core.SimuLizarRuntimeComponent; import org.palladiosimulator.simulizar.di.component.dependency.SimEngineComponent.Factory; import org.palladiosimulator.simulizar.di.extension.ExtensionComponent; import org.palladiosimulator.simulizar.di.modules.component.extensions.ExtensionComponentsModule; @@ -17,6 +18,7 @@ import org.palladiosimulator.simulizar.test.commons.annotation.UseSimuLizarExtension; import org.palladiosimulator.simulizar.test.commons.di.components.DaggerTestSimEngineComponent; import org.palladiosimulator.simulizar.test.commons.di.components.DaggerTestSimuLizarRootComponent; +import org.palladiosimulator.simulizar.test.commons.di.components.DaggerTestSimuLizarRuntimeComponent; import org.palladiosimulator.simulizar.test.commons.di.components.TestSimuLizarRootComponent.TestConfigurationModule; import org.palladiosimulator.simulizar.test.commons.extension.SimuLizarTestExtensionCommons; @@ -49,9 +51,10 @@ public IJob get() { for (var extension : extensions) { var extCls = extension.value(); try { - var factory = (ExtensionComponent.Factory) extCls.getMethod("factory").invoke(null); + var factory = (ExtensionComponent.Factory) extCls.getMethod("factory") + .invoke(null); extensionFactories.add(factory); - + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new RuntimeException( @@ -59,16 +62,18 @@ public IJob get() { } } var component = DaggerTestSimuLizarRootComponent.factory() - .create(configuration, - new RootComponentFactoriesModule() { - @Override - public Factory providesSimEngineComponentFactory() { - return DaggerTestSimEngineComponent.factory(); - } - }, - new ExtensionComponentsModule(extensionFactories, ImmutableSet.of()), - new MDSDBlackboardProvidingModule(blackboard), - new TestConfigurationModule() { + .create(configuration, new RootComponentFactoriesModule() { + @Override + public Factory providesSimEngineComponentFactory() { + return DaggerTestSimEngineComponent.factory(); + } + + @Override + public SimuLizarRuntimeComponent.Factory providesRuntimeComponentFactory() { + return DaggerTestSimuLizarRuntimeComponent.factory(); + } + }, new ExtensionComponentsModule(extensionFactories, ImmutableSet.of()), + new MDSDBlackboardProvidingModule(blackboard), new TestConfigurationModule() { @Override public boolean activateModelLoading() { return false; diff --git a/tests/org.palladiosimulator.simulizar.tests/META-INF/MANIFEST.MF b/tests/org.palladiosimulator.simulizar.tests/META-INF/MANIFEST.MF index 7979b17b..6a057dce 100644 --- a/tests/org.palladiosimulator.simulizar.tests/META-INF/MANIFEST.MF +++ b/tests/org.palladiosimulator.simulizar.tests/META-INF/MANIFEST.MF @@ -20,7 +20,8 @@ Require-Bundle: org.eclipse.xtext.xbase.lib, org.palladiosimulator.examples.package;bundle-version="4.3.0", org.palladiosimulator.simulizar.test.commons;bundle-version="5.1.0", org.palladiosimulator.simulizar.events, - org.palladiosimulator.simulizar.monitorrepository.feedthrough;bundle-version="5.1.0" + org.palladiosimulator.simulizar.monitorrepository.feedthrough;bundle-version="5.1.0", + org.palladiosimulator.simulizar.action.repository;bundle-version="5.1.0" Import-Package: com.google.common.util.concurrent.internal;version="1.0.1", net.bytebuddy.dynamic.loading;version="1.6.0", org.hamcrest;version="2.2.0", diff --git a/tests/org.palladiosimulator.simulizar.tests/src/org/palladiosimulator/simulizar/simulation/tests/QVTOExecutionTest.java b/tests/org.palladiosimulator.simulizar.tests/src/org/palladiosimulator/simulizar/simulation/tests/QVTOExecutionTest.java new file mode 100644 index 00000000..dea51b03 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/src/org/palladiosimulator/simulizar/simulation/tests/QVTOExecutionTest.java @@ -0,0 +1,94 @@ +package org.palladiosimulator.simulizar.simulation.tests; + +import static org.hamcrest.Matchers.closeTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import javax.measure.Measure; +import javax.measure.quantity.Duration; +import javax.measure.unit.SI; + +import org.junit.jupiter.api.Test; +import org.palladiosimulator.edp2.models.ExperimentData.ExperimentRun; +import org.palladiosimulator.metricspec.constants.MetricDescriptionConstants; +import org.palladiosimulator.pcm.usagemodel.UsageScenario; +import org.palladiosimulator.simulizar.launcher.SimulizarConstants; +import org.palladiosimulator.simulizar.reconfiguration.qvto.DaggerQVTOReconfigurationComponent; +import org.palladiosimulator.simulizar.test.commons.annotation.LoadPCMInstanceFromBundle; +import org.palladiosimulator.simulizar.test.commons.annotation.RunSimuLizar; +import org.palladiosimulator.simulizar.test.commons.annotation.SetConfigProperty; +import org.palladiosimulator.simulizar.test.commons.annotation.SimulationConfig; +import org.palladiosimulator.simulizar.test.commons.annotation.UseSimuLizarExtension; +import org.palladiosimulator.simulizar.test.commons.util.MeasurementTestUtils; + +import de.uka.ipd.sdq.workflow.jobs.JobFailedException; +import de.uka.ipd.sdq.workflow.jobs.UserCanceledException; +import tools.mdsd.junit5utils.annotations.PluginTestOnly; + +@PluginTestOnly +class QVTOExecutionTest { + + /** + * Tests the execution of a simple qvto reconfiguration. The reconfiguration changes the Usage + * Model's Population Parameter from 1 -> 2 In the beginning until the 2000s Simulation Time is + * reached, Population == 1 Between 2000s and 4000s Population == 2 After 4000 until the end of + * the simulation the Population is 1 again. This results into two consecutive measurements + * between 2000 and 4000. The ThinkTime is 99.0, which results into one measurement every 100s. + * The responseTime itself doesn't change due to the reconfiguration. Only the amount of + * measurements every 100s changes from 1 -> 2 -> 1 + */ + @Test + @LoadPCMInstanceFromBundle(bundleName = "org.palladiosimulator.simulizar.tests", basePath = "testmodels/transformationQVTTest", modelFiles = { + "default.allocation", "default.usagemodel", "default.repository", "defaultMonitor.monitorrepository" }) + @UseSimuLizarExtension(DaggerQVTOReconfigurationComponent.class) + @SimulationConfig(maxMeasurements = "100") + @SetConfigProperty(id = SimulizarConstants.RECONFIGURATION_RULES_FOLDER, value = "platform:/plugin/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/reconfigurations") + @RunSimuLizar + void testQVTOPopulationReconfiguration(UsageScenario scenario, ExperimentRun expRun) + throws JobFailedException, UserCanceledException { + var measurement = MeasurementTestUtils.getMeasurementOfAt(expRun.getMeasurement(), + MetricDescriptionConstants.RESPONSE_TIME_METRIC_TUPLE, scenario); + assertTrue(measurement.isPresent()); + + List> responseTimeMeasurements = MeasurementTestUtils + .allMeasurementsOfMetric(measurement.get(), MetricDescriptionConstants.RESPONSE_TIME_METRIC); + List> timeMeasurements = MeasurementTestUtils.allMeasurementsOfMetric(measurement.get(), + MetricDescriptionConstants.POINT_IN_TIME_METRIC); + assertEquals(responseTimeMeasurements.size(), timeMeasurements.size()); + + double expectedMeasurementTime = 1.0; + + for (int i = 0; i < 100; i++) { + if (i < 20) { + assertEquals(expectedMeasurementTime, timeMeasurements.get(i) + .doubleValue(SI.SECOND), 0.001); + expectedMeasurementTime += 100.0; + } + if (i >= 20 && i <= 60) { + assertEquals(expectedMeasurementTime, timeMeasurements.get(i) + .doubleValue(SI.SECOND), 0.001); + expectedMeasurementTime += 1.0; + System.out.println("expectedMeaurementTime: " + expectedMeasurementTime); + System.out.println("Measurement: " + timeMeasurements.get(i) + .doubleValue(SI.SECOND)); + assertEquals(expectedMeasurementTime, timeMeasurements.get(i + 1) + .doubleValue(SI.SECOND), 0.001); + expectedMeasurementTime += 99.0; + i++; + } + // From here as the second phase with Population = 2.0 ends with value 4002, + // The following measurements are off by 1.0s + if (i > 61) { + assertEquals(expectedMeasurementTime + 1.0, timeMeasurements.get(i) + .doubleValue(SI.SECOND), 0.001); + expectedMeasurementTime += 100.0; + } + } + // Check whether all the response time stay at 1.0 + MeasurementTestUtils.allDoubleMeasurementValuesMatch(measurement.get(), + MetricDescriptionConstants.RESPONSE_TIME_METRIC, SI.SECOND, closeTo(1.0, 0.001)); + } + +} diff --git a/tests/org.palladiosimulator.simulizar.tests/src/org/palladiosimulator/simulizar/simulation/tests/UsageevolutionTest.java b/tests/org.palladiosimulator.simulizar.tests/src/org/palladiosimulator/simulizar/simulation/tests/UsageevolutionTest.java new file mode 100644 index 00000000..d849718e --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/src/org/palladiosimulator/simulizar/simulation/tests/UsageevolutionTest.java @@ -0,0 +1,149 @@ +package org.palladiosimulator.simulizar.simulation.tests; + +import static org.hamcrest.Matchers.closeTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.palladiosimulator.simulizar.test.commons.hamcrest.Matchers.asDoubleIn; + +import java.util.List; + +import javax.measure.Measure; +import javax.measure.quantity.Duration; +import javax.measure.quantity.Quantity; +import javax.measure.unit.SI; +import javax.measure.unit.Unit; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.Test; +import org.palladiosimulator.edp2.models.ExperimentData.ExperimentRun; +import org.palladiosimulator.edp2.models.ExperimentData.Measurement; +import org.palladiosimulator.metricspec.BaseMetricDescription; +import org.palladiosimulator.metricspec.constants.MetricDescriptionConstants; +import org.palladiosimulator.pcm.usagemodel.UsageScenario; +import org.palladiosimulator.simulizar.launcher.SimulizarConstants; +import org.palladiosimulator.simulizar.test.commons.annotation.LoadPCMInstanceFromBundle; +import org.palladiosimulator.simulizar.test.commons.annotation.RunSimuLizar; +import org.palladiosimulator.simulizar.test.commons.annotation.SetConfigProperty; +import org.palladiosimulator.simulizar.test.commons.annotation.SimulationConfig; +import org.palladiosimulator.simulizar.test.commons.util.MeasurementTestUtils; + +import de.uka.ipd.sdq.workflow.jobs.JobFailedException; +import de.uka.ipd.sdq.workflow.jobs.UserCanceledException; +import tools.mdsd.junit5utils.annotations.PluginTestOnly; + +@PluginTestOnly +class UsageevolutionTest { + + /** + * Tests Usageevolution with a simple deterministic example. This test only tests the correct + * responste time evolution. + */ + @Test + @LoadPCMInstanceFromBundle(bundleName = "org.palladiosimulator.simulizar.tests", basePath = "testmodels/usageevolutionTest", modelFiles = { + "default.allocation", "default.usagemodel", "default.repository", "default.usageevolution" }) + @SimulationConfig(maxMeasurements = "100") + @RunSimuLizar + void testUsageevolutionResponseTimeVariation(UsageScenario scenario, ExperimentRun expRun) + throws JobFailedException, UserCanceledException { + var measurement = MeasurementTestUtils.getMeasurementOfAt(expRun.getMeasurement(), + MetricDescriptionConstants.RESPONSE_TIME_METRIC_TUPLE, scenario); + assertTrue(measurement.isPresent()); + + List> responseTimeMeasurements = MeasurementTestUtils + .allMeasurementsOfMetric(measurement.get(), MetricDescriptionConstants.RESPONSE_TIME_METRIC); + List> timeMeasurements = MeasurementTestUtils.allMeasurementsOfMetric(measurement.get(), + MetricDescriptionConstants.POINT_IN_TIME_METRIC); + assertEquals(responseTimeMeasurements.size(), timeMeasurements.size()); + + // The simulated test scenario evolves response time and user amount. + // Population is 1 and Think Time is 99.0 + // It evolves in 3 stages. + // Stage 1: 2000s with constant 1.0 20 measurements in 20 timesteps + // Stage 2: 2000s with constant 2.0 (Leads to Response Time 4.0 as both values evolve) + // 40 Measurements in 20 Timesteps (two parallel) + // Stage 3: 6000s with constant 1.0 40 measurements in 40 timesteps + // It is important to know, that this constant evolves the user requests from 1 to 2 aswell + // as the response time. + // ^ + // | ...[20]... + // | + // | + // |...[20].. ....[40]..... + // ----------------------------------------> + // Number in Brackets means total 20 measuring Points + // In Stage 2 every Point is representing two measurements as both values evolved to 2 they + // have the exact same + // resonse time at the same point in time. + for (int i = 0; i < 100; i++) { + if ((i < 20)) { + assertEquals(responseTimeMeasurements.get(i) + .doubleValue(SI.SECOND), 1.0, 0.001); + } + if (i >= 20 && i < 60) { + assertEquals(responseTimeMeasurements.get(i) + .doubleValue(SI.SECOND), 4.0, 0.001); + } + if (i >= 60) { + assertEquals(responseTimeMeasurements.get(i) + .doubleValue(SI.SECOND), 1.0, 0.001); + } + + // Test Measurement Time Stamps + assertEquals((Double) timeMeasurements.get(19) + .doubleValue(SI.SECOND), 1901.0, 0.001); + assertEquals((Double) timeMeasurements.get(20) + .doubleValue(SI.SECOND), 2004.0, 0.001); + assertEquals((Double) timeMeasurements.get(21) + .doubleValue(SI.SECOND), 2004.0, 0.001); + assertEquals((Double) timeMeasurements.get(22) + .doubleValue(SI.SECOND), 2107.0, 0.001); + // Section 1 -> Section 2 matching evolution of response time + assertEquals((Double) responseTimeMeasurements.get(19) + .doubleValue(SI.SECOND), 1.0, 0.001); + assertEquals((Double) responseTimeMeasurements.get(20) + .doubleValue(SI.SECOND), 4.0, 0.001); + assertEquals((Double) responseTimeMeasurements.get(21) + .doubleValue(SI.SECOND), 4.0, 0.001); + assertEquals((Double) responseTimeMeasurements.get(22) + .doubleValue(SI.SECOND), 4.0, 0.001); + // Stage 2 -> Stage 3 same as above but with Section 3 only having 1 user again. + assertEquals((Double) timeMeasurements.get(59) + .doubleValue(SI.SECOND), 3961.0, 0.001); + assertEquals((Double) timeMeasurements.get(60) + .doubleValue(SI.SECOND), 4061.0, 0.001); + assertEquals((Double) timeMeasurements.get(61) + .doubleValue(SI.SECOND), 4161.0, 0.001); + assertEquals((Double) responseTimeMeasurements.get(59) + .doubleValue(SI.SECOND), 4.0, 0.001); + assertEquals((Double) responseTimeMeasurements.get(60) + .doubleValue(SI.SECOND), 1.0, 0.001); + assertEquals((Double) responseTimeMeasurements.get(61) + .doubleValue(SI.SECOND), 1.0, 0.001); + } + } + + /** + * Tests how the values behave if the usageevolution model is not loaded. This means it is + * tested, whether no evolution happens without usage evolution. + */ + @Test + @LoadPCMInstanceFromBundle(bundleName = "org.palladiosimulator.simulizar.tests", basePath = "testmodels/usageevolutionTest", modelFiles = { + "default.allocation", "default.usagemodel", "default.repository" }) + @SimulationConfig(maxMeasurements = "100") + @RunSimuLizar + void testNoEvolutionWithoutUsageEvolution(UsageScenario scenario, ExperimentRun expRun) + throws JobFailedException, UserCanceledException { + var measurement = MeasurementTestUtils.getMeasurementOfAt(expRun.getMeasurement(), + MetricDescriptionConstants.RESPONSE_TIME_METRIC_TUPLE, scenario); + assertTrue(measurement.isPresent()); + + List> responseTimeMeasurements = MeasurementTestUtils + .allMeasurementsOfMetric(measurement.get(), MetricDescriptionConstants.RESPONSE_TIME_METRIC); + List> timeMeasurements = MeasurementTestUtils.allMeasurementsOfMetric(measurement.get(), + MetricDescriptionConstants.POINT_IN_TIME_METRIC); + assertEquals(responseTimeMeasurements.size(), timeMeasurements.size()); + // No Evolution means, that the response time stays the same for the all measurements at 1.0 + MeasurementTestUtils.allDoubleMeasurementValuesMatch(measurement.get(), + MetricDescriptionConstants.RESPONSE_TIME_METRIC, SI.SECOND, closeTo(1.0, 0.001)); + } +} diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/.project b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/.project new file mode 100644 index 00000000..03b6ea1d --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/.project @@ -0,0 +1,12 @@ + + + transformationQVTTest + + + + + + + org.eclipse.sirius.nature.modelingproject + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/My.resourceenvironment b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/My.resourceenvironment new file mode 100644 index 00000000..6a4ca4ad --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/My.resourceenvironment @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/UsageevolutionTest-Simulizar.launch b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/UsageevolutionTest-Simulizar.launch new file mode 100644 index 00000000..4efe8cc1 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/UsageevolutionTest-Simulizar.launch @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/constant.dlim b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/constant.dlim new file mode 100644 index 00000000..c40f0fc3 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/constant.dlim @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.allocation b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.allocation new file mode 100644 index 00000000..38c81fd4 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.allocation @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.dlim b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.dlim new file mode 100644 index 00000000..08ca3f0d --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.dlim @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.measuringpoint b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.measuringpoint new file mode 100644 index 00000000..5567b665 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.measuringpoint @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.repository b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.repository new file mode 100644 index 00000000..4b086c87 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.repository @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.system b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.system new file mode 100644 index 00000000..e855e7dc --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.system @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.usageevolution b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.usageevolution new file mode 100644 index 00000000..9ed96474 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.usageevolution @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.usagemodel b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.usagemodel new file mode 100644 index 00000000..c088c750 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/default.usagemodel @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/defaultMonitor.monitorrepository b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/defaultMonitor.monitorrepository new file mode 100644 index 00000000..383b8fe2 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/defaultMonitor.monitorrepository @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/reconfigurations/testReconfigTrigger.qvto b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/reconfigurations/testReconfigTrigger.qvto new file mode 100644 index 00000000..d8ebb953 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/reconfigurations/testReconfigTrigger.qvto @@ -0,0 +1,100 @@ +/* + * This reconfiguration is used to automatically test the QVTO reconfiguration. + * It is used for a deterministic model and reconfigures deterministically. + * The reconfiguration changes the parameter ClosedWorkload.population. + * In the unit test, the response time is then tracked. + */ + +import org.palladiosimulator.simulizar.action.repository.black.SimulationStateLibrary; + +modeltype PRM uses 'http://simulizar.palladiosimulator.org/RuntimeMeasurement/1.0'; +modeltype PCM_ALLOC uses 'http://palladiosimulator.org/PalladioComponentModel/Allocation/5.2'; +modeltype PCM_REP uses 'http://palladiosimulator.org/PalladioComponentModel/Repository/5.2'; +modeltype PCM_SEFF uses 'http://palladiosimulator.org/PalladioComponentModel/SEFF/5.2'; +modeltype PCM_SYS uses 'http://palladiosimulator.org/PalladioComponentModel/System/5.2'; +modeltype PCM_RES_ENV uses 'http://palladiosimulator.org/PalladioComponentModel/ResourceEnvironment/5.2'; +modeltype PCM_RES_TYPE uses 'http://palladiosimulator.org/PalladioComponentModel/ResourceType/5.2'; +modeltype PCM_USAGE uses 'http://palladiosimulator.org/PalladioComponentModel/UsageModel/5.2'; +modeltype PCM_FEATURE_CONF uses 'http://sdq.ipd.uka.de/FeatureConfig/2.0'; +modeltype PCM_FEATURE_MOD uses 'http://sdq.ipd.uka.de/FeatureModel/2.0'; +modeltype PCM_CORE uses 'http://palladiosimulator.org/PalladioComponentModel/Core/5.2'; +modeltype PCM_COMP uses 'http://palladiosimulator.org/PalladioComponentModel/Core/Composition/5.2'; +modeltype PCM_ENTITY uses 'http://palladiosimulator.org/PalladioComponentModel/Core/Entity/5.2'; +modeltype PCM_PARAM uses 'http://palladiosimulator.org/PalladioComponentModel/Parameter/5.2'; +modeltype PCM_STOEX uses 'http://sdq.ipd.uka.de/StochasticExpressions/2.2'; + + +transformation TestQVTO( in prm : PRM, + inout pcmUsage : PCM_USAGE) { + + + // Define Threshold and Scale Down + property reconfigUpTime : Real = 2000.0; + property reconfigDownTime : Real = 4000.0; + + /** + * The main transformation. + * This is the entry point to the overall transformation. + */ + main() { + log('QVTO Reconfiguration Test started'); + assert fatal(prm.rootObjects()[RuntimeMeasurement]->size() > 0) + with log ("No Measurements found!"); +// pcmUsage.objectsOfType(ClosedWorkload)-> map reconfigureClosedWorkload(1); +// log("Reconfigure Population from Closed Workload 2.0 -> 1.0"); + -- mapping from 2.0 to 1.0 between 4000 and 6000 + + var workloads = pcmUsage.objectsOfType(ClosedWorkload); + // Warum funktioniert mit den rootObjects das mapping später nicht? Hier müsste ich eigentlich dann casten + // Oder wie macht "man" das normalerweise, wenn man "rootObjects" verwenden soll. + //var usagemodel = pcmUsage.rootObjects(); + var usagemodels = pcmUsage.objectsOfType(UsageModel); + + -- mapping from 1.0 to 2.0 between 2000 and 4000 + if ( getSimulationTime() > reconfigUpTime and getSimulationTime() < reconfigDownTime) then { + log(getSimulationTime().toString() + " larger 2000, smaller 4000"); + usagemodels = usagemodels-> map reconfigureUsageModelsWorkload(2); + log("Reconfigure Population from Closed Workload 1.0 -> 2.0"); + } endif; + + if ( getSimulationTime() > reconfigDownTime) then { + log(getSimulationTime().toString() + " larger 4000"); + usagemodels = usagemodels-> map reconfigureUsageModelsWorkload(1); + log("Reconfigure Population from Closed Workload 2.0 -> 1.0"); + } endif; + +// -- mapping from 1.0 to 2.0 between 2000 and 4000 +// if ( getSimulationTime() > reconfigUpTime and getSimulationTime() < reconfigDownTime) then { +// log(getSimulationTime().toString() + " larger 2000, smaller 4000"); +// workloads-> map reconfigureClosedWorkload(2); +// log("Reconfigure Population from Closed Workload 1.0 -> 2.0"); +// } endif; +// +// if ( getSimulationTime() > reconfigDownTime) then { +// log(getSimulationTime().toString() + " larger 4000"); +// workloads-> map reconfigureClosedWorkload(1); +// log("Reconfigure Population from Closed Workload 2.0 -> 1.0"); +// } endif; + + } + + mapping inout UsageModel::reconfigureUsageModelsWorkload(newPopulation : Integer) + { + self.subobjectsOfType(UsageScenario)-> map reconfigureUsageScenariosWorkload(newPopulation); + } + + mapping inout UsageScenario::reconfigureUsageScenariosWorkload(newPopulation : Integer) + { + // UsageScenario can only have one workload + self.workload_UsageScenario = self.subobjectsOfType(ClosedWorkload)->map reconfigureClosedWorkload(newPopulation); + } + + mapping inout ClosedWorkload::reconfigureClosedWorkload(newPopulation : Integer) + { + var currentWorkloadThinkTime : String := self.thinkTime_ClosedWorkload.toString(); + log("self ThinkTime: " + self.thinkTime_ClosedWorkload.specification.toString()); + //self.thinkTime_ClosedWorkload.specification := "50.0"; + self._population := newPopulation; + log("Reconfigured Population!"); + } +} \ No newline at end of file diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/representations.aird b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/representations.aird new file mode 100644 index 00000000..f9eed436 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/representations.aird @@ -0,0 +1,990 @@ + + + + My.resourceenvironment + pathmap://PCM_MODELS/Palladio.resourcetype + default.allocation + default.system + default.repository + default.usagemodel + pathmap://PCM_MODELS/FailureTypes.repository + pathmap://PCM_MODELS/PrimitiveTypes.repository + default.usageevolution + default.dlim + constant.dlim + default.measuringpoint + defaultMonitor.monitorrepository + pathmap://METRIC_SPEC_MODELS/commonMetrics.metricspec + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/tempReconfigs/testReconfiguration.qvto b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/tempReconfigs/testReconfiguration.qvto new file mode 100644 index 00000000..cdbc8a3a --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/transformationQVTTest/tempReconfigs/testReconfiguration.qvto @@ -0,0 +1,68 @@ +/* + * This reconfiguration is used to automatically test the QVTO reconfiguration. + * It is used for a deterministic model and reconfigures deterministically. + * The reconfiguration changes the parameter ClosedWorkload.population. + * In the unit test, the response time is then tracked. + */ + +import org.palladiosimulator.simulizar.action.repository.black.SimulationStateLibrary; + +modeltype PRM uses 'http://simulizar.palladiosimulator.org/RuntimeMeasurement/1.0'; +modeltype PCM_ALLOC uses 'http://palladiosimulator.org/PalladioComponentModel/Allocation/5.2'; +modeltype PCM_REP uses 'http://palladiosimulator.org/PalladioComponentModel/Repository/5.2'; +modeltype PCM_SEFF uses 'http://palladiosimulator.org/PalladioComponentModel/SEFF/5.2'; +modeltype PCM_SYS uses 'http://palladiosimulator.org/PalladioComponentModel/System/5.2'; +modeltype PCM_RES_ENV uses 'http://palladiosimulator.org/PalladioComponentModel/ResourceEnvironment/5.2'; +modeltype PCM_RES_TYPE uses 'http://palladiosimulator.org/PalladioComponentModel/ResourceType/5.2'; +modeltype PCM_USAGE uses 'http://palladiosimulator.org/PalladioComponentModel/UsageModel/5.2'; +modeltype PCM_FEATURE_CONF uses 'http://sdq.ipd.uka.de/FeatureConfig/2.0'; +modeltype PCM_FEATURE_MOD uses 'http://sdq.ipd.uka.de/FeatureModel/2.0'; +modeltype PCM_CORE uses 'http://palladiosimulator.org/PalladioComponentModel/Core/5.2'; +modeltype PCM_COMP uses 'http://palladiosimulator.org/PalladioComponentModel/Core/Composition/5.2'; +modeltype PCM_ENTITY uses 'http://palladiosimulator.org/PalladioComponentModel/Core/Entity/5.2'; +modeltype PCM_PARAM uses 'http://palladiosimulator.org/PalladioComponentModel/Parameter/5.2'; +modeltype PCM_STOEX uses 'http://sdq.ipd.uka.de/StochasticExpressions/2.2'; + + +transformation TestQVTO( in prm : PRM, + inout pcmResourceEnvironment : PCM_RES_ENV) { + + + // Define Threshold and Scale Down + property reconfigUpTime : Real = 2000.0; + property reconfigDownTime : Real = 4000.0; + + /** + * The main transformation. + * This is the entry point to the overall transformation. + */ + main() { + log('QVTO ProcessingRate Reconfiguration Test started'); + assert fatal(prm.rootObjects()[RuntimeMeasurement]->size() > 0) + with log ("No Measurements found!"); +// pcmUsage.objectsOfType(ClosedWorkload)-> map reconfigureClosedWorkload(1); +// log("Reconfigure Population from Closed Workload 2.0 -> 1.0"); + -- mapping from 2.0 to 1.0 between 4000 and 6000 + + var resourceSpecifications = pcmResourceEnvironment.objectsOfType(ProcessingResourceSpecification); + -- mapping from 1.0 to 2.0 between 2000 and 4000 + if ( getSimulationTime() > reconfigUpTime and getSimulationTime() < reconfigDownTime) then { + log(getSimulationTime().toString() + " größer 2000, kleiner 4000"); + resourceSpecifications-> map reconfigureProcessingRate(2); + log("Reconfigure ProcessingRate from 1.0 -> 2.0"); + } endif; + + if ( getSimulationTime() > reconfigDownTime) then { + log(getSimulationTime().toString() + " größer 4000"); + resourceSpecifications-> map reconfigureProcessingRate(1); + log("Reconfigure ProcessingRate from 1.0 -> 2.0"); + } endif; + + } + + mapping inout ProcessingResourceSpecification::reconfigureProcessingRate(newValue : Real) : ProcessingResourceSpecification + { + processingRate_ProcessingResourceSpecification.specification := newValue.toString(); + log("Processing Rate Reconfigure DONE!"); + } +} \ No newline at end of file diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/.project b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/.project new file mode 100644 index 00000000..1ad305e5 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/.project @@ -0,0 +1,12 @@ + + + usageevolutionTest + + + + + + + org.eclipse.sirius.nature.modelingproject + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/My.resourceenvironment b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/My.resourceenvironment new file mode 100644 index 00000000..6a4ca4ad --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/My.resourceenvironment @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/UsageevolutionTest-Simulizar.launch b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/UsageevolutionTest-Simulizar.launch new file mode 100644 index 00000000..4efe8cc1 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/UsageevolutionTest-Simulizar.launch @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/constant.dlim b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/constant.dlim new file mode 100644 index 00000000..c40f0fc3 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/constant.dlim @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.allocation b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.allocation new file mode 100644 index 00000000..38c81fd4 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.allocation @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.dlim b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.dlim new file mode 100644 index 00000000..08ca3f0d --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.dlim @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.repository b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.repository new file mode 100644 index 00000000..4b086c87 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.repository @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.system b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.system new file mode 100644 index 00000000..e855e7dc --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.system @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.usageevolution b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.usageevolution new file mode 100644 index 00000000..9ed96474 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.usageevolution @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.usagemodel b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.usagemodel new file mode 100644 index 00000000..c088c750 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/default.usagemodel @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/representations.aird b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/representations.aird new file mode 100644 index 00000000..af2e5138 --- /dev/null +++ b/tests/org.palladiosimulator.simulizar.tests/testmodels/usageevolutionTest/representations.aird @@ -0,0 +1,987 @@ + + + + My.resourceenvironment + pathmap://PCM_MODELS/Palladio.resourcetype + default.allocation + default.system + default.repository + default.usagemodel + pathmap://PCM_MODELS/FailureTypes.repository + pathmap://PCM_MODELS/PrimitiveTypes.repository + default.usageevolution + default.dlim + constant.dlim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +