/**
* Copyright 2014-2017 Linagora, Université Joseph Fourier, Floralis
*
* The present code is developed in the scope of the joint LINAGORA -
* Université Joseph Fourier - Floralis research program and is designated
* as a "Result" pursuant to the terms and conditions of the LINAGORA
* - Université Joseph Fourier - Floralis research program. Each copyright
* holder of Results enumerated here above fully & independently holds complete
* ownership of the complete Intellectual Property rights applicable to the whole
* of said Results, and may freely exploit it in any manner which does not infringe
* the moral rights of the other copyright holders.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.roboconf.dm.management.legacy;
import static net.roboconf.core.Constants.LOCAL_RESOURCE_PREFIX;
import static net.roboconf.core.Constants.PROJECT_DIR_DESC;
import static net.roboconf.core.Constants.PROJECT_DIR_GRAPH;
import static net.roboconf.core.Constants.PROJECT_FILE_DESCRIPTOR;
import static net.roboconf.core.Constants.SCOPED_SCRIPT_AT_AGENT_SUFFIX;
import static net.roboconf.core.Constants.SCOPED_SCRIPT_AT_DM_CONFIGURE_SUFFIX;
import static net.roboconf.core.Constants.TARGET_INSTALLER;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
import net.roboconf.core.internal.tests.TestApplication;
import net.roboconf.core.internal.tests.TestUtils;
import net.roboconf.core.model.ApplicationTemplateDescriptor;
import net.roboconf.core.model.beans.ApplicationTemplate;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.utils.Utils;
import net.roboconf.dm.internal.environment.messaging.DmMessageProcessor;
import net.roboconf.dm.internal.test.TestManagerWrapper;
import net.roboconf.dm.internal.test.TestTargetResolver;
import net.roboconf.dm.internal.utils.ConfigurationUtils;
import net.roboconf.dm.management.ManagedApplication;
import net.roboconf.dm.management.Manager;
import net.roboconf.dm.management.events.IDmListener;
import net.roboconf.dm.management.exceptions.AlreadyExistingException;
import net.roboconf.dm.management.exceptions.ImpossibleInsertionException;
import net.roboconf.dm.management.exceptions.UnauthorizedActionException;
import net.roboconf.messaging.api.MessagingConstants;
import net.roboconf.messaging.api.internal.client.test.TestClient;
import net.roboconf.messaging.api.messages.Message;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifHeartbeat;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifMachineDown;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdRemoveInstance;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdResynchronize;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdSetScopedInstance;
import net.roboconf.target.api.TargetHandler;
import net.roboconf.target.api.TargetHandlerParameters;
/**
* @author Vincent Zurczak - Linagora
* @author Pierre Bourret - Université Joseph Fourier
*/
public class ManagerBasicsTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private Manager manager;
private TestManagerWrapper managerWrapper;
private TestClient msgClient;
private TestTargetResolver targetResolver;
@Before
public void resetManager() throws Exception {
File directory = this.folder.newFolder();
resetManager( directory );
}
private void resetManager( File directory ) throws Exception {
this.targetResolver = new TestTargetResolver();
this.manager = new Manager();
this.manager.setTargetResolver( this.targetResolver );
this.manager.configurationMngr().setWorkingDirectory( directory );
this.manager.setMessagingType( MessagingConstants.FACTORY_TEST );
this.manager.start();
// Register mocked listeners - mainly for code coverage reasons
this.manager.listenerAppears( Mockito.mock( IDmListener.class ));
// Create the wrapper
this.managerWrapper = new TestManagerWrapper( this.manager );
this.managerWrapper.configureMessagingForTest();
this.manager.reconfigure();
this.msgClient = (TestClient) this.managerWrapper.getInternalMessagingClient();
this.msgClient.clearMessages();
// Disable the messages timer for predictability
TestUtils.getInternalField( this.manager, "timer", Timer.class ).cancel();
}
@After
public void stopManager() throws Exception {
this.manager.stop();
// Some tests create a new manager, which save instances
// at the current project's root when it is stopped.
File dir = new File( "./applications" );
Utils.deleteFilesRecursively( dir );
}
@Test
public void testStop() throws Exception {
Timer timer = TestUtils.getInternalField( this.manager, "timer", Timer.class );
Assert.assertNotNull( timer );
this.manager.stop();
timer = TestUtils.getInternalField( this.manager, "timer", Timer.class );
Assert.assertNull( timer );
this.manager.stop();
Assert.assertNull( timer );
}
@Test
public void testStop_invalidConfiguration() throws Exception {
this.manager = new Manager();
this.manager.configurationMngr().setWorkingDirectory( this.folder.newFolder());
this.managerWrapper = new TestManagerWrapper( this.manager );
Timer timer = TestUtils.getInternalField( this.manager, "timer", Timer.class );
Assert.assertNull( timer );
this.manager.stop();
timer = TestUtils.getInternalField( this.manager, "timer", Timer.class );
Assert.assertNull( timer );
}
@Test
public void testStop_messagingException() throws Exception {
this.msgClient.failSubscribing.set( true );
this.msgClient.failClosingConnection.set( true );
Timer timer = TestUtils.getInternalField( this.manager, "timer", Timer.class );
Assert.assertNotNull( timer );
this.manager.stop();
timer = TestUtils.getInternalField( this.manager, "timer", Timer.class );
Assert.assertNull( timer );
}
@Test( expected = ImpossibleInsertionException.class )
public void testAddInstance_impossibleInsertion_rootInstance() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
String existingInstanceName = app.getMySqlVm().getName();
this.manager.instancesMngr().addInstance( ma, null, new Instance( existingInstanceName ));
}
@Test( expected = ImpossibleInsertionException.class )
public void testAddInstance_impossibleInsertion_childInstance() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
String existingInstanceName = app.getMySql().getName();
this.manager.instancesMngr().addInstance( ma, app.getMySqlVm(), new Instance( existingInstanceName ));
}
@Test
public void testAddInstance_successRoot() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
Assert.assertEquals( 2, app.getRootInstances().size());
Instance newInstance = new Instance( "mail-vm" ).component( app.getMySqlVm().getComponent());
this.manager.instancesMngr().addInstance( ma, null, newInstance );
Assert.assertEquals( 3, app.getRootInstances().size());
Assert.assertTrue( app.getRootInstances().contains( newInstance ));
}
@Test( expected = IOException.class )
public void testAddInstance_invalidConfiguration() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
Assert.assertEquals( 2, app.getRootInstances().size());
Instance newInstance = new Instance( "mail-vm" ).component( app.getMySqlVm().getComponent());
this.manager = new Manager();
this.managerWrapper = new TestManagerWrapper( this.manager );
this.managerWrapper.addManagedApplication( ma );
this.manager.instancesMngr().addInstance( ma, null, newInstance );
}
@Test
public void testAddInstance_successChild() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
// Insert a MySQL instance under the Tomcat VM
Assert.assertEquals( 1, app.getTomcatVm().getChildren().size());
Instance newInstance = new Instance( app.getMySql().getName()).component( app.getMySql().getComponent());
this.manager.instancesMngr().addInstance( ma, app.getTomcatVm(), newInstance );
Assert.assertEquals( 2, app.getTomcatVm().getChildren().size());
Assert.assertTrue( app.getTomcatVm().getChildren().contains( newInstance ));
}
@Test( expected = UnauthorizedActionException.class )
public void testRemoveInstance_unauthorized() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
app.getMySql().setStatus( InstanceStatus.DEPLOYED_STARTED );
this.manager.instancesMngr().removeInstance( ma, app.getMySqlVm());
}
@Test
public void testRemoveInstance_success_1() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
Assert.assertEquals( 2, app.getRootInstances().size());
Assert.assertEquals( 0, ma.getScopedInstanceToAwaitingMessages().size());
this.manager.instancesMngr().removeInstance( ma, app.getTomcatVm());
Assert.assertEquals( 1, app.getRootInstances().size());
Assert.assertEquals( app.getMySqlVm(), app.getRootInstances().iterator().next());
Assert.assertEquals( 1, ma.getScopedInstanceToAwaitingMessages().size());
List<Message> messages = ma.getScopedInstanceToAwaitingMessages().get( app.getTomcatVm());
Assert.assertEquals( 1, messages.size());
Assert.assertEquals( MsgCmdRemoveInstance.class, messages.get( 0 ).getClass());
Assert.assertEquals(
InstanceHelpers.computeInstancePath( app.getTomcatVm()),
((MsgCmdRemoveInstance) messages.get( 0 )).getInstancePath());
}
@Test
public void testRemoveInstance_success_2() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
app.getTomcatVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
Assert.assertEquals( 2, app.getRootInstances().size());
Assert.assertEquals( 0, ma.getScopedInstanceToAwaitingMessages().size());
this.manager.instancesMngr().removeInstance( ma, app.getTomcat());
Assert.assertEquals( 2, app.getRootInstances().size());
Assert.assertEquals( app.getMySqlVm(), app.getRootInstances().iterator().next());
Assert.assertEquals( 1, this.msgClient.allSentMessages.size());
Assert.assertEquals( MsgCmdRemoveInstance.class, this.msgClient.allSentMessages.get( 0 ).getClass());
MsgCmdRemoveInstance msg = (MsgCmdRemoveInstance) this.msgClient.allSentMessages.get( 0 );
Assert.assertEquals( InstanceHelpers.computeInstancePath( app.getTomcat()), msg.getInstancePath());
}
@Test( expected = IOException.class )
public void testRemoveInstance_invalidConfiguration() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
app.getTomcatVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
Assert.assertEquals( 2, app.getRootInstances().size());
Assert.assertEquals( 0, ma.getScopedInstanceToAwaitingMessages().size());
this.manager = new Manager();
this.manager.configurationMngr().setWorkingDirectory( this.folder.newFolder());
this.managerWrapper = new TestManagerWrapper( this.manager );
this.managerWrapper.addManagedApplication( ma );
this.manager.instancesMngr().removeInstance( ma, app.getTomcat());
}
@Test
public void testCreateApplication_withTags() throws Exception {
File directory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( directory.exists());
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.assertNotNull( tpl );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.managerWrapper.getNameToManagedApplication().size());
ManagedApplication ma = this.manager.applicationMngr().createApplication( "toto", "desc", tpl.getName(), tpl.getQualifier());
Assert.assertNotNull( ma );
Assert.assertEquals( 1, this.managerWrapper.getNameToManagedApplication().size());
Assert.assertEquals( ma.getDirectory().getName(), ma.getName());
Assert.assertEquals( "toto", ma.getName());
File expected = new File( this.manager.configurationMngr().getWorkingDirectory(), ConfigurationUtils.APPLICATIONS );
Assert.assertEquals( expected, ma.getDirectory().getParentFile());
}
@Test( expected = AlreadyExistingException.class )
public void testCreateApplication_conflict() throws Exception {
File directory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( directory.exists());
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.assertNotNull( tpl );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.managerWrapper.getNameToManagedApplication().size());
ManagedApplication ma = this.manager.applicationMngr().createApplication( "toto", "desc", tpl.getName(), tpl.getQualifier());
Assert.assertNotNull( ma );
Assert.assertEquals( 1, this.managerWrapper.getNameToManagedApplication().size());
this.manager.applicationMngr().createApplication( "toto", "desc", tpl );
}
@Test
public void testLoadNewApplication_success() throws Exception {
File directory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( directory.exists());
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.assertNotNull( tpl );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.managerWrapper.getNameToManagedApplication().size());
ManagedApplication ma = this.manager.applicationMngr().createApplication( "toto", "desc", tpl );
Assert.assertNotNull( ma );
Assert.assertEquals( 1, this.managerWrapper.getNameToManagedApplication().size());
Assert.assertEquals( ma.getDirectory().getName(), ma.getName());
Assert.assertEquals( "toto", ma.getApplication().getName());
File expected = new File( this.manager.configurationMngr().getWorkingDirectory(), ConfigurationUtils.APPLICATIONS );
Assert.assertEquals( expected, ma.getDirectory().getParentFile());
}
@Test
public void testLoadNewApplication_targetConflict() throws Exception {
// Copy an application and add it a target.properties
File firstDirectory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( firstDirectory.exists());
File directory = this.folder.newFolder();
Utils.copyDirectory( firstDirectory, directory );
File targetDir = new File( directory, PROJECT_DIR_GRAPH + "/VM" );
Assert.assertTrue( targetDir.mkdir());
String content = "id = test-target-conflict\nhandler: whatever";
Utils.writeStringInto( content, new File( targetDir, "target.properties" ));
// Load the template once
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.manager.targetsMngr().listAllTargets().size());
ApplicationTemplate tpl1 = this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.assertNotNull( tpl1 );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 1, this.manager.targetsMngr().listAllTargets().size());
// Update the source directory (change the application name, but keep the target properties).
// So, we have two templates that share a same target properties => conflict.
File f = new File( directory, PROJECT_DIR_DESC + "/" + PROJECT_FILE_DESCRIPTOR );
ApplicationTemplateDescriptor desc = ApplicationTemplateDescriptor.load( f );
desc.setName( "abcdefghijklmnopqrstuvwxyz" );
ApplicationTemplateDescriptor.save( f, desc );
// Load the new application: it should fail
try {
this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.fail( "An exception was expected here." );
} catch( Exception e ) {
// nothing
}
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 1, this.manager.targetsMngr().listAllTargets().size());
}
@Test
public void testLoadNewApplication_deleteIt_redeployIt_success() throws Exception {
// Copy an application and add it a target.properties
File firstDirectory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( firstDirectory.exists());
File directory = this.folder.newFolder();
Utils.copyDirectory( firstDirectory, directory );
File targetDir = new File( directory, PROJECT_DIR_GRAPH + "/VM" );
Assert.assertTrue( targetDir.mkdir());
String content = "id = test-target\nhandler: whatever";
Utils.writeStringInto( content, new File( targetDir, "target.properties" ));
// Deploy the template
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.manager.targetsMngr().listAllTargets().size());
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.assertNotNull( tpl );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 1, this.manager.targetsMngr().listAllTargets().size());
// Undeploy it
this.manager.applicationTemplateMngr().deleteApplicationTemplate( tpl.getName(), tpl.getQualifier());
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 1, this.manager.targetsMngr().listAllTargets().size());
// Update a little bit the target properties
content = "id = test-target\nhandler: whatever2";
Utils.writeStringInto( content, new File( targetDir, "target.properties" ));
// Deploy it again.
// We should not have any conflict related to the target.
tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.assertNotNull( tpl );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 1, this.manager.targetsMngr().listAllTargets().size());
// Undeploy it, again
this.manager.applicationTemplateMngr().deleteApplicationTemplate( tpl.getName(), tpl.getQualifier());
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 1, this.manager.targetsMngr().listAllTargets().size());
// Change the target ID
content = "id = test-other-target\nhandler: whatever2";
Utils.writeStringInto( content, new File( targetDir, "target.properties" ));
// Deploy it again.
// We should not have any conflict (different target ID).
tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.assertNotNull( tpl );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 2, this.manager.targetsMngr().listAllTargets().size());
}
@Test
public void testLoadNewApplication_withTargets_invalidAppLocation() throws Exception {
// Copy an application and add it a target.properties
File firstDirectory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( firstDirectory.exists());
File normalTplDirectory = ConfigurationUtils.findTemplateDirectory(
new ApplicationTemplate( "Legacy LAMP" ).qualifier( "sample" ),
this.manager.configurationMngr().getWorkingDirectory());
File directory = new File( normalTplDirectory, "intermediate/subdir" );
Assert.assertTrue( directory.mkdirs());
Utils.copyDirectory( firstDirectory, directory );
File targetDir = new File( directory, PROJECT_DIR_GRAPH + "/VM" );
Assert.assertTrue( targetDir.mkdir());
String content = "id = test-target-conflict\nhandler: whatever";
Utils.writeStringInto( content, new File( targetDir, "target.properties" ));
// Load the template.
// It should fail, since it is located under the directory where the DM would save it.
// We want to verify that the targets loaded from this template are correctly unregistered.
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.manager.targetsMngr().listAllTargets().size());
try {
this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
Assert.fail( "An exception was expected here." );
} catch( Exception e ) {
// nothing
}
// No target and template were registered
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.manager.targetsMngr().listAllTargets().size());
}
@Test
public void testLoadApplicationTemplate_invalidConfiguration() throws Exception {
this.manager = new Manager();
this.manager.configurationMngr().setWorkingDirectory( this.folder.newFolder());
this.managerWrapper = new TestManagerWrapper( this.manager );
// No messaging is configured
try {
this.manager.messagingMngr().checkMessagingConfiguration();
Assert.fail( "The configuration is supposed to be invalid." );
} catch( IOException e ) {
// nothing
}
File directory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( directory.exists());
this.manager.applicationTemplateMngr().loadApplicationTemplate( directory );
}
@Test
public void testConfigurationChanged_withApps_noInstanceDeployed() throws Exception {
// Copy an application in the configuration
File source = TestUtils.findApplicationDirectory( "lamp" );
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( source );
this.manager.applicationMngr().createApplication( "lamp3", "test", tpl );
// Reset the manager's configuration (simply reload it)
this.manager.reconfigure();
this.manager.messagingMngr().checkMessagingConfiguration();
// Check there is an application
Assert.assertEquals( 1, this.managerWrapper.getNameToManagedApplication().size());
ManagedApplication ma = this.managerWrapper.getNameToManagedApplication().get( "lamp3" );
Assert.assertNotNull( ma );
Assert.assertEquals( 3, ma.getApplication().getRootInstances().size());
Assert.assertEquals( 6, InstanceHelpers.getAllInstances( ma.getApplication()).size());
for( Instance inst : InstanceHelpers.getAllInstances( ma.getApplication()))
Assert.assertEquals( InstanceStatus.NOT_DEPLOYED, inst.getStatus());
}
@Test
public void testConfigurationChanged_andShutdown_withApps_withInstances() throws Exception {
// Copy an application in the configuration
File source = TestUtils.findApplicationDirectory( "lamp" );
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( source );
ManagedApplication ma = this.manager.applicationMngr().createApplication( "lamp", "test", tpl );
Instance apache = InstanceHelpers.findInstanceByPath( ma.getApplication(), "/Apache VM" );
Assert.assertNotNull( apache );
String path = InstanceHelpers.computeInstancePath( apache );
// Make sure the VM is considered as deployed in the pseudo-IaaS
TargetHandler th = this.targetResolver.findTargetHandler( new HashMap<String,String>( 0 ));
Assert.assertNotNull( th );
th.createMachine( new TargetHandlerParameters().scopedInstancePath( path ).applicationName( ma.getName()));
// Update the instances
apache.data.put( Instance.IP_ADDRESS, "192.168.1.23" );
apache.data.put( Instance.MACHINE_ID, path );
apache.data.put( "whatever", "something" );
apache.setStatus( InstanceStatus.PROBLEM );
// Save the manager's state
this.manager.stop();
// Reset the manager (reload the configuration)
this.manager.reconfigure();
// Check there is the right application
Assert.assertEquals( 1, this.managerWrapper.getNameToManagedApplication().size());
ma = this.managerWrapper.getNameToManagedApplication().get( "lamp" );
Assert.assertNotNull( ma );
Assert.assertEquals( 3, ma.getApplication().getRootInstances().size());
Assert.assertEquals( 6, InstanceHelpers.getAllInstances( ma.getApplication()).size());
for( Instance inst : InstanceHelpers.getAllInstances( ma.getApplication())) {
if( ! inst.equals( apache ))
Assert.assertEquals( InstanceStatus.NOT_DEPLOYED, inst.getStatus());
}
apache = InstanceHelpers.findInstanceByPath( ma.getApplication(), "/Apache VM" );
Assert.assertEquals( "192.168.1.23", apache.data.get( Instance.IP_ADDRESS ));
Assert.assertEquals( path, apache.data.get( Instance.MACHINE_ID ));
Assert.assertEquals( "something", apache.data.get( "whatever" ));
Assert.assertEquals( ma.getName(), apache.data.get( Instance.APPLICATION_NAME ));
}
@Test
public void testResynchronizeAgents_withConnection() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.manager.instancesMngr().resynchronizeAgents( ma );
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
app.getTomcatVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYING );
this.manager.instancesMngr().resynchronizeAgents( ma );
Assert.assertEquals( 1, this.msgClient.allSentMessages.size());
Assert.assertEquals( MsgCmdResynchronize.class, this.msgClient.allSentMessages.get( 0 ).getClass());
this.msgClient.allSentMessages.clear();
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
this.manager.instancesMngr().resynchronizeAgents( ma );
Assert.assertEquals( 2, this.msgClient.allSentMessages.size());
Assert.assertEquals( MsgCmdResynchronize.class, this.msgClient.allSentMessages.get( 0 ).getClass());
Assert.assertEquals( MsgCmdResynchronize.class, this.msgClient.allSentMessages.get( 1 ).getClass());
}
@Test( expected = IOException.class )
public void testResynchronizeAgents_noConnection() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.getMessagingClient().closeConnection();
app.getTomcatVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
this.manager.instancesMngr().resynchronizeAgents( ma );
}
@Test( expected = IOException.class )
public void testResynchronizeAgents_invalidConfiguration() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
app.getTomcatVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
this.manager = new Manager();
this.manager.configurationMngr().setWorkingDirectory( this.folder.newFolder());
this.managerWrapper = new TestManagerWrapper( this.manager );
this.manager.instancesMngr().resynchronizeAgents( ma );
}
@Test
public void testMsgNotifHeartbeat_requestModel() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
this.msgClient.allSentMessages.clear();
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
MsgNotifHeartbeat msg = new MsgNotifHeartbeat( app.getName(), app.getMySqlVm(), "192.168.1.45" );
msg.setModelRequired( true );
this.managerWrapper.getMessagingClient().getMessageProcessor().storeMessage( msg );
Thread.sleep( 100 );
Assert.assertEquals( 1, this.msgClient.allSentMessages.size());
Message sentMessage = this.msgClient.allSentMessages.get( 0 );
Assert.assertEquals( MsgCmdSetScopedInstance.class, sentMessage.getClass());
Assert.assertNotNull(((MsgCmdSetScopedInstance) sentMessage).getScopedInstance());
}
@Test
public void testMsgNotifHeartbeat_requestModel_nonRoot() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
this.msgClient.allSentMessages.clear();
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
// War is not a target / scoped instance: nothing will happen
MsgNotifHeartbeat msg = new MsgNotifHeartbeat( app.getName(), app.getWar(), "192.168.1.45" );
msg.setModelRequired( true );
this.managerWrapper.getMessagingClient().getMessageProcessor().storeMessage( msg );
Thread.sleep( 100 );
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
// Let's try again, but we change the WAR installer
app.getWar().getComponent().installerName( TARGET_INSTALLER );
this.managerWrapper.getMessagingClient().getMessageProcessor().storeMessage( msg );
Thread.sleep( 100 );
Assert.assertEquals( 1, this.msgClient.allSentMessages.size());
Message sentMessage = this.msgClient.allSentMessages.get( 0 );
Assert.assertEquals( MsgCmdSetScopedInstance.class, sentMessage.getClass());
Assert.assertNotNull(((MsgCmdSetScopedInstance) sentMessage).getScopedInstance());
}
@Test
public void applicationsShouldBeDeletedEvenWhenNoMessagingServer() throws Exception {
this.manager = new Manager();
this.manager.configurationMngr().setWorkingDirectory( this.folder.newFolder());
this.managerWrapper = new TestManagerWrapper( this.manager );
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
Assert.assertEquals( 0, this.managerWrapper.getNameToManagedApplication().size());
this.managerWrapper.addManagedApplication( ma );
Assert.assertEquals( 1, this.managerWrapper.getNameToManagedApplication().size());
try {
this.manager.messagingMngr().checkMessagingConfiguration();
Assert.fail( "An exception should have been thrown, there is no messaging server in this test!" );
} catch( Exception e ) {
// ignore
}
this.manager.applicationMngr().deleteApplication( ma );
Assert.assertEquals( 0, this.managerWrapper.getNameToManagedApplication().size());
}
@Test
public void testSomeGetters() throws Exception {
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertNull( this.manager.applicationMngr().findApplicationByName( "invalid" ));
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
Assert.assertEquals( app, this.manager.applicationMngr().findApplicationByName( app.getName()));
}
@Test
public void verifyMsgNotifMachineDown_allowsRedeployment() throws Exception {
// Prepare the model
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
this.managerWrapper.addManagedApplication( ma );
String targetId = this.manager.targetsMngr().createTarget( "id: tid\nhandler: h" );
this.manager.targetsMngr().associateTargetWith( targetId, app, null );
// Try a first deployment
Assert.assertEquals( InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus());
this.manager.instancesMngr().deployAndStartAll( ma, app.getMySqlVm());
Assert.assertEquals( InstanceStatus.DEPLOYING, app.getMySqlVm().getStatus());
// Simulate the incoming of a heart beat message
DmMessageProcessor processor = (DmMessageProcessor) this.managerWrapper.getMessagingClient().getMessageProcessor();
processor.processMessage( new MsgNotifHeartbeat( app.getName(), app.getMySqlVm(), "127.0.0.1" ));
Assert.assertEquals( InstanceStatus.DEPLOYED_STARTED, app.getMySqlVm().getStatus());
// Simulate the incoming of a "machine down" notification
processor.processMessage( new MsgNotifMachineDown( app.getName(), app.getMySqlVm()));
Assert.assertEquals( InstanceStatus.NOT_DEPLOYED, app.getMySqlVm().getStatus());
// Try to redeploy: it should work (no remains of the previous attempt)
this.manager.instancesMngr().deployAndStartAll( ma, app.getMySqlVm());
Assert.assertEquals( InstanceStatus.DEPLOYING, app.getMySqlVm().getStatus());
}
@Test
public void verifyApplicationWithRandomVariables_load() throws Exception {
// Deploy the template
File dir = TestUtils.findApplicationDirectory( "app-with-random-ports" );
Assert.assertTrue( dir.isDirectory());
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( dir );
Assert.assertNotNull( tpl );
Instance instance1 = InstanceHelpers.findInstanceByPath( tpl, "/vm/container1" );
Assert.assertNotNull( instance1 );
// No value set for random values in templates
Assert.assertNull( InstanceHelpers.findAllExportedVariables( instance1 ).get( "Container1.httpPort" ));
// Create an application
ManagedApplication app1 = this.manager.applicationMngr().createApplication( "app1", "", tpl );
Assert.assertNotNull( app1 );
instance1 = InstanceHelpers.findInstanceByPath( app1.getApplication(), "/vm/container1" );
Assert.assertNotNull( instance1 );
// Random values are set in applications
Assert.assertEquals( "10000", InstanceHelpers.findAllExportedVariables( instance1 ).get( "Container1.ajpPort" ));
Assert.assertEquals( "10001", InstanceHelpers.findAllExportedVariables( instance1 ).get( "Container1.httpPort" ));
// Verify the 2nd container
Instance instance2 = InstanceHelpers.findInstanceByPath( app1.getApplication(), "/vm/container2" );
Assert.assertNotNull( instance2 );
// This value is not generated since it was set manually in the instances definition
Assert.assertEquals( "45012", InstanceHelpers.findAllExportedVariables( instance2 ).get( "Container2.port" ));
}
@Test
public void verifyApplicationWithRandomVariables_restore() throws Exception {
// Deploy and validate
verifyApplicationWithRandomVariables_load();
// Stop the manager
this.manager.stop();
// Reset it (except the configuration directory!)
resetManager( this.manager.configurationMngr().getWorkingDirectory());
// Verify what was restored.
// We expect the same ports than before.
ManagedApplication app1 = this.managerWrapper.getNameToManagedApplication().get( "app1" );
Assert.assertNotNull( app1 );
Instance instance1 = InstanceHelpers.findInstanceByPath( app1.getApplication(), "/vm/container1" );
Assert.assertNotNull( instance1 );
Assert.assertEquals( "10000", InstanceHelpers.findAllExportedVariables( instance1 ).get( "Container1.ajpPort" ));
Assert.assertEquals( "10001", InstanceHelpers.findAllExportedVariables( instance1 ).get( "Container1.httpPort" ));
Instance instance2 = InstanceHelpers.findInstanceByPath( app1.getApplication(), "/vm/container2" );
Assert.assertNotNull( instance2 );
Assert.assertEquals( "45012", InstanceHelpers.findAllExportedVariables( instance2 ).get( "Container2.port" ));
}
@Test
public void testTargetScriptsChain() throws Exception {
// We need to add targets
File originalDirectory = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( originalDirectory.exists());
File directoryCopy = this.folder.newFolder();
Utils.copyDirectory( originalDirectory, directoryCopy );
File targetDir = new File( directoryCopy, PROJECT_DIR_GRAPH + "/VM" );
Assert.assertTrue( targetDir.mkdir());
Assert.assertTrue( new File( targetDir, "apple/lib" ).mkdirs());
Assert.assertTrue( new File( targetDir, "oops" ).mkdir());
Utils.writeStringInto( "id: apple\nhandler: h", new File( targetDir, "apple.properties" ));
Utils.writeStringInto( "", new File( targetDir, "apple/" + SCOPED_SCRIPT_AT_AGENT_SUFFIX + "sh" ));
Utils.writeStringInto( "", new File( targetDir, "apple/" + LOCAL_RESOURCE_PREFIX + "-" + SCOPED_SCRIPT_AT_DM_CONFIGURE_SUFFIX + "sh" ));
Utils.writeStringInto( "", new File( targetDir, "apple/lib/apple2.properties" ));
Utils.writeStringInto( "id: oops\nhandler: h", new File( targetDir, "oops.properties" ));
Utils.writeStringInto( "", new File( targetDir, "oops/oops.sh" ));
// Load the application template
Assert.assertEquals( 0, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 0, this.manager.targetsMngr().listAllTargets().size());
ApplicationTemplate tpl = this.manager.applicationTemplateMngr().loadApplicationTemplate( directoryCopy );
Assert.assertEquals( 1, this.manager.applicationTemplateMngr().getApplicationTemplates().size());
Assert.assertEquals( 2, this.manager.targetsMngr().listAllTargets().size());
Assert.assertEquals( 2, this.manager.targetsMngr().listPossibleTargets( tpl ).size());
// Associate scoped instances with targets
this.manager.targetsMngr().associateTargetWith( "apple", tpl, null );
this.manager.targetsMngr().associateTargetWith( "oops", tpl, "/MySQL VM" );
Assert.assertEquals( "apple", this.manager.targetsMngr().findTargetId( tpl, null ));
Assert.assertEquals( "oops", this.manager.targetsMngr().findTargetId( tpl, "/MySQL VM" ));
// Verify the resources sent to an agent
Map<String,byte[]> resources = this.manager.targetsMngr().findScriptResourcesForAgent( "apple" );
Assert.assertEquals( 2, resources.size());
Assert.assertNotNull( resources.get( SCOPED_SCRIPT_AT_AGENT_SUFFIX + "sh" ));
Assert.assertNotNull( resources.get( "lib/apple2.properties" ));
resources = this.manager.targetsMngr().findScriptResourcesForAgent( "oops" );
Assert.assertEquals( 1, resources.size());
Assert.assertNotNull( resources.get( "oops.sh" ));
// Verify the DM's scripts
File scriptFile = this.manager.targetsMngr().findScriptForDm( tpl, null );
Assert.assertNotNull( scriptFile );
Assert.assertTrue( scriptFile.exists());
Instance scopedInstance = InstanceHelpers.findInstanceByPath( tpl, "/MySQL VM" );
Assert.assertNotNull( scopedInstance );
scriptFile = this.manager.targetsMngr().findScriptForDm( tpl, scopedInstance );
Assert.assertNull( scriptFile );
}
}