Blame tests/filter/custom.c

Packit Service 20376f
#include "clar_libgit2.h"
Packit Service 20376f
#include "posix.h"
Packit Service 20376f
#include "blob.h"
Packit Service 20376f
#include "filter.h"
Packit Service 20376f
#include "buf_text.h"
Packit Service 20376f
#include "git2/sys/filter.h"
Packit Service 20376f
#include "git2/sys/repository.h"
Packit Service 20376f
#include "custom_helpers.h"
Packit Service 20376f
Packit Service 20376f
/* going TO_WORKDIR, filters are executed low to high
Packit Service 20376f
 * going TO_ODB, filters are executed high to low
Packit Service 20376f
 */
Packit Service 20376f
#define BITFLIP_FILTER_PRIORITY -1
Packit Service 20376f
#define REVERSE_FILTER_PRIORITY -2
Packit Service 20376f
Packit Service 20376f
#ifdef GIT_WIN32
Packit Service 20376f
# define NEWLINE "\r\n"
Packit Service 20376f
#else
Packit Service 20376f
# define NEWLINE "\n"
Packit Service 20376f
#endif
Packit Service 20376f
Packit Service 20376f
static char workdir_data[] =
Packit Service 20376f
	"some simple" NEWLINE
Packit Service 20376f
	"data" NEWLINE
Packit Service 20376f
	"that will be" NEWLINE
Packit Service 20376f
	"trivially" NEWLINE
Packit Service 20376f
	"scrambled." NEWLINE;
Packit Service 20376f
Packit Service 20376f
#define REVERSED_DATA_LEN 51
Packit Service 20376f
Packit Service 20376f
/* Represents the data above scrambled (bits flipped) after \r\n -> \n
Packit Service 20376f
 * conversion, then bytewise reversed
Packit Service 20376f
 */
Packit Service 20376f
static unsigned char bitflipped_and_reversed_data[] =
Packit Service 20376f
	{ 0xf5, 0xd1, 0x9b, 0x9a, 0x93, 0x9d, 0x92, 0x9e, 0x8d, 0x9c, 0x8c,
Packit Service 20376f
	  0xf5, 0x86, 0x93, 0x93, 0x9e, 0x96, 0x89, 0x96, 0x8d, 0x8b, 0xf5,
Packit Service 20376f
	  0x9a, 0x9d, 0xdf, 0x93, 0x93, 0x96, 0x88, 0xdf, 0x8b, 0x9e, 0x97,
Packit Service 20376f
	  0x8b, 0xf5, 0x9e, 0x8b, 0x9e, 0x9b, 0xf5, 0x9a, 0x93, 0x8f, 0x92,
Packit Service 20376f
	  0x96, 0x8c, 0xdf, 0x9a, 0x92, 0x90, 0x8c };
