/**
* Copyright 2015-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.internal.api.impl;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
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.Constants;
import net.roboconf.core.internal.tests.TestApplication;
import net.roboconf.core.internal.tests.TestApplicationTemplate;
import net.roboconf.core.model.beans.Application;
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.model.runtime.TargetUsageItem;
import net.roboconf.core.model.runtime.TargetWrapperDescriptor;
import net.roboconf.core.utils.Utils;
import net.roboconf.dm.internal.utils.ConfigurationUtils;
import net.roboconf.dm.management.api.IConfigurationMngr;
import net.roboconf.dm.management.api.ITargetsMngr;
import net.roboconf.dm.management.exceptions.UnauthorizedActionException;
/**
* @author Vincent Zurczak - Linagora
* @author Amadou Diarraa - UGA
*/
public class TargetsMngrImplTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private ITargetsMngr mngr;
private IConfigurationMngr configurationMngr;
@Before
public void prepareMngr() throws Exception {
this.configurationMngr = Mockito.mock( IConfigurationMngr.class );
Mockito.when( this.configurationMngr.getWorkingDirectory()).thenReturn( this.folder.newFolder());
this.mngr = new TargetsMngrImpl( this.configurationMngr );
}
@Test
public void testNormalCrudScenarios() throws Exception {
Assert.assertNull( this.mngr.findRawTargetProperties( "whatever" ));
String targetId = this.mngr.createTarget( "id: tid\nprop: ok\nhandler: h" );
Assert.assertEquals( "tid", targetId );
String newTargetId = this.mngr.createTarget( "ok: ok\nid: tok\nhandler: h" );
Assert.assertNotNull( newTargetId );
String props = this.mngr.findRawTargetProperties( targetId );
Assert.assertEquals( "prop: ok\nhandler: h", props );
props = this.mngr.findRawTargetProperties( newTargetId );
Assert.assertEquals( "ok: ok\nhandler: h", props.trim());
this.mngr.updateTarget( targetId, "prop2: ko\nprop1: done\nhandler: ok" );
props = this.mngr.findRawTargetProperties( targetId );
Assert.assertEquals( "prop2: ko\nprop1: done\nhandler: ok", props );
// Missing handler
try {
this.mngr.updateTarget( targetId, "prop2: ko\nprop1: done" );
Assert.fail( "Update should have failed, the handler is missing." );
} catch( IOException e ) {
// nothing
}
props = this.mngr.findRawTargetProperties( targetId );
Assert.assertEquals( "prop2: ko\nprop1: done\nhandler: ok", props );
this.mngr.deleteTarget( targetId );
Assert.assertNull( this.mngr.findRawTargetProperties( targetId ));
}
@Test
public void testCreateTarget_targetIdIsRemovedCorrectly() throws Exception {
String[] properties = {
"id: tid\nprop: ok\nhandler: h\nprop-after: ok",
"id: tid\r\nprop: ok\nhandler: h\nprop-after: ok",
"prop: ok\nhandler: h\nprop-after: ok\nid = tid",
"prop: ok\nhandler: h\r\nprop-after: ok\r\nid :tid",
"prop: ok\nhandler: h\r\nprop-after: ok\r\nid :tid\n\n",
"prop: ok\r\nid :tid\nhandler: h\nprop-after: ok",
"prop: ok\r\nid :tid\nhandler: h\nprop-after: ok\n",
};
for( String s : properties ) {
String targetId = this.mngr.createTarget( s );
Assert.assertEquals( s, "tid", targetId );
Assert.assertEquals( 1, ((TargetsMngrImpl) this.mngr).targetIds.size());
String props = this.mngr.findRawTargetProperties( targetId );
Assert.assertEquals( s, "prop: ok\nhandler: h\nprop-after: ok", props.replace( "\r", "" ).trim());
this.mngr.deleteTarget( targetId );
Assert.assertEquals( 0, ((TargetsMngrImpl) this.mngr).targetIds.size());
}
}
@Test
public void testCreateTargetFromFile() throws Exception {
File f = this.folder.newFile("toto.properties");
Utils.writeStringInto( "id: tid\nprop: value\nhandler: h", f );
File targetDir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/tid" );
Assert.assertFalse( targetDir.exists());
String targetId = this.mngr.createTarget( f, null );
Assert.assertEquals( "tid", targetId );
Assert.assertTrue( targetDir.exists());
Assert.assertEquals( 1, targetDir.listFiles().length);
String props = this.mngr.findRawTargetProperties( targetId );
Assert.assertEquals( "prop: value\nhandler: h", props );
this.mngr.deleteTarget( targetId );
Assert.assertFalse( targetDir.exists());
Assert.assertNull( this.mngr.findRawTargetProperties( targetId ));
Assert.assertFalse( targetDir.exists());
}
@Test( expected = IOException.class )
public void testCreateTargetFromFile_noApplicationTemplate_conflict() throws Exception {
// Create a target
File f = this.folder.newFile("toto.properties");
try {
Utils.writeStringInto( "id: tid\nprop: value\nhandler: h", f );
File targetDir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/tid" );
Assert.assertFalse( targetDir.exists());
String targetId = this.mngr.createTarget( f, null );
Assert.assertEquals( "tid", targetId );
Assert.assertTrue( targetDir.exists());
Assert.assertEquals( 1, targetDir.listFiles().length);
} catch( Exception e ) {
Assert.fail( "No exception was expected here." );
}
// Recreate it => conflict
this.mngr.createTarget( f, null );
}
@Test
public void testCreateTargetFromFile_withApplicationTemplate_noConflict() throws Exception {
// Create a target
File f = this.folder.newFile("toto.properties");
TestApplicationTemplate tpl = new TestApplicationTemplate();
try {
Utils.writeStringInto( "id: tid\nprop: value\nhandler: h", f );
File targetDir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/tid" );
Assert.assertFalse( targetDir.exists());
String targetId = this.mngr.createTarget( f, tpl );
Assert.assertEquals( "tid", targetId );
Assert.assertTrue( targetDir.exists());
Assert.assertEquals( 2, targetDir.listFiles().length);
} catch( Exception e ) {
Assert.fail( "No exception was expected here." );
}
// Create it with the same template => no conflict
this.mngr.createTarget( f, tpl );
}
@Test( expected = IOException.class )
public void testCreateTargetFromFile_withApplicationTemplate_conflict() throws Exception {
// Create a target
File f = this.folder.newFile("toto.properties");
TestApplicationTemplate tpl1 = new TestApplicationTemplate();
try {
Utils.writeStringInto( "id: tid\nprop: value\nhandler: h", f );
File targetDir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/tid" );
Assert.assertFalse( targetDir.exists());
String targetId = this.mngr.createTarget( f, tpl1 );
Assert.assertEquals( "tid", targetId );
Assert.assertTrue( targetDir.exists());
Assert.assertEquals( 2, targetDir.listFiles().length);
} catch( Exception e ) {
Assert.fail( "No exception was expected here." );
}
// Create it from another template => conflict
TestApplicationTemplate tpl2 = new TestApplicationTemplate();
tpl2.setName( "whatever" );
this.mngr.createTarget( f, tpl2 );
}
@Test( expected = IOException.class )
public void testCreateTargetFromFile_mix_conflict() throws Exception {
// Create a target
File f = this.folder.newFile("toto.properties");
try {
Utils.writeStringInto( "id: tid\nprop: value\nhandler: h", f );
File targetDir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/tid" );
Assert.assertFalse( targetDir.exists());
String targetId = this.mngr.createTarget( f, null );
Assert.assertEquals( "tid", targetId );
Assert.assertTrue( targetDir.exists());
Assert.assertEquals( 1, targetDir.listFiles().length);
} catch( Exception e ) {
Assert.fail( "No exception was expected here." );
}
// Create it from another template => conflict
TestApplicationTemplate tpl2 = new TestApplicationTemplate();
this.mngr.createTarget( f, tpl2 );
}
@Test
public void testCreateTargetFromFileAndApplicationTemplate() throws Exception {
File f = this.folder.newFile("toto.properties");
Utils.writeStringInto( "id: tid\nprop: value\nhandler: h", f );
File targetDir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/tid" );
Assert.assertFalse( targetDir.exists());
String targetId = this.mngr.createTarget( f, new TestApplicationTemplate());
Assert.assertEquals( "tid", targetId );
Assert.assertTrue( targetDir.exists());
Assert.assertEquals( 2, targetDir.listFiles().length);
String props = this.mngr.findRawTargetProperties( targetId );
Assert.assertEquals( "prop: value\nhandler: h", props );
this.mngr.deleteTarget( targetId );
Assert.assertFalse( targetDir.exists());
Assert.assertNull( this.mngr.findRawTargetProperties( targetId ));
Assert.assertFalse( targetDir.exists());
}
@Test( expected = UnauthorizedActionException.class )
public void testUpdateTarget_whenTargetDoesNotExist() throws Exception {
this.mngr.updateTarget( "inexisting", "prop: ok\nhandler: h" );
}
@Test( expected = IllegalArgumentException.class )
public void testAssociateTargetWith_nonScopedInstance() throws Exception {
TestApplication app = new TestApplication();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySql());
String targetId = this.mngr.createTarget( "prop: ok\nid: abc\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, mySqlPath );
}
@Test( expected = IllegalArgumentException.class )
public void testDissociateTargetFrom_nonScopedInstance() throws Exception {
TestApplication app = new TestApplication();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySql());
this.mngr.dissociateTargetFrom( app, mySqlPath );
}
@Test( expected = IllegalArgumentException.class )
public void testFindTargetId_nonScopedInstance_strict() throws Exception {
TestApplication app = new TestApplication();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySql());
this.mngr.findTargetId( app, mySqlPath, true );
}
@Test( expected = IllegalArgumentException.class )
public void testFindTargetId_nonScopedInstance_notStrict() throws Exception {
TestApplication app = new TestApplication();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySql());
this.mngr.findTargetId( app, mySqlPath, false );
}
@Test
public void testAssociations() throws Exception {
TestApplication app = new TestApplication();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
String tomcatPath = InstanceHelpers.computeInstancePath( app.getTomcatVm());
// Only MySQL has an associated target
String targetId = this.mngr.createTarget( "prop: ok\nid: abc\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, mySqlPath );
String associatedId = this.mngr.findTargetId( app, mySqlPath );
Assert.assertEquals( targetId, associatedId );
// There is no value for Tomcat, nor default target for the application
Assert.assertNull( this.mngr.findTargetId( app, tomcatPath ));
// Let's define a default target for the whole application
String defaultTargetId = this.mngr.createTarget( "prop: ok\nid: def\nhandler: h" );
this.mngr.associateTargetWith( defaultTargetId, app, null );
associatedId = this.mngr.findTargetId( app, mySqlPath );
Assert.assertEquals( targetId, associatedId );
associatedId = this.mngr.findTargetId( app, mySqlPath, true );
Assert.assertEquals( targetId, associatedId );
associatedId = this.mngr.findTargetId( app, tomcatPath );
Assert.assertEquals( defaultTargetId, associatedId );
Assert.assertNull( this.mngr.findTargetId( app, tomcatPath, true ));
// Remove the custom association for MySQL
this.mngr.dissociateTargetFrom( app, mySqlPath );
associatedId = this.mngr.findTargetId( app, mySqlPath );
Assert.assertEquals( defaultTargetId, associatedId );
Assert.assertNull( this.mngr.findTargetId( app, mySqlPath, true ));
// Make sure we cannot delete a default target
this.mngr.dissociateTargetFrom( app, null );
associatedId = this.mngr.findTargetId( app, mySqlPath );
Assert.assertEquals( defaultTargetId, associatedId );
// Make sure we can override a default target
this.mngr.associateTargetWith( targetId, app, null );
associatedId = this.mngr.findTargetId( app, mySqlPath );
Assert.assertEquals( targetId, associatedId );
associatedId = this.mngr.findTargetId( app, tomcatPath );
Assert.assertEquals( targetId, associatedId );
}
@Test( expected = IOException.class )
public void testAssociationWithInvalidTargetId() throws Exception {
TestApplication app = new TestApplication();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
this.mngr.associateTargetWith( "invalid", app, mySqlPath );
}
@Test
public void testAssociationWithComponentName() throws Exception {
// Setup
TestApplication app = new TestApplication();
String componentName = "@" + app.getMySqlVm().getComponent().getName();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
String tomcatPath = InstanceHelpers.computeInstancePath( app.getTomcatVm());
// Create only an association with a component
String targetId = this.mngr.createTarget( "prop: ok\nid: abc\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, componentName );
Assert.assertNull( this.mngr.findTargetId( app, null, true ));
Assert.assertEquals( targetId, this.mngr.findTargetId( app, componentName, true ));
Assert.assertEquals( targetId, this.mngr.findTargetId( app, tomcatPath ));
Assert.assertNull( targetId, this.mngr.findTargetId( app, tomcatPath, true ));
Assert.assertEquals( targetId, this.mngr.findTargetId( app, mySqlPath ));
Assert.assertNull( targetId, this.mngr.findTargetId( app, mySqlPath, true ));
// Now, set a default target for the application and another one for a specific instance
String tid1 = this.mngr.createTarget( "prop: ok\nid: tid1\nhandler: h" );
String tid2 = this.mngr.createTarget( "prop: ok\nid: tid2\nhandler: h" );
this.mngr.associateTargetWith( tid1, app, null );
this.mngr.associateTargetWith( tid2, app, mySqlPath );
Assert.assertEquals( tid1, this.mngr.findTargetId( app, null ));
Assert.assertEquals( tid1, this.mngr.findTargetId( app, null, true ));
Assert.assertEquals( tid2, this.mngr.findTargetId( app, mySqlPath ));
Assert.assertEquals( tid2, this.mngr.findTargetId( app, mySqlPath, true ));
Assert.assertEquals( targetId, this.mngr.findTargetId( app, tomcatPath ));
Assert.assertNull( targetId, this.mngr.findTargetId( app, tomcatPath, true ));
Assert.assertEquals( targetId, this.mngr.findTargetId( app, componentName ));
Assert.assertEquals( targetId, this.mngr.findTargetId( app, componentName, true ));
// Dissociate the component and the target
this.mngr.dissociateTargetFrom( app, componentName );
Assert.assertEquals( tid1, this.mngr.findTargetId( app, null ));
Assert.assertEquals( tid1, this.mngr.findTargetId( app, null, true ));
Assert.assertEquals( tid2, this.mngr.findTargetId( app, mySqlPath ));
Assert.assertEquals( tid2, this.mngr.findTargetId( app, mySqlPath, true ));
// We inherit the default target
Assert.assertEquals( tid1, this.mngr.findTargetId( app, tomcatPath ));
Assert.assertNull( tid1, this.mngr.findTargetId( app, tomcatPath, true ));
// And no more binding for the component...
Assert.assertNull( targetId, this.mngr.findTargetId( app, componentName, true ));
// ... except it inherits the default application target.
Assert.assertEquals( tid1, this.mngr.findTargetId( app, componentName ));
}
@Test
public void testAssociationWithInvalidComponentName() throws Exception {
TestApplication app = new TestApplication();
String targetId = this.mngr.createTarget( "prop: ok\nid: abc\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, "@invalid" );
Assert.assertNull( this.mngr.findTargetId( app, null ));
Assert.assertNull( this.mngr.findTargetId( app, "@invalid", true ));
}
@Test
public void testAssociationWithInvalidInstancePath() throws Exception {
TestApplication app = new TestApplication();
String targetId = this.mngr.createTarget( "prop: ok\nid: abc\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, "/vm/invalid" );
Assert.assertNull( this.mngr.findTargetId( app, null ));
Assert.assertNull( this.mngr.findTargetId( app, "/vm/invalid" ));
}
@Test
public void testDisssociationWithInvalidTargetId() throws Exception {
TestApplication app = new TestApplication();
String mySqlPath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
// No association
this.mngr.dissociateTargetFrom( app, mySqlPath );
// No exception
}
@Test
public void testDisssociationWithInvalidInstancePath() throws Exception {
TestApplication app = new TestApplication();
// No association
this.mngr.dissociateTargetFrom( app, "/vm/invalid" );
// No exception
}
@Test( expected = UnauthorizedActionException.class )
public void testAssociations_onADeployedInstance() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
String targetId = this.mngr.createTarget( "prop: ok\nid: tid\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, instancePath );
}
@Test( expected = UnauthorizedActionException.class )
public void testDisssociations_onADeployedInstance() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
this.mngr.dissociateTargetFrom( app, instancePath );
}
@Test
public void testHints_noHint() throws Exception {
TestApplication app1 = new TestApplication();
app1.name( "app1" );
TestApplication app2 = new TestApplication();
app2.name( "app2" );
String t1 = this.mngr.createTarget( "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h" );
String t2 = this.mngr.createTarget( "id: t2\nprop: ok\nhandler: docker" );
List<TargetWrapperDescriptor> beans = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 2, beans.size());
TargetWrapperDescriptor b1 = beans.get( 0 );
Assert.assertEquals( t1, b1.getId());
Assert.assertEquals( "target 1", b1.getName());
Assert.assertEquals( "t1's target", b1.getDescription());
Assert.assertNotNull( b1.getHandler());
Assert.assertFalse( b1.isDefault());
TargetWrapperDescriptor b2 = beans.get( 1 );
Assert.assertEquals( t2, b2.getId());
Assert.assertEquals( "docker", b2.getHandler());
Assert.assertNull( b2.getName() );
Assert.assertNull( b2.getDescription());
Assert.assertFalse( b2.isDefault());
Assert.assertEquals( 2, this.mngr.listPossibleTargets( app2 ).size());
}
@Test
public void testHints_hintOnApplication() throws Exception {
TestApplication app1 = new TestApplication();
app1.name( "app1" );
TestApplication app2 = new TestApplication();
app2.name( "app2" );
String t1 = this.mngr.createTarget( "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h" );
String t2 = this.mngr.createTarget( "id: t2\nprop: ok\nhandler: docker" );
// Hint between app1 and t1.
// t1 has now a scope, which includes app1.
// Therefore, t1 should not be listed for app2 (not in the scope).
this.mngr.addHint( t1, app1 );
List<TargetWrapperDescriptor> beans = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 2, beans.size());
TargetWrapperDescriptor b1 = beans.get( 0 );
Assert.assertEquals( t1, b1.getId());
Assert.assertEquals( "target 1", b1.getName());
Assert.assertEquals( "t1's target", b1.getDescription());
Assert.assertNotNull( b1.getHandler());
Assert.assertFalse( b1.isDefault());
TargetWrapperDescriptor b2 = beans.get( 1 );
Assert.assertEquals( t2, b2.getId());
Assert.assertEquals( "docker", b2.getHandler());
Assert.assertNull( b2.getName());
Assert.assertNull( b2.getDescription());
Assert.assertFalse( b2.isDefault());
beans = this.mngr.listPossibleTargets( app2 );
Assert.assertEquals( 1, beans.size());
b2 = beans.get( 0 );
Assert.assertEquals( t2, b2.getId());
Assert.assertEquals( "docker", b2.getHandler());
Assert.assertNull( b2.getName());
Assert.assertNull( b2.getDescription());
Assert.assertFalse( b2.isDefault());
}
@Test
public void testHints_removeHintOnApplication() throws Exception {
TestApplication app1 = new TestApplication();
app1.name( "app1" );
TestApplication app2 = new TestApplication();
app2.name( "app2" );
String t1 = this.mngr.createTarget( "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h" );
String t2 = this.mngr.createTarget( "id: t2\nprop: ok\nhandler: docker\nhandler: h" );
// Hint between app1 and t1.
// t1 has now a scope, which includes app1.
// Therefore, t1 should not be listed for app2 (not in the scope).
this.mngr.addHint( t1, app1 );
List<TargetWrapperDescriptor> beans = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 2, beans.size());
beans = this.mngr.listPossibleTargets( app2 );
Assert.assertEquals( 1, beans.size());
// Remove the hint on the WRONG application => nothing changes
this.mngr.removeHint( t1, app2 );
beans = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 2, beans.size());
beans = this.mngr.listPossibleTargets( app2 );
Assert.assertEquals( 1, beans.size());
// Remove the hint on the WRONG application => nothing changes
this.mngr.removeHint( t2, app1 );
beans = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 2, beans.size());
beans = this.mngr.listPossibleTargets( app2 );
Assert.assertEquals( 1, beans.size());
// Remove the hint on the one we used
this.mngr.removeHint( t1, app1 );
beans = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 2, beans.size());
beans = this.mngr.listPossibleTargets( app2 );
Assert.assertEquals( 2, beans.size());
}
@Test
public void testHints_hintOnApplicationTemplate() throws Exception {
TestApplication app1 = new TestApplication();
app1.name( "app1" );
TestApplication app2 = new TestApplication();
app2.name( "app2" );
Application app3 = new Application( "app3", new ApplicationTemplate( "tpl" ).qualifier( "v1" ));
String t1 = this.mngr.createTarget( "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h" );
String t2 = this.mngr.createTarget( "id: t2\nprop: ok\nhandler: docker" );
// Hint between app1 and app2's template and t1.
// t1 has now a scope, which includes (indirectly) app1 and app2.
// Therefore, t1 should not be listed for app3 (not in the scope).
this.mngr.addHint( t1, app1.getTemplate());
List<TargetWrapperDescriptor> beans = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 2, beans.size());
TargetWrapperDescriptor b1 = beans.get( 0 );
Assert.assertEquals( t1, b1.getId());
Assert.assertEquals( "target 1", b1.getName());
Assert.assertEquals( "t1's target", b1.getDescription());
Assert.assertNotNull( b1.getHandler());
Assert.assertFalse( b1.isDefault());
TargetWrapperDescriptor b2 = beans.get( 1 );
Assert.assertEquals( t2, b2.getId());
Assert.assertEquals( "docker", b2.getHandler());
Assert.assertNull( b2.getName());
Assert.assertNull( b2.getDescription());
Assert.assertFalse( b2.isDefault());
List<TargetWrapperDescriptor> otherBeans = this.mngr.listPossibleTargets( app2 );
Assert.assertEquals( beans, otherBeans );
otherBeans = this.mngr.listPossibleTargets( app2.getTemplate());
Assert.assertEquals( beans, otherBeans );
beans = this.mngr.listPossibleTargets( app3 );
Assert.assertEquals( 1, beans.size());
b2 = beans.get( 0 );
Assert.assertEquals( t2, b2.getId());
Assert.assertEquals( "docker", b2.getHandler());
Assert.assertNull( b2.getName());
Assert.assertNull( b2.getDescription());
Assert.assertFalse( b2.isDefault());
}
@Test
public void testFindRawTargetProperties_noProperties() {
Assert.assertEquals( 0, this.mngr.findRawTargetProperties( new TestApplication(), "/whatever" ).size());
}
@Test
public void testFindRawTargetProperties_withProperties() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
String targetId = this.mngr.createTarget( "prop: ok\nid: tid\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, instancePath );
Map<String,String> props = this.mngr.findRawTargetProperties( app, instancePath );
Assert.assertEquals( 2, props.size());
Assert.assertEquals( "ok", props.get( "prop" ));
Assert.assertEquals( "h", props.get( "handler" ));
}
@Test
public void testRestoreCache() throws Exception {
Assert.assertEquals( 0, ((TargetsMngrImpl) this.mngr).targetIds.size());
Assert.assertEquals( "1", this.mngr.createTarget( "prop: ok\nid: 1\nhandler: h" ));
Assert.assertEquals( "2", this.mngr.createTarget( "prop: ok\nid: 2\nhandler: h" ));
Assert.assertEquals( "abc", this.mngr.createTarget( "prop: ok\nid: abc\nhandler: h" ));
Assert.assertEquals( "4", this.mngr.createTarget( "prop: ok\nid: 4\nhandler: h" ));
Assert.assertEquals( 4, ((TargetsMngrImpl) this.mngr).targetIds.size());
// Delete a valid and an invalid ones
this.mngr.deleteTarget( "abc" );
this.mngr.deleteTarget( "invalid-id" );
Assert.assertEquals( 3, ((TargetsMngrImpl) this.mngr).targetIds.size());
// Create a new manager and check restoration works
this.mngr = new TargetsMngrImpl( this.configurationMngr );
Assert.assertEquals( 3, ((TargetsMngrImpl) this.mngr).targetIds.size());
// Add associations and make sure it works
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
Assert.assertNull( this.mngr.findTargetId( app, instancePath ));
this.mngr.associateTargetWith( "4", app, instancePath );
Assert.assertEquals( "4", this.mngr.findTargetId( app, instancePath ));
// Create another manager
this.mngr = new TargetsMngrImpl( this.configurationMngr );
Assert.assertEquals( "hop", this.mngr.createTarget( "id: hop\nprop: ok\nhandler: h" ));
Assert.assertEquals( "4", this.mngr.findTargetId( app, instancePath ));
Assert.assertEquals( 4, ((TargetsMngrImpl) this.mngr).targetIds.size());
}
@Test
public void testApplicationWasDeleted() throws Exception {
// Prepare the model
TestApplication app1 = new TestApplication();
app1.name( "app1" );
TestApplication app2 = new TestApplication();
app2.name( "app2" );
String t1 = this.mngr.createTarget( "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h" );
String t2 = this.mngr.createTarget( "id: t2\nprop: ok\nhandler: docker" );
String path = InstanceHelpers.computeInstancePath( app1.getTomcatVm());
// Create hints and associations
this.mngr.associateTargetWith( t1, app1.getTemplate(), null );
this.mngr.associateTargetWith( t1, app1, null );
this.mngr.associateTargetWith( t2, app1, path );
this.mngr.associateTargetWith( t2, app2, null );
this.mngr.addHint( t1, app1 );
this.mngr.addHint( t2, app1 );
this.mngr.addHint( t2, app2 );
// #744: also test locks
this.mngr.lockAndGetTarget( app2, app2.getTomcatVm());
// Verify preconditions
Assert.assertEquals( t1, this.mngr.findTargetId( app1, null ));
Assert.assertEquals( t2, this.mngr.findTargetId( app1, path ));
Assert.assertEquals( 2, this.mngr.listPossibleTargets( app1 ).size());
Assert.assertEquals( t2, this.mngr.findTargetId( app2, null ));
Assert.assertEquals( t2, this.mngr.findTargetId( app2, path ));
Assert.assertEquals( 1, this.mngr.listPossibleTargets( app2 ).size());
Assert.assertEquals( t1, this.mngr.findTargetId( app1.getTemplate(), path ));
Assert.assertEquals( 0, this.mngr.listPossibleTargets( app1.getTemplate()).size());
// Delete the application
this.mngr.applicationWasDeleted( app1 );
// Verify post-conditions
Assert.assertNull( this.mngr.findTargetId( app1, null ));
Assert.assertNull( this.mngr.findTargetId( app1, path ));
// t1 has not hint anymore, so it becomes global
List<TargetWrapperDescriptor> hints = this.mngr.listPossibleTargets( app1 );
Assert.assertEquals( 1, hints.size());
Assert.assertEquals( t1, hints.get( 0 ).getId());
Assert.assertEquals( t2, this.mngr.findTargetId( app2, null ));
Assert.assertEquals( t2, this.mngr.findTargetId( app2, path ));
// t1 is global now
Assert.assertEquals( 2, this.mngr.listPossibleTargets( app2 ).size());
// t1 is global now
Assert.assertEquals( t1, this.mngr.findTargetId( app1.getTemplate(), path ));
Assert.assertEquals( 1, this.mngr.listPossibleTargets( app1.getTemplate()).size());
// Delete the template of app1
this.mngr.applicationWasDeleted( app1.getTemplate());
// Verify post-conditions
Assert.assertNull( this.mngr.findTargetId( app1, null ));
Assert.assertNull( this.mngr.findTargetId( app1, path ));
Assert.assertEquals( 1, this.mngr.listPossibleTargets( app1 ).size());
Assert.assertEquals( t2, this.mngr.findTargetId( app2, null ));
Assert.assertEquals( t2, this.mngr.findTargetId( app2, path ));
Assert.assertEquals( 2, this.mngr.listPossibleTargets( app2 ).size());
Assert.assertNull( this.mngr.findTargetId( app1.getTemplate(), path ));
Assert.assertEquals( 1, this.mngr.listPossibleTargets( app1.getTemplate()).size());
// Delete app2
this.mngr.applicationWasDeleted( app2 );
// Verify post-conditions
// t2 does not have any hint anymore => it is global
Assert.assertNull( this.mngr.findTargetId( app1, null ));
Assert.assertNull( this.mngr.findTargetId( app1, path ));
Assert.assertEquals( 2, this.mngr.listPossibleTargets( app1 ).size());
Assert.assertNull( this.mngr.findTargetId( app2, null ));
Assert.assertNull( this.mngr.findTargetId( app2, path ));
Assert.assertEquals( 2, this.mngr.listPossibleTargets( app2 ).size());
Assert.assertNull( this.mngr.findTargetId( app1.getTemplate(), path ));
Assert.assertEquals( 2, this.mngr.listPossibleTargets( app1.getTemplate()).size());
// We should be able to delete both targets as they are neither associated nor LOCKED
this.mngr.deleteTarget( t1 );
this.mngr.deleteTarget( t2 );
}
@Test
public void testLocking_ByOneInstance() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
Assert.assertEquals( 0, this.mngr.listAllTargets().size());
String targetId = this.mngr.createTarget( "prop: ok\nid=tid\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, instancePath );
Map<String,String> props = this.mngr.lockAndGetTarget( app, app.getMySqlVm());
Assert.assertEquals( 2, props.size());
Assert.assertEquals( "ok", props.get( "prop" ));
Assert.assertEquals( "h", props.get( "handler" ));
Assert.assertEquals( 1, this.mngr.listAllTargets().size());
try {
this.mngr.deleteTarget( targetId );
Assert.fail( "A target is locked <=> We cannot delete it." );
} catch( UnauthorizedActionException e ) {
// nothing
}
this.mngr.unlockTarget( app, app.getMySqlVm());
Assert.assertEquals( 1, this.mngr.listAllTargets().size());
this.mngr.deleteTarget( targetId );
Assert.assertEquals( 0, this.mngr.listAllTargets().size());
}
@Test
public void testLocking_ByTwoInstances() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
Assert.assertEquals( 0, this.mngr.listAllTargets().size());
String targetId = this.mngr.createTarget( "prop: ok\nid: tid\nhandler: h" );
this.mngr.associateTargetWith( targetId, app, instancePath );
this.mngr.associateTargetWith( targetId, app, null );
Map<String,String> props = this.mngr.lockAndGetTarget( app, app.getMySqlVm());
Assert.assertEquals( 2, props.size());
Assert.assertEquals( "ok", props.get( "prop" ));
Assert.assertEquals( "h", props.get( "handler" ));
props = this.mngr.lockAndGetTarget( app, app.getTomcatVm());
Assert.assertEquals( 2, props.size());
Assert.assertEquals( "ok", props.get( "prop" ));
Assert.assertEquals( "h", props.get( "handler" ));
Assert.assertEquals( 1, this.mngr.listAllTargets().size());
try {
this.mngr.deleteTarget( targetId );
Assert.fail( "A target is locked <=> We cannot delete it." );
} catch( UnauthorizedActionException e ) {
// nothing
}
this.mngr.unlockTarget( app, app.getMySqlVm());
Assert.assertEquals( 1, this.mngr.listAllTargets().size());
try {
this.mngr.deleteTarget( targetId );
Assert.fail( "A target is locked <=> We cannot delete it." );
} catch( UnauthorizedActionException e ) {
// nothing
}
this.mngr.unlockTarget( app, app.getTomcatVm());
this.mngr.deleteTarget( targetId );
Assert.assertEquals( 0, this.mngr.listAllTargets().size());
}
@Test( expected = IOException.class )
public void testLocking_noTarget() throws Exception {
TestApplication app = new TestApplication();
Assert.assertEquals( 0, this.mngr.listAllTargets().size());
this.mngr.lockAndGetTarget( app, app.getMySqlVm());
}
@Test
public void testCopyOriginalMapping_onInstancePath() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
String t1 = this.mngr.createTarget( "prop: ok\nid: t1\nhandler: h" );
String t2 = this.mngr.createTarget( "prop: ok\nid: t2\nhandler: h" );
// Association is on the template AND the instance
Assert.assertNull( this.mngr.findTargetId( app, instancePath ));
this.mngr.associateTargetWith( t1, app.getTemplate(), instancePath );
Assert.assertNull( this.mngr.findTargetId( app, instancePath ));
this.mngr.copyOriginalMapping( app );
Assert.assertEquals( t1, this.mngr.findTargetId( app, instancePath ));
// We can override the association
this.mngr.associateTargetWith( t2, app, instancePath );
Assert.assertEquals( t2, this.mngr.findTargetId( app, instancePath ));
}
@Test
public void testCopyOriginalMapping_onDefault() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
String t1 = this.mngr.createTarget( "prop: ok\nid: t1\nhandler: h" );
String t2 = this.mngr.createTarget( "prop: ok\nid: t2\nhandler: h" );
// Association is on the template and BY DEFAULT
Assert.assertNull( this.mngr.findTargetId( app, instancePath ));
this.mngr.associateTargetWith( t1, app.getTemplate(), null );
Assert.assertNull( this.mngr.findTargetId( app, instancePath ));
this.mngr.copyOriginalMapping( app );
Assert.assertEquals( t1, this.mngr.findTargetId( app, instancePath ));
// We can override the association
this.mngr.associateTargetWith( t2, app, instancePath );
Assert.assertEquals( t2, this.mngr.findTargetId( app, instancePath ));
}
@Test
public void testCopyOriginalMapping_withComponents() throws Exception {
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
String t1 = this.mngr.createTarget( "prop: ok\nid: t1\nhandler: h" );
String t2 = this.mngr.createTarget( "prop: ok\nid: t2\nhandler: h" );
// Association is on the template and BY DEFAULT
Assert.assertNull( this.mngr.findTargetId( app, instancePath ));
this.mngr.associateTargetWith( t1, app.getTemplate(), null );
Assert.assertNull( this.mngr.findTargetId( app.getTemplate(), instancePath, true ));
Assert.assertEquals( t1, this.mngr.findTargetId( app.getTemplate(), instancePath, false ));
Assert.assertNull( this.mngr.findTargetId( app, instancePath, true ));
Assert.assertNull( this.mngr.findTargetId( app, instancePath, false ));
this.mngr.associateTargetWith( t2, app.getTemplate(), "@" + app.getMySqlVm().getComponent().getName());
Assert.assertNull( this.mngr.findTargetId( app.getTemplate(), instancePath, true ));
Assert.assertEquals( t2, this.mngr.findTargetId( app.getTemplate(), instancePath, false ));
Assert.assertNull( this.mngr.findTargetId( app, instancePath, true ));
Assert.assertNull( this.mngr.findTargetId( app, instancePath, false ));
// Copy the mapping
this.mngr.copyOriginalMapping( app );
Assert.assertNull( this.mngr.findTargetId( app, instancePath, true ));
Assert.assertEquals( t2, this.mngr.findTargetId( app, instancePath, false ));
// Remove the component association
this.mngr.dissociateTargetFrom( app, "@" + app.getMySqlVm().getComponent().getName());
Assert.assertNull( this.mngr.findTargetId( app, instancePath, true ));
Assert.assertEquals( t1, this.mngr.findTargetId( app, instancePath, false ));
// We can override the association
this.mngr.associateTargetWith( t2, app, instancePath );
Assert.assertEquals( t2, this.mngr.findTargetId( app, instancePath, true ));
Assert.assertEquals( t2, this.mngr.findTargetId( app, instancePath, false ));
}
@Test
public void testCopyOriginalMapping_withException() throws Exception {
// Check that when the association fails for one instance,
// it does not prevent others from being processed.
TestApplication app = new TestApplication();
String instancePath = InstanceHelpers.computeInstancePath( app.getMySqlVm());
String tomcatPath = InstanceHelpers.computeInstancePath( app.getTomcatVm());
String t1 = this.mngr.createTarget( "prop: ok\nid: t1\nhandler: h" );
String t2 = this.mngr.createTarget( "prop: ok\nid: t2\nhandler: h" );
// Association is on the template
Assert.assertNull( this.mngr.findTargetId( app, instancePath ));
this.mngr.associateTargetWith( t1, app.getTemplate(), instancePath );
this.mngr.associateTargetWith( t1, app.getTemplate(), tomcatPath );
// Set a new default for the application
this.mngr.associateTargetWith( t2, app, null );
Assert.assertEquals( t2, this.mngr.findTargetId( app, instancePath ));
Assert.assertEquals( t2, this.mngr.findTargetId( app, tomcatPath ));
// Change the state
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
// The mapping won't be overwritten for the running instance
this.mngr.copyOriginalMapping( app );
Assert.assertEquals( t2, this.mngr.findTargetId( app, instancePath ));
Assert.assertEquals( t1, this.mngr.findTargetId( app, tomcatPath ));
}
@Test
public void testBuildList_exception() throws Exception {
// Two targets, but only one with valid properties.
// The invalid one won't be listed.
File dir1 = this.folder.newFolder();
File dir2 = this.folder.newFolder();
Utils.writeStringInto( "prop: done", new File( dir1, Constants.TARGET_PROPERTIES_FILE_NAME ));
List<File> targetDirectories = new ArrayList<>( 2 );
targetDirectories.add( dir1 );
targetDirectories.add( dir2 );
List<TargetWrapperDescriptor> beans = ((TargetsMngrImpl) this.mngr).buildList( targetDirectories, null );
Assert.assertEquals( 1, beans.size());
Assert.assertEquals( dir1.getName(), beans.get( 0 ).getId());
}
@Test
public void testFindTargetById() throws Exception {
File dir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/5" );
Utils.createDirectory( dir );
Utils.writeStringInto( "prop: done\nhandler = test", new File( dir, Constants.TARGET_PROPERTIES_FILE_NAME ));
TargetWrapperDescriptor twb = this.mngr.findTargetById( dir.getName());
Assert.assertNotNull( twb );
Assert.assertEquals( dir.getName(), twb.getId());
Assert.assertEquals( "test", twb.getHandler());
Assert.assertFalse( twb.isDefault());
Assert.assertNull( twb.getName());
Assert.assertNull( twb.getDescription());
}
@Test
public void testFindUsageStatistics_inexistingTarget() throws Exception {
List<TargetUsageItem> items = this.mngr.findUsageStatistics( "4" );
Assert.assertEquals( 0, items.size());
}
@Test
public void testFindUsageStatistics() throws Exception {
// Setup
TestApplication app = new TestApplication();
Instance newRootInstance = new Instance( "newRoot" ).component( app.getMySqlVm().getComponent());
app.getRootInstances().add( newRootInstance );
String t1 = this.mngr.createTarget( "prop: ok\nid: t1\nhandler: h" );
String t2 = this.mngr.createTarget( "prop: ok\nid: t2\nhandler: h" );
String t3 = this.mngr.createTarget( "prop: ok\nid: t3\nhandler: h" );
this.mngr.associateTargetWith( t1, app, InstanceHelpers.computeInstancePath( app.getMySqlVm()));
this.mngr.associateTargetWith( t1, app, InstanceHelpers.computeInstancePath( newRootInstance ));
this.mngr.associateTargetWith( t2, app, null );
// Checks
List<TargetUsageItem> items = this.mngr.findUsageStatistics( t1 );
Assert.assertEquals( 1, items.size());
TargetUsageItem item = items.get( 0 );
Assert.assertEquals( app.getName(), item.getName());
Assert.assertNull( item.getQualifier());
Assert.assertFalse( item.isUsing());
Assert.assertTrue( item.isReferencing());
items = this.mngr.findUsageStatistics( t2 );
Assert.assertEquals( 1, items.size());
item = items.get( 0 );
Assert.assertEquals( app.getName(), item.getName());
Assert.assertNull( item.getQualifier());
Assert.assertFalse( item.isUsing());
Assert.assertTrue( item.isReferencing());
items = this.mngr.findUsageStatistics( t3 );
Assert.assertEquals( 0, items.size());
// Mark one as used
this.mngr.lockAndGetTarget( app, app.getTomcatVm());
items = this.mngr.findUsageStatistics( t1 );
Assert.assertEquals( 1, items.size());
item = items.get( 0 );
Assert.assertEquals( app.getName(), item.getName());
Assert.assertNull( item.getQualifier());
Assert.assertFalse( item.isUsing());
Assert.assertTrue( item.isReferencing());
items = this.mngr.findUsageStatistics( t3 );
Assert.assertEquals( 0, items.size());
items = this.mngr.findUsageStatistics( t2 );
Assert.assertEquals( 1, items.size());
item = items.get( 0 );
Assert.assertEquals( app.getName(), item.getName());
Assert.assertNull( item.getQualifier());
Assert.assertTrue( item.isReferencing());
// The change is here!
Assert.assertTrue( item.isUsing());
// Release it
this.mngr.unlockTarget( app, app.getTomcatVm());
items = this.mngr.findUsageStatistics( t1 );
Assert.assertEquals( 1, items.size());
item = items.get( 0 );
Assert.assertEquals( app.getName(), item.getName());
Assert.assertNull( item.getQualifier());
Assert.assertFalse( item.isUsing());
Assert.assertTrue( item.isReferencing());
items = this.mngr.findUsageStatistics( t2 );
Assert.assertEquals( 1, items.size());
item = items.get( 0 );
Assert.assertEquals( app.getName(), item.getName());
Assert.assertNull( item.getQualifier());
Assert.assertFalse( item.isUsing());
Assert.assertTrue( item.isReferencing());
items = this.mngr.findUsageStatistics( t3 );
Assert.assertEquals( 0, items.size());
// Remove the association for the named instance
this.mngr.dissociateTargetFrom( app, InstanceHelpers.computeInstancePath( app.getMySqlVm()));
items = this.mngr.findUsageStatistics( t1 );
Assert.assertEquals( 1, items.size());
this.mngr.dissociateTargetFrom( app, InstanceHelpers.computeInstancePath( newRootInstance ));
items = this.mngr.findUsageStatistics( t1 );
Assert.assertEquals( 0, items.size());
items = this.mngr.findUsageStatistics( t2 );
Assert.assertEquals( 1, items.size());
item = items.get( 0 );
Assert.assertEquals( app.getName(), item.getName());
Assert.assertNull( item.getQualifier());
Assert.assertFalse( item.isUsing());
Assert.assertTrue( item.isReferencing());
items = this.mngr.findUsageStatistics( t3 );
Assert.assertEquals( 0, items.size());
}
@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 testFindScriptResourcesForAgent() throws Exception {
// Precondition: all the right scripts were copied in the target directory.
// Prepare our resources
Properties props = new Properties();
props.setProperty( "id", "tid1" );
props.setProperty( "handler", "h" );
File propsFile = this.folder.newFile( "my-target.properties" );
Utils.writePropertiesFile( props, propsFile );
TestApplication app = new TestApplication();
String targetId1 = this.mngr.createTarget( propsFile, app.getTemplate());
String targetId2 = this.mngr.createTarget( "id: tid2\nhandler: h" );
File dir1 = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/" + targetId1 + "/" + Constants.PROJECT_SUB_DIR_SCRIPTS );
File dir2 = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/" + targetId2 + "/" + Constants.PROJECT_SUB_DIR_SCRIPTS );
Assert.assertTrue( new File( dir1, "sub" ).mkdirs());
Assert.assertTrue( new File( dir2, "sub" ).mkdirs());
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, Constants.SCOPED_SCRIPT_AT_AGENT_SUFFIX + "sh" ));
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, "sub/whatever.sh" ));
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, "sub/" + Constants.LOCAL_RESOURCE_PREFIX + "whatever.sh" ));
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, "some-properties-for-whatever.properties" ));
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, "sub/properties-for-whatever.properties" ));
Utils.writeStringInto( "#!/bin/bash\necho touch toto.txt", new File( dir2, "toto-script.py" ));
// Associate the application with the first target ID
this.mngr.associateTargetWith( targetId1, app, null );
Map<String,byte[]> resources = this.mngr.findScriptResourcesForAgent( targetId1 );
Assert.assertEquals( 4, resources.size());
Assert.assertTrue( resources.containsKey( Constants.SCOPED_SCRIPT_AT_AGENT_SUFFIX + "sh" ));
Assert.assertTrue( resources.containsKey( "sub/whatever.sh" ));
Assert.assertTrue( resources.containsKey( "some-properties-for-whatever.properties" ));
Assert.assertTrue( resources.containsKey( "sub/properties-for-whatever.properties" ));
Map<String,byte[]> resourcesByInst = this.mngr.findScriptResourcesForAgent( app, app.getMySqlVm());
Assert.assertEquals( resources.keySet(), resourcesByInst.keySet());
// Change the target for the scoped instance
this.mngr.associateTargetWith( targetId2, app, InstanceHelpers.computeInstancePath( app.getMySqlVm()));
resources = this.mngr.findScriptResourcesForAgent( targetId1 );
Assert.assertEquals( 4, resources.size());
Assert.assertTrue( resources.containsKey( Constants.SCOPED_SCRIPT_AT_AGENT_SUFFIX + "sh" ));
Assert.assertTrue( resources.containsKey( "sub/whatever.sh" ));
Assert.assertTrue( resources.containsKey( "some-properties-for-whatever.properties" ));
Assert.assertTrue( resources.containsKey( "sub/properties-for-whatever.properties" ));
resourcesByInst = this.mngr.findScriptResourcesForAgent( app, app.getMySqlVm());
Assert.assertEquals( 1, resourcesByInst.size());
Assert.assertTrue( resourcesByInst.containsKey( "toto-script.py" ));
}
@Test
public void testFindScriptForDm() throws Exception {
// Precondition: all the right scripts were copied in the target directory.
// Prepare our resources
TestApplication app = new TestApplication();
String targetId1 = this.mngr.createTarget( "id: tid1\nhandler: h" );
File dir1 = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/" + targetId1 + "/" + Constants.PROJECT_SUB_DIR_SCRIPTS );
Assert.assertTrue( new File( dir1, "sub" ).mkdirs());
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, "sub/whatever.sh" ));
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, "sub/" + Constants.LOCAL_RESOURCE_PREFIX + "whatever.sh" ));
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( dir1, "sub/properties-for-whatever.properties" ));
// Associate the application with the first target ID
this.mngr.associateTargetWith( targetId1, app, null );
File dmScript = this.mngr.findScriptForDm( app, app.getMySqlVm());
Assert.assertNull( dmScript );
Utils.writeStringInto(
"#!/bin/bash\necho Bonjour le monde cruel > toto.txt",
new File( dir1, "target." + Constants.SCOPED_SCRIPT_AT_DM_CONFIGURE_SUFFIX + ".sh" ));
dmScript = this.mngr.findScriptForDm( app, app.getMySqlVm());
Assert.assertNotNull( dmScript );
Assert.assertEquals( "target." + Constants.SCOPED_SCRIPT_AT_DM_CONFIGURE_SUFFIX + ".sh", dmScript.getName());
}
@Test
public void testCopyScriptsInTargetDirectory() throws IOException {
File f = new File( this.folder.newFolder(), "toto.properties" );
Assert.assertTrue( new File( f.getParentFile(), "toto" ).mkdir());
Utils.writeStringInto( "id: tid\nprop: value\nhandler: h", f );
Utils.writeStringInto( "#!/bin/bash\necho Bonjour le monde cruel > toto.txt", new File( f.getParentFile(), "toto/toto.sh" ));
Utils.writeStringInto( "#!/bin/bash\ntouch titi.txt", new File( f.getParentFile(), "titi.sh" ));
Utils.writeStringInto( "#!/bin/bash\necho tototo", new File( f.getParentFile(), "toto/script.sh" ));
File targetDir = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.TARGETS + "/tid" );
Assert.assertFalse( targetDir.exists());
TestApplicationTemplate appT = new TestApplicationTemplate();
String targetId = this.mngr.createTarget( f, appT );
Assert.assertEquals( "tid", targetId );
Assert.assertTrue( targetDir.exists());
Assert.assertEquals( 3, targetDir.list().length);
Assert.assertTrue( new File( targetDir, "target.properties" ).exists());
Assert.assertTrue( new File( targetDir, "created.from" ).exists());
Assert.assertTrue( new File( targetDir, Constants.PROJECT_SUB_DIR_SCRIPTS ).isDirectory());
targetDir = new File( targetDir, Constants.PROJECT_SUB_DIR_SCRIPTS );
Assert.assertEquals( 2, targetDir.list().length);
Assert.assertTrue( new File( targetDir, "toto.sh" ).exists());
Assert.assertTrue( new File( targetDir, "script.sh" ).exists());
Assert.assertFalse( new File( targetDir, "titi.sh").exists());
}
}