package alien4cloud.tosca.parser; import java.io.FileNotFoundException; import java.nio.file.Paths; import java.util.List; import java.util.Set; import java.util.Map.Entry; import javax.annotation.Resource; import org.alien4cloud.tosca.model.definitions.PropertyConstraint; import org.alien4cloud.tosca.model.definitions.PropertyDefinition; import org.alien4cloud.tosca.model.definitions.RequirementDefinition; import org.alien4cloud.tosca.model.definitions.ScalarPropertyValue; import org.alien4cloud.tosca.model.definitions.constraints.GreaterThanConstraint; import org.alien4cloud.tosca.model.definitions.constraints.LessThanConstraint; import org.alien4cloud.tosca.model.definitions.constraints.MaxLengthConstraint; import org.alien4cloud.tosca.model.definitions.constraints.MinLengthConstraint; import org.alien4cloud.tosca.model.types.CapabilityType; import org.alien4cloud.tosca.model.types.NodeType; import org.alien4cloud.tosca.model.types.RelationshipType; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.google.common.collect.Lists; import alien4cloud.component.ICSARRepositorySearchService; import alien4cloud.tosca.ArchiveParserTest; import alien4cloud.tosca.model.ArchiveRoot; import alien4cloud.tosca.parser.impl.ErrorCode; import alien4cloud.utils.MapUtil; /** * Test tosca parsing for Tosca Simple profile in YAML wd03 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:tosca/parser-application-context.xml") public abstract class AbstractToscaParserSimpleProfileTest { protected abstract String getRootDirectory(); protected abstract String getToscaVersion(); @Resource protected ToscaParser parser; @Resource protected ICSARRepositorySearchService csarRepositorySearchService; @Test public void testDefinitionVersionValid() throws FileNotFoundException, ParsingException { ParsingResult<ArchiveRoot> parsingResult = parser.parseFile(Paths.get(getRootDirectory(), "tosca-definition-version.yml")); Assert.assertEquals(0, parsingResult.getContext().getParsingErrors().size()); ArchiveRoot archiveRoot = parsingResult.getResult(); Assert.assertNotNull(archiveRoot.getArchive()); Assert.assertEquals(getToscaVersion(), archiveRoot.getArchive().getToscaDefinitionsVersion()); } @SuppressWarnings("unchecked") @Test public void testNodeType() throws FileNotFoundException, ParsingException { Mockito.reset(csarRepositorySearchService); NodeType mockedResult = Mockito.mock(NodeType.class); Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(NodeType.class), Mockito.eq("tosca.nodes.SoftwareComponent"), Mockito.any(Set.class))).thenReturn(mockedResult); Mockito.when(mockedResult.getDerivedFrom()).thenReturn(Lists.newArrayList("tosca.nodes.Root")); Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(NodeType.class), Mockito.eq("tosca.nodes.Root"), Mockito.any(Set.class))) .thenReturn(mockedResult); Mockito.when( csarRepositorySearchService.getElementInDependencies(Mockito.eq(NodeType.class), Mockito.eq("tosca.nodes.Compute"), Mockito.any(Set.class))) .thenReturn(mockedResult); CapabilityType mockedCapabilityResult = Mockito.mock(CapabilityType.class); Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(CapabilityType.class), Mockito.eq("mytypes.mycapabilities.MyCapabilityTypeName"), Mockito.any(Set.class))).thenReturn(mockedCapabilityResult); Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(CapabilityType.class), Mockito.eq("mytypes.mycapabilities.MyCapabilityTypeName"), Mockito.any(Set.class))).thenReturn(mockedCapabilityResult); Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(CapabilityType.class), Mockito.eq("tosca.capabilities.Endpoint"), Mockito.any(Set.class))).thenReturn(mockedCapabilityResult); RelationshipType hostedOn = new RelationshipType(); Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(RelationshipType.class), Mockito.eq("tosca.relationships.HostedOn"), Mockito.any(Set.class))).thenReturn(hostedOn); ParsingResult<ArchiveRoot> parsingResult = parser.parseFile(Paths.get(getRootDirectory(), "tosca-node-type.yml")); ArchiveParserTest.displayErrors(parsingResult); assertNoBlocker(parsingResult); ArchiveRoot archiveRoot = parsingResult.getResult(); Assert.assertNotNull(archiveRoot.getArchive()); Assert.assertEquals(getToscaVersion(), archiveRoot.getArchive().getToscaDefinitionsVersion()); Assert.assertEquals(1, archiveRoot.getNodeTypes().size()); // check node type. Entry<String, NodeType> entry = archiveRoot.getNodeTypes().entrySet().iterator().next(); Assert.assertEquals("my_company.my_types.MyAppNodeType", entry.getKey()); NodeType nodeType = entry.getValue(); Assert.assertEquals(Lists.newArrayList("tosca.nodes.SoftwareComponent", "tosca.nodes.Root"), nodeType.getDerivedFrom()); Assert.assertEquals("My company’s custom applicaton", nodeType.getDescription()); // validate properties parsing Assert.assertEquals(4, nodeType.getProperties().size()); PropertyDefinition def1 = new PropertyDefinition(); def1.setType("string"); def1.setDefault(new ScalarPropertyValue("default")); def1.setDescription("application password"); List<PropertyConstraint> constraints = Lists.newArrayList(); constraints.add(new MinLengthConstraint(6)); constraints.add(new MaxLengthConstraint(10)); def1.setConstraints(constraints); PropertyDefinition def2 = new PropertyDefinition(); def2.setType("integer"); def2.setDescription("application port number"); PropertyDefinition def3 = new PropertyDefinition(); def3.setType("scalar-unit.size"); def3.setDefault(new ScalarPropertyValue("1 GB")); LessThanConstraint ltConstraint = new LessThanConstraint(); ltConstraint.setLessThan("1 TB"); constraints = Lists.<PropertyConstraint> newArrayList(ltConstraint); def3.setConstraints(constraints); PropertyDefinition def4 = new PropertyDefinition(); def4.setType("scalar-unit.time"); def4.setDefault(new ScalarPropertyValue("1 d")); GreaterThanConstraint gtConstraint = new GreaterThanConstraint(); gtConstraint.setGreaterThan("1 h"); constraints = Lists.<PropertyConstraint> newArrayList(gtConstraint); def4.setConstraints(constraints); Assert.assertEquals(MapUtil.newHashMap(new String[] { "my_app_password", "my_app_duration", "my_app_size", "my_app_port" }, new PropertyDefinition[] { def1, def4, def3, def2 }), nodeType.getProperties()); // check requirements Assert.assertEquals(2, nodeType.getRequirements().size()); RequirementDefinition rd0 = nodeType.getRequirements().get(0); Assert.assertEquals("host", rd0.getId()); Assert.assertEquals(1, rd0.getLowerBound()); Assert.assertEquals(1, rd0.getUpperBound()); RequirementDefinition rd1 = nodeType.getRequirements().get(1); Assert.assertEquals("other", rd1.getId()); Assert.assertEquals(0, rd1.getLowerBound()); Assert.assertEquals(Integer.MAX_VALUE, rd1.getUpperBound()); // validate attributes parsing // nodeType.getAttributes() // nodeType.getInterfaces() // nodeType.getCapabilities() // nodeType.get } public static int countErrorByLevelAndCode(ParsingResult<?> parsingResult, ParsingErrorLevel errorLevel, ErrorCode errorCode) { int finalCount = 0; for (int i = 0; i < parsingResult.getContext().getParsingErrors().size(); i++) { ParsingError error = parsingResult.getContext().getParsingErrors().get(i); if (error.getErrorLevel().equals(errorLevel) && (error.getErrorCode().equals(errorCode) || errorCode == null)) { finalCount++; } } return finalCount; } public static void assertNoBlocker(ParsingResult<?> parsingResult) { Assert.assertFalse(countErrorByLevelAndCode(parsingResult, ParsingErrorLevel.ERROR, null) > 0); } }