/*******************************************************************************
* Copyright (c) 2012-2017 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.factory.server.spi.tck;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.model.factory.Button;
import org.eclipse.che.api.factory.server.FactoryImage;
import org.eclipse.che.api.factory.server.model.impl.ActionImpl;
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl;
import org.eclipse.che.api.factory.server.model.impl.ButtonAttributesImpl;
import org.eclipse.che.api.factory.server.model.impl.ButtonImpl;
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
import org.eclipse.che.api.factory.server.model.impl.IdeImpl;
import org.eclipse.che.api.factory.server.model.impl.OnAppClosedImpl;
import org.eclipse.che.api.factory.server.model.impl.OnAppLoadedImpl;
import org.eclipse.che.api.factory.server.model.impl.OnProjectsLoadedImpl;
import org.eclipse.che.api.factory.server.model.impl.PoliciesImpl;
import org.eclipse.che.api.factory.server.spi.FactoryDao;
import org.eclipse.che.api.machine.server.model.impl.CommandImpl;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentRecipeImpl;
import org.eclipse.che.api.workspace.server.model.impl.ExtendedMachineImpl;
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.ServerConf2Impl;
import org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.commons.lang.Pair;
import org.eclipse.che.commons.test.tck.TckListener;
import org.eclipse.che.commons.test.tck.repository.TckRepository;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static java.util.stream.Collectors.toList;
import static org.testng.Assert.assertEquals;
/**
* Tests {@link FactoryDao} contract.
*
* @author Anton Korneta
*/
@Listeners(TckListener.class)
@Test(suiteName = FactoryDaoTest.SUITE_NAME)
public class FactoryDaoTest {
public static final String SUITE_NAME = "FactoryDaoTck";
private static final int ENTRY_COUNT = 5;
private FactoryImpl[] factories;
private UserImpl[] users;
@Inject
private FactoryDao factoryDao;
@Inject
private TckRepository<FactoryImpl> factoryTckRepository;
@Inject
private TckRepository<UserImpl> userTckRepository;
@BeforeMethod
public void setUp() throws Exception {
factories = new FactoryImpl[ENTRY_COUNT];
users = new UserImpl[ENTRY_COUNT];
for (int i = 0; i < ENTRY_COUNT; i++) {
users[i] = new UserImpl("userId_" + i, "email_" + i, "name" + i);
}
for (int i = 0; i < ENTRY_COUNT; i++) {
factories[i] = createFactory(i, users[i].getId());
}
userTckRepository.createAll(Arrays.asList(users));
factoryTckRepository.createAll(Stream.of(factories).map(FactoryImpl::new).collect(toList()));
}
@AfterMethod
public void cleanUp() throws Exception {
factoryTckRepository.removeAll();
userTckRepository.removeAll();
}
@Test(dependsOnMethods = "shouldGetFactoryById")
public void shouldCreateFactory() throws Exception {
final FactoryImpl factory = createFactory(10, users[0].getId());
factory.getCreator().setUserId(factories[0].getCreator().getUserId());
factoryDao.create(factory);
assertEquals(factoryDao.getById(factory.getId()), new FactoryImpl(factory));
}
@Test(expectedExceptions = NullPointerException.class)
public void shouldThrowNpeWhenCreateNullFactory() throws Exception {
factoryDao.create(null);
}
@Test(expectedExceptions = ConflictException.class)
public void shouldThrowConflictExceptionWhenCreatingFactoryWithExistingId() throws Exception {
final FactoryImpl factory = createFactory(10, users[0].getId());
final FactoryImpl existing = factories[0];
factory.getCreator().setUserId(existing.getCreator().getUserId());
factory.setId(existing.getId());
factoryDao.create(factory);
}
@Test(expectedExceptions = ConflictException.class)
public void shouldThrowConflictExceptionWhenCreatingFactoryWithExistingNameAndUserId() throws Exception {
final FactoryImpl factory = createFactory(10, users[0].getId());
final FactoryImpl existing = factories[0];
factory.getCreator().setUserId(existing.getCreator().getUserId());
factory.setName(existing.getName());
factoryDao.create(factory);
}
@Test
public void shouldUpdateFactory() throws Exception {
final FactoryImpl update = factories[0];
final String userId = update.getCreator().getUserId();
update.setName("new-name");
update.setV("5_0");
final long currentTime = System.currentTimeMillis();
update.setPolicies(new PoliciesImpl("ref", "per-click", currentTime, currentTime + 1000));
update.setCreator(new AuthorImpl(userId, currentTime));
update.setButton(new ButtonImpl(new ButtonAttributesImpl("green", "icon", "opacity 0.9", true),
Button.Type.NOLOGO));
update.getIde().getOnAppClosed().getActions().add(new ActionImpl("remove file", ImmutableMap.of("file1", "/che/core/pom.xml")));
update.getIde().getOnAppLoaded().getActions().add(new ActionImpl("edit file", ImmutableMap.of("file2", "/che/core/pom.xml")));
update.getIde().getOnProjectsLoaded().getActions().add(new ActionImpl("open file", ImmutableMap.of("file2", "/che/pom.xml")));
factoryDao.update(update);
assertEquals(factoryDao.getById(update.getId()), update);
}
@Test(expectedExceptions = ConflictException.class)
public void shouldThrowConflictExceptionWhenUpdateFactoryWithExistingNameAndUserId() throws Exception {
final FactoryImpl update = factories[0];
update.setName(factories[1].getName());
update.getCreator().setUserId(factories[1].getCreator().getUserId());
factoryDao.update(update);
}
@Test(expectedExceptions = NullPointerException.class)
public void shouldThrowNpeWhenFactoryUpdateIsNull() throws Exception {
factoryDao.update(null);
}
@Test(expectedExceptions = NotFoundException.class)
public void shouldThrowNotFoundExceptionWhenUpdatingNonExistingFactory() throws Exception {
factoryDao.update(createFactory(10, users[0].getId()));
}
@Test
public void shouldGetFactoryById() throws Exception {
final FactoryImpl factory = factories[0];
assertEquals(factoryDao.getById(factory.getId()), factory);
}
@Test(expectedExceptions = NullPointerException.class)
public void shouldThrowNpeWhenGettingFactoryByNullId() throws Exception {
factoryDao.getById(null);
}
@Test(expectedExceptions = NotFoundException.class)
public void shouldThrowNotFoundExceptionWhenFactoryWithGivenIdDoesNotExist() throws Exception {
factoryDao.getById("non-existing");
}
@Test
public void shouldGetFactoryByIdAttribute() throws Exception {
final FactoryImpl factory = factories[0];
final List<Pair<String, String>> attributes = ImmutableList.of(Pair.of("id", factory.getId()));
final List<FactoryImpl> result = factoryDao.getByAttribute(1, 0, attributes);
assertEquals(new HashSet<>(result), ImmutableSet.of(factory));
}
@Test(dependsOnMethods = "shouldUpdateFactory")
public void shouldFindFactoryByEmbeddedAttributes() throws Exception {
final List<Pair<String, String>> attributes = ImmutableList.of(Pair.of("policies.referer", "referrer"),
Pair.of("policies.create", "perClick"),
Pair.of("workspace.defaultEnv", "env1"));
final FactoryImpl factory1 = factories[1];
final FactoryImpl factory3 = factories[3];
factory1.getPolicies().setCreate("perAccount");
factory3.getPolicies().setReferer("ref2");
factoryDao.update(factory1);
factoryDao.update(factory3);
final List<FactoryImpl> result = factoryDao.getByAttribute(factories.length, 0, attributes);
assertEquals(new HashSet<>(result), ImmutableSet.of(factories[0], factories[2], factories[4]));
}
@Test
public void shouldFindAllFactoriesWhenAttributesNotSpecified() throws Exception {
final List<Pair<String, String>> attributes = emptyList();
final List<FactoryImpl> result = factoryDao.getByAttribute(factories.length, 0, attributes);
assertEquals(new HashSet<>(result), new HashSet<>(asList(factories)));
}
@Test(expectedExceptions = NotFoundException.class, dependsOnMethods = "shouldGetFactoryById")
public void shouldRemoveFactory() throws Exception {
final String factoryId = factories[0].getId();
factoryDao.remove(factoryId);
factoryDao.getById(factoryId);
}
@Test(expectedExceptions = NullPointerException.class)
public void shouldThrowNpeWhenRemovingNullFactory() throws Exception {
factoryDao.remove(null);
}
@Test
public void shouldDoNothingWhenRemovingNonExistingFactory() throws Exception {
factoryDao.remove("non-existing");
}
private static FactoryImpl createFactory(int index, String userId) {
final long timeMs = System.currentTimeMillis();
final ButtonImpl factoryButton = new ButtonImpl(new ButtonAttributesImpl("red", "logo", "style", true),
Button.Type.LOGO);
final AuthorImpl creator = new AuthorImpl(userId, timeMs);
final PoliciesImpl policies = new PoliciesImpl("referrer", "perClick", timeMs, timeMs + 1000);
final Set<FactoryImage> images = new HashSet<>();
final List<ActionImpl> a1 = new ArrayList<>(singletonList(new ActionImpl("id" + index, ImmutableMap.of("key1", "value1"))));
final OnAppLoadedImpl onAppLoaded = new OnAppLoadedImpl(a1);
final List<ActionImpl> a2 = new ArrayList<>(singletonList(new ActionImpl("id" + index, ImmutableMap.of("key2", "value2"))));
final OnProjectsLoadedImpl onProjectsLoaded = new OnProjectsLoadedImpl(a2);
final List<ActionImpl> a3 = new ArrayList<>(singletonList(new ActionImpl("id" + index, ImmutableMap.of("key3", "value3"))));
final OnAppClosedImpl onAppClosed = new OnAppClosedImpl(a3);
final IdeImpl ide = new IdeImpl(onAppLoaded, onProjectsLoaded, onAppClosed);
final FactoryImpl factory = FactoryImpl.builder()
.generateId()
.setVersion("4_0")
.setName("factoryName" + index)
.setButton(factoryButton)
.setCreator(creator)
.setPolicies(policies)
.setImages(images)
.setIde(ide)
.build();
factory.setWorkspace(createWorkspaceConfig(index));
return factory;
}
public static WorkspaceConfigImpl createWorkspaceConfig(int index) {
// Project Sources configuration
final SourceStorageImpl source1 = new SourceStorageImpl();
source1.setType("type1");
source1.setLocation("location1");
source1.setParameters(new HashMap<>(ImmutableMap.of("param1", "value1")));
final SourceStorageImpl source2 = new SourceStorageImpl();
source2.setType("type2");
source2.setLocation("location2");
source2.setParameters(new HashMap<>(ImmutableMap.of("param4", "value1")));
// Project Configuration
final ProjectConfigImpl pCfg1 = new ProjectConfigImpl();
pCfg1.setPath("/path1");
pCfg1.setType("type1");
pCfg1.setName("project1");
pCfg1.setDescription("description1");
pCfg1.getMixins().addAll(asList("mixin1", "mixin2"));
pCfg1.setSource(source1);
final ProjectConfigImpl pCfg2 = new ProjectConfigImpl();
pCfg2.setPath("/path2");
pCfg2.setType("type2");
pCfg2.setName("project2");
pCfg2.setDescription("description2");
pCfg2.getMixins().addAll(asList("mixin3", "mixin4"));
pCfg2.setSource(source2);
final List<ProjectConfigImpl> projects = new ArrayList<>(asList(pCfg1, pCfg2));
// Commands
final CommandImpl cmd1 = new CommandImpl("name1", "cmd1", "type1");
cmd1.getAttributes().putAll(ImmutableMap.of("key1", "value1"));
final CommandImpl cmd2 = new CommandImpl("name2", "cmd2", "type2");
cmd2.getAttributes().putAll(ImmutableMap.of("key4", "value4"));
final List<CommandImpl> commands = new ArrayList<>(asList(cmd1, cmd2));
// Machine configs
final ExtendedMachineImpl exMachine1 = new ExtendedMachineImpl();
final ServerConf2Impl serverConf1 = new ServerConf2Impl("2265", "http", singletonMap("prop1", "val"));
final ServerConf2Impl serverConf2 = new ServerConf2Impl("2266", "ftp", singletonMap("prop1", "val"));
exMachine1.setServers(ImmutableMap.of("ref1", serverConf1, "ref2", serverConf2));
exMachine1.setAgents(ImmutableList.of("agent5", "agent4"));
exMachine1.setAttributes(singletonMap("att1", "val"));
final ExtendedMachineImpl exMachine2 = new ExtendedMachineImpl();
final ServerConf2Impl serverConf3 = new ServerConf2Impl("2333", "https", singletonMap("prop2", "val"));
final ServerConf2Impl serverConf4 = new ServerConf2Impl("2334", "wss", singletonMap("prop2", "val"));
exMachine2.setServers(ImmutableMap.of("ref1", serverConf3, "ref2", serverConf4));
exMachine2.setAgents(ImmutableList.of("agent2", "agent1"));
exMachine2.setAttributes(singletonMap("att1", "val"));
final ExtendedMachineImpl exMachine3 = new ExtendedMachineImpl();
final ServerConf2Impl serverConf5 = new ServerConf2Impl("2333", "https", singletonMap("prop2", "val"));
exMachine3.setServers(singletonMap("ref1", serverConf5));
exMachine3.setAgents(ImmutableList.of("agent6", "agent2"));
exMachine3.setAttributes(singletonMap("att1", "val"));
// Environments
final EnvironmentRecipeImpl recipe1 = new EnvironmentRecipeImpl();
recipe1.setLocation("https://eclipse.che/Dockerfile");
recipe1.setType("dockerfile");
recipe1.setContentType("text/x-dockerfile");
recipe1.setContent("content");
final EnvironmentImpl env1 = new EnvironmentImpl();
env1.setMachines(new HashMap<>(ImmutableMap.of("machine1", exMachine1,
"machine2", exMachine2,
"machine3", exMachine3)));
env1.setRecipe(recipe1);
final EnvironmentRecipeImpl recipe2 = new EnvironmentRecipeImpl();
recipe2.setLocation("https://eclipse.che/Dockerfile");
recipe2.setType("dockerfile");
recipe2.setContentType("text/x-dockerfile");
recipe2.setContent("content");
final EnvironmentImpl env2 = new EnvironmentImpl();
env2.setMachines(new HashMap<>(ImmutableMap.of("machine1", exMachine1,
"machine3", exMachine3)));
env2.setRecipe(recipe2);
final Map<String, EnvironmentImpl> environments = ImmutableMap.of("env1", env1, "env2", env2);
// Workspace configuration
final WorkspaceConfigImpl wCfg = new WorkspaceConfigImpl();
wCfg.setDefaultEnv("env1");
wCfg.setName("cfgName_" + index);
wCfg.setDescription("description");
wCfg.setCommands(commands);
wCfg.setProjects(projects);
wCfg.setEnvironments(environments);
return wCfg;
}
}