Skip to content

Commit 7697e54

Browse files
committed
Test cancel from indexer progress callback
This adds tests that try canceling an indexer operation from within the progress callback. After writing the tests, I wanted to run this under valgrind and had a number of errors in that situation because mmap wasn't working. I added a CMake option to force emulation of mmap and consolidated the Amiga-specific code into that new place (so we don't actually need separate Amiga code now, just have to turn on -DNO_MMAP). Additionally, I made the indexer code propagate error codes more reliably than it used to.
1 parent 8b22d86 commit 7697e54

File tree

10 files changed

+95
-88
lines changed

10 files changed

+95
-88
lines changed

CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ OPTION( ANDROID "Build for android NDK" OFF )
3333

3434
OPTION( USE_ICONV "Link with and use iconv library" OFF )
3535
OPTION( USE_SSH "Link with libssh to enable SSH support" ON )
36+
OPTION( VALGRIND "Configure build for valgrind" OFF )
3637

3738
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
3839
SET( USE_ICONV ON )
@@ -340,9 +341,11 @@ IF (WIN32 AND NOT CYGWIN)
340341
ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0501)
341342
FILE(GLOB SRC_OS src/win32/*.c src/win32/*.h)
342343
ELSEIF (AMIGA)
343-
ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R)
344-
FILE(GLOB SRC_OS src/amiga/*.c src/amiga/*.h)
344+
ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R -DNO_MMAP)
345345
ELSE()
346+
IF (VALGRIND)
347+
ADD_DEFINITIONS(-DNO_MMAP)
348+
ENDIF()
346349
FILE(GLOB SRC_OS src/unix/*.c src/unix/*.h)
347350
ENDIF()
348351
FILE(GLOB SRC_GIT2 src/*.c src/*.h src/transports/*.c src/transports/*.h src/xdiff/*.c src/xdiff/*.h)

include/git2/pack.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ typedef enum {
5252
GIT_PACKBUILDER_ADDING_OBJECTS = 0,
5353
GIT_PACKBUILDER_DELTAFICATION = 1,
5454
} git_packbuilder_stage_t;
55-
55+
5656
/**
5757
* Initialize a new packbuilder
5858
*
@@ -143,6 +143,7 @@ GIT_EXTERN(int) git_packbuilder_write(
143143
GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb);
144144

145145
typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload);
146+
146147
/**
147148
* Create the new pack and pass each object to the callback
148149
*

src/amiga/map.c

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/indexer.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -441,21 +441,21 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
441441

442442
processed = stats->indexed_objects;
443443

444-
if (git_filebuf_write(&idx->pack_file, data, size) < 0)
445-
return -1;
444+
if ((error = git_filebuf_write(&idx->pack_file, data, size)) < 0)
445+
return error;
446446

447447
hash_partially(idx, data, (int)size);
448448

449449
/* Make sure we set the new size of the pack */
450450
if (idx->opened_pack) {
451451
idx->pack->mwf.size += size;
452452
} else {
453-
if (open_pack(&idx->pack, idx->pack_file.path_lock) < 0)
454-
return -1;
453+
if ((error = open_pack(&idx->pack, idx->pack_file.path_lock)) < 0)
454+
return error;
455455
idx->opened_pack = 1;
456456
mwf = &idx->pack->mwf;
457-
if (git_mwindow_file_register(&idx->pack->mwf) < 0)
458-
return -1;
457+
if ((error = git_mwindow_file_register(&idx->pack->mwf)) < 0)
458+
return error;
459459
}
460460

461461
if (!idx->parsed_header) {
@@ -464,8 +464,8 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
464464
if ((unsigned)idx->pack->mwf.size < sizeof(struct git_pack_header))
465465
return 0;
466466

467-
if (parse_header(&idx->hdr, idx->pack) < 0)
468-
return -1;
467+
if ((error = parse_header(&idx->hdr, idx->pack)) < 0)
468+
return error;
469469

470470
idx->parsed_header = 1;
471471
idx->nr_objects = ntohl(hdr->hdr_entries);
@@ -503,6 +503,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
503503

504504
/* As the file grows any windows we try to use will be out of date */
505505
git_mwindow_free_all(mwf);
506+
506507
while (processed < idx->nr_objects) {
507508
git_packfile_stream *stream = &idx->stream;
508509
git_off_t entry_start = idx->off;
@@ -520,7 +521,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
520521
return 0;
521522
}
522523
if (error < 0)
523-
return error;
524+
goto on_error;
524525

525526
git_mwindow_close(&w);
526527
idx->entry_start = entry_start;
@@ -533,7 +534,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
533534
return 0;
534535
}
535536
if (error < 0)
536-
return error;
537+
goto on_error;
537538

538539
idx->have_delta = 1;
539540
} else {
@@ -542,9 +543,10 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
542543
}
543544

