Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

PushConnectionTest.java 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Copyright (C) 2015, 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. package org.eclipse.jgit.transport;
  11. import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_REPORT_STATUS;
  12. import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;
  13. import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_OTHER_REASON;
  14. import static org.junit.Assert.assertEquals;
  15. import static org.junit.Assert.fail;
  16. import java.io.IOException;
  17. import java.io.StringWriter;
  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import org.eclipse.jgit.errors.TransportException;
  24. import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
  25. import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
  26. import org.eclipse.jgit.junit.TestRepository;
  27. import org.eclipse.jgit.lib.Constants;
  28. import org.eclipse.jgit.lib.NullProgressMonitor;
  29. import org.eclipse.jgit.lib.ObjectId;
  30. import org.eclipse.jgit.lib.ObjectInserter;
  31. import org.eclipse.jgit.lib.RefUpdate;
  32. import org.eclipse.jgit.lib.Repository;
  33. import org.junit.After;
  34. import org.junit.Before;
  35. import org.junit.Test;
  36. public class PushConnectionTest {
  37. private URIish uri;
  38. private TestProtocol<Object> testProtocol;
  39. private Object ctx = new Object();
  40. private InMemoryRepository server;
  41. private InMemoryRepository client;
  42. private List<String> processedRefs;
  43. private ObjectId obj1;
  44. private ObjectId obj2;
  45. private ObjectId obj3;
  46. private String refName = "refs/tags/blob";
  47. @Before
  48. public void setUp() throws Exception {
  49. server = newRepo("server");
  50. client = newRepo("client");
  51. processedRefs = new ArrayList<>();
  52. testProtocol = new TestProtocol<>(null, (Object req, Repository db) -> {
  53. ReceivePack rp = new ReceivePack(db);
  54. rp.setPreReceiveHook((ReceivePack receivePack,
  55. Collection<ReceiveCommand> cmds) -> {
  56. for (ReceiveCommand cmd : cmds) {
  57. processedRefs.add(cmd.getRefName());
  58. }
  59. });
  60. return rp;
  61. });
  62. uri = testProtocol.register(ctx, server);
  63. try (ObjectInserter ins = server.newObjectInserter()) {
  64. obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test"));
  65. obj3 = ins.insert(Constants.OBJ_BLOB, Constants.encode("not"));
  66. ins.flush();
  67. RefUpdate u = server.updateRef(refName);
  68. u.setNewObjectId(obj1);
  69. assertEquals(RefUpdate.Result.NEW, u.update());
  70. }
  71. try (ObjectInserter ins = client.newObjectInserter()) {
  72. obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file"));
  73. ins.flush();
  74. }
  75. }
  76. @After
  77. public void tearDown() {
  78. Transport.unregister(testProtocol);
  79. }
  80. private static InMemoryRepository newRepo(String name) {
  81. return new InMemoryRepository(new DfsRepositoryDescription(name));
  82. }
  83. @Test
  84. public void testWrongOldIdDoesNotReplace() throws IOException {
  85. RemoteRefUpdate rru = new RemoteRefUpdate(null, null, obj2, refName,
  86. false, null, obj3);
  87. Map<String, RemoteRefUpdate> updates = new HashMap<>();
  88. updates.put(rru.getRemoteName(), rru);
  89. try (Transport tn = testProtocol.open(uri, client, "server");
  90. PushConnection connection = tn.openPush()) {
  91. connection.push(NullProgressMonitor.INSTANCE, updates);
  92. }
  93. assertEquals(REJECTED_OTHER_REASON, rru.getStatus());
  94. assertEquals("invalid old id sent", rru.getMessage());
  95. }
  96. @Test
  97. public void invalidCommand() throws IOException {
  98. try (Transport tn = testProtocol.open(uri, client, "server");
  99. InternalPushConnection c = (InternalPushConnection) tn.openPush()) {
  100. StringWriter msgs = new StringWriter();
  101. PacketLineOut pckOut = c.pckOut;
  102. @SuppressWarnings("resource")
  103. SideBandInputStream in = new SideBandInputStream(c.in,
  104. NullProgressMonitor.INSTANCE, msgs, null);
  105. // Explicitly invalid command, but sane enough capabilities.
  106. StringBuilder buf = new StringBuilder();
  107. buf.append("42");
  108. buf.append(' ');
  109. buf.append(obj2.name());
  110. buf.append(' ');
  111. buf.append("refs/heads/A" + obj2.name());
  112. buf.append('\0').append(CAPABILITY_SIDE_BAND_64K);
  113. buf.append(' ').append(CAPABILITY_REPORT_STATUS);
  114. buf.append('\n');
  115. pckOut.writeString(buf.toString());
  116. pckOut.end();
  117. try {
  118. in.read();
  119. fail("expected TransportException");
  120. } catch (TransportException e) {
  121. assertEquals(
  122. "remote: error: invalid protocol: wanted 'old new ref'",
  123. e.getMessage());
  124. }
  125. }
  126. }
  127. @Test
  128. public void limitCommandBytes() throws IOException {
  129. Map<String, RemoteRefUpdate> updates = new HashMap<>();
  130. for (int i = 0; i < 4; i++) {
  131. RemoteRefUpdate rru = new RemoteRefUpdate(
  132. null, null, obj2, "refs/test/T" + i,
  133. false, null, ObjectId.zeroId());
  134. updates.put(rru.getRemoteName(), rru);
  135. }
  136. server.getConfig().setInt("receive", null, "maxCommandBytes", 195);
  137. try (Transport tn = testProtocol.open(uri, client, "server");
  138. PushConnection connection = tn.openPush()) {
  139. try {
  140. connection.push(NullProgressMonitor.INSTANCE, updates);
  141. fail("server did not abort");
  142. } catch (TransportException e) {
  143. String msg = e.getMessage();
  144. assertEquals("remote: Too many commands", msg);
  145. }
  146. }
  147. }
  148. @Test
  149. public void commandOrder() throws Exception {
  150. List<RemoteRefUpdate> updates = new ArrayList<>();
  151. try (TestRepository<?> tr = new TestRepository<>(client)) {
  152. // Arbitrary non-sorted order.
  153. for (int i = 9; i >= 0; i--) {
  154. String name = "refs/heads/b" + i;
  155. tr.branch(name).commit().create();
  156. RemoteRefUpdate rru = new RemoteRefUpdate(client, name, name,
  157. false, null, ObjectId.zeroId());
  158. updates.add(rru);
  159. }
  160. }
  161. PushResult result;
  162. try (Transport tn = testProtocol.open(uri, client, "server")) {
  163. result = tn.push(NullProgressMonitor.INSTANCE, updates);
  164. }
  165. for (RemoteRefUpdate remoteUpdate : result.getRemoteUpdates()) {
  166. assertEquals(
  167. "update should succeed on " + remoteUpdate.getRemoteName(),
  168. RemoteRefUpdate.Status.OK, remoteUpdate.getStatus());
  169. }
  170. List<String> expected = remoteRefNames(updates);
  171. assertEquals(
  172. "ref names processed by ReceivePack should match input ref names in order",
  173. expected, processedRefs);
  174. assertEquals(
  175. "remote ref names should match input ref names in order",
  176. expected, remoteRefNames(result.getRemoteUpdates()));
  177. }
  178. private static List<String> remoteRefNames(Collection<RemoteRefUpdate> updates) {
  179. List<String> result = new ArrayList<>();
  180. for (RemoteRefUpdate u : updates) {
  181. result.add(u.getRemoteName());
  182. }
  183. return result;
  184. }
  185. }