Skip to content

Commit 4bf7d7c

Browse files
jeffhostetlerdscho
authored andcommitted
test-gvfs-prococol, t5799: tests for gvfs-helper
Create t/helper/test-gvfs-protocol.c and t/t5799-gvfs-helper.sh to test gvfs-helper. Create t/helper/test-gvfs-protocol.c as a stand-alone web server that speaks the GVFS Protocol [1] and serves loose objects and packfiles to clients. It is borrows heavily from the code in daemon.c. It includes a "mayhem" mode to cause various network and HTTP errors to test the retry/recovery ability of gvfs-helper. Create t/t5799-gvfs-helper.sh to test gvfs-helper. [1] https://github.com/microsoft/VFSForGit/blob/master/Protocol.md Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 093a100 commit 4bf7d7c

File tree

8 files changed

+2838
-7
lines changed

8 files changed

+2838
-7
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,7 @@ endif
17721772
BASIC_CFLAGS += $(CURL_CFLAGS)
17731773

17741774
PROGRAM_OBJS += gvfs-helper.o
1775+
TEST_PROGRAMS_NEED_X += test-gvfs-protocol
17751776

17761777
REMOTE_CURL_PRIMARY = git-remote-http$X
17771778
REMOTE_CURL_ALIASES = git-remote-https$X git-remote-ftp$X git-remote-ftps$X

bin-wrappers/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
/git-upload-pack
77
/scalar
88
/test-fake-ssh
9+
/test-gvfs-protocol
910
/test-tool

