| // Copyright (C) 2016 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.googlesource.gerrit.plugins.uploadvalidator; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.DuplicatePathnameValidator.conflict; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.EMPTY_CONTENT; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.EMPTY_PLUGIN_CONFIG; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.createDirCacheEntry; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.createEmptyDirCacheEntries; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.makeCommit; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.transformMessage; |
| import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.transformMessages; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Sets; |
| import com.google.gerrit.server.git.validators.CommitValidationMessage; |
| import java.io.IOException; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Set; |
| import org.eclipse.jgit.dircache.DirCacheEntry; |
| import org.eclipse.jgit.junit.TestRepository; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.revwalk.RevCommit; |
| import org.eclipse.jgit.revwalk.RevWalk; |
| import org.eclipse.jgit.treewalk.TreeWalk; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class DuplicatePathnameValidatorTest extends ValidatorTestCase { |
| private static final ImmutableList<String> INITIAL_PATHNAMES = |
| ImmutableList.of("a", "ab", "f1/a", "f1/ab", "f2/a", "f2/ab", "f2/sF1/a", "f2/sF1/ab"); |
| |
| private final List<String> vistedPaths = Lists.newArrayList(); |
| private final List<CommitValidationMessage> messages = Lists.newArrayList(); |
| |
| private TestRepository<Repository> testRepo; |
| private Set<String> changedPaths; |
| private DuplicatePathnameValidator validator; |
| |
| private void runCheck( |
| List<String> existingTreePaths, |
| Set<String> testPaths, |
| List<CommitValidationMessage> messages, |
| List<String> visitedPaths) |
| throws Exception { |
| RevCommit c = |
| makeCommit( |
| testRepo.getRevWalk(), |
| createEmptyDirCacheEntries(existingTreePaths, testRepo), |
| testRepo); |
| try (TreeWalk tw = new TreeWalk(repo)) { |
| tw.setRecursive(false); |
| tw.addTree(c.getTree()); |
| tw.setFilter(new ListVisitedPathsFilter(visitedPaths)); |
| validator.checkForDuplicatesAgainstTheWholeTree(tw, testPaths, messages); |
| } |
| } |
| |
| @Override |
| @Before |
| public void init() throws IOException { |
| super.init(); |
| testRepo = new TestRepository<>(repo); |
| validator = new DuplicatePathnameValidator(null, null, null, null); |
| validator.setLocale(Locale.ENGLISH); |
| } |
| |
| @Test |
| public void testSkipSubTreesWithImproperPrefix() throws Exception { |
| changedPaths = Sets.newHashSet("f1/A"); |
| runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths); |
| assertThat(transformMessages(messages)) |
| .containsExactly(transformMessage(conflict("f1/A", "f1/a"))); |
| assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f1/a", "f1/ab", "f2"); |
| } |
| |
| @Test |
| public void testFindConflictingSubtree() throws Exception { |
| changedPaths = Sets.newHashSet("F1/a"); |
| runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths); |
| assertThat(transformMessages(messages)).containsExactly(transformMessage(conflict("F1", "f1"))); |
| assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f2"); |
| } |
| |
| @Test |
| public void testFindConflictingSubtree2() throws Exception { |
| changedPaths = Sets.newHashSet("f2/sf1", "F1/a"); |
| runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths); |
| assertThat(transformMessages(messages)) |
| .containsExactly( |
| transformMessage(conflict("F1", "f1")), transformMessage(conflict("f2/sf1", "f2/sF1"))); |
| assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f2", "f2/a", "f2/ab", "f2/sF1"); |
| } |
| |
| @Test |
| public void testFindDuplicates() throws Exception { |
| changedPaths = Sets.newHashSet("AB", "f1/A", "f2/Ab"); |
| runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths); |
| assertThat(transformMessages(messages)) |
| .containsExactly( |
| transformMessage(conflict("AB", "ab")), |
| transformMessage(conflict("f1/A", "f1/a")), |
| transformMessage(conflict("f2/Ab", "f2/ab"))); |
| assertThat(vistedPaths) |
| .containsExactly("a", "ab", "f1", "f1/a", "f1/ab", "f2", "f2/a", "f2/ab", "f2/sF1"); |
| } |
| |
| @Test |
| public void testFindNoDuplicates() throws Exception { |
| changedPaths = Sets.newHashSet("a", "ab", "f1/ab"); |
| runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths); |
| assertThat(messages).isEmpty(); |
| assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f1/a", "f1/ab", "f2"); |
| } |
| |
| @Test |
| public void testCheckInsideOfCommit() throws Exception { |
| List<String> filenames = Lists.newArrayList(INITIAL_PATHNAMES); |
| // add files with conflicting pathnames |
| filenames.add("A"); |
| filenames.add("F1/ab"); |
| filenames.add("f2/sF1/aB"); |
| try (RevWalk rw = new RevWalk(repo)) { |
| RevCommit c = makeCommit(rw, createEmptyDirCacheEntries(filenames, testRepo), testRepo); |
| List<CommitValidationMessage> m = validator.performValidation(repo, c, rw); |
| assertThat(m).hasSize(4); |
| // During checking inside of the commit it's unknown which file is checked |
| // first, because of that, both capabilities must be checked. |
| assertThat(transformMessages(m)) |
| .containsAnyOf( |
| transformMessage(conflict("A", "a")), transformMessage(conflict("a", "A"))); |
| |
| assertThat(transformMessages(m)) |
| .containsAnyOf( |
| transformMessage(conflict("F1", "f1")), transformMessage(conflict("f1", "F1"))); |
| |
| assertThat(transformMessages(m)) |
| .containsAnyOf( |
| transformMessage(conflict("F1/ab", "f1/ab")), |
| transformMessage(conflict("f1/ab", "F1/ab"))); |
| |
| assertThat(transformMessages(m)) |
| .containsAnyOf( |
| transformMessage(conflict("f2/sF1/aB", "f2/sF1/ab")), |
| transformMessage(conflict("f2/sF1/ab", "f2/sF1/aB"))); |
| } |
| } |
| |
| @Test |
| public void testCheckRenaming() throws Exception { |
| try (RevWalk rw = new RevWalk(repo)) { |
| RevCommit c = |
| makeCommit(rw, createEmptyDirCacheEntries(INITIAL_PATHNAMES, testRepo), testRepo); |
| DirCacheEntry[] entries = new DirCacheEntry[INITIAL_PATHNAMES.size()]; |
| for (int x = 0; x < INITIAL_PATHNAMES.size(); x++) { |
| // Rename files |
| entries[x] = |
| createDirCacheEntry(INITIAL_PATHNAMES.get(x).toUpperCase(), EMPTY_CONTENT, testRepo); |
| } |
| RevCommit c1 = makeCommit(rw, entries, testRepo, c); |
| List<CommitValidationMessage> m = validator.performValidation(repo, c1, rw); |
| assertThat(m).isEmpty(); |
| } |
| } |
| |
| @Test |
| public void validatorInactiveWhenConfigEmpty() { |
| assertThat(DuplicatePathnameValidator.isActive(EMPTY_PLUGIN_CONFIG)).isFalse(); |
| } |
| |
| @Test |
| public void defaultLocale() { |
| assertThat(DuplicatePathnameValidator.getLocale(EMPTY_PLUGIN_CONFIG)).isEqualTo(Locale.ENGLISH); |
| } |
| |
| @Test |
| public void testGetParentFolder() { |
| assertThat(validator.allParentFolders(INITIAL_PATHNAMES)) |
| .containsExactlyElementsIn(ImmutableList.of("f1", "f2", "f2/sF1")); |
| } |
| } |