xref: /JGit/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java (revision 5c5f7c6b146b24f2bd4afae1902df85ad6e57ea3)
1 /*
2  * Copyright (C) 2009-2017, Google Inc. and others
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Distribution License v. 1.0 which is available at
6  * https://www.eclipse.org/org/documents/edl-v10.php.
7  *
8  * SPDX-License-Identifier: BSD-3-Clause
9  */
10 
11 package org.eclipse.jgit.junit.http;
12 
13 import static org.junit.Assert.fail;
14 
15 import java.io.IOException;
16 import java.net.URI;
17 import java.net.URISyntaxException;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Set;
23 
24 import org.eclipse.jetty.servlet.ServletContextHandler;
25 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
26 import org.eclipse.jgit.junit.TestRepository;
27 import org.eclipse.jgit.lib.AnyObjectId;
28 import org.eclipse.jgit.lib.Constants;
29 import org.eclipse.jgit.lib.ObjectId;
30 import org.eclipse.jgit.lib.Repository;
31 import org.eclipse.jgit.revwalk.RevCommit;
32 import org.eclipse.jgit.revwalk.RevObject;
33 import org.eclipse.jgit.transport.RefSpec;
34 import org.eclipse.jgit.transport.RemoteRefUpdate;
35 import org.eclipse.jgit.transport.URIish;
36 
37 /**
38  * Base class for HTTP related transport testing.
39  */
40 public abstract class HttpTestCase extends LocalDiskRepositoryTestCase {
41 	/** Constant <code>master="Constants.R_HEADS + Constants.MASTER"</code> */
42 	protected static final String master = Constants.R_HEADS + Constants.MASTER;
43 
44 	/** In-memory application server; subclass must start. */
45 	protected AppServer server;
46 
47 	/** {@inheritDoc} */
48 	@Override
setUp()49 	public void setUp() throws Exception {
50 		super.setUp();
51 		server = createServer();
52 	}
53 
54 	/** {@inheritDoc} */
55 	@Override
tearDown()56 	public void tearDown() throws Exception {
57 		server.tearDown();
58 		super.tearDown();
59 	}
60 
61 	/**
62 	 * Create the {@link AppServer}.This default implementation creates a server
63 	 * without SSLsupport listening for HTTP connections on a dynamically chosen
64 	 * port, which can be gotten once the server has been started via its
65 	 * {@link org.eclipse.jgit.junit.http.AppServer#getPort()} method.
66 	 * Subclasses may override if they need a more specialized server.
67 	 *
68 	 * @return the {@link org.eclipse.jgit.junit.http.AppServer}.
69 	 * @since 4.9
70 	 */
createServer()71 	protected AppServer createServer() {
72 		return new AppServer();
73 	}
74 
75 	/**
76 	 * Create TestRepository
77 	 *
78 	 * @return the TestRepository
79 	 * @throws IOException
80 	 */
createTestRepository()81 	protected TestRepository<Repository> createTestRepository()
82 			throws IOException {
83 		return new TestRepository<>(createBareRepository());
84 	}
85 
86 	/**
87 	 * Convert path to URIish
88 	 *
89 	 * @param path
90 	 * @return the URIish
91 	 * @throws URISyntaxException
92 	 */
toURIish(String path)93 	protected URIish toURIish(String path) throws URISyntaxException {
94 		URI u = server.getURI().resolve(path);
95 		return new URIish(u.toString());
96 	}
97 
98 	/**
99 	 * Convert a path relative to the app's context path to a URIish
100 	 *
101 	 * @param app
102 	 * @param name
103 	 * @return the warnings (if any) from the last execution
104 	 * @throws URISyntaxException
105 	 */
toURIish(ServletContextHandler app, String name)106 	protected URIish toURIish(ServletContextHandler app, String name)
107 			throws URISyntaxException {
108 		String p = app.getContextPath();
109 		if (!p.endsWith("/") && !name.startsWith("/"))
110 			p += "/";
111 		p += name;
112 		return toURIish(p);
113 	}
114 
115 	/**
116 	 * Get requests.
117 	 *
118 	 * @return list of events
119 	 */
getRequests()120 	protected List<AccessEvent> getRequests() {
121 		return server.getRequests();
122 	}
123 
124 	/**
125 	 * Get requests.
126 	 *
127 	 * @param base
128 	 * @param path
129 	 *
130 	 * @return list of events
131 	 */
getRequests(URIish base, String path)132 	protected List<AccessEvent> getRequests(URIish base, String path) {
133 		return server.getRequests(base, path);
134 	}
135 
136 	/**
137 	 * Get requests.
138 	 *
139 	 * @param path
140 	 *
141 	 * @return list of events
142 	 */
getRequests(String path)143 	protected List<AccessEvent> getRequests(String path) {
144 		return server.getRequests(path);
145 	}
146 
147 	/**
148 	 * Run fsck
149 	 *
150 	 * @param db
151 	 * @param tips
152 	 * @throws Exception
153 	 */
fsck(Repository db, RevObject... tips)154 	protected static void fsck(Repository db, RevObject... tips)
155 			throws Exception {
156 		try (TestRepository<? extends Repository> tr =
157 				new TestRepository<>(db)) {
158 			tr.fsck(tips);
159 		}
160 	}
161 
162 	/**
163 	 * Mirror refs
164 	 *
165 	 * @param refs
166 	 * @return set of RefSpecs
167 	 */
mirror(String... refs)168 	protected static Set<RefSpec> mirror(String... refs) {
169 		HashSet<RefSpec> r = new HashSet<>();
170 		for (String name : refs) {
171 			RefSpec rs = new RefSpec(name);
172 			rs = rs.setDestination(name);
173 			rs = rs.setForceUpdate(true);
174 			r.add(rs);
175 		}
176 		return r;
177 	}
178 
179 	/**
180 	 * Push a commit
181 	 *
182 	 * @param from
183 	 * @param q
184 	 * @return collection of RefUpdates
185 	 * @throws IOException
186 	 */
push(TestRepository from, RevCommit q)187 	protected static Collection<RemoteRefUpdate> push(TestRepository from,
188 			RevCommit q) throws IOException {
189 		final Repository db = from.getRepository();
190 		final String srcExpr = q.name();
191 		final String dstName = master;
192 		final boolean forceUpdate = true;
193 		final String localName = null;
194 		final ObjectId oldId = null;
195 
196 		RemoteRefUpdate u = new RemoteRefUpdate(db, srcExpr, dstName,
197 				forceUpdate, localName, oldId);
198 		return Collections.singleton(u);
199 	}
200 
201 	/**
202 	 * Create loose object path
203 	 *
204 	 * @param base
205 	 * @param id
206 	 * @return path of the loose object
207 	 */
loose(URIish base, AnyObjectId id)208 	public static String loose(URIish base, AnyObjectId id) {
209 		final String objectName = id.name();
210 		final String d = objectName.substring(0, 2);
211 		final String f = objectName.substring(2);
212 		return join(base, "objects/" + d + "/" + f);
213 	}
214 
215 	/**
216 	 * Join a base URIish and a path
217 	 *
218 	 * @param base
219 	 * @param path
220 	 *            a relative path
221 	 * @return the joined path
222 	 */
join(URIish base, String path)223 	public static String join(URIish base, String path) {
224 		if (path.startsWith("/"))
225 			fail("Cannot join absolute path " + path + " to URIish " + base);
226 
227 		String dir = base.getPath();
228 		if (!dir.endsWith("/"))
229 			dir += "/";
230 		return dir + path;
231 	}
232 
233 	/**
234 	 * Rewrite a url
235 	 *
236 	 * @param url
237 	 * @param newProtocol
238 	 * @param newPort
239 	 * @return the rewritten url
240 	 */
rewriteUrl(String url, String newProtocol, int newPort)241 	protected static String rewriteUrl(String url, String newProtocol,
242 			int newPort) {
243 		String newUrl = url;
244 		if (newProtocol != null && !newProtocol.isEmpty()) {
245 			int schemeEnd = newUrl.indexOf("://");
246 			if (schemeEnd >= 0) {
247 				newUrl = newProtocol + newUrl.substring(schemeEnd);
248 			}
249 		}
250 		if (newPort > 0) {
251 			newUrl = newUrl.replaceFirst(":\\d+/", ":" + newPort + "/");
252 		} else {
253 			// Remove the port, if any
254 			newUrl = newUrl.replaceFirst(":\\d+/", "/");
255 		}
256 		return newUrl;
257 	}
258 
259 	/**
260 	 * Extend a path
261 	 *
262 	 * @param uri
263 	 * @param pathComponents
264 	 * @return the extended URIish
265 	 * @throws URISyntaxException
266 	 */
extendPath(URIish uri, String pathComponents)267 	protected static URIish extendPath(URIish uri, String pathComponents)
268 			throws URISyntaxException {
269 		String raw = uri.toString();
270 		String newComponents = pathComponents;
271 		if (!newComponents.startsWith("/")) {
272 			newComponents = '/' + newComponents;
273 		}
274 		if (!newComponents.endsWith("/")) {
275 			newComponents += '/';
276 		}
277 		int i = raw.lastIndexOf('/');
278 		raw = raw.substring(0, i) + newComponents + raw.substring(i + 1);
279 		return new URIish(raw);
280 	}
281 }
282