View Javadoc
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
49  	public void setUp() throws Exception {
50  		super.setUp();
51  		server = createServer();
52  	}
53  
54  	/** {@inheritDoc} */
55  	@Override
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  	 */
71  	protected AppServer createServer() {
72  		return new AppServer();
73  	}
74  
75  	/**
76  	 * Create TestRepository
77  	 *
78  	 * @return the TestRepository
79  	 * @throws IOException
80  	 */
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  	 */
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 	 */
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 	 */
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 	 */
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 	 */
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 	 */
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 	 */
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 	 */
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 	 */
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 	 */
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 	 */
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 	 */
267 	protected static URIish./../../../../org/eclipse/jgit/transport/URIish.html#URIish">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 }