/******************************************************************************* * 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.plugin.svn.server.utils; import com.google.common.base.Joiner; import com.google.common.io.Files; import org.eclipse.che.api.core.util.LineConsumer; import org.eclipse.che.api.core.util.LineConsumerFactory; import org.eclipse.che.api.user.server.model.impl.ProfileImpl; import org.eclipse.che.api.user.server.spi.ProfileDao; import org.eclipse.che.api.vfs.VirtualFileSystem; import org.eclipse.che.api.vfs.VirtualFileSystemProvider; import org.eclipse.che.api.vfs.impl.file.LocalVirtualFileSystemProvider; import org.eclipse.che.commons.env.EnvironmentContext; import org.eclipse.che.commons.subject.SubjectImpl; import org.eclipse.che.dto.server.DtoFactory; import org.eclipse.che.plugin.svn.server.SubversionApi; import org.eclipse.che.plugin.svn.server.SubversionException; import org.eclipse.che.plugin.svn.server.repository.RepositoryUrlProvider; import org.eclipse.che.plugin.svn.server.upstream.CommandLineResult; import org.eclipse.che.plugin.svn.server.upstream.UpstreamUtils; import org.eclipse.che.plugin.svn.shared.AddRequest; import org.eclipse.che.plugin.svn.shared.CLIOutputResponse; import org.eclipse.che.plugin.svn.shared.CLIOutputWithRevisionResponse; import org.eclipse.che.plugin.svn.shared.CheckoutRequest; import org.eclipse.che.plugin.svn.shared.CommitRequest; import org.eclipse.che.plugin.svn.shared.Depth; import org.eclipse.che.plugin.svn.shared.PropertySetRequest; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * Test utilities. */ public class TestUtils { private static DtoFactory dtoFactory = DtoFactory.getInstance(); private static SubversionApi subversionApi = new SubversionApi(new RepositoryUrlProvider() { @Override public String getRepositoryUrl(final String projectPath){ return ""; } }, null); public static final String[] GREEK_TREE = new String[] { "/", "/branches/", "/branches/2.0/", "/branches/2.0/A/", "/branches/2.0/A/mu", "/tags/", "/tags/1.0/A/", "/tags/1.0/A/gu", "/trunk/", "/trunk/A/", "/trunk/A/mu", "/trunk/A/B/", "/trunk/A/B/lambda", "/trunk/A/B/E/", "/trunk/A/B/E/alpha", "/trunk/A/B/E/beta", "/trunk/A/B/F/", "/trunk/A/C/", "/trunk/A/D/", "/trunk/A/D/gamma", "/trunk/A/D/H/", "/trunk/A/D/H/chi", "/trunk/A/D/H/psi", "/trunk/A/D/H/omega", "/trunk/A/D/G/", "/trunk/A/D/G/pi", "/trunk/A/D/G/rho", "/trunk/A/D/G/tau", "/iota" }; private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class); /** * Creates a virtual file system. * * @return the virtual file system * @throws Exception * if anything goes wrong */ public static VirtualFileSystem createVirtualFileSystem() throws Exception { File rootDirectory = java.nio.file.Files.createTempDirectory(null).toFile(); VirtualFileSystemProvider vfsProvider = new LocalVirtualFileSystemProvider(rootDirectory, null); return vfsProvider.getVirtualFileSystem(); } public static class SystemOutLineConsumer implements LineConsumer { @Override public void writeLine(String line) throws IOException { LOG.debug(line); } @Override public void close() throws IOException { } } public static class SystemOutLineConsumerFactory implements LineConsumerFactory { @Override public LineConsumer newLineConsumer() { return new SystemOutLineConsumer(); } } /** * Throws an exception if the CLI result is no a valid "success" response. * <p/> * <b>Note:</b> Might make sense to move this to a core API instead of a test API * * @param result * the CLI result * @throws Exception * if the CLI result indicates an error */ public static void handleCLIResult(final CommandLineResult result) throws Exception { if (result.getExitCode() != 0) { throw new SubversionException(Joiner.on("\n") .join(result.getStderr().size() != 0 ? result.getStderr() .toArray(new String[result.getStderr().size()]) : result.getStdout() .toArray(new String[result.getStdout().size()]))); } } /** * Creates a user and makes that user be the current user. * * @param userProfileDao * the User Profile DAO * @throws Exception * if anything goes wrong */ public static void createTestUser(final ProfileDao userProfileDao) throws Exception { // set current user EnvironmentContext.getCurrent().setSubject(new SubjectImpl("codenvy", "codenvy", null, false)); // rules for mock final Map<String, String> profileAttributes = new HashMap<>(); profileAttributes.put("firstName", "Codenvy"); profileAttributes.put("lastName", "Codenvy"); profileAttributes.put("email", "che@eclipse.org"); Mockito.when(userProfileDao.getById("codenvy")) .thenReturn(new ProfileImpl("codenvy", profileAttributes)); } /** * Creates a new Subversion repository in a temporary location with the Greek Tree structure within it. * * @return the path to the repository root * @throws Exception * if anything goes wrong */ public static File createGreekTreeRepository() throws Exception { final File repoRoot = Files.createTempDir(); final File wcRoot = Files.createTempDir(); // Clean up after execution repoRoot.deleteOnExit(); wcRoot.deleteOnExit(); // Create the repository final CommandLineResult result = UpstreamUtils.executeCommandLine(null, "svnadmin", new String[] { "create", repoRoot.getAbsolutePath() }, -1, repoRoot); // Make sure the result is fine handleCLIResult(result); // Checkout the repository final CLIOutputWithRevisionResponse coResponse = subversionApi.checkout(dtoFactory.createDto(CheckoutRequest.class) .withProjectPath(wcRoot.getAbsolutePath()) .withUrl("file:///" + repoRoot.getAbsolutePath())); assertTrue(coResponse.getRevision() > -1); final List<String> pathsToAdd = new ArrayList<>(); // Create the directory structure for (final String path : GREEK_TREE) { final File fileForPath = new File(wcRoot, path); final String[] pathParts = path.split("/"); // Create parent directories (Probably not necessary) Files.createParentDirs(fileForPath); if (!path.endsWith("/") && fileForPath.createNewFile()) { Files.write(("This is the file '" + pathParts[pathParts.length - 1] + "'.").getBytes(), fileForPath); pathsToAdd.add(path.substring(1)); } } // Add the files in the working copy to version control subversionApi.add(dtoFactory.createDto(AddRequest.class).withProjectPath(wcRoot.getAbsolutePath()) .withPaths(pathsToAdd) .withAddParents(true)); //Add properties final CLIOutputResponse propResponse = subversionApi.propset(dtoFactory.createDto(PropertySetRequest.class) .withValue("user") .withProjectPath(wcRoot.getAbsolutePath()) .withPath(".") .withForce(true) .withDepth(Depth.FULLY_RECURSIVE) .withName("owner")); assertTrue(propResponse.getOutput().size() > 0); // Commit the changes final CLIOutputWithRevisionResponse cResponse = subversionApi.commit(dtoFactory.createDto(CommitRequest.class) .withProjectPath(wcRoot.getAbsolutePath()) .withMessage("Initial commit.")); assertEquals(1L, cResponse.getRevision()); return repoRoot; } public static <T> Matcher<List<T>> sameAsList(final List<T> expectedList) { return new BaseMatcher<List<T>>() { @Override public void describeTo(final Description description) { description.appendText("should contain all and only these elements").appendValue(expectedList); } @Override public boolean matches(final Object o) { List<T> actualList; try { actualList = (List<T>)o; } catch (ClassCastException e) { return false; } return actualList.containsAll(expectedList); } }; } }