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.provider.ScmProvider; 034import org.apache.maven.scm.repository.ScmRepository; 035import org.codehaus.plexus.util.StringUtils; 036 037/** 038 * Base class for all TcK tests. 039 * <p> 040 * Basically all it does is to setup a default test enviroment 041 * common for all tck tests. The default setup includes: 042 * <ol> 043 * <li>Delete all default locations (working copy, updating copy etc)</li> 044 * <li>Initialize the repository</li> 045 * <li>Check out the repository to the working copy</li> 046 * </ol> 047 * 048 * @author <a href="mailto:torbjorn@smorgrav.org">Torbj�rn Eikli Sm�rgrav</a> 049 * 050 */ 051public abstract class ScmTckTestCase 052 extends ScmTestCase 053{ 054 private ScmRepository scmRepository; 055 056 private List<String> scmFileNames; 057 058 /** 059 * @return A provider specific and valid url for the repository 060 * @throws Exception if any 061 */ 062 public abstract String getScmUrl() 063 throws Exception; 064 065 /** 066 * <p> 067 * Get the list of file names that is supposed to be in the test repo. 068 * </p> 069 * <ul> 070 * <li>/pom.xml</li> 071 * <li>/readme.txt</li> 072 * <li>/src/main/java/Application.java</li> 073 * <li>/src/test/java/Test.java</li> 074 * </ul> 075 * 076 * @return {@link List} of {@link String} objects 077 */ 078 protected List<String> getScmFileNames() 079 { 080 return scmFileNames; 081 } 082 083 /** 084 * <p> 085 * Initialize repository at the {@link #getScmUrl()} location with the files in {@link #getScmFileNames()} 086 * </p> 087 * <p> 088 * The setup is also asserting on the existence of these files. <br> 089 * This should only be used by this class (thus do not call this method from derived classes) 090 * </p> 091 * <b>Note</b>: 'svnadmin' should be a system command. 092 * 093 * @throws Exception if any 094 */ 095 public abstract void initRepo() 096 throws Exception; 097 098 /** 099 * {@inheritDoc} 100 */ 101 protected void setUp() 102 throws Exception 103 { 104 super.setUp(); 105 106 scmRepository = null; 107 108 scmFileNames = new ArrayList<String>( 4 ); 109 scmFileNames.add( "/pom.xml" ); 110 scmFileNames.add( "/readme.txt" ); 111 scmFileNames.add( "/src/main/java/Application.java" ); 112 scmFileNames.add( "/src/test/java/Test.java" ); 113 114 initRepo(); 115 116 checkOut( getWorkingCopy(), getScmRepository() ); 117 118 Iterator<String> it = getScmFileNames().iterator(); 119 while ( it.hasNext() ) 120 { 121 assertFile( getWorkingCopy(), it.next() ); 122 } 123 } 124 125 /** 126 * This method is available to those SCM clients that need to perform 127 * a cleanup at the end of the tests. It is needed when server side 128 * operations are performed, or the check out dirs are outside 129 * of the normal target directory. 130 */ 131 public void removeRepo() 132 throws Exception 133 { 134 } 135 136 /** 137 * Provided to allow removeRepo() to be called. 138 * @see junit.framework.TestCase#tearDown() 139 */ 140 @Override 141 protected void tearDown() 142 throws Exception 143 { 144 super.tearDown(); 145 removeRepo(); 146 } 147 148 /** 149 * Convenience method to get the ScmRepository for this provider 150 */ 151 protected ScmRepository getScmRepository() 152 throws Exception 153 { 154 if ( scmRepository == null ) 155 { 156 scmRepository = getScmManager().makeScmRepository( getScmUrl() ); 157 } 158 159 return scmRepository; 160 } 161 162 /** 163 * Convenience method to check out files from the repository 164 */ 165 protected CheckOutScmResult checkOut( File workingDirectory, ScmRepository repository ) 166 throws Exception 167 { 168 CheckOutScmResult result = 169 getScmManager().getProviderByUrl( getScmUrl() ).checkOut( repository, new ScmFileSet( workingDirectory ), 170 (ScmVersion) null ); 171 172 assertTrue( "Check result was successful, output: " + result.getCommandOutput(), result.isSuccess() ); 173 174 return result; 175 } 176 177 /** 178 * Convenience method to check in files to the repository 179 */ 180 protected CheckInScmResult checkIn( File workingDirectory, ScmRepository repository ) 181 throws Exception 182 { 183 CheckInScmResult result = getScmManager().getProviderByUrl( getScmUrl() ) 184 .checkIn( repository, new ScmFileSet( workingDirectory ), (ScmVersion) null, "Initial Checkin" ); 185 186 assertTrue( "Check result was successful, output: " + result.getCommandOutput(), result.isSuccess() ); 187 188 return result; 189 } 190 191 /** 192 * Convenience method to add a file to the working tree at the working directory 193 */ 194 protected void addToWorkingTree( File workingDirectory, File file, ScmRepository repository ) 195 throws Exception 196 { 197 ScmProvider provider = getScmManager().getProviderByUrl( getScmUrl() ); 198 199 CommandParameters commandParameters = new CommandParameters(); 200 commandParameters.setString( CommandParameter.FORCE_ADD, Boolean.TRUE.toString() ); 201 202 AddScmResult result = provider.add( repository, new ScmFileSet( workingDirectory, file ), commandParameters ); 203 204 assertTrue( "Check result was successful, output: " + result.getCommandOutput(), result.isSuccess() ); 205 206 List<ScmFile> addedFiles = result.getAddedFiles(); 207 208 if ( new File( workingDirectory, file.getPath() ).isFile() ) 209 { 210 // Don't check directory add because some SCM tools ignore it 211 assertEquals( "Expected 1 file in the added files list " + addedFiles, 1, addedFiles.size() ); 212 } 213 } 214 215 /** 216 * take the files of the given list, add them to a TreeMap and 217 * use the pathName String as key for the Map. 218 * This function is useful for every TCK which has to check for the 219 * existence of more than 1 file of the returned ScmResult, regardless 220 * of their order in the list. 221 * All backslashes in the path will be replaced by forward slashes 222 * for Windows compatibility. 223 * 224 * @param files List with {@code ScmFile}s 225 * @return Map key=pathName, value=ScmFile 226 */ 227 protected Map<String, ScmFile> mapFilesByPath( List<ScmFile> files ) 228 { 229 if ( files == null ) 230 { 231 return null; 232 } 233 234 Map<String, ScmFile> mappedFiles = new TreeMap<String, ScmFile>(); 235 for ( ScmFile scmFile : files ) 236 { 237 String path = StringUtils.replace( scmFile.getPath(), "\\", "/" ); 238 mappedFiles.put( path, scmFile ); 239 } 240 241 return mappedFiles; 242 } 243 244 protected EditScmResult edit( File basedir, String includes, String excludes, ScmRepository repository ) 245 throws Exception 246 { 247 if ( this.getScmManager().getProviderByRepository( this.getScmRepository() ).requiresEditMode() ) 248 { 249 ScmFileSet fileSet = new ScmFileSet( basedir, includes, excludes ); 250 return getScmManager().edit( getScmRepository(), fileSet ); 251 } 252 return new EditScmResult( "", "", "", true ); 253 } 254 255}