Packit Service 20376f
Packit Service 20376f
#define BITFLIPPED_AND_REVERSED_DATA_LEN 51
Packit Service 20376f
Packit Service 20376f
static git_repository *g_repo = NULL;
Packit Service 20376f
Packit Service 20376f
static void register_custom_filters(void);
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__initialize(void)
Packit Service 20376f
{
Packit Service 20376f
	register_custom_filters();
Packit Service 20376f
Packit Service 20376f
	g_repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile(
Packit Service 20376f
		"empty_standard_repo/.gitattributes",
Packit Service 20376f
		"hero* bitflip reverse\n"
Packit Service 20376f
		"herofile text\n"
Packit Service 20376f
		"heroflip -reverse binary\n"
Packit Service 20376f
		"villain erroneous\n"
Packit Service 20376f
		"*.bin binary\n");
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__cleanup(void)
Packit Service 20376f
{
Packit Service 20376f
	cl_git_sandbox_cleanup();
Packit Service 20376f
	g_repo = NULL;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static void register_custom_filters(void)
Packit Service 20376f
{
Packit Service 20376f
	static int filters_registered = 0;
Packit Service 20376f
Packit Service 20376f
	if (!filters_registered) {
Packit Service 20376f
		cl_git_pass(git_filter_register(
Packit Service 20376f
			"bitflip", create_bitflip_filter(), BITFLIP_FILTER_PRIORITY));
Packit Service 20376f
Packit Service 20376f
		cl_git_pass(git_filter_register(
Packit Service 20376f
			"reverse", create_reverse_filter("+reverse"),
Packit Service 20376f
			REVERSE_FILTER_PRIORITY));
Packit Service 20376f
Packit Service 20376f
		/* re-register reverse filter with standard filter=xyz priority */
Packit Service 20376f
		cl_git_pass(git_filter_register(
Packit Service 20376f
			"pre-reverse",
Packit Service 20376f
			create_reverse_filter("+prereverse"),
Packit Service 20376f
			GIT_FILTER_DRIVER_PRIORITY));
Packit Service 20376f
Packit Service 20376f
		cl_git_pass(git_filter_register(
Packit Service 20376f
			"erroneous",
Packit Service 20376f
			create_erroneous_filter("+erroneous"),
Packit Service 20376f
			GIT_FILTER_DRIVER_PRIORITY));
Packit Service 20376f
Packit Service 20376f
		filters_registered = 1;
Packit Service 20376f
	}
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__to_odb(void)
Packit Service 20376f
{
Packit Service 20376f
	git_filter_list *fl;
Packit Service 20376f
	git_buf out = { 0 };
Packit Service 20376f
	git_buf in = GIT_BUF_INIT_CONST(workdir_data, strlen(workdir_data));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_ODB, 0));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in);;
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(BITFLIPPED_AND_REVERSED_DATA_LEN, out.size);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(
Packit Service 20376f
		0, memcmp(bitflipped_and_reversed_data, out.ptr, out.size));
Packit Service 20376f
Packit Service 20376f
	git_filter_list_free(fl);
Packit Service 20376f
	git_buf_free(&out;;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__to_workdir(void)
Packit Service 20376f
{
Packit Service 20376f
	git_filter_list *fl;
Packit Service 20376f
	git_buf out = { 0 };
Packit Service 20376f
	git_buf in = GIT_BUF_INIT_CONST(
Packit Service 20376f
		bitflipped_and_reversed_data, BITFLIPPED_AND_REVERSED_DATA_LEN);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE, 0));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in);;
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(strlen(workdir_data), out.size);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(
Packit Service 20376f
		0, memcmp(workdir_data, out.ptr, out.size));
Packit Service 20376f
Packit Service 20376f
	git_filter_list_free(fl);
Packit Service 20376f
	git_buf_free(&out;;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__can_register_a_custom_filter_in_the_repository(void)
Packit Service 20376f
{
Packit Service 20376f
	git_filter_list *fl;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE, 0));
Packit Service 20376f
	/* expect: bitflip, reverse, crlf */
Packit Service 20376f
	cl_assert_equal_sz(3, git_filter_list_length(fl));
Packit Service 20376f
	git_filter_list_free(fl);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&fl, g_repo, NULL, "herocorp", GIT_FILTER_TO_WORKTREE, 0));
Packit Service 20376f
	/* expect: bitflip, reverse - possibly crlf depending on global config */
Packit Service 20376f
	{
Packit Service 20376f
		size_t flen = git_filter_list_length(fl);
Packit Service 20376f
		cl_assert(flen == 2 || flen == 3);
Packit Service 20376f
	}
Packit Service 20376f
	git_filter_list_free(fl);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&fl, g_repo, NULL, "hero.bin", GIT_FILTER_TO_WORKTREE, 0));
Packit Service 20376f
	/* expect: bitflip, reverse */
Packit Service 20376f
	cl_assert_equal_sz(2, git_filter_list_length(fl));
Packit Service 20376f
	git_filter_list_free(fl);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&fl, g_repo, NULL, "heroflip", GIT_FILTER_TO_WORKTREE, 0));
Packit Service 20376f
	/* expect: bitflip (because of -reverse) */
Packit Service 20376f
	cl_assert_equal_sz(1, git_filter_list_length(fl));
Packit Service 20376f
	git_filter_list_free(fl);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&fl, g_repo, NULL, "doesntapplytome.bin",
Packit Service 20376f
		GIT_FILTER_TO_WORKTREE, 0));
Packit Service 20376f
	/* expect: none */
Packit Service 20376f
	cl_assert_equal_sz(0, git_filter_list_length(fl));
Packit Service 20376f
	git_filter_list_free(fl);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__order_dependency(void)
