SubmoduleSectionParser: do not use mocks for testing
Mock tests are testing too much the internals, which we don't really need to test. All we're interested in is correctness of the outcome, so we test from the outside now. This will make refactoring in the future way easier. Also this shifts the attention to testing the right thing. Looking at the `execute` method, which follows the structure of SubmoduleSectionParser.parse (e.g. the while loop chopping off the last '/') doesn't provide an enhanced understanding to the reader, who may want to treat the class as a black box and only see what goes in and what comes out. Change-Id: Icdf2394e38b42fa7ebd0e25d35fceb11cf17b9e0
This commit is contained in:
@@ -1,290 +0,0 @@
|
||||
// Copyright (C) 2011 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.google.gerrit.server.util;
|
||||
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.createStrictMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
import com.google.gerrit.server.project.ProjectState;
|
||||
|
||||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.BlobBasedConfig;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class SubmoduleSectionParserTest extends LocalDiskRepositoryTestCase {
|
||||
private static final String THIS_SERVER = "localhost";
|
||||
private ProjectCache projectCache;
|
||||
private BlobBasedConfig bbc;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
projectCache = createStrictMock(ProjectCache.class);
|
||||
bbc = createStrictMock(BlobBasedConfig.class);
|
||||
}
|
||||
|
||||
private void doReplay() {
|
||||
replay(projectCache, bbc);
|
||||
}
|
||||
|
||||
private void doVerify() {
|
||||
verify(projectCache, bbc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmodulesParseWithCorrectSections() throws Exception {
|
||||
final Map<String, SubmoduleSection> sectionsToReturn = new TreeMap<>();
|
||||
sectionsToReturn.put("a", new SubmoduleSection("ssh://localhost/a", "a",
|
||||
"."));
|
||||
sectionsToReturn.put("b", new SubmoduleSection("ssh://localhost/b", "b",
|
||||
"."));
|
||||
sectionsToReturn.put("c", new SubmoduleSection("ssh://localhost/test/c",
|
||||
"c-path", "refs/heads/master"));
|
||||
sectionsToReturn.put("d", new SubmoduleSection("ssh://localhost/d",
|
||||
"d-parent/the-d-folder", "refs/heads/test"));
|
||||
sectionsToReturn.put("e", new SubmoduleSection("ssh://localhost/e.git", "e",
|
||||
"."));
|
||||
|
||||
Map<String, String> reposToBeFound = new HashMap<>();
|
||||
reposToBeFound.put("a", "a");
|
||||
reposToBeFound.put("b", "b");
|
||||
reposToBeFound.put("c", "test/c");
|
||||
reposToBeFound.put("d", "d");
|
||||
reposToBeFound.put("e", "e");
|
||||
|
||||
final Branch.NameKey superBranchNameKey =
|
||||
new Branch.NameKey(new Project.NameKey("super-project"),
|
||||
"refs/heads/master");
|
||||
|
||||
Set<SubmoduleSubscription> expectedSubscriptions = new HashSet<>();
|
||||
expectedSubscriptions
|
||||
.add(new SubmoduleSubscription(superBranchNameKey, new Branch.NameKey(
|
||||
new Project.NameKey("a"), "refs/heads/master"), "a"));
|
||||
expectedSubscriptions
|
||||
.add(new SubmoduleSubscription(superBranchNameKey, new Branch.NameKey(
|
||||
new Project.NameKey("b"), "refs/heads/master"), "b"));
|
||||
expectedSubscriptions.add(new SubmoduleSubscription(superBranchNameKey,
|
||||
new Branch.NameKey(new Project.NameKey("test/c"), "refs/heads/master"),
|
||||
"c-path"));
|
||||
expectedSubscriptions.add(new SubmoduleSubscription(superBranchNameKey,
|
||||
new Branch.NameKey(new Project.NameKey("d"), "refs/heads/test"),
|
||||
"d-parent/the-d-folder"));
|
||||
expectedSubscriptions
|
||||
.add(new SubmoduleSubscription(superBranchNameKey, new Branch.NameKey(
|
||||
new Project.NameKey("e"), "refs/heads/master"), "e"));
|
||||
|
||||
execute(superBranchNameKey, sectionsToReturn, reposToBeFound,
|
||||
expectedSubscriptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmodulesParseWithAnInvalidSection() throws Exception {
|
||||
final Map<String, SubmoduleSection> sectionsToReturn = new TreeMap<>();
|
||||
sectionsToReturn.put("a", new SubmoduleSection("ssh://localhost/a", "a",
|
||||
"."));
|
||||
// This one is invalid since "b" is not a recognized project
|
||||
sectionsToReturn.put("b", new SubmoduleSection("ssh://localhost/b", "b",
|
||||
"."));
|
||||
sectionsToReturn.put("c", new SubmoduleSection("ssh://localhost/test/c",
|
||||
"c-path", "refs/heads/master"));
|
||||
sectionsToReturn.put("d", new SubmoduleSection("ssh://localhost/d",
|
||||
"d-parent/the-d-folder", "refs/heads/test"));
|
||||
sectionsToReturn.put("e", new SubmoduleSection("ssh://localhost/e.git", "e",
|
||||
"."));
|
||||
|
||||
// "b" will not be in this list
|
||||
Map<String, String> reposToBeFound = new HashMap<>();
|
||||
reposToBeFound.put("a", "a");
|
||||
reposToBeFound.put("c", "test/c");
|
||||
reposToBeFound.put("d", "d");
|
||||
reposToBeFound.put("e", "e");
|
||||
|
||||
final Branch.NameKey superBranchNameKey =
|
||||
new Branch.NameKey(new Project.NameKey("super-project"),
|
||||
"refs/heads/master");
|
||||
|
||||
Set<SubmoduleSubscription> expectedSubscriptions = new HashSet<>();
|
||||
expectedSubscriptions
|
||||
.add(new SubmoduleSubscription(superBranchNameKey, new Branch.NameKey(
|
||||
new Project.NameKey("a"), "refs/heads/master"), "a"));
|
||||
expectedSubscriptions.add(new SubmoduleSubscription(superBranchNameKey,
|
||||
new Branch.NameKey(new Project.NameKey("test/c"), "refs/heads/master"),
|
||||
"c-path"));
|
||||
expectedSubscriptions.add(new SubmoduleSubscription(superBranchNameKey,
|
||||
new Branch.NameKey(new Project.NameKey("d"), "refs/heads/test"),
|
||||
"d-parent/the-d-folder"));
|
||||
expectedSubscriptions
|
||||
.add(new SubmoduleSubscription(superBranchNameKey, new Branch.NameKey(
|
||||
new Project.NameKey("e"), "refs/heads/master"), "e"));
|
||||
|
||||
execute(superBranchNameKey, sectionsToReturn, reposToBeFound,
|
||||
expectedSubscriptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmoduleSectionToOtherServer() throws Exception {
|
||||
Map<String, SubmoduleSection> sectionsToReturn = new HashMap<>();
|
||||
// The url is not to this server.
|
||||
sectionsToReturn.put("a", new SubmoduleSection("ssh://review.source.com/a",
|
||||
"a", "."));
|
||||
|
||||
Set<SubmoduleSubscription> expectedSubscriptions = Collections.emptySet();
|
||||
execute(new Branch.NameKey(new Project.NameKey("super-project"),
|
||||
"refs/heads/master"), sectionsToReturn, new HashMap<String, String>(),
|
||||
expectedSubscriptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProjectNotFound() throws Exception {
|
||||
Map<String, SubmoduleSection> sectionsToReturn = new HashMap<>();
|
||||
sectionsToReturn.put("a", new SubmoduleSection("ssh://localhost/a", "a",
|
||||
"."));
|
||||
|
||||
Set<SubmoduleSubscription> expectedSubscriptions = Collections.emptySet();
|
||||
execute(new Branch.NameKey(new Project.NameKey("super-project"),
|
||||
"refs/heads/master"), sectionsToReturn, new HashMap<String, String>(),
|
||||
expectedSubscriptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProjectWithSlashesNotFound() throws Exception {
|
||||
Map<String, SubmoduleSection> sectionsToReturn = new HashMap<>();
|
||||
sectionsToReturn.put("project", new SubmoduleSection(
|
||||
"ssh://localhost/company/tools/project", "project", "."));
|
||||
|
||||
Set<SubmoduleSubscription> expectedSubscriptions = Collections.emptySet();
|
||||
execute(new Branch.NameKey(new Project.NameKey("super-project"),
|
||||
"refs/heads/master"), sectionsToReturn, new HashMap<String, String>(),
|
||||
expectedSubscriptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmodulesParseWithSubProjectFound() throws Exception {
|
||||
Map<String, SubmoduleSection> sectionsToReturn = new TreeMap<>();
|
||||
sectionsToReturn.put("a/b", new SubmoduleSection(
|
||||
"ssh://localhost/a/b", "a/b", "."));
|
||||
|
||||
Map<String, String> reposToBeFound = new HashMap<>();
|
||||
reposToBeFound.put("a/b", "a/b");
|
||||
reposToBeFound.put("b", "b");
|
||||
|
||||
Branch.NameKey superBranchNameKey =
|
||||
new Branch.NameKey(new Project.NameKey("super-project"),
|
||||
"refs/heads/master");
|
||||
|
||||
Set<SubmoduleSubscription> expectedSubscriptions = new HashSet<>();
|
||||
expectedSubscriptions
|
||||
.add(new SubmoduleSubscription(superBranchNameKey, new Branch.NameKey(
|
||||
new Project.NameKey("a/b"), "refs/heads/master"), "a/b"));
|
||||
execute(superBranchNameKey, sectionsToReturn, reposToBeFound,
|
||||
expectedSubscriptions);
|
||||
}
|
||||
|
||||
private void execute(final Branch.NameKey superProjectBranch,
|
||||
final Map<String, SubmoduleSection> sectionsToReturn,
|
||||
final Map<String, String> reposToBeFound,
|
||||
final Set<SubmoduleSubscription> expectedSubscriptions) throws Exception {
|
||||
expect(bbc.getSubsections("submodule"))
|
||||
.andReturn(sectionsToReturn.keySet());
|
||||
|
||||
for (Map.Entry<String, SubmoduleSection> entry : sectionsToReturn.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
final SubmoduleSection section = entry.getValue();
|
||||
expect(bbc.getString("submodule", id, "url")).andReturn(section.getUrl());
|
||||
expect(bbc.getString("submodule", id, "path")).andReturn(
|
||||
section.getPath());
|
||||
expect(bbc.getString("submodule", id, "branch")).andReturn(
|
||||
section.getBranch());
|
||||
|
||||
if (THIS_SERVER.equals(new URI(section.getUrl()).getHost())) {
|
||||
String projectNameCandidate;
|
||||
final String urlExtractedPath = new URI(section.getUrl()).getPath();
|
||||
int fromIndex = urlExtractedPath.length() - 1;
|
||||
while (fromIndex > 0) {
|
||||
fromIndex = urlExtractedPath.lastIndexOf('/', fromIndex - 1);
|
||||
projectNameCandidate = urlExtractedPath.substring(fromIndex + 1);
|
||||
if (projectNameCandidate.endsWith(Constants.DOT_GIT_EXT)) {
|
||||
projectNameCandidate = projectNameCandidate.substring(0, //
|
||||
projectNameCandidate.length() - Constants.DOT_GIT_EXT.length());
|
||||
}
|
||||
if (reposToBeFound.containsValue(projectNameCandidate)) {
|
||||
expect(projectCache.get(new Project.NameKey(projectNameCandidate)))
|
||||
.andReturn(createNiceMock(ProjectState.class));
|
||||
} else {
|
||||
expect(projectCache.get(new Project.NameKey(projectNameCandidate)))
|
||||
.andReturn(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doReplay();
|
||||
|
||||
final SubmoduleSectionParser ssp =
|
||||
new SubmoduleSectionParser(projectCache, bbc, THIS_SERVER,
|
||||
superProjectBranch);
|
||||
|
||||
Set<SubmoduleSubscription> returnedSubscriptions = ssp.parseAllSections();
|
||||
|
||||
doVerify();
|
||||
|
||||
assertEquals(expectedSubscriptions, returnedSubscriptions);
|
||||
}
|
||||
|
||||
private static final class SubmoduleSection {
|
||||
private final String url;
|
||||
private final String path;
|
||||
private final String branch;
|
||||
|
||||
SubmoduleSection(final String url, final String path,
|
||||
final String branch) {
|
||||
this.url = url;
|
||||
this.path = path;
|
||||
this.branch = branch;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getBranch() {
|
||||
return branch;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user