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.provider.git.command.checkin;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.nio.file.Files;
25  import java.nio.file.Path;
26  import java.nio.file.StandardCopyOption;
27  
28  import org.apache.maven.scm.CommandParameter;
29  import org.apache.maven.scm.CommandParameters;
30  import org.apache.maven.scm.PlexusJUnit4TestCase;
31  import org.apache.maven.scm.ScmException;
32  import org.apache.maven.scm.ScmFileSet;
33  import org.apache.maven.scm.command.checkin.CheckInScmResult;
34  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
35  import org.apache.maven.scm.provider.git.GitScmTestUtils;
36  import org.apache.maven.scm.provider.git.util.GitUtil;
37  import org.apache.maven.scm.repository.ScmRepository;
38  import org.apache.maven.scm.tck.command.checkin.CheckInCommandTckTest;
39  import org.codehaus.plexus.util.FileUtils;
40  import org.junit.Test;
41  
42  import static org.junit.Assert.assertFalse;
43  
44  /**
45   * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
46   */
47  public abstract class GitCheckInCommandTckTest extends CheckInCommandTckTest {
48  
49      /**
50       * {@inheritDoc}
51       */
52      public void initRepo() throws Exception {
53          GitScmTestUtils.initRepo("src/test/resources/repository/", getRepositoryRoot(), getWorkingDirectory());
54      }
55  
56      @Override
57      protected CheckOutScmResult checkOut(File workingDirectory, ScmRepository repository) throws Exception {
58          try {
59              return super.checkOut(workingDirectory, repository);
60          } finally {
61              GitScmTestUtils.setDefaultGitConfig(workingDirectory);
62          }
63      }
64  
65      @Test
66      public void testUpToDatePush() throws Exception {
67          File checkedOutRepo = getWorkingCopy();
68  
69          ScmRepository scmRepository = getScmManager().makeScmRepository(getScmUrl());
70          checkoutRepoInto(checkedOutRepo, scmRepository);
71  
72          // Add a default user to the config
73          GitScmTestUtils.setDefaultGitConfig(checkedOutRepo);
74  
75          CheckInScmResult result =
76                  getScmManager().checkIn(scmRepository, new ScmFileSet(checkedOutRepo), "No change commit message");
77  
78          assertResultIsSuccess(result);
79      }
80  
81      @Test
82      public void testRejectedNonFastForwardPush() throws Exception {
83          File blockingRepo = PlexusJUnit4TestCase.getTestFile("target/scm-test/blocking-repo");
84          File rejectedRepo = PlexusJUnit4TestCase.getTestFile("target/scm-test/rejected-repo");
85  
86          ScmRepository scmRepository = getScmManager().makeScmRepository(getScmUrl());
87          checkoutRepoInto(rejectedRepo, scmRepository);
88          checkoutRepoInto(blockingRepo, scmRepository);
89  
90          // Add a default user to the config
91          GitScmTestUtils.setDefaultGitConfig(rejectedRepo);
92          GitScmTestUtils.setDefaultGitConfig(blockingRepo);
93  
94          ScmFileSet blockingFileSet = createWorkspaceChange(rejectedRepo);
95  
96          CommandParameters commandParameters = new CommandParameters();
97          commandParameters.setString(CommandParameter.MESSAGE, "Blocking commit");
98  
99          CheckInScmResult blockingResult = getScmManager().checkIn(scmRepository, blockingFileSet, commandParameters);
100         assertResultIsSuccess(blockingResult);
101 
102         ScmFileSet rejectedFileSet = createWorkspaceChange(blockingRepo);
103 
104         commandParameters = new CommandParameters();
105         commandParameters.setString(CommandParameter.MESSAGE, "Rejected commit");
106 
107         CheckInScmResult checkInScmResult = getScmManager().checkIn(scmRepository, rejectedFileSet, commandParameters);
108         assertFalse(
109                 "check-in should have been rejected since fast forward was not possible", checkInScmResult.isSuccess());
110     }
111 
112     @Test
113     public void testCommitWithRejectingPreCommitHook() throws Exception {
114         GitScmTestUtils.setupRejectAllCommitsPreCommitHook(getWorkingCopy());
115         GitScmTestUtils.setDefaultGitConfig(getWorkingCopy());
116         ScmFileSet addedFile = createWorkspaceChange(getWorkingCopy());
117         try {
118             CheckInScmResult result =
119                     getScmManager().checkIn(getScmRepository(), addedFile, "Commit with pre-commit hook");
120             assertFalse(
121                     "check-in should have been rejected since pre-push hook rejects all commits", result.isSuccess());
122         } catch (ScmException e) {
123             // some providers may use an exception to indicate a failed commit
124 
125         }
126     }
127 
128     @Test
129     public void testCommitNoVerify() throws Exception {
130         GitScmTestUtils.setupRejectAllCommitsPreCommitHook(getWorkingCopy());
131         GitScmTestUtils.setDefaultGitConfig(getWorkingCopy());
132         ScmFileSet addedFile = createWorkspaceChange(getWorkingCopy());
133         Path gitSettingsFile =
134                 createTempFileFromClasspathResource("/git-settings-no-verify.xml", GitUtil.GIT_SETTINGS_FILENAME);
135         GitUtil.setSettingsDirectory(
136                 gitSettingsFile.getParent().toFile()); // ensure that the settings are read from the .git directory
137         try {
138             CheckInScmResult result =
139                     getScmManager().checkIn(getScmRepository(), addedFile, "Commit with pre-commit hook");
140             assertResultIsSuccess(result);
141         } finally {
142             GitUtil.setSettingsDirectory(GitUtil.DEFAULT_SETTINGS_DIRECTORY); // reset to default settings directory
143             Files.delete(gitSettingsFile); // delete the temporary settings file
144             Files.delete(gitSettingsFile.getParent()); // delete the temporary settings directory
145         }
146     }
147 
148     private CheckOutScmResult checkoutRepoInto(File workingCopy, ScmRepository scmRepository) throws Exception {
149         FileUtils.deleteDirectory(workingCopy);
150         workingCopy.mkdir();
151 
152         CheckOutScmResult result = getScmManager().checkOut(scmRepository, new ScmFileSet(workingCopy), null);
153 
154         assertResultIsSuccess(result);
155         return result;
156     }
157 
158     private ScmFileSet createWorkspaceChange(File repo) throws IOException {
159         File beerFile = new File(repo.getAbsolutePath(), "beer.xml");
160         FileUtils.fileWrite(beerFile.getAbsolutePath(), "1 litre");
161         return new ScmFileSet(repo, beerFile.getName());
162     }
163 
164     /**
165      * Creates a new file below a new temporary directory and copies the content of a classpath resource into it.
166      * The caller is responsible for deleting the temporary directory afterwards.
167      *
168      * @param resourceName from where to populate the file (relative to {@code clazz})
169      * @param fileName the file name to create below
170      * @return the newly created file
171      * @throws IOException in case of an error creating the file or copying the resource
172      */
173     private static Path createTempFileFromClasspathResource(String resourceName, String fileName) throws IOException {
174         Path tmpDirectory = Files.createTempDirectory("maven-scm-git-test-");
175         Path tmpFile = tmpDirectory.resolve(fileName);
176         try (InputStream inputStream = GitCheckInCommandTckTest.class.getResourceAsStream(resourceName)) {
177             if (inputStream == null) {
178                 throw new IOException("Resource not found: " + resourceName);
179             }
180             Files.copy(inputStream, tmpFile, StandardCopyOption.REPLACE_EXISTING);
181         }
182         return tmpFile;
183     }
184 }