summaryrefslogtreecommitdiff
path: root/tests/libgit2/transport/register.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/libgit2/transport/register.c')
-rw-r--r--tests/libgit2/transport/register.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/tests/libgit2/transport/register.c b/tests/libgit2/transport/register.c
new file mode 100644
index 000000000..4d3c09726
--- /dev/null
+++ b/tests/libgit2/transport/register.c
@@ -0,0 +1,224 @@
+#include "clar_libgit2.h"
+#include "git2/sys/remote.h"
+#include "git2/sys/transport.h"
+
+static const char *proxy_url = "https://proxy";
+static git_transport _transport = GIT_TRANSPORT_INIT;
+
+static int dummy_transport(git_transport **transport, git_remote *owner, void *param)
+{
+ *transport = &_transport;
+ GIT_UNUSED(owner);
+ GIT_UNUSED(param);
+ return 0;
+}
+
+void test_transport_register__custom_transport(void)
+{
+ git_transport *transport;
+
+ cl_git_pass(git_transport_register("something", dummy_transport, NULL));
+
+ cl_git_pass(git_transport_new(&transport, NULL, "something://somepath"));
+
+ cl_assert(transport == &_transport);
+
+ cl_git_pass(git_transport_unregister("something"));
+}
+
+void test_transport_register__custom_transport_error_doubleregister(void)
+{
+ cl_git_pass(git_transport_register("something", dummy_transport, NULL));
+
+ cl_git_fail_with(git_transport_register("something", dummy_transport, NULL), GIT_EEXISTS);
+
+ cl_git_pass(git_transport_unregister("something"));
+}
+
+void test_transport_register__custom_transport_error_remove_non_existing(void)
+{
+ cl_git_fail_with(git_transport_unregister("something"), GIT_ENOTFOUND);
+}
+
+void test_transport_register__custom_transport_ssh(void)
+{
+ const char *urls[] = {
+ "ssh://somehost:somepath",
+ "ssh+git://somehost:somepath",
+ "git+ssh://somehost:somepath",
+ "git@somehost:somepath",
+ "ssh://somehost:somepath%20with%20%spaces",
+ "ssh://somehost:somepath with spaces"
+ };
+ git_transport *transport;
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(urls); i++) {
+#ifndef GIT_SSH
+ cl_git_fail_with(git_transport_new(&transport, NULL, urls[i]), -1);
+#else
+ cl_git_pass(git_transport_new(&transport, NULL, urls[i]));
+ transport->free(transport);
+#endif
+ }
+
+ cl_git_pass(git_transport_register("ssh", dummy_transport, NULL));
+
+ cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath"));
+
+ cl_assert(transport == &_transport);
+
+ cl_git_pass(git_transport_unregister("ssh"));
+
+ for (i = 0; i < ARRAY_SIZE(urls); i++) {
+#ifndef GIT_SSH
+ cl_git_fail_with(git_transport_new(&transport, NULL, urls[i]), -1);
+#else
+ cl_git_pass(git_transport_new(&transport, NULL, urls[i]));
+ transport->free(transport);
+#endif
+ }
+}
+
+static int custom_subtransport_stream__read(
+ git_smart_subtransport_stream *stream,
+ char *buffer,
+ size_t buf_size,
+ size_t *bytes_read)
+{
+ GIT_UNUSED(stream);
+ GIT_UNUSED(buffer);
+ GIT_UNUSED(buf_size);
+
+ *bytes_read = 0;
+
+ git_error_set_str(42, "unimplemented");
+ return GIT_EUSER;
+}
+
+static int custom_subtransport_stream__write(
+ git_smart_subtransport_stream *stream,
+ const char *buffer,
+ size_t len)
+{
+ GIT_UNUSED(stream);
+ GIT_UNUSED(buffer);
+ GIT_UNUSED(len);
+
+ git_error_set_str(42, "unimplemented");
+ return GIT_EUSER;
+}
+
+static void custom_subtransport_stream__free(
+ git_smart_subtransport_stream *stream)
+{
+ git__free(stream);
+}
+
+struct custom_subtransport {
+ git_smart_subtransport subtransport;
+ git_transport *owner;
+ int *called;
+};
+
+static int custom_subtransport__action(
+ git_smart_subtransport_stream **out,
+ git_smart_subtransport *transport,
+ const char *url,
+ git_smart_service_t action)
+{
+ struct custom_subtransport *t = (struct custom_subtransport *)transport;
+ git_remote_connect_options opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
+ int ret;
+
+ GIT_UNUSED(url);
+ GIT_UNUSED(action);
+
+ ret = git_transport_remote_connect_options(&opts, t->owner);
+
+ /* increase the counter once if this function was called at all and once more if the URL matches. */
+ (*t->called)++;
+ if (strcmp(proxy_url, opts.proxy_opts.url) == 0)
+ (*t->called)++;
+
+ git_remote_connect_options_dispose(&opts);
+
+ *out = git__calloc(1, sizeof(git_smart_subtransport_stream));
+ (*out)->subtransport = transport;
+ (*out)->read = custom_subtransport_stream__read;
+ (*out)->write = custom_subtransport_stream__write;
+ (*out)->free = custom_subtransport_stream__free;
+
+ return ret;
+}
+
+static int custom_subtransport__close(git_smart_subtransport *transport)
+{
+ GIT_UNUSED(transport);
+
+ return 0;
+}
+
+static void custom_subtransport__free(git_smart_subtransport *transport)
+{
+ GIT_UNUSED(transport);
+
+ git__free(transport);
+}
+
+static int custom_transport_callback(git_smart_subtransport **out, git_transport *owner, void *param)
+{
+ struct custom_subtransport *subtransport = git__calloc(1, sizeof(struct custom_subtransport));
+ subtransport->called = (int *)param;
+ subtransport->owner = owner;
+ subtransport->subtransport.action = custom_subtransport__action;
+ subtransport->subtransport.close = custom_subtransport__close;
+ subtransport->subtransport.free = custom_subtransport__free;
+
+ *out = &subtransport->subtransport;
+
+ return 0;
+}
+
+
+static int custom_transport(git_transport **out, git_remote *owner, void *param)
+{
+ struct git_smart_subtransport_definition definition;
+ definition.callback = custom_transport_callback;
+ definition.rpc = false;
+ definition.param = param;
+ return git_transport_smart(out, owner, &definition);
+}
+
+void test_transport_register__custom_transport_callbacks(void)
+{
+ git_transport *transport;
+ int called = 0;
+ const char *url = "custom://somepath";
+ git_remote_connect_options opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
+ git_repository *repo;
+ git_remote *remote;
+
+ cl_git_pass(git_repository_init(&repo, "./transport", 0));
+ cl_git_pass(git_remote_create(&remote, repo, "test",
+ cl_fixture("testrepo.git")));
+
+ cl_git_pass(git_transport_register("custom", custom_transport, &called));
+
+ cl_git_pass(git_transport_new(&transport, remote, url));
+
+ opts.follow_redirects = GIT_REMOTE_REDIRECT_NONE;
+ opts.proxy_opts.url = proxy_url;
+
+ /* This is expected to fail, since the subtransport_stream is not implemented */
+ transport->connect(transport, url, GIT_SERVICE_UPLOADPACK_LS, &opts);
+ /* the counter is increased twice if everything goes as planned */
+ cl_assert_equal_i(2, called);
+ cl_git_pass(transport->close(transport));
+ transport->free(transport);
+
+ cl_git_pass(git_transport_unregister("custom"));
+ git_remote_free(remote);
+ git_repository_free(repo);
+ cl_fixture_cleanup("testrepo.git");
+}