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 org.apache.maven.scm.manager.ScmManager; 023import org.apache.maven.scm.repository.ScmRepository; 024import org.codehaus.plexus.ContainerConfiguration; 025import org.codehaus.plexus.PlexusConstants; 026import org.codehaus.plexus.util.FileUtils; 027import org.codehaus.plexus.util.StringUtils; 028import org.codehaus.plexus.util.cli.CommandLineUtils; 029import org.codehaus.plexus.util.cli.CommandLineUtils.StringStreamConsumer; 030import org.codehaus.plexus.util.cli.Commandline; 031import org.junit.Before; 032 033import java.io.File; 034import java.io.FileWriter; 035import java.io.IOException; 036import java.util.Calendar; 037import java.util.Date; 038import java.util.TimeZone; 039 040import static org.junit.Assert.assertEquals; 041import static org.junit.Assert.assertFalse; 042import static org.junit.Assert.assertTrue; 043import static org.junit.Assert.fail; 044import static org.junit.Assume.assumeTrue; 045 046/** 047 * Base class for all SCM tests. Consumers will typically 048 * extend this class while tck test would extend ScmTckTestCase. 049 * <br> 050 * This class basically defines default locations for the 051 * test environment and implements convenience methods. 052 * 053 * @author <a href="mailto:jason@maven.org">Jason van Zyl</a> 054 * 055 */ 056public abstract class ScmTestCase 057 extends PlexusJUnit4TestSupport 058{ 059 protected static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone( "GMT" ); 060 061 private static boolean debugExecute; 062 063 private ScmManager scmManager; 064 065 @Before 066 @Override 067 public void setUp() 068 throws Exception 069 { 070 super.setUp(); 071 072 deleteDirectory( getRepositoryRoot() ); 073 assertFalse( getRepositoryRoot().exists() ); 074 deleteDirectory( getWorkingCopy() ); 075 assertFalse( getWorkingCopy().exists() ); 076 deleteDirectory( getWorkingDirectory() ); 077 assertFalse( getWorkingDirectory().exists() ); 078 deleteDirectory( getAssertionCopy() ); 079 assertFalse( getAssertionCopy().exists() ); 080 deleteDirectory( getUpdatingCopy() ); 081 assertFalse( getUpdatingCopy().exists() ); 082 083 scmManager = null; 084 } 085 086 @Override 087 protected void customizeContainerConfiguration( final ContainerConfiguration configuration ) 088 { 089 configuration.setClassPathScanning( PlexusConstants.SCANNING_INDEX ).setAutoWiring( true ); 090 } 091 092 /** 093 * @return default location of the test read/write repository 094 */ 095 protected File getRepositoryRoot() 096 { 097 return PlexusJUnit4TestSupport.getTestFile( "target/scm-test/repository" ); 098 } 099 100 /** 101 * @return Location of the revisioned (read only) repository 102 */ 103 protected File getRepository() 104 { 105 return PlexusJUnit4TestSupport.getTestFile( "/src/test/repository" ); 106 } 107 108 /** 109 * @return location of the working copy (always checkout) 110 */ 111 protected File getWorkingCopy() 112 { 113 return PlexusJUnit4TestSupport.getTestFile( "target/scm-test/working-copy" ); 114 } 115 116 /** 117 * Legacy method - same as getWorkingCopy() 118 * 119 * @return location of the working copy (always checkout) 120 */ 121 protected File getWorkingDirectory() 122 { 123 return getWorkingCopy(); 124 } 125 126 /** 127 * @return default location for doing assertions on a working tree 128 */ 129 protected File getAssertionCopy() 130 { 131 return PlexusJUnit4TestSupport.getTestFile( "target/scm-test/assertion-copy" ); 132 } 133 134 /** 135 * @return default location for doing update operations on a working tree 136 */ 137 protected File getUpdatingCopy() 138 { 139 return PlexusJUnit4TestSupport.getTestFile( "target/scm-test/updating-copy" ); 140 } 141 142 protected ScmManager getScmManager() 143 throws Exception 144 { 145 if ( scmManager == null ) 146 { 147 scmManager = lookup( ScmManager.class ); 148 } 149 150 return scmManager; 151 } 152 153 protected ScmRepository makeScmRepository( String scmUrl ) 154 throws Exception 155 { 156 return getScmManager().makeScmRepository( scmUrl ); 157 } 158 159 public void assertPath( String expectedPath, String actualPath ) 160 throws Exception 161 { 162 assertEquals( expectedPath.replace( '\\', '/' ), actualPath.replace( '\\', '/' ) ); 163 } 164 165 protected void assertFile( File root, String fileName ) 166 throws Exception 167 { 168 File file = new File( root, fileName ); 169 170 assertTrue( "Missing file: '" + file.getAbsolutePath() + "'.", file.exists() ); 171 172 assertTrue( "File isn't a file: '" + file.getAbsolutePath() + "'.", file.isFile() ); 173 174 String expected = fileName; 175 176 String actual = FileUtils.fileRead( file ); 177 178 assertEquals( "The file doesn't contain the expected contents. File: " + file.getAbsolutePath(), expected, 179 actual ); 180 } 181 182 protected void assertResultIsSuccess( ScmResult result ) 183 { 184 if ( result.isSuccess() ) 185 { 186 return; 187 } 188 189 printOutputError( result ); 190 191 fail( "The command result success flag was false." ); 192 } 193 194 protected void printOutputError( ScmResult result ) 195 { 196 System.err.println( "----------------------------------------------------------------------" ); 197 System.err.println( "Provider message" ); 198 System.err.println( "----------------------------------------------------------------------" ); 199 System.err.println( result.getProviderMessage() ); 200 System.err.println( "----------------------------------------------------------------------" ); 201 202 System.err.println( "----------------------------------------------------------------------" ); 203 System.err.println( "Command output" ); 204 System.err.println( "----------------------------------------------------------------------" ); 205 System.err.println( result.getCommandOutput() ); 206 System.err.println( "----------------------------------------------------------------------" ); 207 } 208 209 protected ScmFileSet getScmFileSet() 210 { 211 return new ScmFileSet( getWorkingCopy() ); 212 } 213 214 protected static void setDebugExecute( boolean debugExecute ) 215 { 216 ScmTestCase.debugExecute = debugExecute; 217 } 218 219 /** 220 * Execute the command line 221 * 222 * @param workingDirectory not null 223 * @param executable not null, should be a system command 224 * @param arguments not null 225 * @throws Exception if any 226 * @see CommandLineUtils#executeCommandLine(Commandline, org.codehaus.plexus.util.cli.StreamConsumer, 227 * org.codehaus.plexus.util.cli.StreamConsumer) 228 */ 229 public static void execute( File workingDirectory, String executable, String arguments ) 230 throws Exception 231 { 232 Commandline cl = new Commandline(); 233 234 cl.setExecutable( executable ); 235 236 cl.setWorkingDirectory( workingDirectory.getAbsolutePath() ); 237 238 cl.addArguments( CommandLineUtils.translateCommandline( arguments ) ); 239 240 StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer(); 241 242 StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 243 244 System.out.println( "Test command line: " + cl ); 245 246 int exitValue = CommandLineUtils.executeCommandLine( cl, stdout, stderr ); 247 248 if ( debugExecute || exitValue != 0 ) 249 { 250 System.err.println( "-----------------------------------------" ); 251 System.err.println( "Command line: " + cl ); 252 System.err.println( "Working directory: " + cl.getWorkingDirectory() ); 253 System.err.println( "-----------------------------------------" ); 254 System.err.println( "Standard output: " ); 255 System.err.println( "-----------------------------------------" ); 256 System.err.println( stdout.getOutput() ); 257 System.err.println( "-----------------------------------------" ); 258 259 System.err.println( "Standard error: " ); 260 System.err.println( "-----------------------------------------" ); 261 System.err.println( stderr.getOutput() ); 262 System.err.println( "-----------------------------------------" ); 263 } 264 265 if ( exitValue != 0 ) 266 { 267 fail( "Exit value wasn't 0, was:" + exitValue ); 268 } 269 } 270 271 protected static void makeDirectory( File basedir, String fileName ) 272 { 273 File dir = new File( basedir, fileName ); 274 275 if ( !dir.exists() ) 276 { 277 assertTrue( dir.mkdirs() ); 278 } 279 } 280 281 protected static void makeFile( File basedir, String fileName ) 282 throws IOException 283 { 284 makeFile( basedir, fileName, fileName ); 285 } 286 287 public static void makeFile( File basedir, String fileName, String contents ) 288 throws IOException 289 { 290 File file = new File( basedir, fileName ); 291 292 File parent = file.getParentFile(); 293 294 if ( !parent.exists() ) 295 { 296 assertTrue( parent.mkdirs() ); 297 } 298 299 try ( FileWriter writer = new FileWriter( file ) ) 300 { 301 writer.write( contents ); 302 } 303 } 304 305 protected void deleteDirectory( File directory ) 306 throws IOException 307 { 308 FileUtils.deleteDirectory( directory ); 309 } 310 311 public static Date getDate( int year, int month, int day ) 312 { 313 return getDate( year, month, day, 0, 0, 0, null ); 314 } 315 316 protected static Date getDate( int year, int month, int day, TimeZone tz ) 317 { 318 return getDate( year, month, day, 0, 0, 0, tz ); 319 } 320 321 protected static Date getDate( int year, int month, int day, int hourOfDay, int minute, int second, TimeZone tz ) 322 { 323 Calendar cal = Calendar.getInstance(); 324 325 if ( tz != null ) 326 { 327 cal.setTimeZone( tz ); 328 } 329 cal.set( year, month, day, hourOfDay, minute, second ); 330 cal.set( Calendar.MILLISECOND, 0 ); 331 332 return cal.getTime(); 333 } 334 335 public void assertCommandLine( String expectedCommand, File expectedWorkingDirectory, Commandline actualCommand ) 336 throws IOException 337 { 338 Commandline cl = new Commandline( expectedCommand ); 339 if ( expectedWorkingDirectory != null ) 340 { 341 cl.setWorkingDirectory( expectedWorkingDirectory.getAbsolutePath() ); 342 } 343 String expectedCommandLineAsExecuted = StringUtils.join( cl.getShellCommandline(), " " ); 344 String actualCommandLineAsExecuted = StringUtils.join( actualCommand.getShellCommandline(), " " ); 345 assertEquals( expectedCommandLineAsExecuted, actualCommandLineAsExecuted ); 346 } 347 348 public static void checkScmPresence( String scmProviderCommand ) 349 { 350 assumeTrue( "Skipping tests because the required command '" + scmProviderCommand + "' is not available.", 351 ScmTestCase.isSystemCmd( scmProviderCommand ) ); 352 } 353 354 /** 355 * @param cmd the executable to run, not null. 356 * @return true if and only if the command is on the path 357 */ 358 public static boolean isSystemCmd( String cmd ) 359 { 360 try 361 { 362 Runtime.getRuntime().exec( cmd ); 363 364 return true; 365 } 366 catch ( IOException e ) 367 { 368 return false; 369 } 370 } 371 372 public static void printSystemCmdUnavail( String cmd, String testName ) 373 { 374 System.err.printf( "'%s' is not a system command. Ignored %s.%n", cmd, testName ); 375 } 376}