mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 00:43:41 +00:00
Port tests from PR 1683
This ports over some of the tests from https://github.com/libgit2/libgit2/pull/1683 by @yorah and @ethomson
This commit is contained in:
parent
0e32635fcf
commit
b47349b8dc
@ -54,6 +54,11 @@ typedef struct {
|
||||
size_t asize, size;
|
||||
} git_buf;
|
||||
|
||||
/**
|
||||
* Static initializer for git_buf from static buffer
|
||||
*/
|
||||
#define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) }
|
||||
|
||||
/**
|
||||
* Free the memory referred to by the git_buf.
|
||||
*
|
||||
|
@ -59,6 +59,19 @@ GIT_EXTERN(int) git_filter_list_new(
|
||||
GIT_EXTERN(int) git_filter_list_push(
|
||||
git_filter_list *fl, git_filter *filter, void *payload);
|
||||
|
||||
/**
|
||||
* Look up how many filters are in the list
|
||||
*
|
||||
* We will attempt to apply all of these filters to any data passed in,
|
||||
* but note that the filter apply action still has the option of skipping
|
||||
* data that is passed in (for example, the CRLF filter will skip data
|
||||
* that appears to be binary).
|
||||
*
|
||||
* @param fl A filter list
|
||||
* @return The number of filters in the list
|
||||
*/
|
||||
GIT_EXTERN(size_t) git_filter_list_length(const git_filter_list *fl);
|
||||
|
||||
/**
|
||||
* A filter source represents a file/blob to be processed
|
||||
*/
|
||||
|
@ -548,6 +548,11 @@ int git_filter_list_push(
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t git_filter_list_length(const git_filter_list *fl)
|
||||
{
|
||||
return fl ? git_array_size(fl->filters) : 0;
|
||||
}
|
||||
|
||||
static int filter_list_out_buffer_from_raw(
|
||||
git_buf *out, const void *ptr, size_t size)
|
||||
{
|
||||
|
@ -5,10 +5,16 @@ static git_repository *g_repo = NULL;
|
||||
|
||||
void test_filter_crlf__initialize(void)
|
||||
{
|
||||
git_config *cfg;
|
||||
|
||||
g_repo = cl_git_sandbox_init("crlf");
|
||||
|
||||
cl_git_mkfile("crlf/.gitattributes",
|
||||
"*.txt text\n*.bin binary\n*.crlf text eol=crlf\n*.lf text eol=lf\n");
|
||||
|
||||
cl_git_pass(git_repository_config(&cfg, g_repo));
|
||||
cl_git_pass(git_config_set_string(cfg, "core.autocrlf", "true"));
|
||||
git_config_free(cfg);
|
||||
}
|
||||
|
||||
void test_filter_crlf__cleanup(void)
|
||||
@ -22,13 +28,6 @@ void test_filter_crlf__to_worktree(void)
|
||||
git_filter *crlf;
|
||||
git_buf in = { 0 }, out = { 0 };
|
||||
|
||||
{
|
||||
git_config *cfg;
|
||||
cl_git_pass(git_repository_config(&cfg, g_repo));
|
||||
cl_git_pass(git_config_set_string(cfg, "core.autocrlf", "true"));
|
||||
git_config_free(cfg);
|
||||
}
|
||||
|
||||
cl_git_pass(git_filter_list_new(&fl, g_repo, GIT_FILTER_TO_WORKTREE));
|
||||
|
||||
crlf = git_filter_lookup(GIT_FILTER_CRLF);
|
||||
@ -57,13 +56,6 @@ void test_filter_crlf__to_odb(void)
|
||||
git_filter *crlf;
|
||||
git_buf in = { 0 }, out = { 0 };
|
||||
|
||||
{
|
||||
git_config *cfg;
|
||||
cl_git_pass(git_repository_config(&cfg, g_repo));
|
||||
cl_git_pass(git_config_set_string(cfg, "core.autocrlf", "true"));
|
||||
git_config_free(cfg);
|
||||
}
|
||||
|
||||
cl_git_pass(git_filter_list_new(&fl, g_repo, GIT_FILTER_TO_ODB));
|
||||
|
||||
crlf = git_filter_lookup(GIT_FILTER_CRLF);
|
||||
|
@ -22,5 +22,4 @@
|
||||
#define MORE_CRLF_TEXT_AS_LF "crlf\ncrlf\nlf\ncrlf\ncrlf\n"
|
||||
#define MORE_LF_TEXT_AS_LF "lf\nlf\ncrlf\nlf\nlf\n"
|
||||
|
||||
|
||||
#endif
|
||||
|
247
tests-clar/filter/custom.c
Normal file
247
tests-clar/filter/custom.c
Normal file
@ -0,0 +1,247 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "posix.h"
|
||||
#include "blob.h"
|
||||
#include "filter.h"
|
||||
#include "buf_text.h"
|
||||
#include "git2/sys/filter.h"
|
||||
#include "git2/sys/repository.h"
|
||||
|
||||
#define BITFLIP_FILTER_PRIORITY 20
|
||||
#define REVERSE_FILTER_PRIORITY 25
|
||||
|
||||
#define VERY_SECURE_ENCRYPTION(b) ((b) ^ 0xff)
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
# define NEWLINE "\r\n"
|
||||
#else
|
||||
# define NEWLINE "\n"
|
||||
#endif
|
||||
|
||||
static char workdir_data[] =
|
||||
"some simple" NEWLINE
|
||||
"data" NEWLINE
|
||||
"that will be" NEWLINE
|
||||
"trivially" NEWLINE
|
||||
"scrambled." NEWLINE;
|
||||
|
||||
/* Represents the data above scrambled (bits flipped) after \r\n -> \n
|
||||
* conversion, then bytewise reversed
|
||||
*/
|
||||
static unsigned char bitflipped_and_reversed_data[] =
|
||||
{ 0xf5, 0xd1, 0x9b, 0x9a, 0x93, 0x9d, 0x92, 0x9e, 0x8d, 0x9c, 0x8c,
|
||||
0xf5, 0x86, 0x93, 0x93, 0x9e, 0x96, 0x89, 0x96, 0x8d, 0x8b, 0xf5,
|
||||
0x9a, 0x9d, 0xdf, 0x93, 0x93, 0x96, 0x88, 0xdf, 0x8b, 0x9e, 0x97,
|
||||
0x8b, 0xf5, 0x9e, 0x8b, 0x9e, 0x9b, 0xf5, 0x9a, 0x93, 0x8f, 0x92,
|
||||
0x96, 0x8c, 0xdf, 0x9a, 0x92, 0x90, 0x8c };
|
||||
|
||||
#define BITFLIPPED_AND_REVERSED_DATA_LEN 51
|
||||
|
||||
static git_repository *g_repo = NULL;
|
||||
|
||||
static void register_custom_filters(void);
|
||||
|
||||
void test_filter_custom__initialize(void)
|
||||
{
|
||||
register_custom_filters();
|
||||
|
||||
g_repo = cl_git_sandbox_init("empty_standard_repo");
|
||||
|
||||
cl_git_mkfile(
|
||||
"empty_standard_repo/.gitattributes",
|
||||
"hero* bitflip reverse\n"
|
||||
"herofile text\n"
|
||||
"heroflip -reverse\n");
|
||||
}
|
||||
|
||||
void test_filter_custom__cleanup(void)
|
||||
{
|
||||
cl_git_sandbox_cleanup();
|
||||
g_repo = NULL;
|
||||
}
|
||||
|
||||
static int bitflip_filter_apply(
|
||||
git_filter *self,
|
||||
void **payload,
|
||||
git_buf *to,
|
||||
const git_buf *from,
|
||||
const git_filter_source *source)
|
||||
{
|
||||
const unsigned char *src = (const unsigned char *)from->ptr;
|
||||
unsigned char *dst;
|
||||
size_t i;
|
||||
|
||||
GIT_UNUSED(self); GIT_UNUSED(payload);
|
||||
|
||||
/* verify that attribute path match worked as expected */
|
||||
cl_assert_equal_i(
|
||||
0, git__strncmp("hero", git_filter_source_path(source), 4));
|
||||
|
||||
if (!from->size)
|
||||
return 0;
|
||||
|
||||
cl_git_pass(git_buf_grow(to, from->size));
|
||||
|
||||
dst = (unsigned char *)to->ptr;
|
||||
|
||||
for (i = 0; i < from->size; i++)
|
||||
dst[i] = VERY_SECURE_ENCRYPTION(src[i]);
|
||||
|
||||
to->size = from->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bitflip_filter_free(git_filter *f)
|
||||
{
|
||||
git__free(f);
|
||||
}
|
||||
|
||||
static git_filter *create_bitflip_filter(void)
|
||||
{
|
||||
git_filter *filter = git__calloc(1, sizeof(git_filter));
|
||||
cl_assert(filter);
|
||||
|
||||
filter->version = GIT_FILTER_VERSION;
|
||||
filter->attributes = "+bitflip";
|
||||
filter->shutdown = bitflip_filter_free;
|
||||
filter->apply = bitflip_filter_apply;
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
static int reverse_filter_apply(
|
||||
git_filter *self,
|
||||
void **payload,
|
||||
git_buf *to,
|
||||
const git_buf *from,
|
||||
const git_filter_source *source)
|
||||
{
|
||||
const unsigned char *src = (const unsigned char *)from->ptr;
|
||||
const unsigned char *end = src + from->size;
|
||||
unsigned char *dst;
|
||||
|
||||
GIT_UNUSED(self); GIT_UNUSED(payload); GIT_UNUSED(source);
|
||||
|
||||
/* verify that attribute path match worked as expected */
|
||||
cl_assert_equal_i(
|
||||
0, git__strncmp("hero", git_filter_source_path(source), 4));
|
||||
|
||||
if (!from->size)
|
||||
return 0;
|
||||
|
||||
cl_git_pass(git_buf_grow(to, from->size));
|
||||
|
||||
dst = (unsigned char *)to->ptr + from->size - 1;
|
||||
|
||||
while (src < end)
|
||||
*dst-- = *src++;
|
||||
|
||||
to->size = from->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void reverse_filter_free(git_filter *f)
|
||||
{
|
||||
git__free(f);
|
||||
}
|
||||
|
||||
static git_filter *create_reverse_filter(void)
|
||||
{
|
||||
git_filter *filter = git__calloc(1, sizeof(git_filter));
|
||||
cl_assert(filter);
|
||||
|
||||
filter->version = GIT_FILTER_VERSION;
|
||||
filter->attributes = "+reverse";
|
||||
filter->shutdown = reverse_filter_free;
|
||||
filter->apply = reverse_filter_apply;
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
static void register_custom_filters(void)
|
||||
{
|
||||
static int filters_registered = 0;
|
||||
|
||||
if (!filters_registered) {
|
||||
cl_git_pass(git_filter_register(
|
||||
"bitflip", create_bitflip_filter(), BITFLIP_FILTER_PRIORITY));
|
||||
|
||||
cl_git_pass(git_filter_register(
|
||||
"reverse", create_reverse_filter(), REVERSE_FILTER_PRIORITY));
|
||||
|
||||
filters_registered = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test_filter_custom__to_odb(void)
|
||||
{
|
||||
git_filter_list *fl;
|
||||
git_buf out = { 0 };
|
||||
git_buf in = GIT_BUF_INIT_CONST(workdir_data, strlen(workdir_data));
|
||||
|
||||
cl_git_pass(git_filter_list_load(
|
||||
&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_ODB));
|
||||
|
||||
cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
|
||||
|
||||
cl_assert_equal_i(BITFLIPPED_AND_REVERSED_DATA_LEN, out.size);
|
||||
|
||||
cl_assert_equal_i(
|
||||
0, memcmp(bitflipped_and_reversed_data, out.ptr, out.size));
|
||||
|
||||
git_filter_list_free(fl);
|
||||
git_buf_free(&out);
|
||||
}
|
||||
|
||||
void test_filter_custom__to_workdir(void)
|
||||
{
|
||||
git_filter_list *fl;
|
||||
git_buf out = { 0 };
|
||||
git_buf in = GIT_BUF_INIT_CONST(
|
||||
bitflipped_and_reversed_data, BITFLIPPED_AND_REVERSED_DATA_LEN);
|
||||
|
||||
cl_git_pass(git_filter_list_load(
|
||||
&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE));
|
||||
|
||||
cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
|
||||
|
||||
cl_assert_equal_i(strlen(workdir_data), out.size);
|
||||
|
||||
cl_assert_equal_i(
|
||||
0, memcmp(workdir_data, out.ptr, out.size));
|
||||
|
||||
git_filter_list_free(fl);
|
||||
git_buf_free(&out);
|
||||
}
|
||||
|
||||
void test_filter_custom__can_register_a_custom_filter_in_the_repository(void)
|
||||
{
|
||||
git_filter_list *fl;
|
||||
|
||||
cl_git_pass(git_filter_list_load(
|
||||
&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE));
|
||||
/* expect: bitflip, reverse, crlf */
|
||||
cl_assert_equal_sz(3, git_filter_list_length(fl));
|
||||
git_filter_list_free(fl);
|
||||
|
||||
cl_git_pass(git_filter_list_load(
|
||||
&fl, g_repo, NULL, "herocorp", GIT_FILTER_TO_WORKTREE));
|
||||
/* expect: bitflip, reverse */
|
||||
cl_assert_equal_sz(2, git_filter_list_length(fl));
|
||||
git_filter_list_free(fl);
|
||||
|
||||
cl_git_pass(git_filter_list_load(
|
||||
&fl, g_repo, NULL, "heroflip", GIT_FILTER_TO_WORKTREE));
|
||||
/* expect: bitflip (because of -reverse) */
|
||||
cl_assert_equal_sz(1, git_filter_list_length(fl));
|
||||
git_filter_list_free(fl);
|
||||
|
||||
cl_git_pass(git_filter_list_load(
|
||||
&fl, g_repo, NULL, "doesntapplytome", GIT_FILTER_TO_WORKTREE));
|
||||
/* expect: none */
|
||||
cl_assert_equal_sz(0, git_filter_list_length(fl));
|
||||
git_filter_list_free(fl);
|
||||
}
|
@ -4,9 +4,10 @@
|
||||
#include "buf_text.h"
|
||||
|
||||
static git_repository *g_repo = NULL;
|
||||
#define NUM_TEST_OBJECTS 9
|
||||
static git_oid g_oids[NUM_TEST_OBJECTS];
|
||||
static const char *g_raw[NUM_TEST_OBJECTS] = {
|
||||
|
||||
#define CRLF_NUM_TEST_OBJECTS 9
|
||||
|
||||
static const char *g_crlf_raw[CRLF_NUM_TEST_OBJECTS] = {
|
||||
"",
|
||||
"foo\nbar\n",
|
||||
"foo\rbar\r",
|
||||
@ -17,19 +18,14 @@ static const char *g_raw[NUM_TEST_OBJECTS] = {
|
||||
"\xEF\xBB\xBF\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\r\n\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\r\n",
|
||||
"\xFE\xFF\x00T\x00h\x00i\x00s\x00!"
|
||||
};
|
||||
static git_off_t g_len[NUM_TEST_OBJECTS] = { -1, -1, -1, -1, -1, 17, -1, -1, 12 };
|
||||
static git_buf_text_stats g_stats[NUM_TEST_OBJECTS] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 2, 0, 6, 0 },
|
||||
{ 0, 0, 2, 0, 0, 6, 0 },
|
||||
{ 0, 0, 2, 2, 2, 6, 0 },
|
||||
{ 0, 0, 4, 4, 1, 31, 0 },
|
||||
{ 0, 1, 1, 2, 1, 9, 5 },
|
||||
{ GIT_BOM_UTF8, 0, 0, 1, 0, 16, 0 },
|
||||
{ GIT_BOM_UTF8, 0, 2, 2, 2, 27, 0 },
|
||||
{ GIT_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 },
|
||||
|
||||
static git_off_t g_crlf_raw_len[CRLF_NUM_TEST_OBJECTS] = {
|
||||
-1, -1, -1, -1, -1, 17, -1, -1, 12
|
||||
};
|
||||
static git_buf g_crlf_filtered[NUM_TEST_OBJECTS] = {
|
||||
|
||||
static git_oid g_crlf_oids[CRLF_NUM_TEST_OBJECTS];
|
||||
|
||||
static git_buf g_crlf_filtered[CRLF_NUM_TEST_OBJECTS] = {
|
||||
{ "", 0, 0 },
|
||||
{ "foo\nbar\n", 0, 8 },
|
||||
{ "foo\rbar\r", 0, 8 },
|
||||
@ -41,30 +37,36 @@ static git_buf g_crlf_filtered[NUM_TEST_OBJECTS] = {
|
||||
{ "\xFE\xFF\x00T\x00h\x00i\x00s\x00!", 0, 12 }
|
||||
};
|
||||
|
||||
static git_buf_text_stats g_crlf_filtered_stats[CRLF_NUM_TEST_OBJECTS] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 2, 0, 6, 0 },
|
||||
{ 0, 0, 2, 0, 0, 6, 0 },
|
||||
{ 0, 0, 2, 2, 2, 6, 0 },
|
||||
{ 0, 0, 4, 4, 1, 31, 0 },
|
||||
{ 0, 1, 1, 2, 1, 9, 5 },
|
||||
{ GIT_BOM_UTF8, 0, 0, 1, 0, 16, 0 },
|
||||
{ GIT_BOM_UTF8, 0, 2, 2, 2, 27, 0 },
|
||||
{ GIT_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 },
|
||||
};
|
||||
|
||||
void test_object_blob_filter__initialize(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
cl_fixture_sandbox("empty_standard_repo");
|
||||
cl_git_pass(p_rename(
|
||||
"empty_standard_repo/.gitted", "empty_standard_repo/.git"));
|
||||
cl_git_pass(git_repository_open(&g_repo, "empty_standard_repo"));
|
||||
g_repo = cl_git_sandbox_init("empty_standard_repo");
|
||||
|
||||
for (i = 0; i < NUM_TEST_OBJECTS; i++) {
|
||||
size_t len = (g_len[i] < 0) ? strlen(g_raw[i]) : (size_t)g_len[i];
|
||||
g_len[i] = (git_off_t)len;
|
||||
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
|
||||
if (g_crlf_raw_len[i] < 0)
|
||||
g_crlf_raw_len[i] = strlen(g_crlf_raw[i]);
|
||||
|
||||
cl_git_pass(
|
||||
git_blob_create_frombuffer(&g_oids[i], g_repo, g_raw[i], len)
|
||||
);
|
||||
cl_git_pass(git_blob_create_frombuffer(
|
||||
&g_crlf_oids[i], g_repo, g_crlf_raw[i], (size_t)g_crlf_raw_len[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void test_object_blob_filter__cleanup(void)
|
||||
{
|
||||
git_repository_free(g_repo);
|
||||
g_repo = NULL;
|
||||
cl_fixture_cleanup("empty_standard_repo");
|
||||
cl_git_sandbox_cleanup();
|
||||
}
|
||||
|
||||
void test_object_blob_filter__unfiltered(void)
|
||||
@ -72,10 +74,15 @@ void test_object_blob_filter__unfiltered(void)
|
||||
int i;
|
||||
git_blob *blob;
|
||||
|
||||
for (i = 0; i < NUM_TEST_OBJECTS; i++) {
|
||||
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_oids[i]));
|
||||
cl_assert(g_len[i] == git_blob_rawsize(blob));
|
||||
cl_assert(memcmp(git_blob_rawcontent(blob), g_raw[i], (size_t)g_len[i]) == 0);
|
||||
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
|
||||
size_t raw_len = (size_t)g_crlf_raw_len[i];
|
||||
|
||||
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
|
||||
|
||||
cl_assert_equal_sz(raw_len, (size_t)git_blob_rawsize(blob));
|
||||
cl_assert_equal_i(
|
||||
0, memcmp(g_crlf_raw[i], git_blob_rawcontent(blob), raw_len));
|
||||
|
||||
git_blob_free(blob);
|
||||
}
|
||||
}
|
||||
@ -87,11 +94,12 @@ void test_object_blob_filter__stats(void)
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
git_buf_text_stats stats;
|
||||
|
||||
for (i = 0; i < NUM_TEST_OBJECTS; i++) {
|
||||
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_oids[i]));
|
||||
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
|
||||
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
|
||||
cl_git_pass(git_blob__getbuf(&buf, blob));
|
||||
git_buf_text_gather_stats(&stats, &buf, false);
|
||||
cl_assert(memcmp(&g_stats[i], &stats, sizeof(stats)) == 0);
|
||||
cl_assert_equal_i(
|
||||
0, memcmp(&g_crlf_filtered_stats[i], &stats, sizeof(stats)));
|
||||
git_blob_free(blob);
|
||||
}
|
||||
|
||||
@ -116,14 +124,15 @@ void test_object_blob_filter__to_odb(void)
|
||||
&fl, g_repo, NULL, "filename.txt", GIT_FILTER_TO_ODB));
|
||||
cl_assert(fl != NULL);
|
||||
|
||||
for (i = 0; i < NUM_TEST_OBJECTS; i++) {
|
||||
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_oids[i]));
|
||||
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
|
||||
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
|
||||
|
||||
cl_git_pass(git_filter_list_apply_to_blob(&out, fl, blob));
|
||||
|
||||
cl_assert(!memcmp(
|
||||
out.ptr, g_crlf_filtered[i].ptr,
|
||||
min(out.size, g_crlf_filtered[i].size)));
|
||||
cl_assert_equal_sz(g_crlf_filtered[i].size, out.size);
|
||||
|
||||
cl_assert_equal_i(
|
||||
0, memcmp(out.ptr, g_crlf_filtered[i].ptr, out.size));
|
||||
|
||||
git_blob_free(blob);
|
||||
}
|
||||
@ -132,4 +141,3 @@ void test_object_blob_filter__to_odb(void)
|
||||
git_buf_free(&out);
|
||||
git_config_free(cfg);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user