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