View Javadoc
1   /*
2    * Copyright (C) 2018, Google LLC.
3    * and other copyright owners as documented in the project's IP log.
4    *
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
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
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.
23   *
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.
28   *
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.
42   */
43  package org.eclipse.jgit.transport;
44  
45  import static org.eclipse.jgit.transport.ObjectIdMatcher.hasOnlyObjectIds;
46  import static org.junit.Assert.assertEquals;
47  import static org.junit.Assert.assertThat;
48  import static org.junit.Assert.assertTrue;
49  
50  import java.io.ByteArrayInputStream;
51  import java.io.ByteArrayOutputStream;
52  import java.io.IOException;
53  
54  import org.eclipse.jgit.errors.PackProtocolException;
55  import org.eclipse.jgit.lib.Config;
56  import org.junit.Test;
57  
58  public class ProtocolV0ParserTest {
59  	/*
60  	 * Convert the input lines to the PacketLine that the parser reads.
61  	 */
62  	private static PacketLineIn formatAsPacketLine(String... inputLines)
63  			throws IOException {
64  		ByteArrayOutputStream send = new ByteArrayOutputStream();
65  		PacketLineOut pckOut = new PacketLineOut(send);
66  		for (String line : inputLines) {
67  			if (line == PacketLineIn.END) {
68  				pckOut.end();
69  			} else if (line == PacketLineIn.DELIM) {
70  				pckOut.writeDelim();
71  			} else {
72  				pckOut.writeString(line);
73  			}
74  		}
75  
76  		return new PacketLineIn(new ByteArrayInputStream(send.toByteArray()));
77  	}
78  
79  	private static TransferConfig defaultConfig() {
80  		Config rc = new Config();
81  		rc.setBoolean("uploadpack", null, "allowfilter", true);
82  		return new TransferConfig(rc);
83  	}
84  
85  	@Test
86  	public void testRecvWantsWithCapabilities()
87  			throws PackProtocolException, IOException {
88  		PacketLineIn pckIn = formatAsPacketLine(
89  				String.join(" ", "want",
90  						"4624442d68ee402a94364191085b77137618633e", "thin-pack",
91  						"no-progress", "include-tag", "ofs-delta", "\n"),
92  				"want f900c8326a43303685c46b279b9f70411bff1a4b\n",
93  				PacketLineIn.END);
94  		ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig());
95  		FetchV0Request request = parser.recvWants(pckIn);
96  		assertTrue(request.getClientCapabilities()
97  				.contains(GitProtocolConstants.OPTION_THIN_PACK));
98  		assertTrue(request.getClientCapabilities()
99  				.contains(GitProtocolConstants.OPTION_NO_PROGRESS));
100 		assertTrue(request.getClientCapabilities()
101 				.contains(GitProtocolConstants.OPTION_INCLUDE_TAG));
102 		assertTrue(request.getClientCapabilities()
103 				.contains(GitProtocolConstants.CAPABILITY_OFS_DELTA));
104 		assertThat(request.getWantIds(),
105 				hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
106 						"f900c8326a43303685c46b279b9f70411bff1a4b"));
107 	}
108 
109 	@Test
110 	public void testRecvWantsWithAgent()
111 			throws PackProtocolException, IOException {
112 		PacketLineIn pckIn = formatAsPacketLine(
113 				String.join(" ", "want",
114 						"4624442d68ee402a94364191085b77137618633e", "thin-pack",
115 						"agent=JGit.test/0.0.1", "\n"),
116 				"want f900c8326a43303685c46b279b9f70411bff1a4b\n",
117 				PacketLineIn.END);
118 		ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig());
119 		FetchV0Request request = parser.recvWants(pckIn);
120 		assertTrue(request.getClientCapabilities()
121 				.contains(GitProtocolConstants.OPTION_THIN_PACK));
122 		assertEquals(1, request.getClientCapabilities().size());
123 		assertEquals("JGit.test/0.0.1", request.getAgent());
124 		assertThat(request.getWantIds(),
125 				hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
126 						"f900c8326a43303685c46b279b9f70411bff1a4b"));
127 	}
128 
129 	/*
130 	 * First round of protocol v0 negotiation. Client send wants, no
131 	 * capabilities.
132 	 */
133 	@Test
134 	public void testRecvWantsWithoutCapabilities()
135 			throws PackProtocolException, IOException {
136 		PacketLineIn pckIn = formatAsPacketLine(
137 				"want 4624442d68ee402a94364191085b77137618633e\n",
138 				"want f900c8326a43303685c46b279b9f70411bff1a4b\n",
139 				PacketLineIn.END);
140 		ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig());
141 		FetchV0Request request = parser.recvWants(pckIn);
142 		assertTrue(request.getClientCapabilities().isEmpty());
143 		assertThat(request.getWantIds(),
144 				hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
145 						"f900c8326a43303685c46b279b9f70411bff1a4b"));
146 	}
147 
148 	@Test
149 	public void testRecvWantsDeepen()
150 			throws PackProtocolException, IOException {
151 		PacketLineIn pckIn = formatAsPacketLine(
152 				"want 4624442d68ee402a94364191085b77137618633e\n",
153 				"want f900c8326a43303685c46b279b9f70411bff1a4b\n", "deepen 3\n",
154 				PacketLineIn.END);
155 		ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig());
156 		FetchV0Request request = parser.recvWants(pckIn);
157 		assertTrue(request.getClientCapabilities().isEmpty());
158 		assertEquals(3, request.getDepth());
159 		assertThat(request.getWantIds(),
160 				hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
161 						"f900c8326a43303685c46b279b9f70411bff1a4b"));
162 	}
163 
164 	@Test
165 	public void testRecvWantsShallow()
166 			throws PackProtocolException, IOException {
167 		PacketLineIn pckIn = formatAsPacketLine(
168 				"want 4624442d68ee402a94364191085b77137618633e\n",
169 				"want f900c8326a43303685c46b279b9f70411bff1a4b\n",
170 				"shallow 4b643d0ef739a1b494e7d6926d8d8ed80d35edf4\n",
171 				PacketLineIn.END);
172 		ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig());
173 		FetchV0Request request = parser.recvWants(pckIn);
174 		assertTrue(request.getClientCapabilities().isEmpty());
175 		assertThat(request.getWantIds(),
176 				hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
177 						"f900c8326a43303685c46b279b9f70411bff1a4b"));
178 		assertThat(request.getClientShallowCommits(),
179 				hasOnlyObjectIds("4b643d0ef739a1b494e7d6926d8d8ed80d35edf4"));
180 	}
181 
182 	@Test
183 	public void testRecvWantsFilter()
184 			throws PackProtocolException, IOException {
185 		PacketLineIn pckIn = formatAsPacketLine(
186 				"want 4624442d68ee402a94364191085b77137618633e\n",
187 				"want f900c8326a43303685c46b279b9f70411bff1a4b\n",
188 				"filter blob:limit=13000\n",
189 				PacketLineIn.END);
190 		ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig());
191 		FetchV0Request request = parser.recvWants(pckIn);
192 		assertTrue(request.getClientCapabilities().isEmpty());
193 		assertThat(request.getWantIds(),
194 				hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
195 						"f900c8326a43303685c46b279b9f70411bff1a4b"));
196 		assertEquals(13000, request.getFilterBlobLimit());
197 	}
198 
199 }