Packit Service 20376f
{
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	git_blob *blob;
Packit Service 20376f
	git_buf buf = { 0 };
Packit Service 20376f
Packit Service 20376f
	/* so if ident and reverse are used together, an interesting thing
Packit Service 20376f
	 * happens - a reversed "$Id$" string is no longer going to trigger
Packit Service 20376f
	 * ident correctly.  When checking out, the filters should be applied
Packit Service 20376f
	 * in order CLRF, then ident, then reverse, so ident expansion should
Packit Service 20376f
	 * work correctly.  On check in, the content should be reversed, then
Packit Service 20376f
	 * ident, then CRLF filtered.  Let's make sure that works...
Packit Service 20376f
	 */
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile(
Packit Service 20376f
		"empty_standard_repo/.gitattributes",
Packit Service 20376f
		"hero.*.rev-ident text ident prereverse eol=lf\n");
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile(
Packit Service 20376f
		"empty_standard_repo/hero.1.rev-ident",
Packit Service 20376f
		"This is a test\n$Id$\nHave fun!\n");
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile(
Packit Service 20376f
		"empty_standard_repo/hero.2.rev-ident",
Packit Service 20376f
		"Another test\n$dI$\nCrazy!\n");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, g_repo));
Packit Service 20376f
	cl_git_pass(git_index_add_bypath(index, "hero.1.rev-ident"));
Packit Service 20376f
	cl_git_pass(git_index_add_bypath(index, "hero.2.rev-ident"));
Packit Service 20376f
	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "Filter chains\n");
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_blob_lookup(&blob, g_repo,
Packit Service 20376f
		& git_index_get_bypath(index, "hero.1.rev-ident", 0)->id));
Packit Service 20376f
	cl_assert_equal_s(
Packit Service 20376f
		"\n!nuf evaH\n$dI$\ntset a si sihT", git_blob_rawcontent(blob));
Packit Service 20376f
	cl_git_pass(git_blob_filtered_content(&buf, blob, "hero.1.rev-ident", 0));
Packit Service 20376f
	/* no expansion because id was reversed at checkin and now at ident
Packit Service 20376f
	 * time, reverse is not applied yet */
Packit Service 20376f
	cl_assert_equal_s(
Packit Service 20376f
		"This is a test\n$Id$\nHave fun!\n", buf.ptr);
Packit Service 20376f
	git_blob_free(blob);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_blob_lookup(&blob, g_repo,
Packit Service 20376f
		& git_index_get_bypath(index, "hero.2.rev-ident", 0)->id));
Packit Service 20376f
	cl_assert_equal_s(
Packit Service 20376f
		"\n!yzarC\n$Id$\ntset rehtonA", git_blob_rawcontent(blob));
Packit Service 20376f
	cl_git_pass(git_blob_filtered_content(&buf, blob, "hero.2.rev-ident", 0));
Packit Service 20376f
	/* expansion because reverse was applied at checkin and at ident time,
Packit Service 20376f
	 * reverse is not applied yet */
Packit Service 20376f
	cl_assert_equal_s(
Packit Service 20376f
		"Another test\n$ 59001fe193103b1016b27027c0c827d036fd0ac8 :dI$\nCrazy!\n", buf.ptr);
Packit Service 20376f
	cl_assert_equal_i(0, git_oid_strcmp(
Packit Service 20376f
		git_blob_id(blob), "8ca0df630d728c0c72072b6101b301391ef10095"));
Packit Service 20376f
	git_blob_free(blob);
Packit Service 20376f
Packit Service 20376f
	git_buf_free(&buf;;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__filter_registry_failure_cases(void)
Packit Service 20376f
{
Packit Service 20376f
	git_filter fake = { GIT_FILTER_VERSION, 0 };
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(GIT_EEXISTS, git_filter_register("bitflip", &fake, 0));
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_filter_unregister(GIT_FILTER_CRLF));
Packit Service 20376f
	cl_git_fail(git_filter_unregister(GIT_FILTER_IDENT));
Packit Service 20376f
	cl_assert_equal_i(GIT_ENOTFOUND, git_filter_unregister("not-a-filter"));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_filter_custom__erroneous_filter_fails(void)
Packit Service 20376f
{
Packit Service 20376f
	git_filter_list *filters;
Packit Service 20376f
	git_buf out = GIT_BUF_INIT;
Packit Service 20376f
	git_buf in = GIT_BUF_INIT_CONST(workdir_data, strlen(workdir_data));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_filter_list_load(
Packit Service 20376f
		&filters, g_repo, NULL, "villain", GIT_FILTER_TO_WORKTREE, 0));
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_filter_list_apply_to_data(&out, filters, &in);;
Packit Service 20376f
Packit Service 20376f
	git_filter_list_free(filters);
Packit Service 20376f
	git_buf_free(&out;;
Packit Service 20376f
}