544545
idx->have_stream = 1;
545-
if (git_packfile_stream_open(stream, idx->pack, idx->off) < 0)
546-
goto on_error;
547546

547+
error = git_packfile_stream_open(stream, idx->pack, idx->off);
548+
if (error < 0)
549+
goto on_error;
548550
}
549551

550552
if (idx->have_delta) {
@@ -858,7 +860,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
858860

859861
/* Test for this before resolve_deltas(), as it plays with idx->off */
860862
if (idx->off < idx->pack->mwf.size - 20) {
861-
giterr_set(GITERR_INDEXER, "unexpected data at the end of the pack");
863+
giterr_set(GITERR_INDEXER, "Unexpected data at the end of the pack");
862864
return -1;
863865
}
864866

src/posix.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,40 @@ int p_write(git_file fd, const void *buf, size_t cnt)
203203
return 0;
204204
}
205205

206+
#ifdef NO_MMAP
206207

208+
#include "map.h"
209+
210+
int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
211+
{
212+
GIT_MMAP_VALIDATE(out, len, prot, flags);
213+
214+
out->data = NULL;
215+
out->len = 0;
216+
217+
if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) {
218+
giterr_set(GITERR_OS, "Trying to map shared-writeable");
219+
return -1;
220+
}
221+
222+
out->data = malloc(len);
223+
GITERR_CHECK_ALLOC(out->data);
224+
225+
if ((p_lseek(fd, offset, SEEK_SET) < 0) || ((size_t)p_read(fd, out->data, len) != len)) {
226+
giterr_set(GITERR_OS, "mmap emulation failed");
227+
return -1;
228+
}
229+
230+
out->len = len;
231+
return 0;
232+
}
233+
234+
int p_munmap(git_map *map)
235+
{
236+
assert(map != NULL);
237+
free(map->data);
238+
239+
return 0;
240+
}
241+
242+
#endif

src/unix/map.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
#include <git2/common.h>
88

9-
#ifndef GIT_WIN32
9+
#if !defined(GIT_WIN32) && !defined(NO_MMAP)
1010

1111
#include "map.h"
1212
#include <sys/mman.h>

src/win32/map.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "map.h"
99
#include <errno.h>
1010

11+
#ifndef NO_MMAP
1112

1213
static DWORD get_page_size(void)
1314
{
@@ -112,4 +113,4 @@ int p_munmap(git_map *map)
112113
return error;
113114
}
114115

115-
116+
#endif

