View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm;
20  
21  import java.io.File;
22  import java.io.FileWriter;
23  import java.io.IOException;
24  import java.util.Calendar;
25  import java.util.Date;
26  import java.util.TimeZone;
27  
28  import org.apache.commons.lang3.StringUtils;
29  import org.apache.maven.scm.manager.ScmManager;
30  import org.apache.maven.scm.repository.ScmRepository;
31  import org.codehaus.plexus.ContainerConfiguration;
32  import org.codehaus.plexus.PlexusConstants;
33  import org.codehaus.plexus.util.FileUtils;
34  import org.codehaus.plexus.util.cli.CommandLineUtils;
35  import org.codehaus.plexus.util.cli.CommandLineUtils.StringStreamConsumer;
36  import org.codehaus.plexus.util.cli.Commandline;
37  import org.junit.Before;
38  
39  import static org.junit.Assert.assertEquals;
40  import static org.junit.Assert.assertFalse;
41  import static org.junit.Assert.assertTrue;
42  import static org.junit.Assert.fail;
43  import static org.junit.Assume.assumeTrue;
44  
45  /**
46   * Base class for all SCM tests. Consumers will typically
47   * extend this class while tck test would extend ScmTckTestCase.
48   * <br>
49   * This class basically defines default locations for the
50   * test environment and implements convenience methods.
51   *
52   * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
53   *
54   */
55  public abstract class ScmTestCase extends PlexusJUnit4TestSupport {
56      protected static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone("GMT");
57  
58      private static boolean debugExecute;
59  
60      private ScmManager scmManager;
61  
62      @Before
63      @Override
64      public void setUp() throws Exception {
65          super.setUp();
66  
67          deleteDirectory(getRepositoryRoot());
68          assertFalse(getRepositoryRoot().exists());
69          deleteDirectory(getWorkingCopy());
70          assertFalse(getWorkingCopy().exists());
71          deleteDirectory(getWorkingDirectory());
72          assertFalse(getWorkingDirectory().exists());
73          deleteDirectory(getAssertionCopy());
74          assertFalse(getAssertionCopy().exists());
75          deleteDirectory(getUpdatingCopy());
76          assertFalse(getUpdatingCopy().exists());
77  
78          scmManager = null;
79      }
80  
81      @Override
82      protected void customizeContainerConfiguration(final ContainerConfiguration configuration) {
83          configuration.setClassPathScanning(PlexusConstants.SCANNING_INDEX).setAutoWiring(true);
84      }
85  
86      /**
87       * @return default location of the test read/write repository
88       */
89      protected File getRepositoryRoot() {
90          return PlexusJUnit4TestSupport.getTestFile("target/scm-test/repository");
91      }
92  
93      /**
94       * @return Location of the revisioned (read only) repository
95       */
96      protected File getRepository() {
97          return PlexusJUnit4TestSupport.getTestFile("/src/test/repository");
98      }
99  
100     /**
101      * @return location of the working copy (always checkout)
102      */
103     protected File getWorkingCopy() {
104         return PlexusJUnit4TestSupport.getTestFile("target/scm-test/working-copy");
105     }
106 
107     /**
108      * Legacy method - same as getWorkingCopy()
109      *
110      * @return location of the working copy (always checkout)
111      */
112     protected File getWorkingDirectory() {
113         return getWorkingCopy();
114     }
115 
116     /**
117      * @return default location for doing assertions on a working tree
118      */
119     protected File getAssertionCopy() {
120         return PlexusJUnit4TestSupport.getTestFile("target/scm-test/assertion-copy");
121     }
122 
123     /**
124      * @return default location for doing update operations on a working tree
125      */
126     protected File getUpdatingCopy() {
127         return PlexusJUnit4TestSupport.getTestFile("target/scm-test/updating-copy");
128     }
129 
130     protected ScmManager getScmManager() throws Exception {
131         if (scmManager == null) {
132             scmManager = lookup(ScmManager.class);
133         }
134 
135         return scmManager;
136     }
137 
138     protected ScmRepository makeScmRepository(String scmUrl) throws Exception {
139         return getScmManager().makeScmRepository(scmUrl);
140     }
141 
142     public void assertPath(String expectedPath, String actualPath) throws Exception {
143         assertEquals(expectedPath.replace('\\', '/'), actualPath.replace('\\', '/'));
144     }
145 
146     protected void assertFile(File root, String fileName) throws Exception {
147         File file = new File(root, fileName);
148 
149         assertTrue("Missing file: '" + file.getAbsolutePath() + "'.", file.exists());
150 
151         assertTrue("File isn't a file: '" + file.getAbsolutePath() + "'.", file.isFile());
152 
153         String expected = fileName;
154 
155         String actual = FileUtils.fileRead(file);
156 
157         assertEquals(
158                 "The file doesn't contain the expected contents. File: " + file.getAbsolutePath(), expected, actual);
159     }
160 
161     protected void assertResultIsSuccess(ScmResult result) {
162         if (result.isSuccess()) {
163             return;
164         }
165 
166         printOutputError(result);
167 
168         fail("The command result success flag was false.");
169     }
170 
171     protected void printOutputError(ScmResult result) {
172         System.err.println("----------------------------------------------------------------------");
173         System.err.println("Provider message");
174         System.err.println("----------------------------------------------------------------------");
175         System.err.println(result.getProviderMessage());
176         System.err.println("----------------------------------------------------------------------");
177 
178         System.err.println("----------------------------------------------------------------------");
179         System.err.println("Command output");
180         System.err.println("----------------------------------------------------------------------");
181         System.err.println(result.getCommandOutput());
182         System.err.println("----------------------------------------------------------------------");
183     }
184 
185     protected ScmFileSet getScmFileSet() {
186         return new ScmFileSet(getWorkingCopy());
187     }
188 
189     protected static void setDebugExecute(boolean debugExecute) {
190         ScmTestCase.debugExecute = debugExecute;
191     }
192 
193     /**
194      * Execute the command line
195      *
196      * @param workingDirectory not null
197      * @param executable       not null, should be a system command
198      * @param arguments        not null
199      * @throws Exception if any
200      * @see CommandLineUtils#executeCommandLine(Commandline, org.codehaus.plexus.util.cli.StreamConsumer,
201      *      org.codehaus.plexus.util.cli.StreamConsumer)
202      */
203     public static void execute(File workingDirectory, String executable, String arguments) throws Exception {
204         Commandline cl = new Commandline();
205 
206         cl.setExecutable(executable);
207 
208         cl.setWorkingDirectory(workingDirectory.getAbsolutePath());
209 
210         cl.addArguments(CommandLineUtils.translateCommandline(arguments));
211 
212         StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
213 
214         StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
215 
216         System.out.println("Test command line: " + cl);
217 
218         int exitValue = CommandLineUtils.executeCommandLine(cl, stdout, stderr);
219 
220         if (debugExecute || exitValue != 0) {
221             System.err.println("-----------------------------------------");
222             System.err.println("Command line: " + cl);
223             System.err.println("Working directory: " + cl.getWorkingDirectory());
224             System.err.println("-----------------------------------------");
225             System.err.println("Standard output: ");
226             System.err.println("-----------------------------------------");
227             System.err.println(stdout.getOutput());
228             System.err.println("-----------------------------------------");
229 
230             System.err.println("Standard error: ");
231             System.err.println("-----------------------------------------");
232             System.err.println(stderr.getOutput());
233             System.err.println("-----------------------------------------");
234         }
235 
236         if (exitValue != 0) {
237             fail("Exit value wasn't 0, was:" + exitValue);
238         }
239     }
240 
241     protected static void makeDirectory(File basedir, String fileName) {
242         File dir = new File(basedir, fileName);
243 
244         if (!dir.exists()) {
245             assertTrue(dir.mkdirs());
246         }
247     }
248 
249     protected static void makeFile(File basedir, String fileName) throws IOException {
250         makeFile(basedir, fileName, fileName);
251     }
252 
253     public static void makeFile(File basedir, String fileName, String contents) throws IOException {
254         File file = new File(basedir, fileName);
255 
256         File parent = file.getParentFile();
257 
258         if (!parent.exists()) {
259             assertTrue(parent.mkdirs());
260         }
261 
262         try (FileWriter writer = new FileWriter(file)) {
263             writer.write(contents);
264         }
265     }
266 
267     protected void deleteDirectory(File directory) throws IOException {
268         FileUtils.deleteDirectory(directory);
269     }
270 
271     public static Date getDate(int year, int month, int day) {
272         return getDate(year, month, day, 0, 0, 0, null);
273     }
274 
275     protected static Date getDate(int year, int month, int day, TimeZone tz) {
276         return getDate(year, month, day, 0, 0, 0, tz);
277     }
278 
279     protected static Date getDate(int year, int month, int day, int hourOfDay, int minute, int second, TimeZone tz) {
280         Calendar cal = Calendar.getInstance();
281 
282         if (tz != null) {
283             cal.setTimeZone(tz);
284         }
285         cal.set(year, month, day, hourOfDay, minute, second);
286         cal.set(Calendar.MILLISECOND, 0);
287 
288         return cal.getTime();
289     }
290 
291     public void assertCommandLine(String expectedCommand, File expectedWorkingDirectory, Commandline actualCommand)
292             throws IOException {
293         Commandline cl = new Commandline(expectedCommand);
294         if (expectedWorkingDirectory != null) {
295             cl.setWorkingDirectory(expectedWorkingDirectory.getAbsolutePath());
296         }
297         String expectedCommandLineAsExecuted = StringUtils.join(cl.getShellCommandline(), " ");
298         String actualCommandLineAsExecuted = StringUtils.join(actualCommand.getShellCommandline(), " ");
299         assertEquals(expectedCommandLineAsExecuted, actualCommandLineAsExecuted);
300     }
301 
302     public static void checkScmPresence(String scmProviderCommand) {
303         assumeTrue(
304                 "Skipping tests because the required command '" + scmProviderCommand + "' is not available.",
305                 ScmTestCase.isSystemCmd(scmProviderCommand));
306     }
307 
308     /**
309      * @param cmd the executable to run, not null.
310      * @return true if and only if the command is on the path
311      */
312     public static boolean isSystemCmd(String cmd) {
313         try {
314             Runtime.getRuntime().exec(cmd);
315 
316             return true;
317         } catch (IOException e) {
318             return false;
319         }
320     }
321 
322     public static void printSystemCmdUnavail(String cmd, String testName) {
323         System.err.printf("'%s' is not a system command. Ignored %s.%n", cmd, testName);
324     }
325 }