From 063a4abece03e1a8c67941937942bef7e6bf9cb1 Mon Sep 17 00:00:00 2001 From: shawnhatch Date: Wed, 4 Jun 2025 21:09:25 -0400 Subject: [PATCH 1/2] Add a SimulationState instance to the DimensionContext --- .../simulation/nucleus/DimensionContext.java | 56 ++++++++++++++----- .../ms/gcm/simulation/nucleus/Experiment.java | 3 + .../nucleus/AT_DimesionContext.java | 14 +++++ .../support/AT_GlobalPropertyDimension.java | 2 + .../support/AT_GroupPropertyDimension.java | 2 + .../support/AT_PersonPropertyDimension.java | 2 + .../support/AT_RegionPropertyDimension.java | 2 + 7 files changed, 66 insertions(+), 15 deletions(-) diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DimensionContext.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DimensionContext.java index 628932fb5..27ccf2a8c 100644 --- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DimensionContext.java +++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DimensionContext.java @@ -13,6 +13,7 @@ */ public final class DimensionContext implements PluginDataBuilderContainer { + private SimulationState simulationState; private Map, List> pluginDataBuilderBaseMap = new LinkedHashMap<>(); private Map, List> pluginDataBuilderWorkingMap = new LinkedHashMap<>(); private Map, List> pluginDataBaseMap = new LinkedHashMap<>(); @@ -28,17 +29,32 @@ public static class Builder { private Builder() { } + private SimulationState simulationState; private Map, List> pluginDataBuilderMap = new LinkedHashMap<>(); private Map, List> pluginDataMap = new LinkedHashMap<>(); + private void validate() { + if(simulationState == null) { + throw new ContractException(NucleusError.NULL_SIMULATION_STATE); + } + } + /** * Returns the DimensionContext instance composed from the inputs to this * builder. + * + * @throws ContractException + *
    + *
  • {@linkplain NucleusError#NULL_SIMULATION_STATE} + * if the simulation state is not set
  • + *
*/ public DimensionContext build() { + validate(); DimensionContext result = new DimensionContext(); result.pluginDataBuilderBaseMap.putAll(pluginDataBuilderMap); result.pluginDataBaseMap.putAll(pluginDataMap); + result.simulationState = simulationState; return result; } @@ -69,6 +85,10 @@ public PluginDataBuilder add(T t) { pluginDataBuilders.add(builder); return builder; } + + public void setSimulationState(SimulationState simulationState) { + this.simulationState = simulationState; + } } /** @@ -120,24 +140,24 @@ public T getPluginDataBuilder(Class classRef) { return classRef.cast(pluginDataBuilder); } - + /** * Returns the stored plugin data builders matching the given class reference. * * @throws ContractException *
    *
  • {@linkplain NucleusError#NULL_PLUGIN_DATA_BUILDER_CLASS} - * if the class reference is null
  • * + * if the class reference is null * *
*/ - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") public List getPluginDataBuilders(Class classRef) { if (classRef == null) { throw new ContractException(NucleusError.NULL_PLUGIN_DATA_BUILDER_CLASS); } - + List result = new ArrayList<>(); - + List pluginDataBuilders = pluginDataBuilderWorkingMap.get(classRef); if (pluginDataBuilders == null) { @@ -150,11 +170,11 @@ public List getPluginDataBuilders(Class clas } pluginDataBuilderWorkingMap.put(classRef, pluginDataBuilders); } - - for(PluginDataBuilder pluginDataBuilder : pluginDataBuilders) { - result.add((T)pluginDataBuilder); + + for (PluginDataBuilder pluginDataBuilder : pluginDataBuilders) { + result.add((T) pluginDataBuilder); } - + return result; } @@ -212,14 +232,13 @@ public T getPluginData(Class classRef) { * if the class reference is null * */ - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") public List getPluginDatas(Class classRef) { - if (classRef == null) { throw new ContractException(NucleusError.NULL_PLUGIN_DATA_CLASS); } - + List result = new ArrayList<>(); List pluginDatas = pluginDataWorkingMap.get(classRef); @@ -233,11 +252,18 @@ public List getPluginDatas(Class classRef) { } pluginDataWorkingMap.put(classRef, pluginDatas); } - - for(PluginData pluginData : pluginDatas) { - result.add((T)pluginData); + + for (PluginData pluginData : pluginDatas) { + result.add((T) pluginData); } return result; } + + /** + * Returns the simulation state. + */ + public SimulationState getSimulationState() { + return simulationState; + } } diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Experiment.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Experiment.java index 12efd335e..71e0d8b55 100644 --- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Experiment.java +++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Experiment.java @@ -534,6 +534,9 @@ private List getNewPluginInstancesFromScenarioId(final int scenarioId) { list.add(contextBuilder.add(pluginData)); } } + + contextBuilder.setSimulationState(data.simulationState); + final DimensionContext dimensionContext = contextBuilder.build(); // initialize the scenario meta data diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java index bade52155..fe6d75d2b 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java @@ -160,6 +160,7 @@ public void testGetPluginDataBuilder() { PluginData p4 = new PluginData2(); DimensionContext.Builder dimensionContextBuilder = DimensionContext.builder(); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); dimensionContextBuilder.add(p1); dimensionContextBuilder.add(p2); @@ -223,6 +224,7 @@ public void testGetPluginDataBuilders() { PluginData p4 = new PluginData2(); DimensionContext.Builder dimensionContextBuilder = DimensionContext.builder(); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); dimensionContextBuilder.add(p1); dimensionContextBuilder.add(p2); @@ -293,6 +295,8 @@ public void testGetPluginData() { PluginData p4 = new PluginData2(); DimensionContext.Builder dimensionContextBuilder = DimensionContext.builder(); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); dimensionContextBuilder.add(p1); dimensionContextBuilder.add(p2); @@ -300,6 +304,7 @@ public void testGetPluginData() { dimensionContextBuilder.add(p4); DimensionContext dimensionContext = dimensionContextBuilder.build(); + // There should be exactly one type one PluginData p = dimensionContext.getPluginData(PluginData1.class); @@ -356,6 +361,7 @@ public void testGetPluginDatas() { PluginData p4 = new PluginData2(); DimensionContext.Builder dimensionContextBuilder = DimensionContext.builder(); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); dimensionContextBuilder.add(p1); dimensionContextBuilder.add(p2); @@ -417,6 +423,7 @@ public void testAdd() { expectedContents.add(p2); DimensionContext.Builder builder = DimensionContext.builder(); + builder.setSimulationState(SimulationState.builder().build()); PluginDataBuilder p1b = builder.add(p1); PluginDataBuilder p2b = builder.add(p2); @@ -449,6 +456,7 @@ public void testBuild() { expectedContents.add(p2); DimensionContext.Builder builder = DimensionContext.builder(); + builder.setSimulationState(SimulationState.builder().build()); PluginDataBuilder p1b = builder.add(p1); PluginDataBuilder p2b = builder.add(p2); @@ -463,6 +471,12 @@ public void testBuild() { assertDoesNotThrow(() -> actualContents.add(dimensionContext.getPluginData(PluginData2.class))); assertEquals(expectedContents, actualContents); + + //precondition test: if the simulation state is null + ContractException contractException = assertThrows(ContractException.class, ()->{ + DimensionContext.builder().build(); + }); + assertEquals(NucleusError.NULL_SIMULATION_STATE, contractException.getErrorType()); } } diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/globalproperties/support/AT_GlobalPropertyDimension.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/globalproperties/support/AT_GlobalPropertyDimension.java index 9131b3396..33eccb2f8 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/globalproperties/support/AT_GlobalPropertyDimension.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/globalproperties/support/AT_GlobalPropertyDimension.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.gcm.simulation.nucleus.DimensionContext; +import gov.hhs.aspr.ms.gcm.simulation.nucleus.SimulationState; import gov.hhs.aspr.ms.gcm.simulation.plugins.globalproperties.datamanagers.GlobalPropertiesPluginData; import gov.hhs.aspr.ms.gcm.simulation.plugins.globalproperties.testsupport.TestGlobalPropertyId; import gov.hhs.aspr.ms.gcm.simulation.plugins.properties.support.PropertyDefinition; @@ -94,6 +95,7 @@ public void testExecuteLevel() { pluginDataBuilder = (GlobalPropertiesPluginData.Builder) dimensionContextBuilder .add(pluginDataBuilder.build()); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); DimensionContext dimensionContext = dimensionContextBuilder.build(); // execute the dimension with the level diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/groups/support/AT_GroupPropertyDimension.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/groups/support/AT_GroupPropertyDimension.java index ce32220bb..0c6471011 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/groups/support/AT_GroupPropertyDimension.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/groups/support/AT_GroupPropertyDimension.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.gcm.simulation.nucleus.DimensionContext; +import gov.hhs.aspr.ms.gcm.simulation.nucleus.SimulationState; import gov.hhs.aspr.ms.gcm.simulation.plugins.groups.datamanagers.GroupsPluginData; import gov.hhs.aspr.ms.gcm.simulation.plugins.groups.testsupport.TestGroupPropertyId; import gov.hhs.aspr.ms.gcm.simulation.plugins.groups.testsupport.TestGroupTypeId; @@ -98,6 +99,7 @@ public void testExecuteLevel() { DimensionContext.Builder dimensionContextBuilder = DimensionContext.builder(); pluginDataBuilder = (GroupsPluginData.Builder) dimensionContextBuilder.add(pluginDataBuilder.build()); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); DimensionContext dimensionContext = dimensionContextBuilder.build(); // execute the dimension with the level diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/personproperties/support/AT_PersonPropertyDimension.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/personproperties/support/AT_PersonPropertyDimension.java index 8e84ef808..2a370647e 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/personproperties/support/AT_PersonPropertyDimension.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/personproperties/support/AT_PersonPropertyDimension.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.gcm.simulation.nucleus.DimensionContext; +import gov.hhs.aspr.ms.gcm.simulation.nucleus.SimulationState; import gov.hhs.aspr.ms.gcm.simulation.plugins.personproperties.datamanagers.PersonPropertiesPluginData; import gov.hhs.aspr.ms.gcm.simulation.plugins.personproperties.testsupport.TestPersonPropertyId; import gov.hhs.aspr.ms.gcm.simulation.plugins.properties.support.PropertyDefinition; @@ -90,6 +91,7 @@ public void testExecuteLevel() { pluginDataBuilder = (PersonPropertiesPluginData.Builder) dimensionContextBuilder .add(pluginDataBuilder.build()); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); DimensionContext dimensionContext = dimensionContextBuilder.build(); // execute the dimension with the level diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/regions/support/AT_RegionPropertyDimension.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/regions/support/AT_RegionPropertyDimension.java index 2a1c07da3..00fc0cd72 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/regions/support/AT_RegionPropertyDimension.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/regions/support/AT_RegionPropertyDimension.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.gcm.simulation.nucleus.DimensionContext; +import gov.hhs.aspr.ms.gcm.simulation.nucleus.SimulationState; import gov.hhs.aspr.ms.gcm.simulation.plugins.properties.support.PropertyDefinition; import gov.hhs.aspr.ms.gcm.simulation.plugins.regions.datamanagers.RegionsPluginData; import gov.hhs.aspr.ms.gcm.simulation.plugins.regions.testsupport.TestRegionPropertyId; @@ -97,6 +98,7 @@ public void testExecuteLevel() { DimensionContext.Builder dimensionContextBuilder = DimensionContext.builder(); pluginDataBuilder = (RegionsPluginData.Builder) dimensionContextBuilder.add(pluginDataBuilder.build()); + dimensionContextBuilder.setSimulationState(SimulationState.builder().build()); DimensionContext dimensionContext = dimensionContextBuilder.build(); // execute the dimension with the level From a5957ea13d0b29fde9911d5e0d669002f76fd175 Mon Sep 17 00:00:00 2001 From: shawnhatch Date: Wed, 4 Jun 2025 21:15:41 -0400 Subject: [PATCH 2/2] Added unit tests --- .../nucleus/AT_DimesionContext.java | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java index fe6d75d2b..199f3e5ea 100644 --- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java +++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DimesionContext.java @@ -247,13 +247,15 @@ public void testGetPluginDataBuilders() { assertEquals(p1.toBuilder(), pluginData1Builders.get(0)); // There should be exactly one type3 builder - List pluginData3Builders = dimensionContext.getPluginDataBuilders(PluginData3.Builder.class); + List pluginData3Builders = dimensionContext + .getPluginDataBuilders(PluginData3.Builder.class); assertNotNull(pluginData3Builders); assertEquals(1, pluginData3Builders.size()); assertEquals(p3.toBuilder(), pluginData3Builders.get(0)); // There should be exactly two type2 builders - List pluginData2Builders = dimensionContext.getPluginDataBuilders(PluginData2.Builder.class); + List pluginData2Builders = dimensionContext + .getPluginDataBuilders(PluginData2.Builder.class); assertNotNull(pluginData2Builders); assertEquals(2, pluginData2Builders.size()); assertTrue(pluginData2Builders.contains(p2.toBuilder())); @@ -269,7 +271,8 @@ public void testGetPluginDataBuilders() { assertTrue(pluginDataBuilders.contains(p4.toBuilder())); // There should be exactly zero type4s - List pluginData4Builders = dimensionContext.getPluginDataBuilders(PluginData4.Builder.class); + List pluginData4Builders = dimensionContext + .getPluginDataBuilders(PluginData4.Builder.class); assertNotNull(pluginData4Builders); assertEquals(0, pluginData4Builders.size()); @@ -304,7 +307,6 @@ public void testGetPluginData() { dimensionContextBuilder.add(p4); DimensionContext dimensionContext = dimensionContextBuilder.build(); - // There should be exactly one type one PluginData p = dimensionContext.getPluginData(PluginData1.class); @@ -412,6 +414,27 @@ public void testGetPluginDatas() { } @Test + @UnitTestMethod(target = DimensionContext.class, name = "getSimulationState", args = {}) + public void testGetSimulationState() { + SimulationState simulationState = SimulationState.builder().build(); + DimensionContext.Builder builder = DimensionContext.builder(); + builder.setSimulationState(simulationState); + DimensionContext dimensionContext = builder.build(); + assertTrue(simulationState == dimensionContext.getSimulationState()); + } + + @Test + @UnitTestMethod(target = DimensionContext.Builder.class, name = "setSimulationState", args = {SimulationState.class}) + public void testSetSimulationState() { + SimulationState simulationState = SimulationState.builder().build(); + DimensionContext.Builder builder = DimensionContext.builder(); + builder.setSimulationState(simulationState); + DimensionContext dimensionContext = builder.build(); + assertTrue(simulationState == dimensionContext.getSimulationState()); + } + + + @Test @UnitTestMethod(target = DimensionContext.Builder.class, name = "add", args = { PluginData.class }) public void testAdd() { PluginData p1 = new PluginData1(); @@ -471,9 +494,9 @@ public void testBuild() { assertDoesNotThrow(() -> actualContents.add(dimensionContext.getPluginData(PluginData2.class))); assertEquals(expectedContents, actualContents); - - //precondition test: if the simulation state is null - ContractException contractException = assertThrows(ContractException.class, ()->{ + + // precondition test: if the simulation state is null + ContractException contractException = assertThrows(ContractException.class, () -> { DimensionContext.builder().build(); }); assertEquals(NucleusError.NULL_SIMULATION_STATE, contractException.getErrorType());