diff options
Diffstat (limited to 'org.eclipse.jgit.http.test/tst')
-rw-r--r-- | org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java new file mode 100644 index 0000000000..fba1a52640 --- /dev/null +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2015, christian.Halstrick <christian.halstrick@sap.com> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.http.test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Collection; +import java.util.Collections; + +import javax.servlet.http.HttpServletRequest; + +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.errors.RepositoryNotFoundException; +import org.eclipse.jgit.errors.TooLargePackException; +import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.http.server.GitServlet; +import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.junit.http.HttpTestCase; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectChecker; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.revwalk.RevBlob; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.PostReceiveHook; +import org.eclipse.jgit.transport.PreReceiveHook; +import org.eclipse.jgit.transport.ReceiveCommand; +import org.eclipse.jgit.transport.ReceivePack; +import org.eclipse.jgit.transport.RemoteRefUpdate; +import org.eclipse.jgit.transport.Transport; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for correct responses of {@link GitServlet}. Especially error + * situations where the {@link GitServlet} faces exceptions during request + * processing are tested + */ +public class GitServletResponseTests extends HttpTestCase { + private Repository srvRepo; + + private URIish srvURI; + + private GitServlet gs; + + private long maxPackSize = 0; // the maximum pack file size used by + // the server + + private PostReceiveHook postHook = null; + + private PreReceiveHook preHook = null; + + private ObjectChecker oc = null; + + /** + * Setup a http server using {@link GitServlet}. Tests should be able to + * configure the maximum pack file size, the object checker and custom hooks + * just before they talk to the server. + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + final TestRepository<Repository> srv = createTestRepository(); + final String repoName = srv.getRepository().getDirectory().getName(); + + ServletContextHandler app = server.addContext("/git"); + gs = new GitServlet(); + gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + public Repository open(HttpServletRequest req, String name) + throws RepositoryNotFoundException, + ServiceNotEnabledException { + if (!name.equals(repoName)) + throw new RepositoryNotFoundException(name); + + final Repository db = srv.getRepository(); + db.incrementOpen(); + return db; + } + }); + gs.setReceivePackFactory(new DefaultReceivePackFactory() { + public ReceivePack create(HttpServletRequest req, Repository db) + throws ServiceNotEnabledException, + ServiceNotAuthorizedException { + ReceivePack recv = super.create(req, db); + if (maxPackSize > 0) + recv.setMaxPackSizeLimit(maxPackSize); + if (postHook != null) + recv.setPostReceiveHook(postHook); + if (preHook != null) + recv.setPreReceiveHook(preHook); + if (oc != null) + recv.setObjectChecker(oc); + return recv; + } + + }); + app.addServlet(new ServletHolder(gs), "/*"); + + server.setUp(); + + srvRepo = srv.getRepository(); + srvURI = toURIish(app, repoName); + + StoredConfig cfg = srvRepo.getConfig(); + cfg.setBoolean("http", null, "receivepack", true); + cfg.save(); + } + + /** + * Configure a {@link GitServlet} that faces a {@link IllegalStateException} + * during executing preReceiveHooks. This used to lead to exceptions with a + * description of "invalid channel 101" on the client side. Make sure + * clients receive the correct response on the correct sideband. + * + * @throws Exception + */ + @Test + public void testRuntimeExceptionInPreReceiveHook() throws Exception { + final TestRepository client = createTestRepository(); + final RevBlob Q_txt = client + .blob("some blob content to measure pack size"); + final RevCommit Q = client.commit().add("Q", Q_txt).create(); + final Repository clientRepo = client.getRepository(); + final String srvBranchName = Constants.R_HEADS + "new.branch"; + Transport t; + + maxPackSize = 0; + postHook = null; + preHook = new PreReceiveHook() { + @Override + public void onPreReceive(ReceivePack rp, + Collection<ReceiveCommand> commands) { + throw new IllegalStateException(); + } + }; + + t = Transport.open(clientRepo, srvURI); + try { + RemoteRefUpdate update = new RemoteRefUpdate(clientRepo, Q.name(), + srvBranchName, false, null, null); + try { + t.push(NullProgressMonitor.INSTANCE, + Collections.singleton(update)); + fail("should not reach this line"); + } catch (Exception e) { + assertTrue(e instanceof TransportException); + } + } finally { + t.close(); + } + } + + /** + * Configure a {@link GitServlet} that faces a {@link IllegalStateException} + * during executing objectChecking. + * + * @throws Exception + */ + @Test + public void testObjectCheckerException() throws Exception { + final TestRepository client = createTestRepository(); + final RevBlob Q_txt = client + .blob("some blob content to measure pack size"); + final RevCommit Q = client.commit().add("Q", Q_txt).create(); + final Repository clientRepo = client.getRepository(); + final String srvBranchName = Constants.R_HEADS + "new.branch"; + Transport t; + + maxPackSize = 0; + postHook = null; + preHook = null; + oc = new ObjectChecker() { + @Override + public void checkCommit(byte[] raw) throws CorruptObjectException { + throw new IllegalStateException(); + } + }; + + t = Transport.open(clientRepo, srvURI); + try { + RemoteRefUpdate update = new RemoteRefUpdate(clientRepo, Q.name(), + srvBranchName, false, null, null); + try { + t.push(NullProgressMonitor.INSTANCE, + Collections.singleton(update)); + fail("should not reach this line"); + } catch (Exception e) { + assertTrue(e instanceof TransportException); + } + } finally { + t.close(); + } + } + + /** + * Configure a {@link GitServlet} that faces a {@link TooLargePackException} + * during persisting the pack and a {@link IllegalStateException} during + * executing postReceiveHooks. This used to lead to exceptions with a + * description of "invalid channel 101" on the client side. Make sure + * clients receive the correct response about the too large pack on the + * correct sideband. + * + * @throws Exception + */ + @Test + public void testUnpackErrorWithSubsequentExceptionInPostReceiveHook() + throws Exception { + final TestRepository client = createTestRepository(); + final RevBlob Q_txt = client + .blob("some blob content to measure pack size"); + final RevCommit Q = client.commit().add("Q", Q_txt).create(); + final Repository clientRepo = client.getRepository(); + final String srvBranchName = Constants.R_HEADS + "new.branch"; + Transport t; + + // this maxPackSize leads to an unPackError + maxPackSize = 400; + // this PostReceiveHook when called after an unsuccesfull unpack will + // lead to an IllegalStateException + postHook = new PostReceiveHook() { + public void onPostReceive(ReceivePack rp, + Collection<ReceiveCommand> commands) { + // the maxPackSize setting caused that the packfile couldn't be + // saved to disk. Calling getPackSize() now will lead to a + // IllegalStateException. + rp.getPackSize(); + } + }; + + t = Transport.open(clientRepo, srvURI); + try { + RemoteRefUpdate update = new RemoteRefUpdate(clientRepo, Q.name(), + srvBranchName, false, null, null); + try { + t.push(NullProgressMonitor.INSTANCE, + Collections.singleton(update)); + fail("should not reach this line"); + } catch (Exception e) { + assertTrue(e instanceof TooLargePackException); + } + } finally { + t.close(); + } + } +} |