/* * The MIT License * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Bruce Chapman, Yahoo! Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package hudson.scm; import hudson.model.Cause; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.Result; import hudson.slaves.DumbSlave; import hudson.util.FormValidation; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.concurrent.Future; import javax.servlet.ServletException; import org.jvnet.hudson.test.Bug; import org.jvnet.hudson.test.Email; import org.jvnet.hudson.test.HudsonHomeLoader.CopyExisting; import org.jvnet.hudson.test.Url; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.wc.SVNRevision; /** * @author Kohsuke Kawaguchi */ public class SubversionCheckoutTest extends AbstractSubversionTest { private static final int LOG_LIMIT = 1000; String kind = ISVNAuthenticationManager.PASSWORD; @Email("http://www.nabble.com/Hudson-1.266-and-1.267%3A-Subversion-authentication-broken--td21156950.html") public void testHttpsCheckOut() throws Exception { FreeStyleProject p = createFreeStyleProject(); p.setScm(new SubversionSCM("https://datacard.googlecode.com/svn/trunk")); FreeStyleBuild b = assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserCause()).get()); assertTrue(b.getWorkspace().child("README.txt").exists()); } @Email("http://hudson.361315.n4.nabble.com/Hudson-1-266-and-1-267-Subversion-authentication-broken-td375737.html") public void testHttpCheckOut() throws Exception { FreeStyleProject p = createFreeStyleProject(); p.setScm(new SubversionSCM("http://svn.codehaus.org/sxc/tags/sxc-0.5/sxc-core/src/test/java/com/envoisolutions/sxc/builder/")); FreeStyleBuild b = assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserCause()).get()); assertTrue(b.getWorkspace().child("Node.java").exists()); } @Url("http://hudson.pastebin.com/m3ea34eea") public void testRemoteCheckOut() throws Exception { DumbSlave s = createSlave(); FreeStyleProject p = createFreeStyleProject(); p.setAssignedLabel(s.getSelfLabel()); p.setScm(new SubversionSCM("http://svn.apache.org/repos/asf/subversion/trunk/doc")); FreeStyleBuild b = assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserCause()).get()); assertTrue(b.getWorkspace().child("README").exists()); b = assertBuildStatusSuccess(p.scheduleBuild2(0).get()); } /** * Tests the "URL@REV" format in SVN URL. */ @Bug(262) public void testRevisionedCheckout() throws Exception { FreeStyleProject p = createFreeStyleProject(); p.setScm(new SubversionSCM("http://svn.apache.org/repos/asf/subversion/trunk/doc@1244918")); FreeStyleBuild b = p.scheduleBuild2(0, new Cause.UserCause()).get(); System.out.println(b.getLog(LOG_LIMIT)); assertTrue(b.getLog(LOG_LIMIT).contains("At revision 1244918")); assertBuildStatus(Result.SUCCESS, b); } /** * Tests the "URL@HEAD" format in the SVN URL */ public void testHeadRevisionCheckout() throws Exception { File testRepo = new CopyExisting(getClass().getResource("two-revisions.zip")).allocate(); SubversionSCM scm = new SubversionSCM("file:///" + testRepo.getPath() + "@HEAD"); FreeStyleProject p = createFreeStyleProject(); p.setScm(scm); FreeStyleBuild b = p.scheduleBuild2(0, new Cause.UserCause()).get(); System.out.println(b.getLog(LOG_LIMIT)); assertTrue(b.getLog(LOG_LIMIT).contains("At revision 2")); assertBuildStatus(Result.SUCCESS, b); } /** * Test parsing of @revision information from the tail of the URL */ public void testModuleLocationRevisions() { SubversionSCM.ModuleLocation m = new SubversionSCM.ModuleLocation("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/trivial-ant@13000", null); SVNRevision r = m.getRevision(null); assertTrue(r.isValid()); assertEquals(13000, r.getNumber()); assertEquals("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/trivial-ant", m.getURL()); m = new SubversionSCM.ModuleLocation("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/trivial-ant@HEAD", null); r = m.getRevision(null); assertTrue(r.isValid()); assertTrue(r == SVNRevision.HEAD); assertEquals("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/trivial-ant", m.getURL()); m = new SubversionSCM.ModuleLocation("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/trivial-ant@FAKE", null); r = m.getRevision(null); assertFalse(r.isValid()); assertEquals("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/trivial-ant@FAKE", m.getURL()); } /** * Test parsing of @revision information from the tail of the URL */ public void testModuleLocationWithDepthIgnoreExternalsOption() throws Exception { FreeStyleProject p = createFreeStyleProject(); SubversionSCM scm = new SubversionSCM( Arrays.asList( new SubversionSCM.ModuleLocation("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/testSubversionExclusion", "c", "infinity", true), new SubversionSCM.ModuleLocation("https://svn.java.net/svn/hudson~svn/trunk/hudson/test-projects/testSubversionExclusion", "d", "files", false)), false, false, null, null, null, null, null, null); p.setScm(scm); submit(new WebClient().getPage(p, "configure").getFormByName("config")); verify(scm, (SubversionSCM) p.getScm()); } /** * Tests a checkout with RevisionParameterAction */ public void testRevisionParameter() throws Exception { FreeStyleProject p = createFreeStyleProject(); String url = "http://svn.apache.org/repos/asf/subversion/trunk/doc"; p.setScm(new SubversionSCM(url)); FreeStyleBuild b = p.scheduleBuild2(0, new Cause.UserCause(), new RevisionParameterAction(new SubversionSCM.SvnInfo(url, 1162787))).get(); System.out.println(b.getLog(LOG_LIMIT)); assertTrue(b.getLog(LOG_LIMIT).contains("At revision 1162787")); assertBuildStatus(Result.SUCCESS, b); } public void testRevisionParameterFolding() throws Exception { FreeStyleProject p = createFreeStyleProject(); String url = "http://svn.apache.org/repos/asf/subversion/trunk/doc"; p.setScm(new SubversionSCM(url)); // Schedule build of a specific revision with a quiet period Future<FreeStyleBuild> f = p.scheduleBuild2(60, new Cause.UserCause(), new RevisionParameterAction(new SubversionSCM.SvnInfo(url, 1162786))); // Schedule another build at a more recent revision p.scheduleBuild2(0, new Cause.UserCause(), new RevisionParameterAction(new SubversionSCM.SvnInfo(url, 1162787))); FreeStyleBuild b = f.get(); System.out.println(b.getLog(LOG_LIMIT)); assertTrue(b.getLog(LOG_LIMIT).contains("At revision 1162787")); assertBuildStatus(Result.SUCCESS,b); } @Bug(5684) public void testDoCheckExcludedUsers() throws IOException, ServletException { String[] validUsernames = new String[]{ "DOMAIN\\user", "user", "us_er", "user123", "User", "", // this one is ignored "DOmain12\\User34", "DOMAIN.user", "continuous-habbo"}; for (String validUsername : validUsernames) { assertEquals( "User " + validUsername + " isn't OK (but it's valid).", FormValidation.Kind.OK, new SubversionSCM.DescriptorImpl().doCheckExcludedUsers(validUsername).kind); } String[] invalidUsernames = new String[]{ "\\user", "DOMAIN\\", "DOMAIN@user"}; for (String invalidUsername : invalidUsernames) { assertEquals( "User " + invalidUsername + " isn't ERROR (but it's not valid).", FormValidation.Kind.ERROR, new SubversionSCM.DescriptorImpl().doCheckExcludedUsers(invalidUsername).kind); } } private void verify(SubversionSCM lhs, SubversionSCM rhs) { SubversionSCM.ModuleLocation[] ll = lhs.getLocations(); SubversionSCM.ModuleLocation[] rl = rhs.getLocations(); assertEquals(ll.length, rl.length); for (int i = 0; i < ll.length; i++) { assertEquals(ll[i].local, rl[i].local); assertEquals(ll[i].remote, rl[i].remote); assertEquals(ll[i].getDepthOption(), rl[i].getDepthOption()); assertEquals(ll[i].isIgnoreExternalsOption(), rl[i].isIgnoreExternalsOption()); } assertNullEquals(lhs.getExcludedRegions(), rhs.getExcludedRegions()); assertNullEquals(lhs.getExcludedUsers(), rhs.getExcludedUsers()); assertNullEquals(lhs.getExcludedRevprop(), rhs.getExcludedRevprop()); assertNullEquals(lhs.getExcludedCommitMessages(), rhs.getExcludedCommitMessages()); assertNullEquals(lhs.getIncludedRegions(), rhs.getIncludedRegions()); } private void assertNullEquals(String left, String right) { if (left == null) left = ""; if (right == null) right = ""; assertEquals(left, right); } }