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