/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.communication.nodeproperties.internal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import java.util.Arrays; import java.util.Collection; import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Test; import de.rcenvironment.core.communication.api.NodeIdentifierService; import de.rcenvironment.core.communication.common.IdentifierException; import de.rcenvironment.core.communication.common.InstanceNodeSessionId; import de.rcenvironment.core.communication.common.NodeIdentifierTestUtils; import de.rcenvironment.core.communication.configuration.NodeConfigurationService; import de.rcenvironment.core.communication.nodeproperties.NodePropertiesService; import de.rcenvironment.core.communication.nodeproperties.NodeProperty; import de.rcenvironment.core.communication.nodeproperties.spi.NodePropertiesChangeListener; import de.rcenvironment.core.communication.nodeproperties.spi.RawNodePropertiesChangeListener; import de.rcenvironment.core.communication.testutils.AbstractVirtualInstanceTest; import de.rcenvironment.core.communication.testutils.TestConfiguration; import de.rcenvironment.core.communication.testutils.VirtualInstance; import de.rcenvironment.core.communication.transport.virtual.VirtualTransportTestConfiguration; import de.rcenvironment.core.utils.common.StringUtils; /** * Tests {@link NodePropertiesService} update propagation between two {@link VirtualInstance}s. * * @author Robert Mischke */ public class NodePropertiesServiceImplTest extends AbstractVirtualInstanceTest { private static final String TEST_PROPERTY_KEY_A = "a"; /** * A wait time im msec that must be larger than the time over which node property updates are aggegated in the tested service. */ private static final int WAIT_TIME_FOR_UPDATE_AGGREGATION = 400; /** * Common setup. */ @Before public void setup() { NodeIdentifierTestUtils.resetTestNodeIdentifierService(false); } /** * Common teardown. */ @After public void teardown() { NodeIdentifierTestUtils.resetTestNodeIdentifierService(true); } /** * Verifies that display name mappings are separated between virtual instances, and name associations are registered on both sides when * connecting. * * @throws Exception none expected */ @Test public void testDisplayNamePropagationOnConnect() throws Exception { setupInstances(2, true, true); final VirtualInstance instanceA = testTopology.getInstance(0); final VirtualInstance instanceB = testTopology.getInstance(1); final NodeIdentifierService nodeIdentifierServiceA = instanceA.getService(NodeIdentifierService.class); final NodeIdentifierService nodeIdentifierServiceB = instanceB.getService(NodeIdentifierService.class); nodeIdentifierServiceA.printAllNameAssociations(System.out, "Name mappings of instance A:"); nodeIdentifierServiceB.printAllNameAssociations(System.out, "Name mappings of instance B:"); assertNull(rawDisplayNameOfFirstAsSeenFromSecond(instanceA, instanceB)); assertNull(rawDisplayNameOfFirstAsSeenFromSecond(instanceB, instanceA)); log.debug("Connnecting virtual test instances"); testTopology.connectAndWait(0, 1, DEFAULT_NODE_REACHABILITY_TIMEOUT); nodeIdentifierServiceA.printAllNameAssociations(System.out, "Name mappings of instance A:"); nodeIdentifierServiceB.printAllNameAssociations(System.out, "Name mappings of instance B:"); assertEquals(getDisplayNameOf(instanceA), rawDisplayNameOfFirstAsSeenFromSecond(instanceA, instanceB)); assertEquals(getDisplayNameOf(instanceB), rawDisplayNameOfFirstAsSeenFromSecond(instanceB, instanceA)); } /** * Verifies that property deletions/removals are properly propagated, and are correctly combined with following updates. * * @throws Exception on unexpected errors */ @Test public void testNullHandlingInUpdatePropagation() throws Exception { setupInstances(2, true, true); final VirtualInstance instanceA = testTopology.getInstance(0); final VirtualInstance instanceB = testTopology.getInstance(1); final NodePropertiesService serviceA = instanceA.getNodePropertiesService(); final NodePropertiesService serviceB = instanceB.getNodePropertiesService(); serviceB.addRawNodePropertiesChangeListener(new RawNodePropertiesChangeListener() { @Override public void onRawNodePropertiesAddedOrModified(Collection<? extends NodeProperty> newProperties) { log.debug("'RawNodePropertiesAddedOrModified' listener callback: " + Arrays.toString(newProperties.toArray())); } }); instanceB.injectService(NodePropertiesChangeListener.class, new NodePropertiesChangeListener() { @Override public void onReachableNodePropertiesChanged(Collection<? extends NodeProperty> addedProperties, Collection<? extends NodeProperty> updatedProperties, Collection<? extends NodeProperty> removedProperties) { log.debug(StringUtils.format("Added: %d, Updated: %d, Removed: %d", addedProperties.size(), updatedProperties.size(), removedProperties.size())); } @Override public void onNodePropertyMapsOfNodesChanged(Map<InstanceNodeSessionId, Map<String, String>> updatedPropertyMaps) { log.debug("Node property maps of these nodes changed: " + updatedPropertyMaps.keySet()); } }); Map<InstanceNodeSessionId, Map<String, String>> allPropertiesAtB; final InstanceNodeSessionId nodeIdOfA = instanceA.getInstanceNodeSessionId(); log.debug("Connnecting virtual test instances"); testTopology.connectAndWait(0, 1, DEFAULT_NODE_REACHABILITY_TIMEOUT); log.info("Setup complete, beginning actual node property tests"); serviceA.addOrUpdateLocalNodeProperty(TEST_PROPERTY_KEY_A, "1"); Thread.sleep(WAIT_TIME_FOR_UPDATE_AGGREGATION); allPropertiesAtB = serviceB.getAllNodeProperties(); assertEquals("1", allPropertiesAtB.get(nodeIdOfA).get(TEST_PROPERTY_KEY_A)); serviceA.addOrUpdateLocalNodeProperty(TEST_PROPERTY_KEY_A, "2"); serviceA.addOrUpdateLocalNodeProperty(TEST_PROPERTY_KEY_A, null); Thread.sleep(WAIT_TIME_FOR_UPDATE_AGGREGATION); allPropertiesAtB = serviceB.getAllNodeProperties(); assertEquals(null, allPropertiesAtB.get(nodeIdOfA).get(TEST_PROPERTY_KEY_A)); // TODO review: should the behavior be changed to remove keys on null value? - misc_ro // assertFalse(allPropertiesAtB.get(nodeIdOfA).containsKey(TEST_PROPERTY_KEY_A)); serviceA.addOrUpdateLocalNodeProperty(TEST_PROPERTY_KEY_A, "3"); serviceA.addOrUpdateLocalNodeProperty(TEST_PROPERTY_KEY_A, null); serviceA.addOrUpdateLocalNodeProperty(TEST_PROPERTY_KEY_A, "4"); Thread.sleep(WAIT_TIME_FOR_UPDATE_AGGREGATION); allPropertiesAtB = serviceB.getAllNodeProperties(); assertEquals("4", allPropertiesAtB.get(nodeIdOfA).get(TEST_PROPERTY_KEY_A)); } @Override protected TestConfiguration defineTestConfiguration() { return new VirtualTransportTestConfiguration(true); } private String getDisplayNameOf(VirtualInstance instance) { return instance.getService(NodeConfigurationService.class).getInitialNodeInformation().getDisplayName(); } private String rawDisplayNameOfFirstAsSeenFromSecond(VirtualInstance virtualInstanceX, VirtualInstance virtualInstanceY) throws IdentifierException { return virtualInstanceY.getService(NodeIdentifierService.class) .parseInstanceNodeSessionIdString(virtualInstanceX.getInstanceNodeSessionId().getInstanceNodeSessionIdString()) .getRawAssociatedDisplayName(); } }