diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java
index 5a52de5b7..4f0638203 100644
--- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java
+++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ActorContext.java
@@ -115,10 +115,36 @@ public boolean actorExists(final ActorId actorId) {
return simulation.actorExists(actorId);
}
+ /**
+ * Returns the data manager instance matching the class reference.
+ *
+ *
+ * @throws ContractException
+ *
+ *
+ * - {@linkplain NucleusError#NULL_DATA_MANAGER_CLASS}
+ * if the class reference is null
+ * - {@linkplain NucleusError#AMBIGUOUS_DATA_MANAGER_CLASS}
+ * if there is more than one data manager instance
+ * matching the class reference
+ * - {@linkplain NucleusError#UNKNOWN_DATA_MANAGER}
+ * if there are no data manager instances matching the
+ * class reference
+ *
+ *
+ */
public T getDataManager(Class dataManagerClass) {
return simulation.getDataManagerForActor(dataManagerClass);
}
+ /**
+ * Returns true if and only if there is exactly one data manager instance
+ * matching the given class reference. Null tolerant.
+ */
+ public boolean dataManagerExists(Class dataManagerClass) {
+ return simulation.dataManagerExists(dataManagerClass);
+ }
+
public double getTime() {
return simulation.time;
}
diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java
index f36786af8..07af91f0b 100644
--- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java
+++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/DataManagerContext.java
@@ -110,10 +110,10 @@ public void releaseObservationEvent(final Event event) {
}
/**
- * Broadcasts the given event to a single actor. This is used
- * for OBSERVATION events that are generated by the data managers. MUTATION
- * events that are generated by the data managers as a proxy for actors and data
- * managers should use releaseMutationEvent() instead.
+ * Broadcasts the given event to a single actor. This is used for OBSERVATION
+ * events that are generated by the data managers. MUTATION events that are
+ * generated by the data managers as a proxy for actors and data managers should
+ * use releaseMutationEvent() instead.
*
* @throws ContractException
*
@@ -198,10 +198,49 @@ public boolean actorExists(final ActorId actorId) {
return simulation.actorExists(actorId);
}
+ /**
+ * Returns the data manager instance matching the class reference.
+ *
+ *
+ * @throws ContractException
+ *
+ *
+ * - {@linkplain NucleusError#NULL_DATA_MANAGER_CLASS}
+ * if the class reference is null
+ * - {@linkplain NucleusError#AMBIGUOUS_DATA_MANAGER_CLASS}
+ * if there is more than one data manager instance
+ * matching the class reference
+ * - {@linkplain NucleusError#UNKNOWN_DATA_MANAGER}
+ * if there are no data manager instances matching the
+ * class reference
+ * - {@linkplain NucleusError#DATA_MANAGER_ACCESS_VIOLATION}
+ * if the invoking data manager does not have access
+ * to the instance associated with the class
+ * reference. This happens where there is not a plugin
+ * dependency chain from the requestor to the
+ * requested if they are contained in different
+ * plugins. Within a plugin, access is granted for
+ * data manager types that were added by their plugin
+ * before the invoking instance.
+ *
+ *
+ *
+ *
+ *
+ */
public T getDataManager(Class dataManagerClass) {
return simulation.getDataManagerForDataManager(dataManagerId, dataManagerClass);
}
+ /**
+ * Returns true if and only if there is exactly one data manager instance
+ * matching the given class reference that is available to the data manager that
+ * is requesting the instance. Null tolerant.
+ */
+ public boolean dataManagerExists(Class dataManagerClass) {
+ return simulation.dataManagerExistsForDataManager(dataManagerId, dataManagerClass);
+ }
+
public double getTime() {
return simulation.time;
}
diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java
index c21c533c4..722285d02 100644
--- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java
+++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/ReportContext.java
@@ -33,8 +33,8 @@ protected ReportContext(Simulation simulation) {
*
* @throws ContractException
*
- * - {@link NucleusError#NULL_PLAN_CONSUMER} if the consumer is
- * null
+ * - {@link NucleusError#NULL_PLAN_CONSUMER} if the
+ * consumer is null
* - {@link NucleusError#PAST_PLANNING_TIME} if the
* plan is scheduled for a time in the past *
* - {@link NucleusError#PLANNING_QUEUE_CLOSED} if
@@ -146,6 +146,14 @@ public T getDataManager(Class dataManagerClass) {
return simulation.getDataManagerForActor(dataManagerClass);
}
+ /**
+ * Returns true if and only if there is exactly one data manager instance
+ * matching the given class reference. Null tolerant.
+ */
+ public boolean dataManagerExists(Class dataManagerClass) {
+ return simulation.dataManagerExists(dataManagerClass);
+ }
+
public double getTime() {
return simulation.time;
}
diff --git a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Simulation.java b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Simulation.java
index 5095719f3..17ef042c5 100644
--- a/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Simulation.java
+++ b/simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/Simulation.java
@@ -1275,6 +1275,40 @@ protected void removeActor(final ActorId actorId) {
containsDeletedActors = true;
}
+ protected boolean dataManagerExists(Class dataManagerClass) {
+ boolean result = false;
+ if (dataManagerClass != null) {
+
+ DataManager dataManager = workingClassToDataManagerMap.get(dataManagerClass);
+ /*
+ * If the working map does not contain the data manager, try to find a single
+ * match from the base map that was collected from the plugins.
+ *
+ * If two or more matches are found, then throw an exception.
+ *
+ * If exactly one match is found, update the working map.
+ *
+ * If no matches are found, nothing is done, but we are vulnerable to somewhat
+ * slower performance if the data manager is sought repeatedly.
+ */
+ if (dataManager == null) {
+ List> candidates = new ArrayList<>();
+ for (Class> c : baseClassToDataManagerMap.keySet()) {
+ if (dataManagerClass.isAssignableFrom(c)) {
+ candidates.add(c);
+ }
+ }
+
+ if (candidates.size() == 1) {
+ dataManager = baseClassToDataManagerMap.get(candidates.get(0));
+ workingClassToDataManagerMap.put(dataManagerClass, dataManager);
+ }
+ }
+ result = dataManager != null;
+ }
+ return result;
+ }
+
@SuppressWarnings("unchecked")
protected T getDataManagerForActor(Class dataManagerClass) {
@@ -1315,6 +1349,58 @@ protected T getDataManagerForActor(Class dataManagerC
}
return (T) dataManager;
}
+
+
+ protected boolean dataManagerExistsForDataManager(DataManagerId dataManagerId,
+ Class dataManagerClass) {
+
+ if (dataManagerClass == null) {
+ return false;
+ }
+
+ DataManager dataManager = workingClassToDataManagerMap.get(dataManagerClass);
+ /*
+ * If the working map does not contain the data manager, try to find a single
+ * match from the base map that was collected from the plugins.
+ *
+ * If two or more matches are found, then throw an exception.
+ *
+ * If exactly one match is found, update the working map.
+ *
+ * If no matches are found, nothing is done, but we are vulnerable to somewhat
+ * slower performance if the data manager is sought repeatedly.
+ */
+ if (dataManager == null) {
+ List> candidates = new ArrayList<>();
+ for (Class> c : baseClassToDataManagerMap.keySet()) {
+ if (dataManagerClass.isAssignableFrom(c)) {
+ candidates.add(c);
+ }
+ }
+ if (candidates.size() > 1) {
+ return false;
+ }
+ if (candidates.size() == 1) {
+ dataManager = baseClassToDataManagerMap.get(candidates.get(0));
+ workingClassToDataManagerMap.put(dataManagerClass, dataManager);
+ }
+ }
+
+ if (dataManager == null) {
+ return false;
+ }
+
+ int requestorId = dataManagerId.getValue();
+ DataManagerId dataManagerId2 = dataManagerToDataManagerIdMap.get(dataManager);
+ int requesteeId = dataManagerId2.getValue();
+
+ boolean accessGranted = dataManagerAccessPermissions[requestorId][requesteeId];
+
+ if (!accessGranted) {
+ return false;
+ }
+ return true;
+ }
@SuppressWarnings("unchecked")
protected T getDataManagerForDataManager(DataManagerId dataManagerId,
@@ -1492,10 +1578,10 @@ protected boolean subscribersExistForEvent(Class extends Event> eventClass) {
}
/*
- * Recursively processes the event through the filter node to the given actor. Events should be
- * processed through the root filter node. Each node's consumers have each such
- * consumer scheduled onto the actor queue for delayed execution of the
- * consumer.
+ * Recursively processes the event through the filter node to the given actor.
+ * Events should be processed through the root filter node. Each node's
+ * consumers have each such consumer scheduled onto the actor queue for delayed
+ * execution of the consumer.
*/
private void broadcastEventToFilterNodeAndActor(final Event event, FilterNode filterNode, ActorId actorId) {
// determine the value of the function for the given event
diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ActorContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ActorContext.java
index acba88e96..0eda0d89f 100644
--- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ActorContext.java
+++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ActorContext.java
@@ -58,6 +58,10 @@ private static class TestDataManager4A extends TestDataManager4 {
}
+ private static class TestDataManager4B extends TestDataManager4 {
+
+ }
+
private static class DataChangeEvent implements Event {
private final DatumType datumType;
private final int value;
@@ -219,13 +223,13 @@ public void testAddPlan_Consumer() {
// show that the last two passive plans did not execute
assertTrue(planExecuted.getValue());
-
+
// precondition test: if the consumer is null
ContractException contractException = assertThrows(ContractException.class, () -> {
Simulation.builder()//
.addPlugin(TestPlugin.getTestPlugin(
TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- c.addPlan(null,0);
+ c.addPlan(null, 0);
})).build()))//
.build()//
.execute();//
@@ -235,12 +239,13 @@ public void testAddPlan_Consumer() {
// precondition test: if the plan is scheduled for a time in the past
contractException = assertThrows(ContractException.class, () -> {
Simulation.builder()//
- .addPlugin(TestPlugin.getTestPlugin(
- TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- c.addPlan((c2)->{},-10);
- })).build()))//
- .build()//
- .execute();//
+ .addPlugin(TestPlugin.getTestPlugin(
+ TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
+ c.addPlan((c2) -> {
+ }, -10);
+ })).build()))//
+ .build()//
+ .execute();//
});
assertEquals(NucleusError.PAST_PLANNING_TIME, contractException.getErrorType());
@@ -248,19 +253,19 @@ public void testAddPlan_Consumer() {
// processing is finished
contractException = assertThrows(ContractException.class, () -> {
Simulation.builder()//
- .addPlugin(TestPlugin.getTestPlugin(
- TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- c.subscribeToSimulationClose((c2)->{
- c2.addPlan((c3)->{},0);
- });
-
- })).build()))//
- .build()//
- .execute();//
+ .addPlugin(TestPlugin.getTestPlugin(
+ TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
+ c.subscribeToSimulationClose((c2) -> {
+ c2.addPlan((c3) -> {
+ }, 0);
+ });
+
+ })).build()))//
+ .build()//
+ .execute();//
});
assertEquals(NucleusError.PLANNING_QUEUE_CLOSED, contractException.getErrorType());
-
}
@Test
@@ -313,12 +318,13 @@ public void testAddPlan_Plan() {
// precondition test: if the plan is scheduled for a time in the past
contractException = assertThrows(ContractException.class, () -> {
Simulation.builder()//
- .addPlugin(TestPlugin.getTestPlugin(
- TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- c.addPlan(new ConsumerActorPlan(-10, (c3)->{}));
- })).build()))//
- .build()//
- .execute();//
+ .addPlugin(TestPlugin.getTestPlugin(
+ TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
+ c.addPlan(new ConsumerActorPlan(-10, (c3) -> {
+ }));
+ })).build()))//
+ .build()//
+ .execute();//
});
assertEquals(NucleusError.PAST_PLANNING_TIME, contractException.getErrorType());
@@ -326,19 +332,19 @@ public void testAddPlan_Plan() {
// processing is finished
contractException = assertThrows(ContractException.class, () -> {
Simulation.builder()//
- .addPlugin(TestPlugin.getTestPlugin(
- TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- c.subscribeToSimulationClose((c2)->{
- c2.addPlan(new ConsumerActorPlan(0, (c3)->{}));
- });
-
- })).build()))//
- .build()//
- .execute();//
+ .addPlugin(TestPlugin.getTestPlugin(
+ TestPluginData.builder().addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
+ c.subscribeToSimulationClose((c2) -> {
+ c2.addPlan(new ConsumerActorPlan(0, (c3) -> {
+ }));
+ });
+
+ })).build()))//
+ .build()//
+ .execute();//
});
assertEquals(NucleusError.PLANNING_QUEUE_CLOSED, contractException.getErrorType());
-
}
@Test
@@ -386,11 +392,12 @@ public void testGetActorId() {
// show that the number of actor ids matches the number of actor aliases
assertEquals(3, observedActorIds.size());
}
-
- @Test
- @UnitTestMethod(target = ActorContext.class, name = "getDataManager", args = { Class.class })
- public void testGetDataManager() {
-
+
+
+
+
+ private void executeGetDataManagerTest(Consumer consumer) {
+
// create the test plugin data builder
TestPluginData.Builder pluginDataBuilder = TestPluginData.builder();
@@ -401,48 +408,90 @@ public void testGetDataManager() {
pluginDataBuilder.addTestDataManager("dm3B", () -> new TestDataManager3B());
pluginDataBuilder.addTestDataManager("dm4A", () -> new TestDataManager4A());
- pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- c.getDataManager(TestDataManager1.class);
- c.getDataManager(TestDataManager3A.class);
- c.getDataManager(TestDataManager3B.class);
- c.getDataManager(TestDataManager4A.class);
- }));
+ pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(0, consumer));
// build the action plugin
TestPluginData testPluginData = pluginDataBuilder.build();
Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
TestSimulation.builder().addPlugin(testPlugin).build().execute();
+ }
+
+ @Test
+ @UnitTestMethod(target = ActorContext.class, name = "getDataManager", args = { Class.class })
+ public void testGetDataManager() {
+
+ //postcondition test:
+ executeGetDataManagerTest((c)->{
+ assertNotNull(c.getDataManager(TestDataManager1.class));
+ assertNotNull(c.getDataManager(TestDataManager3A.class));
+ assertNotNull(c.getDataManager(TestDataManager3B.class));
+ assertNotNull(c.getDataManager(TestDataManager4A.class));
+ assertNotNull(c.getDataManager(TestDataManager4.class));
+ });
+
+ // precondition test: if the class reference is null
+ ContractException contractException = assertThrows(ContractException.class, ()->{
+ executeGetDataManagerTest((c)->{
+ c.getDataManager(null);
+ });
+ });
+ assertEquals(NucleusError.NULL_DATA_MANAGER_CLASS, contractException.getErrorType());
+
+ // precondition test: if the class reference is null
+ contractException = assertThrows(ContractException.class, ()->{
+ executeGetDataManagerTest((c)->{
+ c.getDataManager(TestDataManager3.class);
+ });
+ });
+ assertEquals(NucleusError.AMBIGUOUS_DATA_MANAGER_CLASS, contractException.getErrorType());
+
+ // precondition test: if the class reference is unknown
+ contractException = assertThrows(ContractException.class, ()->{
+ executeGetDataManagerTest((c)->{
+ c.getDataManager(TestDataManager4B.class);
+ });
+ });
+ assertEquals(NucleusError.UNKNOWN_DATA_MANAGER, contractException.getErrorType());
+ }
- // Precondition test 1
+ @Test
+ @UnitTestMethod(target = ActorContext.class, name = "dataManagerExists", args = { Class.class })
+ public void testDataManagerExists() {
+
+ // create the test plugin data builder
+ TestPluginData.Builder pluginDataBuilder = TestPluginData.builder();
+
+ // create a data manager for the actor to find
+
+ pluginDataBuilder.addTestDataManager("dm1", () -> new TestDataManager1());
pluginDataBuilder.addTestDataManager("dm3A", () -> new TestDataManager3A());
pluginDataBuilder.addTestDataManager("dm3B", () -> new TestDataManager3B());
+ pluginDataBuilder.addTestDataManager("dm4A", () -> new TestDataManager4A());
- // show that ambiguous class matching throws an exception
pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- ContractException contractException = assertThrows(ContractException.class,
- () -> c.getDataManager(TestDataManager3.class));
- assertEquals(NucleusError.AMBIGUOUS_DATA_MANAGER_CLASS, contractException.getErrorType());
- }));
+ // show that the explicit class references return true
+ assertTrue(c.dataManagerExists(TestDataManager1.class));
+ assertTrue(c.dataManagerExists(TestDataManager3A.class));
+ assertTrue(c.dataManagerExists(TestDataManager3B.class));
+ assertTrue(c.dataManagerExists(TestDataManager4A.class));
- // build the action plugin
- testPluginData = pluginDataBuilder.build();
- testPlugin = TestPlugin.getTestPlugin(testPluginData);
+ // show that zero class matching returns false
+ assertFalse(c.dataManagerExists(TestDataManager4B.class));
- TestSimulation.builder().addPlugin(testPlugin).build().execute();
+ // show that ambiguous class matching returns false
+ assertFalse(c.dataManagerExists(TestDataManager3.class));
+
+ // show that a null yields a false
+ assertFalse(c.dataManagerExists(null));
- // Precondition test 2
- pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- ContractException contractException = assertThrows(ContractException.class, () -> c.getDataManager(null));
- assertEquals(NucleusError.NULL_DATA_MANAGER_CLASS, contractException.getErrorType());
}));
// build the action plugin
- testPluginData = pluginDataBuilder.build();
- testPlugin = TestPlugin.getTestPlugin(testPluginData);
+ TestPluginData testPluginData = pluginDataBuilder.build();
+ Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
TestSimulation.builder().addPlugin(testPlugin).build().execute();
-
}
@Test
diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java
index 1f6c824f4..de788dfb7 100644
--- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java
+++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_DataManagerContext.java
@@ -151,73 +151,207 @@ public void testSubscribeToSimulationClose() {
}
- @Test
- @UnitTestMethod(target = DataManagerContext.class, name = "getDataManager", args = { Class.class })
- public void testGetDataManager() {
-
+ private void executeGetDataManagerTest(String dmName, Consumer consumer) {
+ PluginId pluginId0 = new SimplePluginId("local plugin 0");
+ PluginId pluginId5 = new SimplePluginId("local plugin 5");
// create the test plugin data builder
TestPluginData.Builder pluginDataBuilder = TestPluginData.builder();
// create a data manager for the actor to find
pluginDataBuilder.addTestDataManager("dm1", () -> new TestDataManager1());
+ pluginDataBuilder.addTestDataManager("dm2", () -> new TestDataManager2());
pluginDataBuilder.addTestDataManager("dm3A", () -> new TestDataManager3A());
pluginDataBuilder.addTestDataManager("dm3B", () -> new TestDataManager3B());
pluginDataBuilder.addTestDataManager("dm4A", () -> new TestDataManager4A());
- pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(0, (c) -> {
- TestDataManager1 testDataManager1 = c.getDataManager(TestDataManager1.class);
- assertNotNull(testDataManager1);
-
- TestDataManager3A testDataManager3A = c.getDataManager(TestDataManager3A.class);
- assertNotNull(testDataManager3A);
+ pluginDataBuilder.addTestDataManagerPlan(dmName, new TestDataManagerPlan(0, consumer));
- TestDataManager3B testDataManager3B = c.getDataManager(TestDataManager3B.class);
- assertNotNull(testDataManager3B);
-
- TestDataManager4A testDataManager4A = c.getDataManager(TestDataManager4A.class);
- assertNotNull(testDataManager4A);
-
- }));
+ pluginDataBuilder.addPluginDependency(pluginId0);
// build the action plugin
TestPluginData testPluginData = pluginDataBuilder.build();
Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
- // execute the engine
- TestSimulation.builder().addPlugin(testPlugin).build().execute();
+ Plugin localPlugin0 = Plugin.builder()//
+ .setPluginId(pluginId0)//
+ .setInitializer((c) -> c.addDataManager(new TestDataManager0()))//
+ .build();
+ Plugin localPlugin5 = Plugin.builder()//
+ .setPluginId(pluginId5)//
+ .setInitializer((c) -> c.addDataManager(new TestDataManager5()))//
+ .build();
+
+ TestSimulation.builder()//
+ .addPlugin(localPlugin0)//
+ .addPlugin(localPlugin5)//
+ .addPlugin(testPlugin).build()//
+ .execute();//
+ }
+
+ @Test
+ @UnitTestMethod(target = DataManagerContext.class, name = "getDataManager", args = { Class.class })
+ public void testGetDataManager() {
+ /*
+ * postcondition test: we demonstrate for all of the test data managers in the
+ * test plugin that they can retrieve the instances that are allowed by the
+ * access rules. Note that TestDataManager0 and TestDataManager5 are defined by
+ * local plugins and only TestDataManager0 is accessible by the remaining data
+ * managers since the test plugin has a plugin dependency on the local plugin
+ * containing the instance of TestDataManager0, but does not have a plugin
+ * dependency on the plugin containing the instance of TestDataManager5.
+ */
+ executeGetDataManagerTest("dm4A", (c) -> {
+ assertNotNull(c.getDataManager(TestDataManager0.class));
+ assertNotNull(c.getDataManager(TestDataManager1.class));
+ assertNotNull(c.getDataManager(TestDataManager2.class));
+ assertNotNull(c.getDataManager(TestDataManager3A.class));
+ assertNotNull(c.getDataManager(TestDataManager3B.class));
+ });
+
+ executeGetDataManagerTest("dm3B", (c) -> {
+ assertNotNull(c.getDataManager(TestDataManager0.class));
+ assertNotNull(c.getDataManager(TestDataManager1.class));
+ assertNotNull(c.getDataManager(TestDataManager2.class));
+ assertNotNull(c.getDataManager(TestDataManager3A.class));
+ });
- // Precondition test 1
+ executeGetDataManagerTest("dm3A", (c) -> {
+ assertNotNull(c.getDataManager(TestDataManager0.class));
+ assertNotNull(c.getDataManager(TestDataManager1.class));
+ assertNotNull(c.getDataManager(TestDataManager2.class));
+ });
+
+ executeGetDataManagerTest("dm2", (c) -> {
+ assertNotNull(c.getDataManager(TestDataManager0.class));
+ assertNotNull(c.getDataManager(TestDataManager1.class));
+ });
+
+ executeGetDataManagerTest("dm1", (c) -> {
+ assertNotNull(c.getDataManager(TestDataManager0.class));
+ });
+
+ // precondition test: if the class reference is null
+ ContractException contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest("dm1", (c) -> {
+ c.getDataManager(null);
+ });
+ });
+ assertEquals(NucleusError.NULL_DATA_MANAGER_CLASS, contractException.getErrorType());
+
+ // precondition test: if the class reference is null
+ contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest("dm1", (c) -> {
+ c.getDataManager(TestDataManager3.class);
+ });
+ });
+ assertEquals(NucleusError.AMBIGUOUS_DATA_MANAGER_CLASS, contractException.getErrorType());
+
+ // precondition test: if the class reference is unknown
+ contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest("dm1", (c) -> {
+ c.getDataManager(TestDataManager4B.class);
+ });
+ });
+ assertEquals(NucleusError.UNKNOWN_DATA_MANAGER, contractException.getErrorType());
+ // precondition test: if the requestor does not have access due to order within
+ // the plugin
+ contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest("dm1", (c) -> {
+ c.getDataManager(TestDataManager2.class);
+ });
+ });
+ assertEquals(NucleusError.DATA_MANAGER_ACCESS_VIOLATION, contractException.getErrorType());
+
+ // precondition test: if the requestor does not have access due to having no
+ // plugin dependency path
+ contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest("dm1", (c) -> {
+ c.getDataManager(TestDataManager5.class);
+ });
+ });
+ assertEquals(NucleusError.DATA_MANAGER_ACCESS_VIOLATION, contractException.getErrorType());
+
+ }
+
+ @Test
+ @UnitTestMethod(target = DataManagerContext.class, name = "dataManagerExists", args = { Class.class })
+ public void testDataManagerExists() {
+
+ // create the test plugin data builder
+ TestPluginData.Builder pluginDataBuilder = TestPluginData.builder();
+
+ // create a data manager for the actor to find
+
+ pluginDataBuilder.addTestDataManager("dm1", () -> new TestDataManager1());
+ pluginDataBuilder.addTestDataManager("dm2", () -> new TestDataManager2());
pluginDataBuilder.addTestDataManager("dm3A", () -> new TestDataManager3A());
pluginDataBuilder.addTestDataManager("dm3B", () -> new TestDataManager3B());
+ pluginDataBuilder.addTestDataManager("dm4A", () -> new TestDataManager4A());
- pluginDataBuilder.addTestDataManagerPlan("dm3A", new TestDataManagerPlan(4, (c) -> {
- ContractException contractException = assertThrows(ContractException.class,
- () -> c.getDataManager(TestDataManager3.class));
- assertEquals(NucleusError.AMBIGUOUS_DATA_MANAGER_CLASS, contractException.getErrorType());
+ // show the various ways bad class references return false
+ pluginDataBuilder.addTestDataManagerPlan("dm1", new TestDataManagerPlan(1, (c) -> {
+ // show that zero class matching returns false
+ assertFalse(c.dataManagerExists(TestDataManager4B.class));
+
+ // show that ambiguous class matching returns false
+ assertFalse(c.dataManagerExists(TestDataManager3.class));
+
+ // show that a null yields a false
+ assertFalse(c.dataManagerExists(null));
}));
- // build the action plugin
- testPluginData = pluginDataBuilder.build();
- testPlugin = TestPlugin.getTestPlugin(testPluginData);
+ // show ordering restrictions are enforced
+ pluginDataBuilder.addTestDataManagerPlan("dm1", new TestDataManagerPlan(1, (c) -> {
+ assertFalse(c.dataManagerExists(TestDataManager1.class));
+ assertFalse(c.dataManagerExists(TestDataManager2.class));
+ assertFalse(c.dataManagerExists(TestDataManager3A.class));
+ assertFalse(c.dataManagerExists(TestDataManager3B.class));
+ assertFalse(c.dataManagerExists(TestDataManager4A.class));
+ }));
- // execute the engine
- TestSimulation.builder().addPlugin(testPlugin).build().execute();
+ // show ordering restrictions are enforced
+ pluginDataBuilder.addTestDataManagerPlan("dm2", new TestDataManagerPlan(1, (c) -> {
+ assertTrue(c.dataManagerExists(TestDataManager1.class));
+ assertFalse(c.dataManagerExists(TestDataManager2.class));
+ assertFalse(c.dataManagerExists(TestDataManager3A.class));
+ assertFalse(c.dataManagerExists(TestDataManager3B.class));
+ assertFalse(c.dataManagerExists(TestDataManager4A.class));
+ }));
- // Precondition test 2
+ // show ordering restrictions are enforced
+ pluginDataBuilder.addTestDataManagerPlan("dm3A", new TestDataManagerPlan(1, (c) -> {
+ assertTrue(c.dataManagerExists(TestDataManager1.class));
+ assertTrue(c.dataManagerExists(TestDataManager2.class));
+ assertFalse(c.dataManagerExists(TestDataManager3A.class));
+ assertFalse(c.dataManagerExists(TestDataManager3B.class));
+ assertFalse(c.dataManagerExists(TestDataManager4A.class));
+ }));
- pluginDataBuilder.addTestDataManager("dm3B", () -> new TestDataManager3B());
+ // show ordering restrictions are enforced
+ pluginDataBuilder.addTestDataManagerPlan("dm3B", new TestDataManagerPlan(1, (c) -> {
+ assertTrue(c.dataManagerExists(TestDataManager1.class));
+ assertTrue(c.dataManagerExists(TestDataManager2.class));
+ assertTrue(c.dataManagerExists(TestDataManager3A.class));
+ assertFalse(c.dataManagerExists(TestDataManager3B.class));
+ assertFalse(c.dataManagerExists(TestDataManager4A.class));
+ }));
- pluginDataBuilder.addTestDataManagerPlan("dm3B", new TestDataManagerPlan(4, (c) -> {
- ContractException contractException = assertThrows(ContractException.class, () -> c.getDataManager(null));
- assertEquals(NucleusError.NULL_DATA_MANAGER_CLASS, contractException.getErrorType());
+ // show ordering restrictions are enforced
+ pluginDataBuilder.addTestDataManagerPlan("dm4A", new TestDataManagerPlan(1, (c) -> {
+ assertTrue(c.dataManagerExists(TestDataManager1.class));
+ assertTrue(c.dataManagerExists(TestDataManager2.class));
+ assertTrue(c.dataManagerExists(TestDataManager3A.class));
+ assertTrue(c.dataManagerExists(TestDataManager3B.class));
+ assertFalse(c.dataManagerExists(TestDataManager4A.class));
}));
// build the action plugin
- testPluginData = pluginDataBuilder.build();
- testPlugin = TestPlugin.getTestPlugin(testPluginData);
+ TestPluginData testPluginData = pluginDataBuilder.build();
+
+ Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
// execute the engine
TestSimulation.builder().addPlugin(testPlugin).build().execute();
@@ -233,7 +367,6 @@ public void testAddPlan_Consumer() {
// test preconditions
pluginDataBuilder.addTestDataManager("dm", () -> new TestDataManager1());
-
/*
* Have the actor add a plan and show that that plan executes
*/
@@ -268,7 +401,7 @@ public void testAddPlan_Consumer() {
.addPlugin(TestPlugin.getTestPlugin(TestPluginData.builder()//
.addTestDataManager("dm", () -> new TestDataManager1())
.addTestDataManagerPlan("dm", new TestDataManagerPlan(0, (c) -> {
- c.addPlan(null,0);
+ c.addPlan(null, 0);
})).build()))//
.build()//
.execute();//
@@ -281,7 +414,8 @@ public void testAddPlan_Consumer() {
.addPlugin(TestPlugin.getTestPlugin(TestPluginData.builder()//
.addTestDataManager("dm", () -> new TestDataManager1())
.addTestDataManagerPlan("dm", new TestDataManagerPlan(0, (c) -> {
- c.addPlan((c2) -> {},-10);
+ c.addPlan((c2) -> {
+ }, -10);
})).build()))//
.build()//
.execute();//
@@ -296,7 +430,8 @@ public void testAddPlan_Consumer() {
.addTestDataManager("dm", () -> new TestDataManager1())
.addTestDataManagerPlan("dm", new TestDataManagerPlan(0, (c) -> {
c.subscribeToSimulationClose(c2 -> {
- c2.addPlan((c3) -> {},0);
+ c2.addPlan((c3) -> {
+ }, 0);
});
})).build()))//
.build()//
@@ -304,7 +439,6 @@ public void testAddPlan_Consumer() {
});
assertEquals(NucleusError.PLANNING_QUEUE_CLOSED, contractException.getErrorType());
-
}
@Test
@@ -557,6 +691,10 @@ private static class TestEvent1 implements Event {
}
+ private static class TestDataManager0 extends DataManager {
+
+ }
+
private static class TestDataManager1 extends TestDataManager {
}
@@ -583,6 +721,14 @@ private static class TestDataManager4A extends TestDataManager4 {
}
+ private static class TestDataManager4B extends TestDataManager4 {
+
+ }
+
+ private static class TestDataManager5 extends DataManager {
+
+ }
+
@Test
@UnitTestMethod(target = DataManagerContext.class, name = "actorExists", args = { ActorId.class })
public void testActorExists() {
diff --git a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java
index 6551a2ae2..ff511fd34 100644
--- a/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java
+++ b/simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/nucleus/AT_ReportContext.java
@@ -1,6 +1,7 @@
package gov.hhs.aspr.ms.gcm.simulation.nucleus;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -56,6 +57,10 @@ private static class TestDataManager4A extends TestDataManager4 {
}
+ private static class TestDataManager4B extends TestDataManager4 {
+
+ }
+
/*
* Executes the simulation by adding TestReport that executes the give consumer
* in a task planned at time zero. Also adds a TestActor with a task scheduled
@@ -143,18 +148,18 @@ public void testAddPlan_Consumer() {
}));
assertEquals(NucleusError.PAST_PLANNING_TIME, contractException.getErrorType());
- // precondition test : if the plan is added to the simulation after event processing is finished
+ // precondition test : if the plan is added to the simulation after event
+ // processing is finished
contractException = assertThrows(ContractException.class, () -> testConsumer((c) -> {
c.addPlan(new ConsumerReportPlan(0, (c1) -> {
- c1.subscribeToSimulationClose((c2->{
- c2.addPlan(c3->{},0);
+ c1.subscribeToSimulationClose((c2 -> {
+ c2.addPlan(c3 -> {
+ }, 0);
}));
}));
}));
assertEquals(NucleusError.PLANNING_QUEUE_CLOSED, contractException.getErrorType());
-
-
}
@Test
@@ -215,7 +220,6 @@ public void testAddPlan_Plan() {
// show that the last two passive plans did not execute
assertEquals(expectedOutput, actualOuput);
-
ContractException contractException = assertThrows(ContractException.class, () -> testConsumer((c) -> {
c.addPlan(null);
}));
@@ -235,38 +239,33 @@ public void testAddPlan_Plan() {
}));
assertEquals(NucleusError.INVALID_PLAN_ARRIVAL_ID, contractException.getErrorType());
- // precondition test : if the plan is added to the simulation after event processing is finished
+ // precondition test : if the plan is added to the simulation after event
+ // processing is finished
contractException = assertThrows(ContractException.class, () -> testConsumer((c) -> {
c.addPlan(new ConsumerReportPlan(0, (c1) -> {
- c1.subscribeToSimulationClose((c2->{
- c2.addPlan(new ConsumerReportPlan(0,(c3->{})));
+ c1.subscribeToSimulationClose((c2 -> {
+ c2.addPlan(new ConsumerReportPlan(0, (c3 -> {
+ })));
}));
}));
}));
assertEquals(NucleusError.PLANNING_QUEUE_CLOSED, contractException.getErrorType());
}
- @Test
- @UnitTestMethod(target = ReportContext.class, name = "getDataManager", args = { Class.class })
- public void testGetDataManager() {
+ private void executeGetDataManagerTest(Consumer consumer) {
+
// create the test plugin data builder
TestPluginData.Builder pluginDataBuilder = TestPluginData.builder();
- // create a data manager for the report to find
+ // create a data manager for the actor to find
pluginDataBuilder.addTestDataManager("dm1", () -> new TestDataManager1());
pluginDataBuilder.addTestDataManager("dm3A", () -> new TestDataManager3A());
pluginDataBuilder.addTestDataManager("dm3B", () -> new TestDataManager3B());
pluginDataBuilder.addTestDataManager("dm4A", () -> new TestDataManager4A());
- pluginDataBuilder.addTestReportPlan("report", new TestReportPlan(0, (c) -> {
- c.getDataManager(TestDataManager1.class);
- c.getDataManager(TestDataManager3A.class);
- c.getDataManager(TestDataManager3B.class);
- c.getDataManager(TestDataManager4A.class);
- }));
-
- pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(Double.POSITIVE_INFINITY, (c) -> {
+ pluginDataBuilder.addTestReportPlan("report", new TestReportPlan(0, consumer));
+ pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(1, (c) -> {
}));
// build the action plugin
@@ -274,39 +273,86 @@ public void testGetDataManager() {
Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
TestSimulation.builder().addPlugin(testPlugin).build().execute();
+ }
+
+ @Test
+ @UnitTestMethod(target = ReportContext.class, name = "getDataManager", args = { Class.class })
+ public void testGetDataManager() {
+ // postcondition test:
+ executeGetDataManagerTest((c) -> {
+ assertNotNull(c.getDataManager(TestDataManager1.class));
+ assertNotNull(c.getDataManager(TestDataManager3A.class));
+ assertNotNull(c.getDataManager(TestDataManager3B.class));
+ assertNotNull(c.getDataManager(TestDataManager4A.class));
+ assertNotNull(c.getDataManager(TestDataManager4.class));
+ });
+
+ // precondition test: if the class reference is null
+ ContractException contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest((c) -> {
+ c.getDataManager(null);
+ });
+ });
+ assertEquals(NucleusError.NULL_DATA_MANAGER_CLASS, contractException.getErrorType());
+
+ // precondition test: if the class reference is null
+ contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest((c) -> {
+ c.getDataManager(TestDataManager3.class);
+ });
+ });
+ assertEquals(NucleusError.AMBIGUOUS_DATA_MANAGER_CLASS, contractException.getErrorType());
+
+ // precondition test: if the class reference is unknown
+ contractException = assertThrows(ContractException.class, () -> {
+ executeGetDataManagerTest((c) -> {
+ c.getDataManager(TestDataManager4B.class);
+ });
+ });
+ assertEquals(NucleusError.UNKNOWN_DATA_MANAGER, contractException.getErrorType());
+
+ }
- // precondition test : if the class reference is ambiguous
+ @Test
+ @UnitTestMethod(target = ReportContext.class, name = "dataManagerExists", args = { Class.class })
+ public void testDataManagerExists() {
+ // create the test plugin data builder
+ TestPluginData.Builder pluginDataBuilder = TestPluginData.builder();
+
+ // create a data manager for the report to find
+
+ pluginDataBuilder.addTestDataManager("dm1", () -> new TestDataManager1());
pluginDataBuilder.addTestDataManager("dm3A", () -> new TestDataManager3A());
pluginDataBuilder.addTestDataManager("dm3B", () -> new TestDataManager3B());
+ pluginDataBuilder.addTestDataManager("dm4A", () -> new TestDataManager4A());
- // show that ambiguous class matching throws an exception
pluginDataBuilder.addTestReportPlan("report", new TestReportPlan(0, (c) -> {
- ContractException contractException = assertThrows(ContractException.class,
- () -> c.getDataManager(TestDataManager3.class));
- assertEquals(NucleusError.AMBIGUOUS_DATA_MANAGER_CLASS, contractException.getErrorType());
- }));
+ // show that the explicit class references return true
+ c.getDataManager(TestDataManager1.class);
+ c.getDataManager(TestDataManager3A.class);
+ c.getDataManager(TestDataManager3B.class);
+ c.getDataManager(TestDataManager4A.class);
- pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(Double.POSITIVE_INFINITY, (c) -> {
- }));
+ // show that zero class matching returns false
+ assertFalse(c.dataManagerExists(TestDataManager4B.class));
- // build the action plugin
- testPluginData = pluginDataBuilder.build();
- testPlugin = TestPlugin.getTestPlugin(testPluginData);
+ // show that ambiguous class matching returns false
+ assertFalse(c.dataManagerExists(TestDataManager3.class));
- TestSimulation.builder().addPlugin(testPlugin).build().execute();
+ // show that a null yields a false
+ assertFalse(c.dataManagerExists(null));
- // Precondition test 2
- pluginDataBuilder.addTestReportPlan("report", new TestReportPlan(0, (c) -> {
- ContractException contractException = assertThrows(ContractException.class, () -> c.getDataManager(null));
- assertEquals(NucleusError.NULL_DATA_MANAGER_CLASS, contractException.getErrorType());
}));
+
pluginDataBuilder.addTestActorPlan("actor", new TestActorPlan(Double.POSITIVE_INFINITY, (c) -> {
}));
+
// build the action plugin
- testPluginData = pluginDataBuilder.build();
- testPlugin = TestPlugin.getTestPlugin(testPluginData);
+ TestPluginData testPluginData = pluginDataBuilder.build();
+ Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
TestSimulation.builder().addPlugin(testPlugin).build().execute();
+
}
@Test