#970 added ngrep dumps for mercurial wire protocol and more realistic tests for isWriteRequest

This commit is contained in:
Sebastian Sdorra
2018-03-29 10:21:34 +02:00
parent d066e59c0d
commit e7dd54c133
7 changed files with 872 additions and 5 deletions

View File

@@ -39,6 +39,9 @@ import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.mockito.Mockito.*;
import static sonia.scm.web.WireProtocolRequestMockFactory.CMDS_HEADS_KNOWN_NODES;
import static sonia.scm.web.WireProtocolRequestMockFactory.Namespace.*;
import org.mockito.runners.MockitoJUnitRunner;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.repository.RepositoryProvider;
@@ -51,15 +54,14 @@ import sonia.scm.repository.RepositoryProvider;
@RunWith(MockitoJUnitRunner.class)
public class HgPermissionFilterTest {
@Mock
private HttpServletRequest request;
@Mock
private ScmConfiguration configuration;
@Mock
private RepositoryProvider repositoryProvider;
private WireProtocolRequestMockFactory wireProtocol = new WireProtocolRequestMockFactory("/scm/hg/repo");
@InjectMocks
private HgPermissionFilter filter;
@@ -82,7 +84,90 @@ public class HgPermissionFilterTest {
}
private boolean isWriteRequest(String method) {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getMethod()).thenReturn(method);
return filter.isWriteRequest(request);
}
}
/**
* Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a
* fresh clone of a repository.
*/
@Test
public void testIsWriteRequestWithClone() {
assertIsReadRequest(wireProtocol.capabilities());
assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS));
assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
}
/**
* Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a
* push of a single changeset.
*/
@Test
public void testIsWriteRequestWithSingleChangesetPush() {
assertIsReadRequest(wireProtocol.capabilities());
assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("c0ceccb3b2f0f5c977ff32b9337519e5f37942c2")));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS));
assertIsWriteRequest(wireProtocol.unbundle(261L, "686173686564+6768033e216468247bd031a0a2d9876d79818f8f"));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsWriteRequest(wireProtocol.pushkey("c0ceccb3b2f0f5c977ff32b9337519e5f37942c2&namespace=phases&new=0&old=1"));
}
/**
* Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a
* push to a single changeset.
*/
@Test
public void testIsWriteRequestWithMultipleChangesetsPush() {
assertIsReadRequest(wireProtocol.capabilities());
assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("ef5993bb4abb32a0565c347844c6d939fc4f4b98")));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS));
assertIsReadRequest(wireProtocol.branchmap());
assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS));
assertIsWriteRequest(wireProtocol.unbundle(746L, "686173686564+95373ca7cd5371cb6c49bb755ee451d9ec585845"));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsWriteRequest(wireProtocol.pushkey("ef5993bb4abb32a0565c347844c6d939fc4f4b98&namespace=phases&new=0&old=1"));
}
/**
* Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a
* push of multiple branches to a new repository.
*/
@Test
public void testIsWriteRequestWithMutlipleBranchesToNewRepositoryPush() {
assertIsReadRequest(wireProtocol.capabilities());
assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("ef5993bb4abb32a0565c347844c6d939fc4f4b98")));
assertIsReadRequest(wireProtocol.known("c0ceccb3b2f0f5c977ff32b9337519e5f37942c2+187ddf37e237c370514487a0bb1a226f11a780b3+b5914611f84eae14543684b2721eec88b0edac12+8b63a323606f10c86b30465570c2574eb7a3a989"));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS));
assertIsWriteRequest(wireProtocol.unbundle(913L, "686173686564+6768033e216468247bd031a0a2d9876d79818f8f"));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsWriteRequest(wireProtocol.pushkey("ef5993bb4abb32a0565c347844c6d939fc4f4b98&namespace=phases&new=0&old=1"));
}
/**
* Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a
* push of a bookmark.
*/
@Test
public void testIsWriteRequestWithBookmarkPush() {
assertIsReadRequest(wireProtocol.capabilities());
assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("ef5993bb4abb32a0565c347844c6d939fc4f4b98")));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS));
assertIsReadRequest(wireProtocol.listkeys(PHASES));
assertIsWriteRequest(wireProtocol.pushkey("markone&namespace=bookmarks&new=ef5993bb4abb32a0565c347844c6d939fc4f4b98&old="));
}
private void assertIsReadRequest(HttpServletRequest request) {
assertFalse(filter.isWriteRequest(request));
}
private void assertIsWriteRequest(HttpServletRequest request) {
assertTrue(filter.isWriteRequest(request));
}
}

View File

@@ -0,0 +1,101 @@
package sonia.scm.web;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import static org.mockito.Mockito.*;
public class WireProtocolRequestMockFactory {
public enum Namespace {
PHASES, BOOKMARKS;
}
public static final String CMDS_HEADS_KNOWN_NODES = "heads+%3Bknown+nodes%3D";
private String repositoryPath;
public WireProtocolRequestMockFactory(String repositoryPath) {
this.repositoryPath = repositoryPath;
}
public HttpServletRequest capabilities() {
return base("GET", "?cmd=capabilities");
}
public HttpServletRequest listkeys(Namespace namespace) {
HttpServletRequest request = base("GET", "?cmd=capabilities");
header(request, "vary", "X-HgArg-1");
header(request, "x-hgarg-1", namespaceValue(namespace));
return request;
}
public HttpServletRequest branchmap() {
return base("GET", "?cmd=branchmap");
}
public HttpServletRequest batch(String... args) {
HttpServletRequest request = base("GET", "?cmd=batch");
args(request, "cmds", args);
return request;
}
public HttpServletRequest unbundle(long contentLength, String... heads) {
HttpServletRequest request = base("POST", "?cmd=unbundle");
header(request, "Content-Length", String.valueOf(contentLength));
args(request, "heads", heads);
return request;
}
public HttpServletRequest pushkey(String... keys) {
HttpServletRequest request = base("POST", "?cmd=pushkey");
args(request, "key", keys);
return request;
}
public HttpServletRequest known(String... nodes) {
HttpServletRequest request = base("POST", "?cmd=pushkey");
args(request, "nodes", nodes);
return request;
}
private void args(HttpServletRequest request, String prefix, String[] values) {
StringBuilder vary = new StringBuilder();
for ( int i=0; i<values.length; i++ ) {
if (i>0) {
vary.append(",");
}
vary.append("X-HgArg-" + (i+1));
header(request, "X-HgArg-" + (i+1), prefix + "=" + values[i]);
}
header(request, "Vary", vary.toString());
}
private HttpServletRequest base(String method, String queryStringValue) {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getRequestURI()).thenReturn(repositoryPath);
when(request.getMethod()).thenReturn(method);
queryString(request, queryStringValue);
header(request, "Accept", "application/mercurial-0.1");
header(request, "Accept-Encoding", "identity");
header(request, "User-Agent", "mercurial/proto-1.0 (Mercurial 4.3.1)");
return request;
}
private void queryString(HttpServletRequest request, String queryString) {
when(request.getQueryString()).thenReturn(queryString);
}
private void header(HttpServletRequest request, String header, String value) {
when(request.getHeader(header)).thenReturn(value);
}
private String namespaceValue(Namespace namespace) {
return "namespace=" + namespace.toString().toLowerCase(Locale.ENGLISH);
}
}