@Test public void verifyAssociationsPersistenceOnDissociation() throws Exception { // Unit test for #579 // One target manager => write associations. String targetId_1 = this.mngr.createTarget("id: t1\nhandler: h"); String targetId_2 = this.mngr.createTarget("id: t2\nhandler: h"); TestApplication app = new TestApplication(); String path = InstanceHelpers.computeInstancePath(app.getMySqlVm()); this.mngr.associateTargetWith(targetId_1, app, null); this.mngr.associateTargetWith(targetId_2, app, path); Assert.assertEquals(targetId_1, this.mngr.findTargetId(app, null, true)); Assert.assertEquals(targetId_2, this.mngr.findTargetId(app, path, true)); // Create another manager and verify the associations ITargetsMngr newMngr = new TargetsMngrImpl(this.configurationMngr); Assert.assertEquals(targetId_1, newMngr.findTargetId(app, null, true)); Assert.assertEquals(targetId_2, newMngr.findTargetId(app, path, true)); // Now, dissociate target_2 and the root instance this.mngr.dissociateTargetFrom(app, path); Assert.assertEquals(targetId_1, this.mngr.findTargetId(app, null, true)); Assert.assertNull(this.mngr.findTargetId(app, path, true)); // Create another manager and verify the associations newMngr = new TargetsMngrImpl(this.configurationMngr); Assert.assertEquals(targetId_1, newMngr.findTargetId(app, null, true)); Assert.assertNull(newMngr.findTargetId(app, path, true)); }
@Test public void testRestoreInstances_nonNullNonMatchingHandler() throws Exception { // Prepare stuff INotificationMngr notificationMngr = Mockito.mock(INotificationMngr.class); IRandomMngr randomMngr = Mockito.mock(IRandomMngr.class); IMessagingMngr messagingMngr = Mockito.mock(IMessagingMngr.class); ITargetConfigurator targetConfigurator = Mockito.mock(ITargetConfigurator.class); ITargetsMngr targetsMngr = Mockito.mock(ITargetsMngr.class); Mockito.when( targetsMngr.findRawTargetProperties( Mockito.any(Application.class), Mockito.anyString())) .thenReturn(new HashMap<String, String>(0)); IConfigurationMngr configurationMngr = new ConfigurationMngrImpl(); configurationMngr.setWorkingDirectory(this.folder.newFolder()); final TargetHandler targetHandlerArgument = Mockito.mock(TargetHandler.class); Mockito.when(targetHandlerArgument.getTargetId()).thenReturn("some target id"); final TargetHandler targetHandler = Mockito.mock(TargetHandler.class); Mockito.when(targetHandler.getTargetId()).thenReturn("some other target id"); IInstancesMngr mngr = new InstancesMngrImpl( messagingMngr, notificationMngr, targetsMngr, randomMngr, targetConfigurator); ((InstancesMngrImpl) mngr) .setTargetHandlerResolver( new TestTargetResolver() { @Override public TargetHandler findTargetHandler(Map<String, String> targetProperties) throws TargetException { return targetHandler; } }); TestApplication app = new TestApplication(); ManagedApplication ma = new ManagedApplication(app); // One scoped instance has a machine ID (considered as running somewhere) app.getMySqlVm().data.put(Instance.MACHINE_ID, "machine-id"); // Try to restore instances mngr.restoreInstanceStates(ma, targetHandlerArgument); // The handler's ID did not match => no restoration and no use of other mocks Mockito.verify(targetsMngr, Mockito.only()) .findRawTargetProperties(Mockito.eq(app), Mockito.anyString()); Mockito.verify(targetHandler, Mockito.only()).getTargetId(); Mockito.verify(targetHandlerArgument, Mockito.only()).getTargetId(); Mockito.verifyZeroInteractions(messagingMngr); Mockito.verifyZeroInteractions(randomMngr); // No notification was sent since there was no change on Tomcat instances Mockito.verifyZeroInteractions(notificationMngr); Mockito.verifyZeroInteractions(targetConfigurator); }
@Test public void testRestoreInstances_rightHandler_vmNotRunning() throws Exception { // Prepare stuff Map<String, String> targetProperties = new HashMap<>(0); INotificationMngr notificationMngr = Mockito.mock(INotificationMngr.class); IRandomMngr randomMngr = Mockito.mock(IRandomMngr.class); IMessagingMngr messagingMngr = Mockito.mock(IMessagingMngr.class); ITargetConfigurator targetConfigurator = Mockito.mock(ITargetConfigurator.class); ITargetsMngr targetsMngr = Mockito.mock(ITargetsMngr.class); Mockito.when( targetsMngr.findRawTargetProperties( Mockito.any(Application.class), Mockito.anyString())) .thenReturn(targetProperties); IConfigurationMngr configurationMngr = new ConfigurationMngrImpl(); configurationMngr.setWorkingDirectory(this.folder.newFolder()); final TargetHandler targetHandlerArgument = Mockito.mock(TargetHandler.class); Mockito.when(targetHandlerArgument.getTargetId()).thenReturn("some target id"); IInstancesMngr mngr = new InstancesMngrImpl( messagingMngr, notificationMngr, targetsMngr, randomMngr, targetConfigurator); ((InstancesMngrImpl) mngr) .setTargetHandlerResolver( new TestTargetResolver() { @Override public TargetHandler findTargetHandler(Map<String, String> targetProperties) throws TargetException { return targetHandlerArgument; } }); TestApplication app = new TestApplication(); ManagedApplication ma = new ManagedApplication(app); // One scoped instance has a machine ID (considered as running somewhere) app.getMySqlVm().data.put(Instance.MACHINE_ID, "machine-id"); // Try to restore instances Assert.assertEquals(InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus()); app.getMySqlVm().setStatus(InstanceStatus.DEPLOYED_STARTED); Mockito.when( targetHandlerArgument.isMachineRunning( Mockito.any(TargetHandlerParameters.class), Mockito.eq("machine-id"))) .thenReturn(false); mngr.restoreInstanceStates(ma, targetHandlerArgument); Assert.assertEquals(InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus()); // The handler's ID matched and the VM is NOT running => no message was sent. Mockito.verify(targetsMngr, Mockito.only()) .findRawTargetProperties(Mockito.eq(app), Mockito.anyString()); Mockito.verify(targetHandlerArgument, Mockito.times(1)) .isMachineRunning(Mockito.any(TargetHandlerParameters.class), Mockito.eq("machine-id")); Mockito.verifyZeroInteractions(messagingMngr); Mockito.verifyZeroInteractions(randomMngr); Mockito.verifyZeroInteractions(targetConfigurator); // A notification was sent for the instance whose state changed Mockito.verify(notificationMngr) .instance(Mockito.any(Instance.class), Mockito.eq(app), Mockito.eq(EventType.CHANGED)); }
@Test public void testTargetsLocking_whenCreatingMachines_withExceptionInDeploy() throws Exception { // Prepare stuff INotificationMngr notificationMngr = Mockito.mock(INotificationMngr.class); ITargetsMngr targetsMngr = Mockito.mock(ITargetsMngr.class); IRandomMngr randomMngr = Mockito.mock(IRandomMngr.class); ITargetConfigurator targetConfigurator = Mockito.mock(ITargetConfigurator.class); IMessagingMngr messagingMngr = Mockito.mock(IMessagingMngr.class); Mockito.when(messagingMngr.getMessagingClient()).thenReturn(Mockito.mock(IDmClient.class)); IConfigurationMngr configurationMngr = new ConfigurationMngrImpl(); configurationMngr.setWorkingDirectory(this.folder.newFolder()); final TargetHandler targetHandler = Mockito.mock(TargetHandler.class); Mockito.when(targetHandler.createMachine(Mockito.any(TargetHandlerParameters.class))) .thenThrow(new TargetException("for test")); IInstancesMngr mngr = new InstancesMngrImpl( messagingMngr, notificationMngr, targetsMngr, randomMngr, targetConfigurator); ((InstancesMngrImpl) mngr) .setTargetHandlerResolver( new TestTargetResolver() { @Override public TargetHandler findTargetHandler(Map<String, String> targetProperties) throws TargetException { return targetHandler; } }); TestApplication app = new TestApplication(); ManagedApplication ma = new ManagedApplication(app); // We will try to create a machine. It will fail. // We must be sure the lock was acquired, and that it was released. final AtomicBoolean acquired = new AtomicBoolean(false); final AtomicBoolean released = new AtomicBoolean(false); Mockito.when(targetsMngr.lockAndGetTarget(app, app.getMySqlVm())) .thenAnswer( new Answer<Map<String, String>>() { @Override public Map<String, String> answer(InvocationOnMock invocation) throws Throwable { acquired.set(true); Map<String, String> result = new HashMap<>(0); return result; } }); Mockito.doAnswer( new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { released.set(true); return null; } }) .when(targetsMngr) .unlockTarget(app, app.getMySqlVm()); // Let's run assertions now Assert.assertFalse(acquired.get()); Assert.assertFalse(released.get()); Assert.assertEquals(InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus()); try { mngr.changeInstanceState(ma, app.getMySqlVm(), InstanceStatus.DEPLOYED_STARTED); Assert.fail("A target exception was expected."); } catch (Exception e) { // nothing } Assert.assertEquals(InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus()); Assert.assertTrue(acquired.get()); Assert.assertTrue(released.get()); // Since the handler failed, nothing was scheduled for post-configuration Mockito.verifyZeroInteractions(targetConfigurator); }
@Test public void testTargetsLocking_whenCreatingMachines_noException() throws Exception { // Prepare stuff INotificationMngr notificationMngr = Mockito.mock(INotificationMngr.class); ITargetsMngr targetsMngr = Mockito.mock(ITargetsMngr.class); IRandomMngr randomMngr = Mockito.mock(IRandomMngr.class); ITargetConfigurator targetConfigurator = Mockito.mock(ITargetConfigurator.class); IMessagingMngr messagingMngr = Mockito.mock(IMessagingMngr.class); Mockito.when(messagingMngr.getMessagingClient()).thenReturn(Mockito.mock(IDmClient.class)); IConfigurationMngr configurationMngr = new ConfigurationMngrImpl(); configurationMngr.setWorkingDirectory(this.folder.newFolder()); IInstancesMngr mngr = new InstancesMngrImpl( messagingMngr, notificationMngr, targetsMngr, randomMngr, targetConfigurator); ((InstancesMngrImpl) mngr).setTargetHandlerResolver(new TestTargetResolver()); TestApplication app = new TestApplication(); ManagedApplication ma = new ManagedApplication(app); // We want to make sure target locking is correctly invoked by the instances manager. // So, we store requests to lock or unlock a target for a given instance. final Map<Instance, Integer> instancePathToLock = new HashMap<>(); Mockito.when(targetsMngr.lockAndGetTarget(app, app.getMySqlVm())) .thenAnswer( new Answer<Map<String, String>>() { @Override public Map<String, String> answer(InvocationOnMock invocation) throws Throwable { Instance inst = invocation.getArgumentAt(1, Instance.class); Integer count = instancePathToLock.get(inst); count = count == null ? 1 : count + 1; instancePathToLock.put(inst, count); Map<String, String> result = new HashMap<>(0); return result; } }); Mockito.doAnswer( new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Instance inst = invocation.getArgumentAt(1, Instance.class); Integer count = instancePathToLock.get(inst); count = count == null ? 0 : count - 1; if (count > 0) instancePathToLock.put(inst, count); else instancePathToLock.remove(inst); return null; } }) .when(targetsMngr) .unlockTarget(app, app.getMySqlVm()); // Let's run assertions now Assert.assertEquals(0, instancePathToLock.size()); Assert.assertEquals(InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus()); mngr.changeInstanceState(ma, app.getMySqlVm(), InstanceStatus.DEPLOYED_STARTED); Assert.assertEquals(1, instancePathToLock.size()); Integer lockCount = instancePathToLock.get(app.getMySqlVm()); Assert.assertNotNull(lockCount); Assert.assertEquals(1, lockCount.intValue()); Assert.assertEquals(InstanceStatus.DEPLOYING, app.getMySqlVm().getStatus()); Mockito.verify(targetConfigurator) .reportCandidate(Mockito.any(TargetHandlerParameters.class), Mockito.eq(app.getMySqlVm())); // Release the machine mngr.changeInstanceState(ma, app.getMySqlVm(), InstanceStatus.NOT_DEPLOYED); Assert.assertEquals(InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus()); Assert.assertEquals(0, instancePathToLock.size()); }