/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.project.server; import org.eclipse.che.api.core.ForbiddenException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.notification.EventService; import org.eclipse.che.api.project.server.handlers.ProjectHandler; import org.eclipse.che.api.project.server.handlers.ProjectHandlerRegistry; import org.eclipse.che.api.project.server.type.AttributeValue; import org.eclipse.che.api.project.server.type.ProjectType; import org.eclipse.che.api.project.server.type.ProjectTypeRegistry; import org.eclipse.che.api.project.shared.dto.ProjectUpdate; import org.eclipse.che.api.project.shared.dto.SourceEstimation; import org.eclipse.che.api.vfs.server.VirtualFile; import org.eclipse.che.api.vfs.server.VirtualFileSystemRegistry; import org.eclipse.che.api.vfs.server.VirtualFileSystemUser; import org.eclipse.che.api.vfs.server.VirtualFileSystemUserContext; import org.eclipse.che.api.vfs.server.impl.memory.MemoryFileSystemProvider; import org.eclipse.che.api.vfs.server.impl.memory.MemoryMountPoint; import org.eclipse.che.dto.server.DtoFactory; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.util.*; /** * @author andrew00x */ public class ProjectTest { private static final String vfsUserName = "dev"; private static final Set<String> vfsUserGroups = new LinkedHashSet<>(Arrays.asList("workspace/developer")); private ProjectManager pm; private static List<String> calculateAttributeValueHolder = Collections.singletonList("hello"); @BeforeMethod public void setUp() throws Exception { final ValueProviderFactory vpf1 = new ValueProviderFactory() { @Override public ValueProvider newInstance(FolderEntry projectFolder) { return new ValueProvider() { @Override public List<String> getValues(String attributeName) { return calculateAttributeValueHolder; //Collections.singletonList("hello"); } @Override public void setValues(String attributeName, List<String> value) { calculateAttributeValueHolder = value; } }; } }; ProjectType pt = new ProjectType("my_project_type", "my project type", true, false) { { addVariableDefinition("calculated_attribute", "attr description", true, vpf1); addVariableDefinition("my_property_1", "attr description", true); addVariableDefinition("my_property_2", "attr description", false); setDefaultBuilder("builder1"); setDefaultRunner("system:/runner/runner1"); } }; Set <ProjectType> types = new HashSet<ProjectType>(); types.add(pt); ProjectTypeRegistry ptRegistry = new ProjectTypeRegistry(types); final EventService eventService = new EventService(); VirtualFileSystemRegistry vfsRegistry = new VirtualFileSystemRegistry(); final MemoryFileSystemProvider memoryFileSystemProvider = new MemoryFileSystemProvider("my_ws", eventService, new VirtualFileSystemUserContext() { @Override public VirtualFileSystemUser getVirtualFileSystemUser() { return new VirtualFileSystemUser(vfsUserName, vfsUserGroups); } }, vfsRegistry); MemoryMountPoint mmp = (MemoryMountPoint)memoryFileSystemProvider.getMountPoint(true); vfsRegistry.registerProvider("my_ws", memoryFileSystemProvider); //ProjectGeneratorRegistry pgRegistry = new ProjectGeneratorRegistry(new HashSet<ProjectGenerator>()); ProjectHandlerRegistry phRegistry = new ProjectHandlerRegistry(new HashSet<ProjectHandler>()); pm = new DefaultProjectManager(vfsRegistry, eventService, ptRegistry, phRegistry); ((DefaultProjectManager)pm).start(); VirtualFile myVfRoot = mmp.getRoot(); myVfRoot.createFolder("my_project").createFolder(Constants.CODENVY_DIR).createFile(Constants.CODENVY_PROJECT_FILE, null, null); // myVfRoot.createFolder("testEstimateProject"); } @AfterMethod public void tearDown() { ((DefaultProjectManager)pm).stop(); } @Test public void testGetProject() throws Exception { Project myProject = pm.getProject("my_ws", "my_project"); Assert.assertNotNull(myProject); } @Test public void testGetProjectDescriptor() throws Exception { Project myProject = pm.getProject("my_ws", "my_project"); Map<String, List<String>> attributes = new HashMap<>(3); //attributes.put("calculated_attribute", Arrays.asList("hello")); attributes.put("my_property_1", Arrays.asList("value_1", "value_2")); attributes.put("my_property_2", Arrays.asList("value_3", "value_4")); ProjectJson json = new ProjectJson(); json.withType("my_project_type").withAttributes(attributes).save(myProject); //ProjectDescription myProjectDescription = myProject.getDescription(); //System.out.println("JSON >> "+json.getAttributes()); //System.out.println(">> >>"+pm.getValueProviderFactories()); ProjectConfig myConfig = myProject.getConfig(); Assert.assertEquals(myConfig.getTypeId(), "my_project_type"); //Assert.assertEquals(myProjectDescription.getProjectType().getName(), "my_project_type"); Assert.assertEquals(pm.getProjectTypeRegistry().getProjectType("my_project_type").getAttributes().size(), 3); //System.out.println(">>>>"+myConfig.getAttribute("calculated_attribute")); Assert.assertEquals(myConfig.getAttributes().size(), 3); AttributeValue attributeVal; Assert.assertNotNull(myConfig.getAttributes().get("calculated_attribute")); attributeVal = myConfig.getAttributes().get("calculated_attribute"); Assert.assertEquals(attributeVal.getList(), Arrays.asList("hello")); Assert.assertNotNull(myConfig.getAttributes().get("my_property_1")); attributeVal = myConfig.getAttributes().get("my_property_1"); Assert.assertEquals(attributeVal.getList(), Arrays.asList("value_1", "value_2")); Assert.assertNotNull(myConfig.getAttributes().get("my_property_2")); attributeVal = myConfig.getAttributes().get("my_property_2"); Assert.assertEquals(attributeVal.getList(), Arrays.asList("value_3", "value_4")); } @Test public void testUpdateProjectDescriptor() throws Exception { Project myProject = pm.getProject("my_ws", "my_project"); Map<String, List<String>> attributes = new HashMap<>(2); attributes.put("my_property_1", Arrays.asList("value_1", "value_2")); ProjectJson projectJson = new ProjectJson("my_project_type", attributes, null, null, "test project"); projectJson.save(myProject); Map <String, AttributeValue> attrs = new HashMap<>(); attrs.put("calculated_attribute", new AttributeValue("updated calculated_attribute")); attrs.put("my_property_1", new AttributeValue("updated value 1")); // wont stored attrs.put("new_my_property_2", new AttributeValue("new value 2")); ProjectConfig myConfig = new ProjectConfig("descr", "my_project_type", attrs, null, null, null); myProject.updateConfig(myConfig); projectJson = ProjectJson.load(myProject); Assert.assertEquals(projectJson.getType(), "my_project_type"); Assert.assertEquals(calculateAttributeValueHolder, Arrays.asList("updated calculated_attribute")); Map<String, List<String>> pm = projectJson.getAttributes(); // only stored (non-provided) attributes Assert.assertEquals(pm.size(), 1); Assert.assertEquals(pm.get("my_property_1"), Arrays.asList("updated value 1")); } @Test public void testModificationDate() throws Exception { Project myProject = pm.getProject("my_ws", "my_project"); long modificationDate1 = myProject.getModificationDate(); Thread.sleep(1000); myProject.getBaseFolder().createFile("test.txt", "test".getBytes(), "text/plain"); long modificationDate2 = myProject.getModificationDate(); Assert.assertTrue(modificationDate2 > modificationDate1); } @Test public void testIfDefaultBuilderRunnerAppearsInProject() throws Exception { Project myProject = pm.getProject("my_ws", "my_project"); Map<String, List<String>> attributes = new HashMap<>(2); attributes.put("my_property_1", Arrays.asList("value_1", "value_2")); ProjectJson projectJson = new ProjectJson("my_project_type", attributes, null , null, "test project"); projectJson.save(myProject); Assert.assertNotNull(myProject.getConfig().getRunners()); Assert.assertEquals(myProject.getConfig().getRunners().getDefault(), "system:/runner/runner1"); Assert.assertNotNull(myProject.getConfig().getBuilders()); Assert.assertEquals(myProject.getConfig().getBuilders().getDefault(), "builder1"); } @Test public void testEstimateProject() throws Exception { VirtualFile root = pm.getVirtualFileSystemRegistry().getProvider("my_ws").getMountPoint(false).getRoot(); root.createFolder("testEstimateProjectGood").createFolder("check"); root.createFolder("testEstimateProjectBad"); final ValueProviderFactory vpf1 = new ValueProviderFactory() { @Override public ValueProvider newInstance(final FolderEntry projectFolder) { return new ValueProvider() { @Override public List<String> getValues(String attributeName) throws ValueStorageException { VirtualFileEntry file = null; try { file = projectFolder.getChild("check"); } catch (ForbiddenException e) { throw new ValueStorageException(e.getMessage()); } catch (ServerException e) { throw new ValueStorageException(e.getMessage()); } if(file == null) throw new ValueStorageException("Check not found"); return Collections.singletonList("checked"); } @Override public void setValues(String attributeName, List<String> value) { //calculateAttributeValueHolder = value; } }; } }; ProjectType pt = new ProjectType("testEstimateProjectPT", "my testEstimateProject type", true, false) { { addVariableDefinition("calculated_attribute", "attr description", true, vpf1); addVariableDefinition("my_property_1", "attr description", true); addVariableDefinition("my_property_2", "attr description", false); setDefaultBuilder("builder1"); setDefaultRunner("system:/runner/runner1"); } }; pm.getProjectTypeRegistry().registerProjectType(pt); Map<String, AttributeValue> attrs = pm.estimateProject("my_ws", "testEstimateProjectGood", "testEstimateProjectPT"); Assert.assertEquals(attrs.size(), 1); Assert.assertNotNull(attrs.get("calculated_attribute")); Assert.assertEquals(attrs.get("calculated_attribute").getString(), "checked"); try { pm.estimateProject("my_ws", "testEstimateProjectBad", "testEstimateProjectPT"); Assert.fail("ValueStorageException should be thrown"); } catch (ValueStorageException e) { } } @Test public void testResolveSources() throws Exception { VirtualFile root = pm.getVirtualFileSystemRegistry().getProvider("my_ws").getMountPoint(false).getRoot(); root.createFolder("testEstimateProjectGood").createFolder("check"); root.createFolder("testEstimateProjectBad"); final ValueProviderFactory vpf1 = new ValueProviderFactory() { @Override public ValueProvider newInstance(final FolderEntry projectFolder) { return new ValueProvider() { @Override public List<String> getValues(String attributeName) throws ValueStorageException { VirtualFileEntry file = null; try { file = projectFolder.getChild("check"); } catch (ForbiddenException e) { throw new ValueStorageException(e.getMessage()); } catch (ServerException e) { throw new ValueStorageException(e.getMessage()); } if(file == null) throw new ValueStorageException("Check not found"); return Collections.singletonList("checked"); } @Override public void setValues(String attributeName, List<String> value) { //calculateAttributeValueHolder = value; } }; } }; ProjectType pt = new ProjectType("testEstimateProjectPT", "my testEstimateProject type", true, false) { { addVariableDefinition("my_calculated_attribute", "attr description", true, vpf1); addVariableDefinition("my_property_1", "attr description", true); addVariableDefinition("my_property_2", "attr description", false); setDefaultBuilder("builder1"); setDefaultRunner("system:/runner/runner1"); } }; pm.getProjectTypeRegistry().registerProjectType(pt); List<SourceEstimation> estimations = pm.resolveSources("my_ws", "testEstimateProjectGood", false); Assert.assertEquals(estimations.size(), 2); // Assert.assertEquals(estimations.get(0).getAttributes().get("my_calculated_attribute").get(0), "checked"); // Assert.assertEquals(estimations.get(0).getType(), "testEstimateProjectPT"); estimations = pm.resolveSources("my_ws", "testEstimateProjectBad", false); Assert.assertEquals(estimations.size(), 1); // Assert.assertNotNull(attrs.get("calculated_attribute")); // Assert.assertEquals(attrs.get("calculated_attribute").getString(), "checked"); // // // try { // pm.estimateProject("my_ws", "testEstimateProjectBad", "testEstimateProjectPT"); // Assert.fail("ValueStorageException should be thrown"); // } catch (ValueStorageException e) { // // } } @Test public void testPTConstraints() throws Exception { pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testMixinAndPrimary", "my type", true, true) {}); pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testPrimary", "my type", true, false) {}); pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testMixin", "my type", false, true) {}); pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testAbstract", "my type", false, false) {}); pm.createProject("my_ws", "all", new ProjectConfig("proj", "testMixinAndPrimary"), null, null); pm.createProject("my_ws", "prim", new ProjectConfig("proj", "testPrimary"), null, null); // not possible to create Project with wrong PT try { pm.createProject("my_ws", "mix", new ProjectConfig("proj", "testMixin"), null, null); Assert.fail("ProjectTypeConstraintException expected"); } catch (ProjectTypeConstraintException e) { } try { pm.createProject("my_ws", "abstr", new ProjectConfig("proj", "testAbstract"), null, null); Assert.fail("ProjectTypeConstraintException expected"); } catch (ProjectTypeConstraintException e) { } ProjectConfig config = pm.getProject("my_ws", "all").getConfig(); config.getMixinTypes().add("testMixin"); pm.getProject("my_ws", "all").updateConfig(config); // not possible to add wrong mixin PT config.getMixinTypes().add("testAbstract"); try { pm.getProject("my_ws", "all").updateConfig(config); Assert.fail("ProjectTypeConstraintException expected"); } catch (ProjectTypeConstraintException e) {} } @Test public void testAddMixin() throws Exception { pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testPrimary", "my type", true, false) { { addConstantDefinition("c1", "","c1"); } }); pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testMixin", "my type", false, true) { { addConstantDefinition("m1", "","m1"); } }); pm.createProject("my_ws", "p1", new ProjectConfig("proj", "testPrimary"), null, null); // pm.createProject("my_ws", "p2", new ProjectConfig("proj", "testPrimary"), null, null); ProjectConfig config = pm.getProject("my_ws", "p1").getConfig(); Assert.assertEquals(config.getMixinTypes().size(), 0); Assert.assertEquals(config.getAttributes().size(), 1); config.getMixinTypes().add("testMixin"); pm.getProject("my_ws", "p1").updateConfig(config); config = pm.getProject("my_ws", "p1").getConfig(); Assert.assertEquals(config.getMixinTypes().size(), 1); Assert.assertEquals("testMixin", config.getMixinTypes().get(0)); Assert.assertEquals(config.getAttributes().size(), 2); // add same mixin as existed config.getMixinTypes().add("testMixin"); try { pm.getProject("my_ws", "p1").updateConfig(config); Assert.fail("ProjectTypeConstraintException (duplicated attributes) expected"); } catch (ProjectTypeConstraintException e) { } //config = pm.getProject("my_ws", "p1").getConfig(); //Assert.assertEquals(config.getMixinTypes().size(), 1); } @Test public void testAddMixinWithProvidedAttrs() throws Exception { final ValueProviderFactory vpfPrimary = new ValueProviderFactory() { @Override public ValueProvider newInstance(final FolderEntry projectFolder) { return new ValueProvider() { @Override public List<String> getValues(String attributeName) throws ValueStorageException { VirtualFileEntry file = checkFolder(); if(file == null) throw new ValueStorageException("Primary folder not found"); return Collections.singletonList("checked"); } @Override public void setValues(String attributeName, List<String> value) throws ValueStorageException { if(checkFolder() == null) { try { projectFolder.createFolder("primary"); } catch (Exception e) { throw new ValueStorageException(e.getMessage()); } } } private VirtualFileEntry checkFolder() throws ValueStorageException { VirtualFileEntry file = null; try { file = projectFolder.getChild("primary"); } catch (Exception e) { throw new ValueStorageException(e.getMessage()); } return file; } }; } }; final ValueProviderFactory vpfMixin = new ValueProviderFactory() { @Override public ValueProvider newInstance(final FolderEntry projectFolder) { return new ValueProvider() { @Override public List<String> getValues(String attributeName) throws ValueStorageException { VirtualFileEntry file = checkFolder(); if(file == null) throw new ValueStorageException("Mixin folder not found"); return Collections.singletonList("checked"); } @Override public void setValues(String attributeName, List<String> value) throws ValueStorageException { if(checkFolder() == null) { try { projectFolder.createFolder("mixin"); } catch (Exception e) { throw new ValueStorageException(e.getMessage()); } } } private VirtualFileEntry checkFolder() throws ValueStorageException { VirtualFileEntry file = null; try { file = projectFolder.getChild("mixin"); } catch (Exception e) { throw new ValueStorageException(e.getMessage()); } return file; } }; } }; pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testPrimary", "my type", true, false) { { addVariableDefinition("p.calculate", "", true, vpfPrimary); } }); pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testMixin", "my type", false, true) { { addVariableDefinition("m.calculate", "", true, vpfMixin); } }); Map <String, AttributeValue> attrs = new HashMap<>(); attrs.put("p.calculate", new AttributeValue("")); ProjectConfig config = new ProjectConfig("proj", "testPrimary", attrs, null, null, null); Project proj = pm.createProject("my_ws", "provided", config , null, null); Assert.assertEquals(proj.getConfig().getMixinTypes().size(), 0); Assert.assertEquals(proj.getConfig().getAttributes().get("p.calculate").getString(), "checked"); config.getMixinTypes().add("testMixin"); config.getAttributes().put("m.calculate", new AttributeValue("")); proj.updateConfig(config); Assert.assertEquals(proj.getConfig().getMixinTypes().size(), 1); Assert.assertEquals(proj.getConfig().getAttributes().get("m.calculate").getString(), "checked"); // reread it in case proj = pm.getProject("my_ws", "provided"); Assert.assertEquals(proj.getConfig().getMixinTypes().size(), 1); Assert.assertEquals(proj.getConfig().getAttributes().get("p.calculate").getString(), "checked"); Assert.assertEquals(proj.getConfig().getAttributes().get("m.calculate").getString(), "checked"); } @Test public void testAddModule() throws Exception { pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testModule", "my type", true, false) { }); Project myProject = pm.getProject("my_ws", "my_project"); myProject.updateConfig(new ProjectConfig("my proj", "testModule")); Assert.assertEquals(myProject.getModules().get().size(), 0); pm.addModule("my_ws", "my_project", "test", new ProjectConfig("descr", "testModule"), null, null); Assert.assertEquals(myProject.getModules().get().size(), 1); Assert.assertEquals(myProject.getModules().get().iterator().next(), "test"); } @Test public void testAddFolderAndProjectAsAModule() throws Exception { pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testAddFolderAsAModule", "my type", true, false) { }); Project parent = pm.getProject("my_ws", "my_project"); parent.updateConfig(new ProjectConfig("my proj", "testAddFolderAsAModule")); Assert.assertEquals(parent.getModules().get().size(), 0); parent.getBaseFolder().createFolder("module"); pm.addModule("my_ws", "my_project", "module", new ProjectConfig("my proj", "testAddFolderAsAModule"), null, null); Assert.assertEquals(parent.getModules().get().size(), 1); Assert.assertEquals(parent.getModules().get().iterator().next(), "module"); Project module2 = pm.createProject("my_ws", "module2", new ProjectConfig("my proj", "testAddFolderAsAModule"), null, null); pm.addModule("my_ws", "my_project", "/module2", null, null, null); Assert.assertEquals(parent.getModules().get().size(), 2); } @Test public void testDtoConverterWithMixin() throws Exception { //final ProjectTypeRegistry registry = injector.getInstance(ProjectTypeRegistry.class); pm.getProjectTypeRegistry().registerProjectType(new ProjectType("testDtoConverterWithMixin", "my type", false, true) { { addVariableDefinition("var2", "var", true); } }); final Map<String, List<String>> attributes = new HashMap<>(); attributes.put("var2", Arrays.asList("var2Value")); final ProjectUpdate projectUpdate = DtoFactory.getInstance().createDto(ProjectUpdate.class) .withType("blank") .withMixinTypes(Arrays.asList("testDtoConverterWithMixin")) .withAttributes(attributes); final ProjectConfig projectConfig = DtoConverter.fromDto2(projectUpdate, pm.getProjectTypeRegistry()); Assert.assertEquals(projectConfig.getTypeId(), "blank"); Assert.assertEquals(projectConfig.getMixinTypes(), Arrays.asList("testDtoConverterWithMixin")); // here the attribute is null because the project type is not the owner of the attribute but we have // a mixin so it should works ? Assert.assertEquals(projectConfig.getAttributes().get("var2"), new AttributeValue("var2Value")); } }