001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm; 020 021import java.io.File; 022import java.util.ArrayList; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Map; 026import java.util.TreeMap; 027 028import org.apache.commons.lang3.StringUtils; 029import org.apache.maven.scm.command.add.AddScmResult; 030import org.apache.maven.scm.command.checkin.CheckInScmResult; 031import org.apache.maven.scm.command.checkout.CheckOutScmResult; 032import org.apache.maven.scm.command.edit.EditScmResult; 033import org.apache.maven.scm.command.remove.RemoveScmResult; 034import org.apache.maven.scm.provider.ScmProvider; 035import org.apache.maven.scm.repository.ScmRepository; 036import org.junit.After; 037import org.junit.Before; 038 039import static org.junit.Assert.assertEquals; 040import static org.junit.Assert.assertTrue; 041import static org.junit.Assume.assumeTrue; 042 043/** 044 * Base class for all TcK tests. 045 * <p> 046 * Basically all it does is to setup a default test enviroment 047 * common for all tck tests. The default setup includes: 048 * <ol> 049 * <li>Delete all default locations (working copy, updating copy etc)</li> 050 * <li>Initialize the repository</li> 051 * <li>Check out the repository to the working copy</li> 052 * </ol> 053 * 054 * @author <a href="mailto:torbjorn@smorgrav.org">Torbj�rn Eikli Sm�rgrav</a> 055 * 056 */ 057public abstract class ScmTckTestCase extends ScmTestCase { 058 private ScmRepository scmRepository; 059 060 private List<String> scmFileNames; 061 062 /** 063 * Some tests can only run if the appropriate application has been installed. 064 * If the provided name is not a runnable application all tests in the class are skipped. 065 * @return The commandline command for the specific scm provider. Or null if none is needed. 066 */ 067 public String getScmProviderCommand() { 068 return null; 069 } 070 071 /** 072 * @return A provider specific and valid url for the repository 073 * @throws Exception if any 074 */ 075 public abstract String getScmUrl() throws Exception; 076 077 /** 078 * <p> 079 * Get the list of file names that is supposed to be in the test repo. 080 * </p> 081 * <ul> 082 * <li>/pom.xml</li> 083 * <li>/readme.txt</li> 084 * <li>/src/main/java/Application.java</li> 085 * <li>/src/test/java/Test.java</li> 086 * </ul> 087 * 088 * @return {@link List} of {@link String} objects 089 */ 090 protected List<String> getScmFileNames() { 091 return scmFileNames; 092 } 093 094 /** 095 * <p> 096 * Initialize repository at the {@link #getScmUrl()} location with the files in {@link #getScmFileNames()} 097 * </p> 098 * <p> 099 * The setup is also asserting on the existence of these files. <br> 100 * This should only be used by this class (thus do not call this method from derived classes) 101 * </p> 102 * <b>Note</b>: 'svnadmin' should be a system command. 103 * 104 * @throws Exception if any 105 */ 106 public abstract void initRepo() throws Exception; 107 108 public void checkScmPresence() { 109 String scmProviderCommand = getScmProviderCommand(); 110 if (scmProviderCommand != null) { 111 assumeTrue( 112 "Skipping tests because the required command '" + scmProviderCommand + "' is not available.", 113 ScmTestCase.isSystemCmd(scmProviderCommand)); 114 } 115 } 116 117 /** 118 * {@inheritDoc} 119 */ 120 @Before 121 @Override 122 public void setUp() throws Exception { 123 checkScmPresence(); 124 super.setUp(); 125 126 scmRepository = null; 127 128 scmFileNames = new ArrayList<>(4); 129 scmFileNames.add("/pom.xml"); 130 scmFileNames.add("/readme.txt"); 131 scmFileNames.add("/src/main/java/Application.java"); 132 scmFileNames.add("/src/test/java/Test.java"); 133 134 initRepo(); 135 136 checkOut(getWorkingCopy(), getScmRepository()); 137 138 Iterator<String> it = getScmFileNames().iterator(); 139 while (it.hasNext()) { 140 assertFile(getWorkingCopy(), it.next()); 141 } 142 } 143 144 /** 145 * This method is available to those SCM clients that need to perform 146 * a cleanup at the end of the tests. It is needed when server side 147 * operations are performed, or the check out dirs are outside 148 * of the normal target directory. 149 */ 150 public void removeRepo() throws Exception {} 151 152 /** 153 * Provided to allow removeRepo() to be called. 154 */ 155 @After 156 @Override 157 public void tearDown() throws Exception { 158 super.tearDown(); 159 removeRepo(); 160 } 161 162 /** 163 * Convenience method to get the ScmRepository for this provider 164 */ 165 protected ScmRepository getScmRepository() throws Exception { 166 if (scmRepository == null) { 167 scmRepository = getScmManager().makeScmRepository(getScmUrl()); 168 } 169 170 return scmRepository; 171 } 172 173 /** 174 * Convenience method to check out files from the repository 175 */ 176 protected CheckOutScmResult checkOut(File workingDirectory, ScmRepository repository) throws Exception { 177 CheckOutScmResult result = getScmManager() 178 .getProviderByUrl(getScmUrl()) 179 .checkOut(repository, new ScmFileSet(workingDirectory), (ScmVersion) null); 180 181 assertTrue("Check result was successful, output: " + result.getCommandOutput(), result.isSuccess()); 182 183 return result; 184 } 185 186 /** 187 * Convenience method to check in files to the repository 188 */ 189 protected CheckInScmResult checkIn(File workingDirectory, ScmRepository repository) throws Exception { 190 CheckInScmResult result = getScmManager() 191 .getProviderByUrl(getScmUrl()) 192 .checkIn(repository, new ScmFileSet(workingDirectory), (ScmVersion) null, "Initial Checkin"); 193 194 assertTrue("Check result was successful, output: " + result.getCommandOutput(), result.isSuccess()); 195 196 return result; 197 } 198 199 /** 200 * Convenience method to remove files from the repository 201 */ 202 protected RemoveScmResult remove(File workingDirectory, ScmRepository repository) throws Exception { 203 RemoveScmResult result = getScmManager() 204 .getProviderByUrl(getScmUrl()) 205 .remove(repository, new ScmFileSet(workingDirectory), "Initial Checkin"); 206 207 assertTrue("Remove result was successful, output: " + result.getCommandOutput(), result.isSuccess()); 208 209 return result; 210 } 211 212 /** 213 * Convenience method to add a file to the working tree at the working directory 214 */ 215 protected void addToWorkingTree(File workingDirectory, File file, ScmRepository repository) throws Exception { 216 ScmProvider provider = getScmManager().getProviderByUrl(getScmUrl()); 217 218 CommandParameters commandParameters = new CommandParameters(); 219 commandParameters.setString(CommandParameter.FORCE_ADD, Boolean.TRUE.toString()); 220 221 AddScmResult result = provider.add(repository, new ScmFileSet(workingDirectory, file), commandParameters); 222 223 assertTrue("Check result was successful, output: " + result.getCommandOutput(), result.isSuccess()); 224 225 List<ScmFile> addedFiles = result.getAddedFiles(); 226 227 if (new File(workingDirectory, file.getPath()).isFile()) { 228 // Don't check directory add because some SCM tools ignore it 229 assertEquals("Expected 1 file in the added files list " + addedFiles, 1, addedFiles.size()); 230 } 231 } 232 233 /** 234 * take the files of the given list, add them to a TreeMap and 235 * use the pathName String as key for the Map. 236 * This function is useful for every TCK which has to check for the 237 * existence of more than 1 file of the returned ScmResult, regardless 238 * of their order in the list. 239 * All backslashes in the path will be replaced by forward slashes 240 * for Windows compatibility. 241 * 242 * @param files List with {@code ScmFile}s 243 * @return Map key=pathName, value=ScmFile 244 */ 245 protected Map<String, ScmFile> mapFilesByPath(List<ScmFile> files) { 246 if (files == null) { 247 return null; 248 } 249 250 Map<String, ScmFile> mappedFiles = new TreeMap<>(); 251 for (ScmFile scmFile : files) { 252 String path = StringUtils.replace(scmFile.getPath(), "\\", "/"); 253 mappedFiles.put(path, scmFile); 254 } 255 256 return mappedFiles; 257 } 258 259 protected EditScmResult edit(File basedir, String includes, String excludes, ScmRepository repository) 260 throws Exception { 261 if (this.getScmManager() 262 .getProviderByRepository(this.getScmRepository()) 263 .requiresEditMode()) { 264 ScmFileSet fileSet = new ScmFileSet(basedir, includes, excludes); 265 return getScmManager().edit(getScmRepository(), fileSet); 266 } 267 return new EditScmResult("", "", "", true); 268 } 269}