contrib/buildsystems/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,20 @@ set(wrapper_scripts
11131113
set(wrapper_test_scripts
11141114
test-fake-ssh test-tool)
11151115

1116+
if(CURL_FOUND)
1117+
list(APPEND wrapper_test_scripts test-gvfs-protocol)
1118+
1119+
add_executable(test-gvfs-protocol ${CMAKE_SOURCE_DIR}/t/helper/test-gvfs-protocol.c)
1120+
target_link_libraries(test-gvfs-protocol common-main)
1121+
1122+
if(MSVC)
1123+
set_target_properties(test-gvfs-protocol
1124+
PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/helper)
1125+
set_target_properties(test-gvfs-protocol
1126+
PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/helper)
1127+
endif()
1128+
endif()
1129+
11161130

11171131
foreach(script ${wrapper_scripts})
11181132
file(STRINGS ${CMAKE_SOURCE_DIR}/bin-wrappers/wrap-for-bin.sh content NEWLINE_CONSUME)

gvfs-helper.c

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@
186186
#include "abspath.h"
187187
#include "progress.h"
188188
#include "trace2.h"
189+
#include "versioncmp.h"
189190

190191
static const char * const main_usage[] = {
191192
N_("git gvfs-helper [<main_options>] config [<options>]"),
@@ -210,6 +211,11 @@ static const char *const server_usage[] = {
210211
NULL
211212
};
212213

214+
static const char *const curl_version_usage[] = {
215+
N_("git gvfs-helper [<main_options>] curl-version [<operator> <version>]"),
216+
NULL
217+
};
218+
213219
/*
214220
* "commitDepth" field in gvfs protocol
215221
*/
@@ -1887,6 +1893,8 @@ static void install_loose(struct gh__request_params *params,
18871893
/*
18881894
* We expect a loose object when we do a GET -or- when we
18891895
* do a POST with only 1 object.
1896+
*
1897+
* Note that this content type is singular, not plural.
18901898
*/
18911899
if (strcmp(status->content_type.buf,
18921900
"application/x-git-loose-object")) {
@@ -2121,14 +2129,17 @@ static void do_throttle_spin(struct gh__request_params *params,
21212129
strbuf_addstr(&region, gh__server_type_label[params->server_type]);
21222130
trace2_region_enter("gvfs-helper", region.buf, NULL);
21232131

2124-
progress = start_progress(the_repository, progress_msg, duration);
2132+
if (gh__cmd_opts.show_progress)
2133+
progress = start_progress(the_repository, progress_msg, duration);
2134+
21252135
while (now < end) {
21262136
display_progress(progress, (now - begin));
21272137

21282138
sleep_millisec(100);
21292139

21302140
now = time(NULL);
21312141
}
2142+
21322143
display_progress(progress, duration);
21332144
stop_progress(&progress);
21342145

@@ -2701,13 +2712,15 @@ static void do__http_post__gvfs_objects(struct gh__response_status *status,
27012712
params.headers = curl_slist_append(params.headers,
27022713
"Content-Type: application/json");
27032714
/*
2704-
* We really always want a packfile. But if the payload only
2705-
* requests 1 OID, the server will send us a single loose
2706-
* objects instead. (Apparently the server ignores us when we
2707-
* only send application/x-git-packfile and does it anyway.)
2715+
* If our POST contains more than one object, we want the
2716+
* server to send us a packfile. We DO NOT want the non-standard
2717+
* concatenated loose object format, so we DO NOT send:
2718+
* "Accept: application/x-git-loose-objects" (plural)
27082719
*
2709-
* So to make it clear to my future self, go ahead and add
2710-
* an accept header for loose objects and own it.
2720+
* However, if the payload only requests 1 OID, the server
2721+
* will send us a single loose object instead of a packfile,
2722+
* so we ACK that and send:
2723+
* "Accept: application/x-git-loose-object" (singular)
27112724
*/
27122725
params.headers = curl_slist_append(params.headers,
27132726
"Accept: application/x-git-packfile");
@@ -3311,6 +3324,37 @@ static enum gh__error_code do_sub_cmd__server(int argc, const char **argv)
33113324
return ec;
33123325
}
33133326

3327+
static enum gh__error_code do_sub_cmd__curl_version(int argc, const char **argv)
3328+
{
3329+
static struct option curl_version_options[] = {
3330+
OPT_END(),
3331+
};
3332+
const char *current_version = curl_version_info(CURLVERSION_NOW)->version;
3333+
3334+
trace2_cmd_mode("curl-version");
3335+
3336+
if (argc > 1 && !strcmp(argv[1], "-h"))
3337+
usage_with_options(curl_version_usage, curl_version_options);
3338+
3339+
argc = parse_options(argc, argv, NULL,
3340+
curl_version_options, curl_version_usage, 0);
3341+
3342+
if (argc == 0)
3343+
printf("%s\n", current_version);
3344+
else if (argc != 2)
3345+
die("expected [<operator> <version>], but got %d parameters", argc);
3346+
else {
3347+
int cmp = versioncmp(current_version, argv[1]);
3348+
3349+
return (strchr(argv[0], '=') && !cmp) ||
3350+
(strchr(argv[0], '>') && cmp > 0) ||
3351+
(strchr(argv[0], '<') && cmp < 0) ?
3352+
GH__ERROR_CODE__OK : GH__ERROR_CODE__ERROR;
3353+
}
3354+
3355+
return GH__ERROR_CODE__OK;
3356+
}
3357+
33143358
static enum gh__error_code do_sub_cmd(int argc, const char **argv)
33153359
{
33163360
if (!strcmp(argv[0], "get"))
@@ -3325,6 +3369,9 @@ static enum gh__error_code do_sub_cmd(int argc, const char **argv)
33253369
if (!strcmp(argv[0], "server"))
33263370
return do_sub_cmd__server(argc, argv);
33273371

3372+
if (!strcmp(argv[0], "curl-version"))
3373+
return do_sub_cmd__curl_version(argc, argv);
3374+
33283375
// TODO have "test" mode that could be used to drive
33293376
// TODO unit testing.
33303377

t/helper/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ test_tool = executable('test-tool',
8888
bin_wrappers += test_tool
8989
test_dependencies += test_tool
9090

91+
test_gvfs_protocol = executable('test-gvfs-protocol',
92+
sources: 'test-gvfs-protocol.c',
93+
dependencies: [libgit_commonmain],
94+
)
95+
bin_wrappers += test_gvfs_protocol
96+
test_dependencies += test_gvfs_protocol
97+
9198
test_fake_ssh = executable('test-fake-ssh',
9299
sources: 'test-fake-ssh.c',
93100
dependencies: [libgit_commonmain],

0 commit comments

Comments
 (0)