Add JUnit tests for HTTP transport
[jgit.git] / org.eclipse.jgit.http.test / tst / org / eclipse / jgit / http / test / DumbClientSmartServerTest.java
blob0b28712f69e4126f0f723007bfe0a5b45a0b6a92
1 /*
2 * Copyright (C) 2010, Google Inc.
3 * and other copyright owners as documented in the project's IP log.
5 * This program and the accompanying materials are made available
6 * under the terms of the Eclipse Distribution License v1.0 which
7 * accompanies this distribution, is reproduced below, and is
8 * available at http://www.eclipse.org/org/documents/edl-v10.php
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
24 * - Neither the name of the Eclipse Foundation, Inc. nor the
25 * names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior
27 * written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 package org.eclipse.jgit.http.test;
46 import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT;
47 import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE;
48 import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA;
49 import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT;
51 import java.io.IOException;
52 import java.util.List;
53 import java.util.Map;
55 import javax.servlet.http.HttpServletRequest;
57 import org.eclipse.jetty.servlet.ServletContextHandler;
58 import org.eclipse.jetty.servlet.ServletHolder;
59 import org.eclipse.jgit.errors.NotSupportedException;
60 import org.eclipse.jgit.errors.RepositoryNotFoundException;
61 import org.eclipse.jgit.http.server.GitServlet;
62 import org.eclipse.jgit.http.server.resolver.RepositoryResolver;
63 import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException;
64 import org.eclipse.jgit.http.test.util.AccessEvent;
65 import org.eclipse.jgit.http.test.util.HttpTestCase;
66 import org.eclipse.jgit.junit.TestRepository;
67 import org.eclipse.jgit.lib.Constants;
68 import org.eclipse.jgit.lib.NullProgressMonitor;
69 import org.eclipse.jgit.lib.Ref;
70 import org.eclipse.jgit.lib.Repository;
71 import org.eclipse.jgit.revwalk.RevBlob;
72 import org.eclipse.jgit.revwalk.RevCommit;
73 import org.eclipse.jgit.transport.FetchConnection;
74 import org.eclipse.jgit.transport.HttpTransport;
75 import org.eclipse.jgit.transport.Transport;
76 import org.eclipse.jgit.transport.TransportHttp;
77 import org.eclipse.jgit.transport.URIish;
79 public class DumbClientSmartServerTest extends HttpTestCase {
80 private Repository remoteRepository;
82 private URIish remoteURI;
84 private RevBlob A_txt;
86 private RevCommit A, B;
88 protected void setUp() throws Exception {
89 super.setUp();
91 final TestRepository src = createTestRepository();
92 final String srcName = src.getRepository().getDirectory().getName();
94 ServletContextHandler app = server.addContext("/git");
95 GitServlet gs = new GitServlet();
96 gs.setRepositoryResolver(new RepositoryResolver() {
97 public Repository open(HttpServletRequest req, String name)
98 throws RepositoryNotFoundException,
99 ServiceNotEnabledException {
100 if (!name.equals(srcName))
101 throw new RepositoryNotFoundException(name);
103 final Repository db = src.getRepository();
104 db.incrementOpen();
105 return db;
108 app.addServlet(new ServletHolder(gs), "/*");
110 server.setUp();
112 remoteRepository = src.getRepository();
113 remoteURI = toURIish(app, srcName);
115 A_txt = src.blob("A");
116 A = src.commit().add("A_txt", A_txt).create();
117 B = src.commit().parent(A).add("A_txt", "C").add("B", "B").create();
118 src.update(master, B);
121 public void testListRemote() throws IOException {
122 Repository dst = createBareRepository();
124 assertEquals("http", remoteURI.getScheme());
126 Map<String, Ref> map;
127 Transport t = Transport.open(dst, remoteURI);
128 ((TransportHttp) t).setUseSmartHttp(false);
129 try {
130 // I didn't make up these public interface names, I just
131 // approved them for inclusion into the code base. Sorry.
132 // --spearce
134 assertTrue("isa TransportHttp", t instanceof TransportHttp);
135 assertTrue("isa HttpTransport", t instanceof HttpTransport);
137 FetchConnection c = t.openFetch();
138 try {
139 map = c.getRefsMap();
140 } finally {
141 c.close();
143 } finally {
144 t.close();
147 assertNotNull("have map of refs", map);
148 assertEquals(2, map.size());
150 assertNotNull("has " + master, map.get(master));
151 assertEquals(B, map.get(master).getObjectId());
153 assertNotNull("has " + Constants.HEAD, map.get(Constants.HEAD));
154 assertEquals(B, map.get(Constants.HEAD).getObjectId());
156 List<AccessEvent> requests = getRequests();
157 assertEquals(2, requests.size());
158 assertEquals(0, getRequests(remoteURI, "git-upload-pack").size());
160 AccessEvent info = requests.get(0);
161 assertEquals("GET", info.getMethod());
162 assertEquals(join(remoteURI, "info/refs"), info.getPath());
163 assertEquals(0, info.getParameters().size());
164 assertNull("no service parameter", info.getParameter("service"));
165 assertEquals("no-cache", info.getRequestHeader(HDR_PRAGMA));
166 assertNotNull("has user-agent", info.getRequestHeader(HDR_USER_AGENT));
167 assertTrue("is jgit agent", info.getRequestHeader(HDR_USER_AGENT)
168 .startsWith("JGit/"));
169 assertEquals("*/*", info.getRequestHeader(HDR_ACCEPT));
170 assertEquals(200, info.getStatus());
171 assertEquals("text/plain;charset=UTF-8", info
172 .getResponseHeader(HDR_CONTENT_TYPE));
174 AccessEvent head = requests.get(1);
175 assertEquals("GET", head.getMethod());
176 assertEquals(join(remoteURI, "HEAD"), head.getPath());
177 assertEquals(0, head.getParameters().size());
178 assertEquals(200, head.getStatus());
179 assertEquals("text/plain", head.getResponseHeader(HDR_CONTENT_TYPE));
182 public void testInitialClone_Small() throws Exception {
183 Repository dst = createBareRepository();
184 assertFalse(dst.hasObject(A_txt));
186 Transport t = Transport.open(dst, remoteURI);
187 ((TransportHttp) t).setUseSmartHttp(false);
188 try {
189 t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
190 } finally {
191 t.close();
194 assertTrue(dst.hasObject(A_txt));
195 assertEquals(B, dst.getRef(master).getObjectId());
196 fsck(dst, B);
198 List<AccessEvent> loose = getRequests(loose(remoteURI, A_txt));
199 assertEquals(1, loose.size());
200 assertEquals("GET", loose.get(0).getMethod());
201 assertEquals(0, loose.get(0).getParameters().size());
202 assertEquals(200, loose.get(0).getStatus());
203 assertEquals("application/x-git-loose-object", loose.get(0)
204 .getResponseHeader(HDR_CONTENT_TYPE));
207 public void testInitialClone_Packed() throws Exception {
208 new TestRepository(remoteRepository).packAndPrune();
210 Repository dst = createBareRepository();
211 assertFalse(dst.hasObject(A_txt));
213 Transport t = Transport.open(dst, remoteURI);
214 ((TransportHttp) t).setUseSmartHttp(false);
215 try {
216 t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
217 } finally {
218 t.close();
221 assertTrue(dst.hasObject(A_txt));
222 assertEquals(B, dst.getRef(master).getObjectId());
223 fsck(dst, B);
225 List<AccessEvent> req;
227 req = getRequests(loose(remoteURI, B));
228 assertEquals(1, req.size());
229 assertEquals("GET", req.get(0).getMethod());
230 assertEquals(0, req.get(0).getParameters().size());
231 assertEquals(404, req.get(0).getStatus());
233 req = getRequests(join(remoteURI, "objects/info/packs"));
234 assertEquals(1, req.size());
235 assertEquals("GET", req.get(0).getMethod());
236 assertEquals(0, req.get(0).getParameters().size());
237 assertEquals(200, req.get(0).getStatus());
238 assertEquals("text/plain;charset=UTF-8", req.get(0).getResponseHeader(
239 HDR_CONTENT_TYPE));
242 public void testPushNotSupported() throws Exception {
243 final TestRepository src = createTestRepository();
244 final RevCommit Q = src.commit().create();
245 final Repository db = src.getRepository();
247 Transport t = Transport.open(db, remoteURI);
248 ((TransportHttp) t).setUseSmartHttp(false);
249 try {
250 try {
251 t.push(NullProgressMonitor.INSTANCE, push(src, Q));
252 fail("push incorrectly completed against a smart server");
253 } catch (NotSupportedException nse) {
254 String exp = "smart HTTP push disabled";
255 assertEquals(exp, nse.getMessage());
257 } finally {
258 t.close();