version.c 3.42 KB
Newer Older
David Turner committed
1 2 3 4 5
#include "clar_libgit2.h"
#include "index.h"

static git_repository *g_repo = NULL;

6 7 8 9 10 11
void test_index_version__cleanup(void)
{
        cl_git_sandbox_cleanup();
        g_repo = NULL;
}

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
void test_index_version__can_read_v4(void)
{
	const char *paths[] = {
	    "file.tx", "file.txt", "file.txz", "foo", "zzz",
	};
	git_index *index;
	size_t i;

	g_repo = cl_git_sandbox_init("indexv4");

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_assert_equal_sz(git_index_entrycount(index), 5);

	for (i = 0; i < ARRAY_SIZE(paths); i++) {
		const git_index_entry *entry =
		    git_index_get_bypath(index, paths[i], GIT_INDEX_STAGE_NORMAL);

		cl_assert(entry != NULL);
	}

	git_index_free(index);
}

David Turner committed
35 36
void test_index_version__can_write_v4(void)
{
37 38 39 40 41 42 43 44 45
	const char *paths[] = {
	    "foo",
	    "foox",
	    "foobar",
	    "foobal",
	    "x",
	    "xz",
	    "xyzzyx"
	};
46
	git_repository *repo;
47
	git_index_entry entry;
David Turner committed
48
	git_index *index;
49
	size_t i;
David Turner committed
50

51
	g_repo = cl_git_sandbox_init("empty_standard_repo");
David Turner committed
52 53 54
	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_index_set_version(index, 4));

55 56 57 58
	for (i = 0; i < ARRAY_SIZE(paths); i++) {
		memset(&entry, 0, sizeof(entry));
		entry.path = paths[i];
		entry.mode = GIT_FILEMODE_BLOB;
59
		cl_git_pass(git_index_add_from_buffer(index, &entry, paths[i],
60 61 62 63
						     strlen(paths[i]) + 1));
	}
	cl_assert_equal_sz(git_index_entrycount(index), ARRAY_SIZE(paths));

David Turner committed
64 65 66
	cl_git_pass(git_index_write(index));
	git_index_free(index);

67 68
	cl_git_pass(git_repository_open(&repo, git_repository_path(g_repo)));
	cl_git_pass(git_repository_index(&index, repo));
David Turner committed
69 70
	cl_assert(git_index_version(index) == 4);

71 72 73 74 75 76
	for (i = 0; i < ARRAY_SIZE(paths); i++) {
		const git_index_entry *e;

		cl_assert(e = git_index_get_bypath(index, paths[i], 0));
		cl_assert_equal_s(paths[i], e->path);
	}
David Turner committed
77 78

	git_index_free(index);
79
	git_repository_free(repo);
David Turner committed
80
}
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

void test_index_version__v4_uses_path_compression(void)
{
	git_index_entry entry;
	git_index *index;
	char path[250], buf[1];
	struct stat st;
	char i, j;

	memset(path, 'a', sizeof(path));
	memset(buf, 'a', sizeof(buf));

	memset(&entry, 0, sizeof(entry));
	entry.path = path;
	entry.mode = GIT_FILEMODE_BLOB;

	g_repo = cl_git_sandbox_init("indexv4");
	cl_git_pass(git_repository_index(&index, g_repo));

	/* write 676 paths of 250 bytes length */
	for (i = 'a'; i <= 'z'; i++) {
		for (j = 'a'; j < 'z'; j++) {
			path[ARRAY_SIZE(path) - 3] = i;
			path[ARRAY_SIZE(path) - 2] = j;
			path[ARRAY_SIZE(path) - 1] = '\0';
106
			cl_git_pass(git_index_add_from_buffer(index, &entry, buf, sizeof(buf)));
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
		}
	}

	cl_git_pass(git_index_write(index));
	cl_git_pass(p_stat(git_index_path(index), &st));

	/*
	 * Without path compression, the written paths would at
	 * least take
	 *
	 *    (entries * pathlen) = len
	 *    (676 * 250) = 169000
	 *
	 *  bytes. As index v4 uses suffix-compression and our
	 *  written paths only differ in the last two entries,
	 *  this number will be much smaller, e.g.
	 *
	 *    (1 * pathlen) + (675 * 2) = len
	 *    676 + 1350 = 2026
	 *
	 *    bytes.
	 *
	 *    Note that the above calculations do not include
	 *    additional metadata of the index, e.g. OIDs or
	 *    index extensions. Including those we get an index
	 *    of approx. 200kB without compression and 40kB with
	 *    compression. As this is a lot smaller than without
	 *    compression, we can verify that path compression is
	 *    used.
	 */
	cl_assert_(st.st_size < 75000, "path compression not enabled");

	git_index_free(index);
}