/**
* 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.core.model;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import net.roboconf.core.Constants;
import net.roboconf.core.ErrorCode;
import net.roboconf.core.ErrorCode.ErrorLevel;
import net.roboconf.core.RoboconfError;
import net.roboconf.core.internal.tests.TestUtils;
import net.roboconf.core.model.RuntimeModelIo.ApplicationLoadResult;
import net.roboconf.core.model.RuntimeModelIo.GraphFileFilter;
import net.roboconf.core.model.beans.Component;
import net.roboconf.core.model.beans.ExportedVariable.RandomKind;
import net.roboconf.core.model.beans.Facet;
import net.roboconf.core.model.beans.Graphs;
import net.roboconf.core.model.beans.ImportedVariable;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.ComponentHelpers;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.model.helpers.RoboconfErrorHelpers;
import net.roboconf.core.utils.Utils;
/**
* @author Vincent Zurczak - Linagora
*/
public class RuntimeModelIoTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
public void testLoadApplication_Lamp_Legacy_1() throws Exception {
File directory = TestUtils.findTestFile( "/applications/lamp-legacy-with-only-components" );
ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
Assert.assertNotNull( result );
Assert.assertNotNull( result.applicationTemplate );
Assert.assertEquals( 4, result.loadErrors.size());
for( RoboconfError error : result.loadErrors )
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());
Assert.assertEquals( "Legacy LAMP", result.applicationTemplate.getName());
Assert.assertEquals( "A sample LAMP application", result.applicationTemplate.getDescription());
Assert.assertEquals( "sample", result.applicationTemplate.getQualifier());
Assert.assertNotNull( result.applicationTemplate.getGraphs());
Graphs g = result.applicationTemplate.getGraphs();
Assert.assertEquals( 1, g.getRootComponents().size());
Component vmComponent = g.getRootComponents().iterator().next();
Assert.assertEquals( "VM", vmComponent.getName());
Assert.assertEquals( "target", vmComponent.getInstallerName());
Assert.assertEquals( 3, vmComponent.getChildren().size());
for( Component childComponent : ComponentHelpers.findAllChildren( vmComponent )) {
Map<String,String> exportedVariables = ComponentHelpers.findAllExportedVariables( childComponent );
Map<String,ImportedVariable> importedVariables = ComponentHelpers.findAllImportedVariables( childComponent );
Collection<Component> children = ComponentHelpers.findAllChildren( childComponent );
if( "Tomcat".equals( childComponent.getName())) {
Assert.assertEquals( "puppet", childComponent.getInstallerName());
Assert.assertEquals( 0, children.size());
Assert.assertEquals( 2, exportedVariables.size());
Assert.assertTrue( exportedVariables.containsKey( "Tomcat.ip" ));
Assert.assertEquals( "8009", exportedVariables.get( "Tomcat.portAJP" ));
Assert.assertEquals( 2, importedVariables.size());
Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isOptional());
Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isExternal());
Assert.assertFalse( importedVariables.get( "MySQL.port" ).isOptional());
Assert.assertFalse( importedVariables.get( "MySQL.port" ).isExternal());
SourceReference sr = result.getObjectToSource().get( childComponent );
Assert.assertNotNull( sr );
Assert.assertEquals( new File( directory, "graph/lamp.graph" ), sr.getSourceFile());
Assert.assertEquals( 22, sr.getLine());
} else if( "MySQL".equals( childComponent.getName())) {
Assert.assertEquals( "puppet", childComponent.getInstallerName());
Assert.assertEquals( 0, children.size());
Assert.assertEquals( 2, exportedVariables.size());
Assert.assertTrue( exportedVariables.containsKey( "MySQL.ip" ));
Assert.assertNull( exportedVariables.get( "MySQL.port" ));
Assert.assertEquals( 0, importedVariables.size());
SourceReference sr = result.getObjectToSource().get( childComponent );
Assert.assertNotNull( sr );
Assert.assertEquals( new File( directory, "graph/lamp.graph" ), sr.getSourceFile());
Assert.assertEquals( 16, sr.getLine());
} else if( "Apache".equals( childComponent.getName())) {
Assert.assertEquals( "puppet", childComponent.getInstallerName());
Assert.assertEquals( 0, children.size());
Assert.assertEquals( 0, exportedVariables.size());
Assert.assertEquals( 2, childComponent.importedVariables.size());
Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isOptional());
Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isExternal());
Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isOptional());
Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isExternal());
SourceReference sr = result.getObjectToSource().get( childComponent );
Assert.assertNotNull( sr );
Assert.assertEquals( new File( directory, "graph/lamp.graph" ), sr.getSourceFile());
Assert.assertEquals( 30, sr.getLine());
} else {
Assert.fail( "Unrecognized child." );
}
}
// Instances
Assert.assertEquals( 3, result.applicationTemplate.getRootInstances().size());
for( Instance i : result.applicationTemplate.getRootInstances()) {
if( "Apache VM".equals( i.getName())) {
Assert.assertEquals( "VM", i.getComponent().getName());
Assert.assertEquals( 1, i.getChildren().size());
Instance child = i.getChildren().iterator().next();
Assert.assertEquals( 0, child.getChildren().size());
Assert.assertEquals( i, child.getParent());
Assert.assertEquals( "Apache", child.getName());
Assert.assertEquals( "Apache", child.getComponent().getName());
} else if( "MySQL VM".equals( i.getName())) {
Assert.assertEquals( "VM", i.getComponent().getName());
Assert.assertEquals( 1, i.getChildren().size());
Instance child = i.getChildren().iterator().next();
Assert.assertEquals( 0, child.getChildren().size());
Assert.assertEquals( i, child.getParent());
Assert.assertEquals( "MySQL", child.getName());
Assert.assertEquals( "MySQL", child.getComponent().getName());
Map<String,String> exportedVariables = InstanceHelpers.findAllExportedVariables( child );
Assert.assertEquals( "3306", exportedVariables.get( "MySQL.port" ));
Assert.assertNull( child.getComponent().exportedVariables.get( "MySQL.port" ));
Assert.assertNotNull( child.getComponent().exportedVariables.get( "port" ));
Assert.assertNull( child.getComponent().exportedVariables.get( "port" ).getValue());
} else if( "Tomcat VM 1".equals( i.getName())) {
Assert.assertEquals( "VM", i.getComponent().getName());
Assert.assertEquals( 1, i.getChildren().size());
Instance child = i.getChildren().iterator().next();
Assert.assertEquals( 0, child.getChildren().size());
Assert.assertEquals( i, child.getParent());
Assert.assertEquals( "Tomcat", child.getName());
Assert.assertEquals( "Tomcat", child.getComponent().getName());
} else {
Assert.fail( "Unrecognized instance." );
}
}
}
@Test
public void testLoadApplication_Lamp_Legacy_2() throws Exception {
File directory = TestUtils.findTestFile( "/applications/lamp-legacy-with-facets-and-so-on" );
ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
Assert.assertNotNull( result );
Assert.assertNotNull( result.applicationTemplate );
Assert.assertEquals( 3, result.loadErrors.size());
for( RoboconfError error : result.loadErrors )
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());
// Test the graph and descriptor
Assert.assertEquals( "Legacy LAMP", result.applicationTemplate.getName());
Assert.assertEquals( "A sample LAMP application", result.applicationTemplate.getDescription());
Assert.assertEquals( "sample", result.applicationTemplate.getQualifier());
Assert.assertEquals( "roboconf-1.0", result.applicationTemplate.getDslId());
Assert.assertNotNull( result.applicationTemplate.getGraphs());
Graphs g = result.applicationTemplate.getGraphs();
Assert.assertEquals( 3, g.getRootComponents().size());
Set<String> rootComponentNames = new HashSet<> ();
for( Component c : g.getRootComponents()) {
rootComponentNames.add( c.getName());
Assert.assertEquals( Constants.TARGET_INSTALLER, ComponentHelpers.findComponentInstaller( c ));
Collection<Facet> facets = ComponentHelpers.findAllFacets( c );
Assert.assertEquals( 1, facets.size());
Assert.assertEquals( "Virtual_Machine", facets.iterator().next().getName());
Assert.assertEquals( 3, ComponentHelpers.findAllChildren( c ).size());
for( Component childComponent : ComponentHelpers.findAllChildren( c )) {
Map<String,String> exportedVariables = ComponentHelpers.findAllExportedVariables( childComponent );
Map<String,ImportedVariable> importedVariables = ComponentHelpers.findAllImportedVariables( childComponent );
Collection<Component> children = ComponentHelpers.findAllChildren( childComponent );
if( "Tomcat".equals( childComponent.getName())) {
Assert.assertEquals( "puppet", childComponent.getInstallerName());
Assert.assertEquals( 0, children.size());
Assert.assertEquals( 1, childComponent.getFacets().size());
Assert.assertEquals( "deployable", childComponent.getFacets().iterator().next().getName());
Assert.assertEquals( 2, exportedVariables.size());
Assert.assertTrue( exportedVariables.containsKey( "Tomcat.ip" ));
Assert.assertEquals( "8009", exportedVariables.get( "Tomcat.portAJP" ));
Assert.assertEquals( 2, importedVariables.size());
Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isOptional());
Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isExternal());
Assert.assertFalse( importedVariables.get( "MySQL.port" ).isOptional());
Assert.assertFalse( importedVariables.get( "MySQL.port" ).isExternal());
} else if( "MySQL".equals( childComponent.getName())) {
Assert.assertEquals( "puppet", childComponent.getInstallerName());
Assert.assertEquals( 0, children.size());
Assert.assertEquals( 1, childComponent.getFacets().size());
Assert.assertEquals( "deployable", childComponent.getFacets().iterator().next().getName());
Assert.assertEquals( 2, exportedVariables.size());
Assert.assertTrue( exportedVariables.containsKey( "MySQL.ip" ));
Assert.assertEquals( "3306", exportedVariables.get( "MySQL.port" ));
Assert.assertEquals( 0, importedVariables.size());
} else if( "Apache".equals( childComponent.getName())) {
Assert.assertEquals( "puppet", childComponent.getInstallerName());
Assert.assertEquals( 0, children.size());
Assert.assertEquals( 0, exportedVariables.size());
Assert.assertEquals( 1, childComponent.getFacets().size());
Assert.assertEquals( "deployable", childComponent.getFacets().iterator().next().getName());
Assert.assertEquals( 2, importedVariables.size());
Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isOptional());
Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isExternal());
Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isOptional());
Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isExternal());
} else {
Assert.fail( "Unrecognized child." );
}
}
}
// Check we got everything in the graph
Assert.assertEquals( 3, rootComponentNames.size());
Assert.assertTrue( rootComponentNames.contains( "VM" ));
Assert.assertTrue( rootComponentNames.contains( "VM_EC2" ));
Assert.assertTrue( rootComponentNames.contains( "VM_Openstack" ));
Component vmOpenstack = ComponentHelpers.findComponent( g, "VM_Openstack" );
Map<String,String> exportedVariables = ComponentHelpers.findAllExportedVariables( vmOpenstack );
Assert.assertEquals( 4, exportedVariables.size());
Assert.assertEquals( "else", exportedVariables.get( "VM_Openstack.something" ));
Assert.assertNull( exportedVariables.get( "Virtual_Machine.ip" ));
Assert.assertTrue( exportedVariables.containsKey( "Virtual_Machine.ip" ));
Assert.assertTrue( exportedVariables.containsKey( "VM_Openstack.ip" ));
Assert.assertTrue( exportedVariables.containsKey( "VM.ip" ));
Assert.assertEquals( ComponentHelpers.findComponent( g, "VM" ), vmOpenstack.getExtendedComponent());
Assert.assertNotNull( vmOpenstack.getExtendedComponent());
// Test the instances
Set<String> expectedPaths = new HashSet<> ();
expectedPaths.add( "/Apache VM" );
expectedPaths.add( "/Apache VM/Apache" );
expectedPaths.add( "/MySQL VM" );
expectedPaths.add( "/MySQL VM/MySQL" );
expectedPaths.add( "/Tomcat VM 1" );
expectedPaths.add( "/Tomcat VM 1/Tomcat" );
expectedPaths.add( "/Tomcat VM 2" );
expectedPaths.add( "/Tomcat VM 2/Tomcat" );
expectedPaths.add( "/Tomcat VM 3" );
expectedPaths.add( "/Tomcat VM 3/Tomcat" );
Set<String> realPaths = new HashSet<> ();
for( Instance inst : InstanceHelpers.getAllInstances( result.getApplicationTemplate()))
realPaths.add( InstanceHelpers.computeInstancePath( inst ));
Assert.assertEquals( expectedPaths.size(), realPaths.size());
realPaths.removeAll( expectedPaths );
Assert.assertEquals( 0, realPaths.size());
Instance tomcat1 = InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/Tomcat VM 1/Tomcat" );
Instance tomcat2 = InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/Tomcat VM 2/Tomcat" );
Instance tomcat3 = InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/Tomcat VM 3/Tomcat" );
Assert.assertEquals( tomcat1.getComponent(), tomcat2.getComponent());
Assert.assertEquals( tomcat1.getComponent(), tomcat3.getComponent());
Assert.assertEquals( tomcat1.channels, tomcat2.channels );
Assert.assertEquals( tomcat1.channels, tomcat3.channels );
Assert.assertEquals( 0, tomcat1.getChildren().size());
Assert.assertEquals( 1, tomcat1.overriddenExports.size());
Assert.assertEquals( "9021", tomcat1.overriddenExports.get( "portAJP" ));
Assert.assertEquals( "9021", InstanceHelpers.findAllExportedVariables( tomcat1 ).get( "Tomcat.portAJP" ));
Assert.assertEquals( 0, tomcat2.getChildren().size());
Assert.assertEquals( 1, tomcat2.overriddenExports.size());
Assert.assertEquals( "9021", tomcat2.overriddenExports.get( "portAJP" ));
Assert.assertEquals( "9021", InstanceHelpers.findAllExportedVariables( tomcat2 ).get( "Tomcat.portAJP" ));
Assert.assertEquals( 0, tomcat3.getChildren().size());
Assert.assertEquals( 1, tomcat3.overriddenExports.size());
Assert.assertEquals( "9021", tomcat3.overriddenExports.get( "portAJP" ));
Assert.assertEquals( "9021", InstanceHelpers.findAllExportedVariables( tomcat3 ).get( "Tomcat.portAJP" ));
}
@Test
public void testLoadApplication_Mongo() throws Exception {
File directory = TestUtils.findTestFile( "/applications/mongo" );
ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
Assert.assertNotNull( result );
Assert.assertNotNull( result.applicationTemplate );
Assert.assertEquals( 0, result.applicationTemplate.externalExports.size());
Assert.assertEquals( 2, result.loadErrors.size());
for( RoboconfError error : result.loadErrors )
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());
Assert.assertEquals( "Mongo", result.applicationTemplate.getName());
Assert.assertNotNull( result.applicationTemplate.getGraphs());
Graphs g = result.applicationTemplate.getGraphs();
Assert.assertEquals( 1, g.getRootComponents().size());
Component vmComponent = g.getRootComponents().iterator().next();
Assert.assertEquals( "VM", vmComponent.getName());
Assert.assertEquals( "target", vmComponent.getInstallerName());
Assert.assertEquals( 0, vmComponent.getFacets().size());
Collection<Component> children = ComponentHelpers.findAllChildren( vmComponent );
Assert.assertEquals( 1, children.size());
Component childComponent = children.iterator().next();
Assert.assertEquals( "puppet", childComponent.getInstallerName());
Assert.assertEquals( 0, childComponent.getChildren().size());
Assert.assertEquals( 2, childComponent.exportedVariables.size());
Assert.assertNull( childComponent.exportedVariables.get( "Mongo.ip" ));
Assert.assertEquals( "27017", ComponentHelpers.findAllExportedVariables( childComponent ).get( "Mongo.port" ));
Assert.assertEquals( 2, childComponent.importedVariables.size());
Assert.assertTrue( childComponent.importedVariables.containsKey( "Mongo.ip" ));
Assert.assertTrue( childComponent.importedVariables.containsKey( "Mongo.port" ));
}
@Test
public void testLoadApplication_AppWithExternalDependencies() throws Exception {
File directory = TestUtils.findTestFile( "/applications/app-with-external-dependencies" );
ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
Assert.assertNotNull( result );
Assert.assertNotNull( result.applicationTemplate );
Assert.assertEquals( 2, result.applicationTemplate.externalExports.size());
Assert.assertEquals( "DEP.c", result.applicationTemplate.externalExports.get( "VM.config" ));
Assert.assertEquals( "DEP.ip", result.applicationTemplate.externalExports.get( "App.ip" ));
Assert.assertEquals( 2, result.loadErrors.size());
for( RoboconfError error : result.loadErrors )
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());
Assert.assertEquals( "app-with-dep", result.applicationTemplate.getName());
Assert.assertNotNull( result.applicationTemplate.getGraphs());
Graphs g = result.applicationTemplate.getGraphs();
Assert.assertEquals( 1, g.getRootComponents().size());
Component vmComponent = g.getRootComponents().iterator().next();
Assert.assertEquals( "VM", vmComponent.getName());
Assert.assertEquals( "target", vmComponent.getInstallerName());
Assert.assertEquals( 0, vmComponent.getFacets().size());
Collection<Component> children = ComponentHelpers.findAllChildren( vmComponent );
Assert.assertEquals( 1, children.size());
Component childComponent = children.iterator().next();
Assert.assertEquals( "App", childComponent.getName());
Assert.assertEquals( "logger", childComponent.getInstallerName());
Assert.assertEquals( 0, childComponent.getChildren().size());
Assert.assertEquals( 1, childComponent.exportedVariables.size());
Assert.assertNull( childComponent.exportedVariables.get( "App.ip" ));
Assert.assertEquals( 2, childComponent.importedVariables.size());
Assert.assertTrue( childComponent.importedVariables.containsKey( "VM.config" ));
Assert.assertFalse( childComponent.importedVariables.get( "VM.config" ).isOptional());
Assert.assertFalse( childComponent.importedVariables.get( "VM.config" ).isExternal());
Assert.assertTrue( childComponent.importedVariables.containsKey( "App1.test" ));
Assert.assertFalse( childComponent.importedVariables.get( "App1.test" ).isOptional());
Assert.assertTrue( childComponent.importedVariables.get( "App1.test" ).isExternal());
}
@Test
public void testLoadApplicationErrors() throws Exception {
File tempDirectory = this.folder.newFolder();
// Descriptor
Iterator<RoboconfError> iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_DESC_DIR, iterator.next().getErrorCode());
File appDir = new File( tempDirectory, Constants.PROJECT_DIR_DESC );
if( ! appDir.mkdir())
throw new IOException( "Failed to create the descriptor directory." );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_DESC_FILE, iterator.next().getErrorCode());
Properties props = new Properties();
props.setProperty( ApplicationTemplateDescriptor.APPLICATION_NAME, "app-name" );
props.setProperty( ApplicationTemplateDescriptor.APPLICATION_QUALIFIER, "snapshot" );
props.setProperty( ApplicationTemplateDescriptor.APPLICATION_DSL_ID, "roboconf-1.0" );
props.setProperty( ApplicationTemplateDescriptor.APPLICATION_GRAPH_EP, "main.graph" );
Utils.writePropertiesFile( props, new File( appDir, Constants.PROJECT_FILE_DESCRIPTOR ));
// Graph
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_GRAPH_DIR, iterator.next().getErrorCode());
File graphDir = new File( tempDirectory, Constants.PROJECT_DIR_GRAPH );
if( ! graphDir.mkdir())
throw new IOException( "Failed to create the graph directory." );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_MISSING_GRAPH_EP, iterator.next().getErrorCode());
File graphFile = new File( graphDir, "main.graph" );
if( ! graphFile.createNewFile())
throw new IOException( "Faild to create a graph file." );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.RM_NO_ROOT_COMPONENT, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( " \n \t\n\n ", graphFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.RM_NO_ROOT_COMPONENT, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( "[ not supported by our parser ]", graphFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.CO_NOT_A_GRAPH, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( " \n\n [ not supported by our parser ] \n\n ", graphFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.CO_NOT_A_GRAPH, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( "comp", graphFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.P_O_C_BRACKET_MISSING, iterator.next().getErrorCode());
String fileContent = "my Toto {\n\tname: toto;\n}";
Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PM_INVALID_NAME, iterator.next().getErrorCode());
fileContent = "instanceof Toto {\n\tname: toto;\n}";
Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PM_INVALID_NAME, iterator.next().getErrorCode());
fileContent = "instance of Toto {\n\tname: toto;\n}";
Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.CO_NOT_A_GRAPH, iterator.next().getErrorCode());
fileContent = "facet MyFacet {\n}\n\nA {\n\tinstaller: target;\n\tfacets: MyFacet;\n}";
Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );
// Instances
Collection<RoboconfError> errors = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors;
Assert.assertEquals( 1, errors.size());
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, errors.iterator().next().getErrorCode());
props.setProperty( ApplicationTemplateDescriptor.APPLICATION_INSTANCES_EP, "init.instances" );
Utils.writePropertiesFile( props, new File( appDir, Constants.PROJECT_FILE_DESCRIPTOR ));
File instDir = new File( tempDirectory, Constants.PROJECT_DIR_INSTANCES );
if( ! instDir.mkdir())
throw new IOException( "Failed to create the instances directory." );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.PROJ_MISSING_INSTANCE_EP, iterator.next().getErrorCode());
File instancesFile = new File( instDir, "init.instances" );
if( ! instancesFile.createNewFile())
throw new IOException( "Failed to create " + instancesFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( " \n \t\n\n ", instancesFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( "[ not supported by our parser ]", instancesFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( " \n\n [ not supported by our parser ] \n\n ", instancesFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
Utils.writeStringInto( " \n\n ip \n\n ", instancesFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.P_O_C_BRACKET_MISSING, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
fileContent = "facet MyFacet {\n}\n\nA {\n\tinstaller: script;\n}";
Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), instancesFile );
iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
Assert.assertFalse( iterator.hasNext());
fileContent = "instance of A {\n\tname: toto;\n}";
Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), instancesFile );
errors = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors;
Assert.assertEquals( 1, errors.size());
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, errors.iterator().next().getErrorCode());
}
@Test
public void testLoadApplication_KarafJoramJndi() throws Exception {
File directory = TestUtils.findTestFile( "/applications/karaf-joram-jndi" );
ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
Assert.assertNotNull( result );
Assert.assertNotNull( result.applicationTemplate );
Assert.assertEquals( 6, result.loadErrors.size());
for( RoboconfError error : result.loadErrors )
Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());
Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf" ));
Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec21" ));
Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec21/jndiec2" ));
Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec22" ));
Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec22/joramec2" ));
}
@Test
public void testInvalidApplicationDescriptor() throws Exception {
File appDirectory = this.folder.newFolder();
File descDirectory = new File( appDirectory, Constants.PROJECT_DIR_DESC );
if( ! descDirectory.mkdir())
throw new IOException();
File descFile = new File( descDirectory, Constants.PROJECT_FILE_DESCRIPTOR );
if( ! descFile.createNewFile())
throw new IOException();
String content = "fail.read = true";
Utils.copyStream( new ByteArrayInputStream( content.getBytes( "UTF-8" )), descFile );
ApplicationLoadResult lr = RuntimeModelIo.loadApplication( appDirectory );
Assert.assertTrue( lr.getLoadErrors().size() > 1 );
Assert.assertEquals( ErrorCode.PROJ_READ_DESC_FILE, lr.getLoadErrors().iterator().next().getErrorCode());
}
@Test
public void testWriteInstances_empty() throws Exception {
File targetFile = this.folder.newFile();
RuntimeModelIo.writeInstances( targetFile, new ArrayList<Instance>( 0 ));
Assert.assertTrue( targetFile.exists());
Assert.assertEquals( 0, targetFile.length());
}
@Test
public void testWriteInstances_notEmpty() throws Exception {
Component component = new Component( "comp" );
Instance instance = new Instance( "inst" ).component( component ).status( InstanceStatus.DEPLOYING ).channel( "c" );
instance.overriddenExports.put( "check", "true" );
instance.data.put( "something", "else" );
File targetFile = this.folder.newFile();
RuntimeModelIo.writeInstances( targetFile, Arrays.asList( instance ));
Assert.assertTrue( targetFile.exists());
Assert.assertTrue( 0 < targetFile.length());
}
@Test
public void testApplicationWithMissingGraph() throws Exception {
File dir = this.folder.newFolder();
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES + "/model.instances" ).createNewFile());
ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
desc.setName( "app name" );
desc.setQualifier( "qualifier" );
desc.setInstanceEntryPoint( "model.instances" );
desc.setDslId( "roboconf-1.0" );
ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );
Iterator<RoboconfError> it = RuntimeModelIo.loadApplicationFlexibly( dir ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.RM_MISSING_APPLICATION_GEP, it.next().getErrorCode());
Assert.assertEquals( ErrorCode.CO_GRAPH_COULD_NOT_BE_BUILT, it.next().getErrorCode());
}
@Test
public void testApplicationWithoutInstances() throws Exception {
File dir = this.folder.newFolder();
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
Utils.writeStringInto(
"id: tid\nhandler: test\nname: n",
new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));
File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
Assert.assertTrue( graphFile.createNewFile());
ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
desc.setName( "app name" );
desc.setQualifier( "qualifier" );
desc.setGraphEntryPoint( "app.graph" );
desc.setDslId( "roboconf-1.0" );
ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );
Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );
Assert.assertEquals( 0, RuntimeModelIo.loadApplication( dir ).loadErrors.size());
}
@Test
public void testUnreachableFile() throws Exception {
// Valid project
File dir = this.folder.newFolder();
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
Utils.writeStringInto(
"id: tid\nhandler: test\nname: n",
new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));
ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
desc.setName( "app name" );
desc.setQualifier( "qualifier" );
desc.setGraphEntryPoint( "app.graph" );
desc.setDslId( "roboconf-1.0" );
ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );
File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );
// Unreachable files
final int length = 3;
File[] copies = new File[ length ];
for( int i=0; i<length; i++ ) {
copies[ i ] = new File( new File( dir, Constants.PROJECT_DIR_GRAPH ), "not-used-" + i + ".graph" );
Utils.copyStream( graphFile, copies[ i ]);
}
// Verify
List<RoboconfError> errors = new ArrayList<>( RuntimeModelIo.loadApplication( dir ).loadErrors );
Assert.assertEquals( length, errors.size());
for( int i=0; i<length; i++ ) {
Assert.assertEquals( ParsingError.class, errors.get( i ).getClass());
Assert.assertEquals( ErrorCode.PROJ_UNREACHABLE_FILE, errors.get( i ).getErrorCode());
Assert.assertEquals( copies[ i ], ((ParsingError) errors.get( i )).getFile());
}
}
@Test
public void testApplicationWithInvalidTarget() throws Exception {
File dir = this.folder.newFolder();
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
Utils.writeStringInto(
"handler: test\nname: n",
new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));
File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
Assert.assertTrue( graphFile.createNewFile());
ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
desc.setName( "app name" );
desc.setQualifier( "qualifier" );
desc.setGraphEntryPoint( "app.graph" );
desc.setDslId( "roboconf-1.0" );
ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );
Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );
Iterator<RoboconfError> it = RuntimeModelIo.loadApplication( dir ).loadErrors.iterator();
Assert.assertEquals( ErrorCode.REC_TARGET_NO_ID, it.next().getErrorCode());
Assert.assertFalse( it.hasNext());
}
@Test
public void testInvalidFileLocation() throws Exception {
// Valid project
File dir = this.folder.newFolder();
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());
Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
Utils.writeStringInto(
"id: tid\nhandler: test\nname: n",
new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));
ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
desc.setName( "app name" );
desc.setQualifier( "qualifier" );
desc.setGraphEntryPoint( "app.graph" );
desc.setDslId( "roboconf-1.0" );
ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );
File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );
// File at an invalid location
final int length = 3;
File[] copies = new File[ length ];
for( int i=0; i<length; i++ ) {
copies[ i ] = new File( dir, "not-used-" + i + ".graph" );
Utils.copyStream( graphFile, copies[ i ]);
}
// Such files are not validated
File invalidInstFile = new File( dir, "invalid.instances" );
Utils.writeStringInto( "inst of {", invalidInstFile );
// Verify
List<RoboconfError> errors = new ArrayList<>( RuntimeModelIo.loadApplication( dir ).loadErrors );
Assert.assertEquals( length + 1, errors.size());
for( int i=0; i<length; i++ ) {
Assert.assertEquals( ParsingError.class, errors.get( i ).getClass());
Assert.assertEquals( ErrorCode.PROJ_INVALID_FILE_LOCATION, errors.get( i ).getErrorCode());
Assert.assertEquals( copies[ i ], ((ParsingError) errors.get( i )).getFile());
}
Assert.assertEquals( ParsingError.class, errors.get( length - 1 ).getClass());
Assert.assertEquals( ErrorCode.PROJ_INVALID_FILE_LOCATION, errors.get( length - 1 ).getErrorCode());
Assert.assertEquals( copies[ length - 1 ], ((ParsingError) errors.get( length - 1 )).getFile());
}
@Test
public void testParsingWithRecipeProject() throws Exception {
// Normal load
File dir = TestUtils.findTestFile( "/reusable.recipe" );
Assert.assertTrue( dir.exists());
ApplicationLoadResult alr = RuntimeModelIo.loadApplication( dir );
RoboconfErrorHelpers.filterErrorsForRecipes( alr );
List<RoboconfError> errors = new ArrayList<>( alr.getLoadErrors());
Assert.assertEquals( 2, errors.size());
Assert.assertEquals( ErrorCode.PROJ_NO_DESC_DIR, errors.get( 0 ).getErrorCode());
Assert.assertEquals( ErrorCode.PROJ_UNREACHABLE_FILE, errors.get( 1 ).getErrorCode());
// Flexible load
alr = RuntimeModelIo.loadApplicationFlexibly( dir );
RoboconfErrorHelpers.filterErrorsForRecipes( alr );
Assert.assertEquals( 0, alr.getLoadErrors().size());
}
@Test
public void testParsingWithInvalidRecipeProject() throws Exception {
File dir = TestUtils.findTestFile( "/reusable.recipe.with.errors" );
Assert.assertTrue( dir.exists());
ApplicationLoadResult alr = RuntimeModelIo.loadApplicationFlexibly( dir );
RoboconfErrorHelpers.filterErrorsForRecipes( alr );
Assert.assertEquals( 1, alr.getLoadErrors().size());
Assert.assertEquals( ErrorCode.RM_UNRESOLVABLE_VARIABLE, alr.getLoadErrors().iterator().next().getErrorCode());
Assert.assertTrue( alr.getLoadErrors().iterator().next().getDetails().contains( "f.*" ));
}
@Test
public void testGraphFileFilter() throws Exception {
GraphFileFilter filter = new GraphFileFilter();
Assert.assertFalse( filter.accept( new File( "inexisting" )));
Assert.assertTrue( filter.accept( this.folder.newFile( "toto.graph" )));
Assert.assertFalse( filter.accept( this.folder.newFile( "toto.txt" )));
Assert.assertFalse( filter.accept( this.folder.newFolder( "sth.graph" )));
}
@Test
public void testParsingWithRandomValues() throws Exception {
File dir = TestUtils.findApplicationDirectory( "app-with-random-ports" );
Assert.assertTrue( dir.isDirectory());
ApplicationLoadResult alr = RuntimeModelIo.loadApplication( dir );
Assert.assertFalse( RoboconfErrorHelpers.containsCriticalErrors( alr.getLoadErrors()));
// Container 1
Instance container1 = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/vm/container1" );
Assert.assertNotNull( container1 );
Assert.assertNull( container1.getComponent().exportedVariables.get( "httpPort" ).getValue());
Assert.assertTrue( container1.getComponent().exportedVariables.get( "httpPort" ).isRandom());
Assert.assertEquals( RandomKind.PORT, container1.getComponent().exportedVariables.get( "httpPort" ).getRandomKind());
Assert.assertNull( container1.getComponent().exportedVariables.get( "ajpPort" ).getValue());
Assert.assertTrue( container1.getComponent().exportedVariables.get( "ajpPort" ).isRandom());
Assert.assertEquals( RandomKind.PORT, container1.getComponent().exportedVariables.get( "ajpPort" ).getRandomKind());
Assert.assertEquals( "test", container1.getComponent().exportedVariables.get( "config" ).getValue());
Assert.assertFalse( container1.getComponent().exportedVariables.get( "config" ).isRandom());
Assert.assertNull( container1.getComponent().exportedVariables.get( "config" ).getRandomKind());
Assert.assertNull( container1.getComponent().exportedVariables.get( "ip" ).getValue());
Assert.assertFalse( container1.getComponent().exportedVariables.get( "ip" ).isRandom());
Assert.assertNull( container1.getComponent().exportedVariables.get( "ip" ).getRandomKind());
Map<String,String> exportedVariables = InstanceHelpers.findAllExportedVariables( container1 );
Assert.assertEquals( "test", exportedVariables.get( "Container1.config" ));
Assert.assertTrue( exportedVariables.containsKey( "Container1.ip" ));
Assert.assertNull( exportedVariables.get( "Container1.ip" ));
Assert.assertTrue( exportedVariables.containsKey( "Container1.httpPort" ));
Assert.assertNull( exportedVariables.get( "Container1.httpPort" ));
Assert.assertTrue( exportedVariables.containsKey( "Container1.ajpPort" ));
Assert.assertNull( exportedVariables.get( "Container1.ajpPort" ));
// Container 2
Instance container2 = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/vm/container2" );
Assert.assertNotNull( container2 );
Assert.assertNull( container2.getComponent().exportedVariables.get( "port" ).getValue());
Assert.assertTrue( container2.getComponent().exportedVariables.get( "port" ).isRandom());
Assert.assertEquals( RandomKind.PORT, container2.getComponent().exportedVariables.get( "port" ).getRandomKind());
Assert.assertNull( container2.getComponent().exportedVariables.get( "ip" ).getValue());
Assert.assertFalse( container2.getComponent().exportedVariables.get( "ip" ).isRandom());
Assert.assertNull( container2.getComponent().exportedVariables.get( "ip" ).getRandomKind());
exportedVariables = InstanceHelpers.findAllExportedVariables( container2 );
Assert.assertTrue( exportedVariables.containsKey( "Container2.ip" ));
Assert.assertNull( exportedVariables.get( "Container2.ip" ));
// This value is found in the instances.
Assert.assertEquals( "45012", exportedVariables.get( "Container2.port" ));
}
@Test
public void testParsingWithInvalidCommands() throws Exception {
// Copy the application and update a command file
File dir = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( dir.isDirectory());
File newDir = this.folder.newFolder();
Utils.copyDirectory( dir, newDir );
File commandFile = new File( newDir, Constants.PROJECT_DIR_COMMANDS + "/scale.commands" );
Assert.assertTrue( commandFile.isFile());
File commandFileCopy = new File( newDir, Constants.PROJECT_DIR_COMMANDS + "/scale.invalid-extension" );
Utils.copyStream( commandFile, commandFileCopy );
Utils.writeStringInto( "this is an invalid command", commandFile );
// Load it and verify it contains errors
ApplicationLoadResult alr = RuntimeModelIo.loadApplication( newDir );
List<RoboconfError> criticalErrors = new ArrayList<> ();
for( RoboconfError error : alr.getLoadErrors()) {
if( error.getErrorCode().getLevel() == ErrorLevel.SEVERE )
criticalErrors.add( error );
}
Assert.assertEquals( 3, criticalErrors.size());
Assert.assertEquals( ErrorCode.CMD_NO_INSTRUCTION, criticalErrors.get( 0 ).getErrorCode());
Assert.assertEquals( ErrorCode.CMD_UNRECOGNIZED_INSTRUCTION, criticalErrors.get( 1 ).getErrorCode());
Assert.assertEquals( ErrorCode.PROJ_INVALID_COMMAND_EXT, criticalErrors.get( 2 ).getErrorCode());
}
@Test
public void testParsingWithInvalidAutonomicRules() throws Exception {
// Copy the application and update a command file
File dir = TestUtils.findApplicationDirectory( "lamp" );
Assert.assertTrue( dir.isDirectory());
File newDir = this.folder.newFolder();
Utils.copyDirectory( dir, newDir );
File ruleFile = new File( newDir, Constants.PROJECT_DIR_RULES_AUTONOMIC + "/sample.drl" );
Assert.assertTrue( ruleFile.isFile());
File ruleFileCopy = new File( newDir, Constants.PROJECT_DIR_RULES_AUTONOMIC + "/sample.drl-invalid-extension" );
Utils.copyStream( ruleFile, ruleFileCopy );
String s = Utils.readFileContent( ruleFile );
s = s.replace( "scale", "inexisting-command" );
Utils.writeStringInto( s, ruleFile );
// Load it and verify it contains errors
ApplicationLoadResult alr = RuntimeModelIo.loadApplication( newDir );
List<RoboconfError> criticalErrors = new ArrayList<> ();
for( RoboconfError error : alr.getLoadErrors()) {
if( error.getErrorCode().getLevel() == ErrorLevel.SEVERE )
criticalErrors.add( error );
}
Assert.assertEquals( 2, criticalErrors.size());
Assert.assertEquals( ErrorCode.RULE_UNKNOWN_COMMAND, criticalErrors.get( 0 ).getErrorCode());
Assert.assertEquals( ErrorCode.PROJ_INVALID_RULE_EXT, criticalErrors.get( 1 ).getErrorCode());
}
@Test
public void testParsingWithInexistingDirectory() {
ApplicationLoadResult alr = RuntimeModelIo.loadApplication( new File( "inexiting" ));
Assert.assertNotNull( alr.getApplicationTemplate());
Assert.assertNull( alr.getApplicationTemplate().getGraphs());
Assert.assertNotSame( 0, alr.getLoadErrors().size());
}
@Test
public void testParsingWithInstancesAndComponentExtensions() throws Exception {
File dir = TestUtils.findApplicationDirectory( "component-extensions" );
Assert.assertTrue( dir.isDirectory());
ApplicationLoadResult alr = RuntimeModelIo.loadApplication( dir );
Assert.assertFalse( RoboconfErrorHelpers.containsCriticalErrors( alr.getLoadErrors()));
// Ambiguous overriding with multiple inheritance
Instance ambiguous = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/container-bootstrap-vm/ambiguous" );
Assert.assertNotNull( ambiguous );
Map<String,String> exportedVariables = InstanceHelpers.findAllExportedVariables( ambiguous );
Assert.assertEquals( 9, exportedVariables.size());
Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "PetalsJBIComponent.componentId" ));
Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "PetalsSL.componentId" ));
Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "PetalsSLPostgreSQL.componentId" ));
Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "componentId" ));
Assert.assertEquals( "SL", exportedVariables.get( "PetalsSL.componentType" ));
Assert.assertEquals( "SL", exportedVariables.get( "PetalsSLPostgreSQL.componentType" ));
Assert.assertEquals( "true", exportedVariables.get( "PetalsSLPostgreSQL.present" ));
Assert.assertEquals( "roboconf-demo", exportedVariables.get( "domainName" ));
Assert.assertEquals( "roboconf-demo-1", exportedVariables.get( "subdomainName" ));
// Specific overriding with multiple inheritance
Instance specific = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/container-bootstrap-vm/specific" );
Assert.assertNotNull( specific );
exportedVariables = InstanceHelpers.findAllExportedVariables( specific );
Assert.assertEquals( 7, exportedVariables.size());
Assert.assertEquals( "comp", exportedVariables.get( "PetalsJBIComponent.componentId" ));
Assert.assertEquals( "sl", exportedVariables.get( "PetalsSL.componentId" ));
Assert.assertEquals( "last", exportedVariables.get( "PetalsSLPostgreSQL.componentId" ));
Assert.assertNull( exportedVariables.get( "componentId" ));
Assert.assertEquals( "SL", exportedVariables.get( "PetalsSL.componentType" ));
Assert.assertEquals( "SL", exportedVariables.get( "PetalsSLPostgreSQL.componentType" ));
Assert.assertEquals( "true", exportedVariables.get( "PetalsSLPostgreSQL.present" ));
Assert.assertEquals( "roboconf-demo", exportedVariables.get( "domainName" ));
Assert.assertNull( exportedVariables.get( "subdomainName" ));
// Instance from a super component
Instance superInstance = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/container-bootstrap-vm/superInstance" );
Assert.assertNotNull( superInstance );
exportedVariables = InstanceHelpers.findAllExportedVariables( superInstance );
Assert.assertEquals( 4, exportedVariables.size());
Assert.assertEquals( "my-sl", exportedVariables.get( "PetalsJBIComponent.componentId" ));
Assert.assertEquals( "my-sl", exportedVariables.get( "PetalsSL.componentId" ));
Assert.assertEquals( "my-sl", exportedVariables.get( "componentId" ));
Assert.assertEquals( "SL", exportedVariables.get( "PetalsSL.componentType" ));
Assert.assertNull( exportedVariables.get( "PetalsSLPostgreSQL.componentId" ));
Assert.assertNull( exportedVariables.get( "domainName" ));
Assert.assertNull( exportedVariables.get( "subdomainName" ));
}
}