package io.cattle.platform.ha.monitor.impl; import static io.cattle.platform.core.constants.CommonStatesConstants.*; import static io.cattle.platform.core.constants.ContainerEventConstants.*; import static io.cattle.platform.core.constants.InstanceConstants.*; import static org.junit.Assert.*; import io.cattle.platform.ha.monitor.model.KnownInstance; import io.cattle.platform.object.meta.impl.DefaultObjectMetaDataManager; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; public class PingInstancesMonitorImplTest { PingInstancesMonitorImpl monitor; Map<String, KnownInstance> knownInstances; Map<String, ReportedInstance> needsSynced; Map<String, String> syncActions; ReportedInstances reportedInstances; static final Set<String> restingStates = new HashSet<String>(); static { restingStates.add(STATE_RUNNING); restingStates.add(STATE_CREATED); restingStates.add(STATE_STOPPED); restingStates.add(REMOVED); } @Before public void setup() { monitor = new PingInstancesMonitorImpl(); monitor.objectMetaDataManager = new DefaultObjectMetaDataManager() { @Override public boolean isTransitioningState(Class<?> resourceType, String state) { return !restingStates.contains(state); } }; knownInstances = new HashMap<String, KnownInstance>(); needsSynced = new HashMap<String, ReportedInstance>(); syncActions = new HashMap<String, String>(); reportedInstances = new ReportedInstances(); } String setupSync(String key, boolean byExternalId, String knownInstanceState, String reportedInstanceState) { return setupSync(key, byExternalId, null, knownInstanceState, reportedInstanceState); } String setupSync(String key, boolean byExternalId, String instanceTriggeredStop, String knownInstanceState, String reportedInstanceState) { key = fullKey(key, byExternalId); String uuid = key + "-uuid"; String externalId = key + "-extid"; String instaceEid = byExternalId ? externalId : null; Date instanceRemoved = REMOVED.equals(knownInstanceState) ? new Date() : null; String reportedUuid = !byExternalId ? uuid : "garbage-" + key; if (knownInstanceState != null) addKnownInstance(uuid, instaceEid, knownInstanceState, instanceRemoved); if (reportedInstanceState != null) addReportedInstance(reportedUuid, externalId, reportedInstanceState); return externalId; } String fullKey(String key, boolean byExternalId) { StringBuilder fullKey = new StringBuilder(); fullKey.append("user-"); fullKey.append(key); if (byExternalId) fullKey.append("-byext"); else fullKey.append("-byuuid"); return fullKey.toString(); } String uuid(String key, boolean byExternalId) { String fullKey = fullKey(key, byExternalId); return fullKey + "-uuid"; } @Test public void testDetermineSyncActions() { // container running in rancher, stopped on host String externalIdA = setupSync("rancher-running-host-stopped", false, STATE_RUNNING, STATE_STOPPED); String externalIdC = setupSync("rancher-running-host-stopped", true, STATE_RUNNING, STATE_STOPPED); // Container running in rancher, not on host String externalIdD = setupSync("rancher-running-host-destroyed", false, STATE_RUNNING, null); String externalIdE = setupSync("rancher-running-host-destroyed", true, STATE_RUNNING, null); // Container stopped in rancher, running on host String externalIdH = setupSync("rancher-stopped-host-running", false, STATE_STOPPED, STATE_RUNNING); String externalIdI = setupSync("rancher-stopped-host-running", true, STATE_STOPPED, STATE_RUNNING); // Container stopped in rancher, destroyed on host String externalIdK = setupSync("rancher-stopped-host-destroyed", false, STATE_STOPPED, null); String externalIdL = setupSync("rancher-stopped-host-destroyed", true, STATE_STOPPED, null); String uuidK = uuid("rancher-stopped-host-destroyed", false); // Container removed in rancher, running on host. Action: force stop String externalIdO = setupSync("rancher-removed-host-running", false, REMOVED, STATE_RUNNING); String externalIdP = setupSync("rancher-removed-host-running", true, REMOVED, STATE_RUNNING); // Container removed in rancher, stopped on host. Action: do nothing String externalIdS = setupSync("rancher-removed-host-stopped", false, REMOVED, STATE_STOPPED); String externalIdT = setupSync("rancher-removed-host-stopped", true, REMOVED, STATE_STOPPED); String uuidS = uuid("rancher-removed-host-stopped", false); String uuidT = uuid("rancher-removed-host-stopped", false); // Container removed in rancher, removed on host, by uuid. Action: do nothing String externalIdW = setupSync("rancher-removed-host-removed", false, REMOVED, null); String externalIdX = setupSync("rancher-removed-host-removed", true, REMOVED, null); String uuidW = uuid("rancher-removed-host-stopped", false); String uuidX = uuid("rancher-removed-host-stopped", false); // Container doesn't exist in rancher, running on host String externalIdAA = setupSync("rancher-notexist-host-running", false, null, STATE_RUNNING); // no-op start String externalIdBB = setupSync("rancher-notexist-host-running", true, null, STATE_RUNNING); // no-op start // Container doesn't exist in rancher, stopped on host. User containers will be created via no-op start and be stopped in subsequent ping String externalIdEE = setupSync("rancher-notexist-host-stopped", false, null, STATE_STOPPED); // no-op start String externalIdFF = setupSync("rancher-notexist-host-stopped", true, null, STATE_STOPPED); // no-op start monitor.determineSyncActions(knownInstances, reportedInstances, needsSynced, syncActions, false); assertSyncAction(externalIdA, EVENT_STOP); assertSyncAction(externalIdC, EVENT_STOP); assertTrue(!needsSynced.containsKey(externalIdD)); assertSyncAction(externalIdE, EVENT_DESTROY); assertSyncAction(externalIdH, EVENT_START); assertSyncAction(externalIdI, EVENT_START); assertDoNothing(externalIdK, uuidK); assertSyncAction(externalIdL, EVENT_DESTROY); assertSyncAction(externalIdO, EVENT_INSTANCE_FORCE_STOP); assertSyncAction(externalIdP, EVENT_INSTANCE_FORCE_STOP); assertDoNothing(externalIdS, uuidS); assertDoNothing(externalIdT, uuidT); assertDoNothing(externalIdW, uuidW); assertDoNothing(externalIdX, uuidX); assertSyncAction(externalIdAA, EVENT_START); assertSyncAction(externalIdBB, EVENT_START); assertSyncAction(externalIdEE, EVENT_START); assertSyncAction(externalIdFF, EVENT_START); } void assertDoNothing(String externalId, String uuid) { assertTrue(!needsSynced.containsKey(externalId)); } void assertSyncAction(String externalId, String action) { assertTrue(needsSynced.containsKey(externalId)); assertEquals(action, syncActions.get(externalId)); } ReportedInstance addReportedInstance(String uuid, String externalId, String state) { ReportedInstance ri = new ReportedInstance(); ri.setExternalId(externalId); ri.setUuid(uuid); ri.setState(state); reportedInstances.byExternalId.put(externalId, ri); reportedInstances.byUuid.put(uuid, ri); return ri; } KnownInstance addKnownInstance(String uuid, String externalId, String state, Date removed) { KnownInstance ki = new KnownInstance(); ki.setExternalId(externalId); ki.setUuid(uuid); ki.setState(state); ki.setRemoved(removed); knownInstances.put(uuid, ki); return ki; } }