tests/pack/indexer.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* This is a packfile with three objects. The second is a delta which
1212
* depends on the third, which is also a delta.
1313
*/
14-
unsigned char out_of_order_pack[] = {
14+
static const unsigned char out_of_order_pack[] = {
1515
0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
1616
0x32, 0x78, 0x9c, 0x63, 0x67, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x76,
1717
0xe6, 0x8f, 0xe8, 0x12, 0x9b, 0x54, 0x6b, 0x10, 0x1a, 0xee, 0x95, 0x10,
@@ -23,13 +23,13 @@ unsigned char out_of_order_pack[] = {
2323
0x19, 0x87, 0x58, 0x80, 0x61, 0x09, 0x9a, 0x33, 0xca, 0x7a, 0x31, 0x92,
2424
0x6f, 0xae, 0x66, 0x75
2525
};
26-
unsigned int out_of_order_pack_len = 112;
26+
static const unsigned int out_of_order_pack_len = 112;
2727

2828
/*
2929
* Packfile with two objects. The second is a delta against an object
3030
* which is not in the packfile
3131
*/
32-
unsigned char thin_pack[] = {
32+
static const unsigned char thin_pack[] = {
3333
0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
3434
0x32, 0x78, 0x9c, 0x63, 0x67, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x76,
3535
0xe6, 0x8f, 0xe8, 0x12, 0x9b, 0x54, 0x6b, 0x10, 0x1a, 0xee, 0x95, 0x10,
@@ -38,18 +38,19 @@ unsigned char thin_pack[] = {
3838
0x3a, 0x6f, 0x39, 0xd1, 0xfe, 0x66, 0x68, 0x6b, 0xa5, 0xe5, 0xe2, 0x97,
3939
0xac, 0x94, 0x6c, 0x76, 0x0b, 0x04
4040
};
41-
unsigned int thin_pack_len = 78;
41+
static const unsigned int thin_pack_len = 78;
4242

43-
unsigned char base_obj[] = { 07, 076 };
44-
unsigned int base_obj_len = 2;
43+
static const unsigned char base_obj[] = { 07, 076 };
44+
static const unsigned int base_obj_len = 2;
4545

4646
void test_pack_indexer__out_of_order(void)
4747
{
48-
git_indexer *idx;
49-
git_transfer_progress stats;
48+
git_indexer *idx = 0;
49+
git_transfer_progress stats = { 0 };
5050

5151
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
52-
cl_git_pass(git_indexer_append(idx, out_of_order_pack, out_of_order_pack_len, &stats));
52+
cl_git_pass(git_indexer_append(
53+
idx, out_of_order_pack, out_of_order_pack_len, &stats));
5354
cl_git_pass(git_indexer_commit(idx, &stats));
5455

5556
cl_assert_equal_i(stats.total_objects, 3);
@@ -61,8 +62,8 @@ void test_pack_indexer__out_of_order(void)
6162

6263
void test_pack_indexer__fix_thin(void)
6364
{
64-
git_indexer *idx;
65-
git_transfer_progress stats;
65+
git_indexer *idx = NULL;
66+
git_transfer_progress stats = { 0 };
6667
git_repository *repo;
6768
git_odb *odb;
6869
git_oid id, should_id;

tests/pack/packbuilder.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ static git_packbuilder *_packbuilder;
1212
static git_indexer *_indexer;
1313
static git_vector _commits;
1414
static int _commits_is_initialized;
15+
static git_transfer_progress _stats;
1516

1617
void test_pack_packbuilder__initialize(void)
1718
{
@@ -20,6 +21,7 @@ void test_pack_packbuilder__initialize(void)
2021
cl_git_pass(git_packbuilder_new(&_packbuilder, _repo));
2122
cl_git_pass(git_vector_init(&_commits, 0, NULL));
2223
_commits_is_initialized = 1;
24+
memset(&_stats, 0, sizeof(_stats));
2325
}
2426

2527
void test_pack_packbuilder__cleanup(void)
@@ -184,11 +186,10 @@ void test_pack_packbuilder__permissions_readwrite(void)
184186
test_write_pack_permission(0666, 0666);
185187
}
186188

187-
static git_transfer_progress stats;
188189
static int foreach_cb(void *buf, size_t len, void *payload)
189190
{
190191
git_indexer *idx = (git_indexer *) payload;
191-
cl_git_pass(git_indexer_append(idx, buf, len, &stats));
192+
cl_git_pass(git_indexer_append(idx, buf, len, &_stats));
192193
return 0;
193194
}
194195

@@ -199,6 +200,24 @@ void test_pack_packbuilder__foreach(void)
199200
seed_packbuilder();
200201
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
201202
cl_git_pass(git_packbuilder_foreach(_packbuilder, foreach_cb, idx));
202-
cl_git_pass(git_indexer_commit(idx, &stats));
203+
cl_git_pass(git_indexer_commit(idx, &_stats));
204+
git_indexer_free(idx);
205+
}
206+
207+
static int foreach_cancel_cb(void *buf, size_t len, void *payload)
208+
{
209+
git_indexer *idx = (git_indexer *)payload;
210+
cl_git_pass(git_indexer_append(idx, buf, len, &_stats));
211+
return (_stats.total_objects > 2) ? -1111 : 0;
212+
}
213+
214+
void test_pack_packbuilder__foreach_with_cancel(void)
215+
{
216+
git_indexer *idx;
217+
218+
seed_packbuilder();
219+
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
220+
cl_git_fail_with(
221+
git_packbuilder_foreach(_packbuilder, foreach_cancel_cb, idx), -1111);
203222
git_indexer_free(idx);
204223
}

tests/valgrind-supp-mac.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,6 @@
102102
...
103103
fun:ssl23_connect
104104
}
105-
{
106-
mac-ssl-uninitialized-4
107-
Memcheck:Param
108-
...
109-
obj:/usr/lib/libcrypto.0.9.8.dylib
110-
...
111-
fun:ssl23_connect
112-
}
113105
{
114106
mac-ssl-leak-1
115107
Memcheck:Leak

0 commit comments

Comments
 (0)