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