/*
* Copyright 2017 ThoughtWorks, Inc.
*
* 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.thoughtworks.go.domain.materials.svn;
import com.googlecode.junit.ext.JunitExtRunner;
import com.googlecode.junit.ext.RunIf;
import com.thoughtworks.go.config.materials.svn.SvnMaterial;
import com.thoughtworks.go.domain.materials.*;
import com.thoughtworks.go.helper.SvnTestRepo;
import com.thoughtworks.go.junitext.EnhancedOSChecker;
import com.thoughtworks.go.util.FileUtil;
import com.thoughtworks.go.util.TestFileUtil;
import com.thoughtworks.go.util.command.*;
import org.hamcrest.Matchers;
import org.hamcrest.core.Is;
import org.jdom2.input.SAXBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import static com.thoughtworks.go.junitext.EnhancedOSChecker.DO_NOT_RUN_ON;
import static com.thoughtworks.go.junitext.EnhancedOSChecker.WINDOWS;
import static com.thoughtworks.go.util.command.ProcessOutputStreamConsumer.inMemoryConsumer;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.*;
@RunWith(JunitExtRunner.class)
public class SvnCommandTest {
public static SvnTestRepo testRepo;
protected static final DotSvnIgnoringFilter DOT_SVN_IGNORING_FILTER = new DotSvnIgnoringFilter();
protected String svnRepositoryUrl;
protected File checkoutFolder;
protected SvnCommand subversion;
protected ProcessOutputStreamConsumer outputStreamConsumer;
private final String svnInfoOutput = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"project1\"\n"
+ " revision=\"27\">\n"
+ "<url>http://localhost/svn/project1</url>\n"
+ "<repository>\n"
+ "<root>http://localhost/svn/project1</root>\n"
+ "<uuid>b51fe673-20c0-4205-a07b-5deb54bb09f3</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"27\">\n"
+ "<author>anthill</author>\n"
+ "<date>2012-10-18T07:54:06.487895Z</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
@Before
public void setup() throws IOException {
testRepo = new SvnTestRepo();
svnRepositoryUrl = testRepo.projectRepositoryUrl();
subversion = new SvnCommand(null, svnRepositoryUrl, "user", "pass", false);
outputStreamConsumer = inMemoryConsumer();
checkoutFolder = TestFileUtil.createUniqueTempFile("workingcopy" + System.currentTimeMillis());
}
@After
public void teardown() {
testRepo.tearDown();
FileUtil.deleteFolder(checkoutFolder);
}
@Test
@RunIf(value = EnhancedOSChecker.class, arguments = {DO_NOT_RUN_ON, WINDOWS})
public void shouldRecogniseSvnAsTheSameIfURLContainsSpaces() throws Exception {
File working = TestFileUtil.createTempFolder("shouldRecogniseSvnAsTheSameIfURLContainsSpaces");
SvnTestRepo repo = new SvnTestRepo("a directory with spaces");
SvnMaterial material = repo.material();
assertThat(material.getUrl(), containsString("%20"));
InMemoryStreamConsumer output = new InMemoryStreamConsumer();
material.freshCheckout(output, new SubversionRevision("3"), working);
assertThat(output.getAllOutput(), containsString("Checked out revision 3"));
InMemoryStreamConsumer output2 = new InMemoryStreamConsumer();
material.updateTo(output2, working, new RevisionContext(new SubversionRevision("4")), new TestSubprocessExecutionContext());
assertThat(output2.getAllOutput(), containsString("Updated to revision 4"));
}
@Test
@RunIf(value = EnhancedOSChecker.class, arguments = {DO_NOT_RUN_ON, WINDOWS})
public void shouldRecogniseSvnAsTheSameIfURLUsesFileProtocol() throws Exception {
SvnTestRepo repo = new SvnTestRepo("svnRepo");
File working = TestFileUtil.createTempFolder("someDir");
SvnMaterial material = repo.material();
InMemoryStreamConsumer output = new InMemoryStreamConsumer();
material.freshCheckout(output, new SubversionRevision("3"), working);
assertThat(output.getAllOutput(), containsString("Checked out revision 3"));
InMemoryStreamConsumer output2 = new InMemoryStreamConsumer();
updateMaterial(material, new SubversionRevision("4"), working, output2);
assertThat(output2.getAllOutput(), containsString("Updated to revision 4"));
}
private void updateMaterial(SvnMaterial material, SubversionRevision revision, File working, InMemoryStreamConsumer output2) {
material.updateTo(output2, working, new RevisionContext(revision), new TestSubprocessExecutionContext());
}
@Test
@RunIf(value = EnhancedOSChecker.class, arguments = {DO_NOT_RUN_ON, WINDOWS})
public void shouldRecogniseSvnAsTheSameIfURLContainsChineseCharacters() throws Exception {
File working = TestFileUtil.createTempFolder("shouldRecogniseSvnAsTheSameIfURLContainsSpaces");
SvnTestRepo repo = new SvnTestRepo("a directory with 司徒空在此");
SvnMaterial material = repo.material();
assertThat(material.getUrl(), containsString("%20"));
InMemoryStreamConsumer output = new InMemoryStreamConsumer();
material.freshCheckout(output, new SubversionRevision("3"), working);
assertThat(output.getAllOutput(), containsString("Checked out revision 3"));
InMemoryStreamConsumer output2 = new InMemoryStreamConsumer();
updateMaterial(material, new SubversionRevision("4"), working, output2);
assertThat(output2.getAllOutput(), containsString("Updated to revision 4"));
}
@Test
public void shouldFilterModifiedFilesByRepositoryURL() throws Exception {
subversion = new SvnCommand(null, testRepo.end2endRepositoryUrl() + "/unit-reports", "user", "pass", false);
List list = subversion.modificationsSince(new SubversionRevision(0));
Modification modification = (Modification) list.get(0);
assertThat(modification.getModifiedFiles().size(), is(3));
for (ModifiedFile file : modification.getModifiedFiles()) {
assertThat(file.getFileName().startsWith("/unit-reports"), is(true));
assertThat(file.getFileName().startsWith("/ft-reports"), is(false));
}
}
@Test
public void shouldNotFilterModifiedFilesWhileURLPointsToRoot() throws Exception {
subversion = new SvnCommand(null, testRepo.end2endRepositoryUrl(), "user", "pass", false);
List list = subversion.modificationsSince(new SubversionRevision(0));
Modification modification = (Modification) list.get(list.size() - 1);
assertThat(modification.getModifiedFiles().size(), is(7));
}
@Test
public void shouldCheckVCSConnection() throws Exception {
ValidationBean validationBean = subversion.checkConnection();
assertThat(validationBean.isValid(), is(true));
}
@Test
public void shouldReplacePasswordWithStarWhenCheckSvnConnection() throws Exception {
SvnCommand command = new SvnCommand(null, "http://do-not-care.com", "user", "password", false);
ValidationBean validationBean = command.checkConnection();
assertThat(validationBean.isValid(), is(false));
assertThat(validationBean.getError(), containsString("INPUT"));
assertThat(validationBean.getError(), containsString("******"));
}
@Test
public void shouldGetModificationsFromSubversionSinceARevision() {
final List list = subversion.modificationsSince(new SubversionRevision("1"));
assertThat(list.size(), is(3));
assertThat(((Modification) list.get(0)).getRevision(), is("4"));
assertThat(((Modification) list.get(1)).getRevision(), is("3"));
assertThat(((Modification) list.get(2)).getRevision(), is("2"));
}
@Test
public void shouldGetLatestModificationFromSubversion() {
final List<Modification> materialRevisions = subversion.latestModification();
assertThat(materialRevisions.size(), is(1));
final Modification modification = materialRevisions.get(0);
assertThat(modification.getComment(), is("Added simple build shell to dump the environment to console."));
assertThat(modification.getModifiedFiles().size(), is(1));
}
@Test
public void shouldCheckoutToSpecificRevision() {
subversion.checkoutTo(outputStreamConsumer, checkoutFolder, revision(2));
assertThat(checkoutFolder.exists(), is(true));
assertThat(checkoutFolder.listFiles().length, org.hamcrest.core.Is.is(not(0)));
assertAtRevision(2, "TestReport-Unit.xml");
}
@Test
public void shouldUpdateToSpecificRevision() {
subversion.checkoutTo(outputStreamConsumer, checkoutFolder, SubversionRevision.HEAD);
assertAtRevision(4, "TestReport-Unit.xml");
subversion.updateTo(outputStreamConsumer, checkoutFolder, revision(2));
assertAtRevision(2, "TestReport-Unit.xml");
subversion.updateTo(outputStreamConsumer, checkoutFolder, revision(3));
assertAtRevision(3, "revision3.txt");
}
@Test
public void shouldThrowExceptionWithTheSecretHiddenWhenUpdateToFails() {
subversion.checkoutTo(outputStreamConsumer, checkoutFolder, SubversionRevision.HEAD);
assertAtRevision(4, "TestReport-Unit.xml");
try {
subversion.updateTo(outputStreamConsumer, checkoutFolder , revision(-1));
fail("should throw exception");
} catch (Exception e) {
assertThat(e.getMessage(), containsString("--password ******"));
}
}
@Test public void shouldUnlockAndRevertWorkingCopy() throws Exception {
subversion.checkoutTo(outputStreamConsumer, checkoutFolder, SubversionRevision.HEAD);
File file = checkoutFolder.listFiles(DOT_SVN_IGNORING_FILTER)[0];
file.delete();
assertThat(file.exists(), is(false));
subversion.cleanupAndRevert(outputStreamConsumer, checkoutFolder);
assertThat(file.exists(), is(true));
}
@Test public void shouldGetWorkingUrl() throws IOException {
subversion.checkoutTo(outputStreamConsumer, checkoutFolder, SubversionRevision.HEAD);
String url = subversion.workingRepositoryUrl(checkoutFolder);
assertThat(URLDecoder.decode(url, "UTF-8"), is(svnRepositoryUrl));
}
protected void assertAtRevision(int rev, String file) {
String[] filenames = checkoutFolder.list(DOT_SVN_IGNORING_FILTER);
assertThat(filenames.length, Is.is(rev));
assertThat(Arrays.asList(filenames), org.junit.matchers.JUnitMatchers.hasItem(file));
}
protected SubversionRevision revision(int revision) {
return new SubversionRevision(revision);
}
public static class DotSvnIgnoringFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return !name.equals(".svn");
}
}
@Test
public void shouldParseSvnInfoWithParthDifferentFromUrl() throws Exception {
String output = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"PurchaseDeliverables\"\n"
+ " revision=\"36788\">\n"
+ "<url>http://svn.somewhere.com/someotherline/bloresvn/TISSIP/branch/DEV/PurchaseDeliverables</url>\n"
+ "<repository>\n"
+ "<root>http://svn.somewhere.com/someotherline</root>\n"
+ "<uuid>f6689194-972b-e749-89bf-11ebdadc4dc5</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"26449\">\n"
+ "<author>nigelfer</author>\n"
+ "<date>2009-02-03T15:43:08.059944Z</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
SvnCommand.SvnInfo svnInfo = new SvnCommand.SvnInfo();
svnInfo.parse(output, new SAXBuilder());
assertThat(svnInfo.getPath(), is("/bloresvn/TISSIP/branch/DEV/PurchaseDeliverables"));
assertThat(svnInfo.getUrl(),
is("http://svn.somewhere.com/someotherline/bloresvn/TISSIP/branch/DEV/PurchaseDeliverables"));
}
@Test
public void shouldParseSvnInfo() throws Exception {
String output = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"someotherline\"\n"
+ " revision=\"36788\">\n"
+ "<url>http://svn.somewhere.com/svn/someotherline</url>\n"
+ "<repository>\n"
+ "<root>http://svn.somewhere.com/svn</root>\n"
+ "<uuid>f6689194-972b-e749-89bf-11ebdadc4dc5</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"36788\">\n"
+ "<author>csebasti</author>\n"
+ "<date>2009-05-30T17:47:27.435599Z</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
SvnCommand.SvnInfo svnInfo = new SvnCommand.SvnInfo();
svnInfo.parse(output, new SAXBuilder());
assertThat(svnInfo.getPath(), is("/someotherline"));
assertThat(svnInfo.getUrl(),
is("http://svn.somewhere.com/svn/someotherline"));
assertThat(svnInfo.getRoot(), is("http://svn.somewhere.com/svn"));
}
@Test
public void shouldParseSvnInfoWithUTF8ChineseNameInUrl() throws Exception {
String output = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"司徒空在此\"\n"
+ " revision=\"4\">\n"
+ "<url>file:///home/cceuser/bigfs/projects/cruise/common/test-resources/unit/data/svnrepo/end2end/%E5%8F%B8%E5%BE%92%E7%A9%BA%E5%9C%A8%E6%AD%A4</url>\n"
+ "<repository>\n"
+ "<root>file:///home/cceuser/bigfs/projects/cruise/common/test-resources/unit/data/svnrepo/end2end</root>\n"
+ "<uuid>f953918e-915c-4459-8d4c-83860cce9d9a</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"4\">\n"
+ "<author></author>\n"
+ "<date>2009-05-31T04:14:44.223393Z</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
SvnCommand.SvnInfo svnInfo = new SvnCommand.SvnInfo();
svnInfo.parse(output, new SAXBuilder());
assertThat(svnInfo.getPath(), is("/司徒空在此"));
assertThat(svnInfo.getUrl(),
is("file:///home/cceuser/bigfs/projects/cruise/common/test-resources/unit/data/svnrepo/end2end/%E5%8F%B8%E5%BE%92%E7%A9%BA%E5%9C%A8%E6%AD%A4"));
}
@Test
public void shouldParseEncodedUrl() {
String output = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"trunk\"\n"
+ " revision=\"8650\">\n"
+ "<url>https://217.45.214.17:8443/svn/Entropy%20System/Envoy%20Enterprise/trunk</url>\n"
+ "<repository>\n"
+ "<root>https://217.45.214.17:8443/svn</root>\n"
+ "<uuid>3ed677eb-f12f-3343-ac77-786e4d01a301</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"8650\">\n"
+ "<author>BuildServer</author>\n"
+ "<date>2009-04-03 15:52:16 +0800 (Fri, 03 Apr 2009)</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
SvnCommand.SvnInfo svnInfo = new SvnCommand.SvnInfo();
svnInfo.parse(output, new SAXBuilder());
assertThat(svnInfo.getUrl(), is("https://217.45.214.17:8443/svn/Entropy%20System/Envoy%20Enterprise/trunk"));
assertThat(svnInfo.getPath(), is("/Entropy System/Envoy Enterprise/trunk"));
}
@Test
public void shouldParseEncodedUrlAndPath() {
String output = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"unit-reports\"\n"
+ " revision=\"3\">\n"
+ "<url>file:///C:/Documents%20and%20Settings/cceuser/Local%20Settings/Temp/testSvnRepo-1243722556125/end2end/unit-reports</url>\n"
+ "<repository>\n"
+ "<root>file:///C:/Documents%20and%20Settings/cceuser/Local%20Settings/Temp/testSvnRepo-1243722556125/end2end</root>\n"
+ "<uuid>f953918e-915c-4459-8d4c-83860cce9d9a</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"1\">\n"
+ "<author>cceuser</author>\n"
+ "<date>2008-03-20T04:00:43.976517Z</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
SvnCommand.SvnInfo svnInfo = new SvnCommand.SvnInfo();
svnInfo.parse(output, new SAXBuilder());
assertThat(svnInfo.getUrl(), is("file:///C:/Documents%20and%20Settings/cceuser/Local%20Settings/Temp/testSvnRepo-1243722556125/end2end/unit-reports"));
assertThat(svnInfo.getPath(), is("/unit-reports"));
}
@Test
public void shouldParsePartlyEncodedUrlAndPath() {
String output = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"unit-reports\"\n"
+ " revision=\"3\">\n"
+ "<url>svn+ssh://hostname/foo%20bar%20baz/end2end</url>\n"
+ "<repository>\n"
+ "<root>svn+ssh://hostname/foo%20bar%20baz</root>\n"
+ "<uuid>f953918e-915c-4459-8d4c-83860cce9d9a</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"1\">\n"
+ "<author>cceuser</author>\n"
+ "<date>2008-03-20T04:00:43.976517Z</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
SvnCommand.SvnInfo svnInfo = new SvnCommand.SvnInfo();
svnInfo.parse(output, new SAXBuilder());
assertThat(svnInfo.getUrl(), is("svn+ssh://hostname/foo%20bar%20baz/end2end"));
assertThat(svnInfo.getPath(), is("/end2end"));
}
@Test
public void shouldHidePasswordInUrl() {
SvnCommand command = new SvnCommand(
null, "https://user:password@217.45.214.17:8443/svn/Entropy%20System/Envoy%20Enterprise/trunk");
assertThat(command.getUrlForDisplay(),
is("https://user:******@217.45.214.17:8443/svn/Entropy%20System/Envoy%20Enterprise/trunk"));
}
@Test
public void shouldSupportUTF8CheckInMessageAndFilename() throws Exception {
String message = "司徒空在此";
String filename = "司徒空在此.scn";
testRepo.checkInOneFile(filename, message);
Modification modification = subversion.latestModification().get(0);
assertThat(modification.getComment(), is(message));
assertThat(modification.getModifiedFiles().get(0).getFileName(), containsString(filename));
}
@Test
public void shouldNotAddEmptyPasswordWhenUsernameIsProvidedWithNoPassword() throws IOException {
SvnCommand command = new SvnCommand(null, "url", "shilpaIsGreat", null, false);
CommandArgument argument = new StringArgument(String.format("--password="));
assertThat(command.buildSvnLogCommandForLatestOne().getArguments(), not(hasItem(argument)));
}
@Test
public void shouldNotAddEmptyPasswordWhenUsernameIsProvidedWithPassword() throws IOException {
SvnCommand command = new SvnCommand(null, "url", "shilpaIsGreat", "noSheIsNot", false);
CommandArgument argument = new StringArgument("--password");
CommandArgument passArg = new PasswordArgument("noSheIsNot");
assertThat(command.buildSvnLogCommandForLatestOne().getArguments(), hasItems(argument, passArg));
}
@Test
public void shouldAddNothingWhenNoUsernameIsNotProvided() throws IOException {
SvnCommand commandWithNullUsername = new SvnCommand(null, "url", null, null, false);
assertThat(commandWithNullUsername.buildSvnLogCommandForLatestOne().toString().contains("--password="), is(false));
assertThat(commandWithNullUsername.buildSvnLogCommandForLatestOne().toString().contains("--username"), is(false));
SvnCommand commandWithEmptyUsername = new SvnCommand(null, "url", " ", " ", false);
assertThat(commandWithEmptyUsername.buildSvnLogCommandForLatestOne().toString().contains("--password="), is(false));
assertThat(commandWithEmptyUsername.buildSvnLogCommandForLatestOne().toString().contains("--username"), is(false));
}
@Test
public void shouldGetSvnInfoAndReturnMapOfUrlToUUID() {
final String svnInfoOutput = "<?xml version=\"1.0\"?>\n"
+ "<info>\n"
+ "<entry\n"
+ " kind=\"dir\"\n"
+ " path=\"project1\"\n"
+ " revision=\"27\">\n"
+ "<url>http://localhost/svn/project1</url>\n"
+ "<repository>\n"
+ "<root>http://localhost/svn/project1</root>\n"
+ "<uuid>b51fe673-20c0-4205-a07b-5deb54bb09f3</uuid>\n"
+ "</repository>\n"
+ "<commit\n"
+ " revision=\"27\">\n"
+ "<author>anthill</author>\n"
+ "<date>2012-10-18T07:54:06.487895Z</date>\n"
+ "</commit>\n"
+ "</entry>\n"
+ "</info>";
final SvnMaterial svnMaterial = mock(SvnMaterial.class);
when(svnMaterial.getUrl()).thenReturn("http://localhost/svn/project1");
when(svnMaterial.getUserName()).thenReturn("user");
when(svnMaterial.getPassword()).thenReturn("password");
final ConsoleResult consoleResult = mock(ConsoleResult.class);
when(consoleResult.outputAsString()).thenReturn(svnInfoOutput);
final HashSet<SvnMaterial> svnMaterials = new HashSet<>();
svnMaterials.add(svnMaterial);
final SvnCommand spy = spy(subversion);
doAnswer(new Answer() {
@Override public Object answer(InvocationOnMock invocation) throws Throwable {
final CommandLine commandLine = (CommandLine) invocation.getArguments()[0];
assertThat(commandLine.toString(), containsString("svn info --xml --username user --password ****** http://localhost/svn/project1"));
return consoleResult;
}
}).when(spy).executeCommand(any(CommandLine.class));
final HashMap<String,String> urlToRemoteUUIDMap = spy.createUrlToRemoteUUIDMap(svnMaterials);
assertThat(urlToRemoteUUIDMap.size(), is(1));
assertThat(urlToRemoteUUIDMap.get("http://localhost/svn/project1"), is("b51fe673-20c0-4205-a07b-5deb54bb09f3"));
}
@Test
public void shouldGetSvnInfoForMultipleMaterialsAndReturnMapOfUrlToUUID() {
final SvnMaterial svnMaterial1 = mock(SvnMaterial.class);
when(svnMaterial1.getUrl()).thenReturn("http://localhost/svn/project1");
final SvnMaterial svnMaterial2 = mock(SvnMaterial.class);
when(svnMaterial2.getUrl()).thenReturn("http://foo.bar");
final HashSet<SvnMaterial> svnMaterials = new HashSet<>();
svnMaterials.add(svnMaterial1);
svnMaterials.add(svnMaterial2);
final SvnCommand spy = spy(subversion);
doAnswer(new Answer() {
@Override public Object answer(InvocationOnMock invocation) throws Throwable {
final ConsoleResult consoleResult = mock(ConsoleResult.class);
when(consoleResult.outputAsString()).thenReturn(svnInfoOutput);
final CommandLine commandLine = (CommandLine) invocation.getArguments()[0];
if (commandLine.toString().contains("http://localhost/svn/project1")) {
return consoleResult;
} else {
throw new RuntimeException("Some thing crapped out");
}
}
}).when(spy).executeCommand(any(CommandLine.class));
HashMap<String,String> urlToRemoteUUIDMap = null;
try {
urlToRemoteUUIDMap = spy.createUrlToRemoteUUIDMap(svnMaterials);
} catch (Exception e) {
fail("Should not have failed although exception was thrown " + e);
}
assertThat(urlToRemoteUUIDMap.size(), is(1));
assertThat(urlToRemoteUUIDMap.get("http://localhost/svn/project1"), is("b51fe673-20c0-4205-a07b-5deb54bb09f3"));
verify(spy, times(2)).executeCommand(any(CommandLine.class));
}
@Test
public void shouldUseCorrectCredentialsPerSvnMaterialWhenQueryingForInfo() throws Exception {
final String svnMaterial1Url = "http://localhost/svn/project1";
final String svnMaterial1User = "svnMaterial1_user";
final String svnMaterial1Password = "svnMaterial1_password";
final SvnMaterial svnMaterial1 = buildMockSvnMaterial(svnMaterial1Url, svnMaterial1User, svnMaterial1Password);
String svnMaterial2Url = "http://localhost/svn/project2";
SvnMaterial svnMaterial2 = buildMockSvnMaterial(svnMaterial2Url, null, null);
HashSet<SvnMaterial> svnMaterials = new HashSet<>();
svnMaterials.add(svnMaterial1);
svnMaterials.add(svnMaterial2);
SvnCommand spy = spy(subversion);
doAnswer(new Answer() {
@Override public Object answer(InvocationOnMock invocation) throws Throwable {
final ConsoleResult consoleResult = mock(ConsoleResult.class);
when(consoleResult.outputAsString()).thenReturn(svnInfoOutput);
verifyCommandLine((CommandLine) invocation.getArguments()[0]);
return consoleResult;
}
private void verifyCommandLine(CommandLine commandLine) {
String commandString = commandLine.toStringForDisplay();
if (commandString.contains(svnMaterial1User)) {
List<CommandArgument> arguments = commandLine.getArguments();
for (CommandArgument argument : arguments) {
if (argument instanceof PasswordArgument) {
assertThat(argument.forCommandline(), is(svnMaterial1Password));
}
}
} else {
assertThat(commandString, not(Matchers.containsString("--username")));
assertThat(commandString, not(Matchers.containsString("password")));
}
}
}).when(spy).executeCommand(any(CommandLine.class));
HashMap<String, String> result = spy.createUrlToRemoteUUIDMap(svnMaterials);
verify(svnMaterial1).getUserName();
verify(svnMaterial1).getPassword();
verify(svnMaterial2).getUserName();
verify(svnMaterial2).getPassword();
}
private SvnMaterial buildMockSvnMaterial(String url, String username, String password) {
final SvnMaterial svnMaterial = mock(SvnMaterial.class);
when(svnMaterial.getUrl()).thenReturn(url);
when(svnMaterial.getUserName()).thenReturn(username);
when(svnMaterial.getPassword()).thenReturn(password);
return svnMaterial;
}
}