summaryrefslogtreecommitdiff
path: root/tests/clar_libgit2.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/clar_libgit2.c')
-rw-r--r--tests/clar_libgit2.c627
1 files changed, 0 insertions, 627 deletions
diff --git a/tests/clar_libgit2.c b/tests/clar_libgit2.c
deleted file mode 100644
index c4550c32a..000000000
--- a/tests/clar_libgit2.c
+++ /dev/null
@@ -1,627 +0,0 @@
-#include "clar_libgit2.h"
-#include "posix.h"
-#include "path.h"
-#include "git2/sys/repository.h"
-
-void cl_git_report_failure(
- int error, int expected, const char *file, const char *func, int line, const char *fncall)
-{
- char msg[4096];
- const git_error *last = git_error_last();
-
- if (expected)
- p_snprintf(msg, 4096, "error %d (expected %d) - %s",
- error, expected, last ? last->message : "<no message>");
- else if (error || last)
- p_snprintf(msg, 4096, "error %d - %s",
- error, last ? last->message : "<no message>");
- else
- p_snprintf(msg, 4096, "no error, expected non-zero return");
-
- clar__assert(0, file, func, line, fncall, msg, 1);
-}
-
-void cl_git_mkfile(const char *filename, const char *content)
-{
- int fd;
-
- fd = p_creat(filename, 0666);
- cl_assert(fd != -1);
-
- if (content) {
- cl_must_pass(p_write(fd, content, strlen(content)));
- } else {
- cl_must_pass(p_write(fd, filename, strlen(filename)));
- cl_must_pass(p_write(fd, "\n", 1));
- }
-
- cl_must_pass(p_close(fd));
-}
-
-void cl_git_write2file(
- const char *path, const char *content, size_t content_len,
- int flags, unsigned int mode)
-{
- int fd;
- cl_assert(path && content);
- cl_assert((fd = p_open(path, flags, mode)) >= 0);
- if (!content_len)
- content_len = strlen(content);
- cl_must_pass(p_write(fd, content, content_len));
- cl_must_pass(p_close(fd));
-}
-
-void cl_git_append2file(const char *path, const char *content)
-{
- cl_git_write2file(path, content, 0, O_WRONLY | O_CREAT | O_APPEND, 0644);
-}
-
-void cl_git_rewritefile(const char *path, const char *content)
-{
- cl_git_write2file(path, content, 0, O_WRONLY | O_CREAT | O_TRUNC, 0644);
-}
-
-void cl_git_rmfile(const char *filename)
-{
- cl_must_pass(p_unlink(filename));
-}
-
-char *cl_getenv(const char *name)
-{
- git_buf out = GIT_BUF_INIT;
- int error = git__getenv(&out, name);
-
- cl_assert(error >= 0 || error == GIT_ENOTFOUND);
-
- if (error == GIT_ENOTFOUND)
- return NULL;
-
- if (out.size == 0) {
- char *dup = git__strdup("");
- cl_assert(dup);
-
- return dup;
- }
-
- return git_buf_detach(&out);
-}
-
-bool cl_is_env_set(const char *name)
-{
- char *env = cl_getenv(name);
- bool result = (env != NULL);
- git__free(env);
- return result;
-}
-
-#ifdef GIT_WIN32
-
-#include "win32/utf-conv.h"
-
-int cl_setenv(const char *name, const char *value)
-{
- wchar_t *wide_name, *wide_value = NULL;
-
- cl_assert(git__utf8_to_16_alloc(&wide_name, name) >= 0);
-
- if (value) {
- cl_assert(git__utf8_to_16_alloc(&wide_value, value) >= 0);
- cl_assert(SetEnvironmentVariableW(wide_name, wide_value));
- } else {
- /* Windows XP returns 0 (failed) when passing NULL for lpValue when
- * lpName does not exist in the environment block. This behavior
- * seems to have changed in later versions. Don't check the return value
- * of SetEnvironmentVariable when passing NULL for lpValue. */
- SetEnvironmentVariableW(wide_name, NULL);
- }
-
- git__free(wide_name);
- git__free(wide_value);
- return 0;
-}
-
-/* This function performs retries on calls to MoveFile in order
- * to provide enhanced reliability in the face of antivirus
- * agents that may be scanning the source (or in the case that
- * the source is a directory, a child of the source). */
-int cl_rename(const char *source, const char *dest)
-{
- git_win32_path source_utf16;
- git_win32_path dest_utf16;
- unsigned retries = 1;
-
- cl_assert(git_win32_path_from_utf8(source_utf16, source) >= 0);
- cl_assert(git_win32_path_from_utf8(dest_utf16, dest) >= 0);
-
- while (!MoveFileW(source_utf16, dest_utf16)) {
- /* Only retry if the error is ERROR_ACCESS_DENIED;
- * this may indicate that an antivirus agent is
- * preventing the rename from source to target */
- if (retries > 5 ||
- ERROR_ACCESS_DENIED != GetLastError())
- return -1;
-
- /* With 5 retries and a coefficient of 10ms, the maximum
- * delay here is 550 ms */
- Sleep(10 * retries * retries);
- retries++;
- }
-
- return 0;
-}
-
-#else
-
-#include <stdlib.h>
-
-int cl_setenv(const char *name, const char *value)
-{
- return (value == NULL) ? unsetenv(name) : setenv(name, value, 1);
-}
-
-int cl_rename(const char *source, const char *dest)
-{
- return p_rename(source, dest);
-}
-
-#endif
-
-static const char *_cl_sandbox = NULL;
-static git_repository *_cl_repo = NULL;
-
-git_repository *cl_git_sandbox_init(const char *sandbox)
-{
- /* Get the name of the sandbox folder which will be created */
- const char *basename = cl_fixture_basename(sandbox);
-
- /* Copy the whole sandbox folder from our fixtures to our test sandbox
- * area. After this it can be accessed with `./sandbox`
- */
- cl_fixture_sandbox(sandbox);
- _cl_sandbox = sandbox;
-
- cl_git_pass(p_chdir(basename));
-
- /* If this is not a bare repo, then rename `sandbox/.gitted` to
- * `sandbox/.git` which must be done since we cannot store a folder
- * named `.git` inside the fixtures folder of our libgit2 repo.
- */
- if (p_access(".gitted", F_OK) == 0)
- cl_git_pass(cl_rename(".gitted", ".git"));
-
- /* If we have `gitattributes`, rename to `.gitattributes`. This may
- * be necessary if we don't want the attributes to be applied in the
- * libgit2 repo, but just during testing.
- */
- if (p_access("gitattributes", F_OK) == 0)
- cl_git_pass(cl_rename("gitattributes", ".gitattributes"));
-
- /* As with `gitattributes`, we may need `gitignore` just for testing. */
- if (p_access("gitignore", F_OK) == 0)
- cl_git_pass(cl_rename("gitignore", ".gitignore"));
-
- cl_git_pass(p_chdir(".."));
-
- /* Now open the sandbox repository and make it available for tests */
- cl_git_pass(git_repository_open(&_cl_repo, basename));
-
- /* Adjust configs after copying to new filesystem */
- cl_git_pass(git_repository_reinit_filesystem(_cl_repo, 0));
-
- return _cl_repo;
-}
-
-git_repository *cl_git_sandbox_init_new(const char *sandbox)
-{
- cl_git_pass(git_repository_init(&_cl_repo, sandbox, false));
- _cl_sandbox = sandbox;
-
- return _cl_repo;
-}
-
-git_repository *cl_git_sandbox_reopen(void)
-{
- if (_cl_repo) {
- git_repository_free(_cl_repo);
- _cl_repo = NULL;
-
- cl_git_pass(git_repository_open(
- &_cl_repo, cl_fixture_basename(_cl_sandbox)));
- }
-
- return _cl_repo;
-}
-
-void cl_git_sandbox_cleanup(void)
-{
- if (_cl_repo) {
- git_repository_free(_cl_repo);
- _cl_repo = NULL;
- }
- if (_cl_sandbox) {
- cl_fixture_cleanup(_cl_sandbox);
- _cl_sandbox = NULL;
- }
-}
-
-bool cl_toggle_filemode(const char *filename)
-{
- struct stat st1, st2;
-
- cl_must_pass(p_stat(filename, &st1));
- cl_must_pass(p_chmod(filename, st1.st_mode ^ 0100));
- cl_must_pass(p_stat(filename, &st2));
-
- return (st1.st_mode != st2.st_mode);
-}
-
-bool cl_is_chmod_supported(void)
-{
- static int _is_supported = -1;
-
- if (_is_supported < 0) {
- cl_git_mkfile("filemode.t", "Test if filemode can be modified");
- _is_supported = cl_toggle_filemode("filemode.t");
- cl_must_pass(p_unlink("filemode.t"));
- }
-
- return _is_supported;
-}
-
-const char* cl_git_fixture_url(const char *fixturename)
-{
- return cl_git_path_url(cl_fixture(fixturename));
-}
-
-const char* cl_git_path_url(const char *path)
-{
- static char url[4096 + 1];
-
- const char *in_buf;
- git_buf path_buf = GIT_BUF_INIT;
- git_buf url_buf = GIT_BUF_INIT;
-
- cl_git_pass(git_path_prettify_dir(&path_buf, path, NULL));
- cl_git_pass(git_buf_puts(&url_buf, "file://"));
-
-#ifdef GIT_WIN32
- /*
- * A FILE uri matches the following format: file://[host]/path
- * where "host" can be empty and "path" is an absolute path to the resource.
- *
- * In this test, no hostname is used, but we have to ensure the leading triple slashes:
- *
- * *nix: file:///usr/home/...
- * Windows: file:///C:/Users/...
- */
- cl_git_pass(git_buf_putc(&url_buf, '/'));
-#endif
-
- in_buf = git_buf_cstr(&path_buf);
-
- /*
- * A very hacky Url encoding that only takes care of escaping the spaces
- */
- while (*in_buf) {
- if (*in_buf == ' ')
- cl_git_pass(git_buf_puts(&url_buf, "%20"));
- else
- cl_git_pass(git_buf_putc(&url_buf, *in_buf));
-
- in_buf++;
- }
-
- cl_assert(url_buf.size < sizeof(url) - 1);
-
- strncpy(url, git_buf_cstr(&url_buf), sizeof(url) - 1);
- url[sizeof(url) - 1] = '\0';
- git_buf_dispose(&url_buf);
- git_buf_dispose(&path_buf);
- return url;
-}
-
-const char *cl_git_sandbox_path(int is_dir, ...)
-{
- const char *path = NULL;
- static char _temp[GIT_PATH_MAX];
- git_buf buf = GIT_BUF_INIT;
- va_list arg;
-
- cl_git_pass(git_buf_sets(&buf, clar_sandbox_path()));
-
- va_start(arg, is_dir);
-
- while ((path = va_arg(arg, const char *)) != NULL) {
- cl_git_pass(git_buf_joinpath(&buf, buf.ptr, path));
- }
- va_end(arg);
-
- cl_git_pass(git_path_prettify(&buf, buf.ptr, NULL));
- if (is_dir)
- git_path_to_dir(&buf);
-
- /* make sure we won't truncate */
- cl_assert(git_buf_len(&buf) < sizeof(_temp));
- git_buf_copy_cstr(_temp, sizeof(_temp), &buf);
-
- git_buf_dispose(&buf);
-
- return _temp;
-}
-
-typedef struct {
- const char *filename;
- size_t filename_len;
-} remove_data;
-
-static int remove_placeholders_recurs(void *_data, git_buf *path)
-{
- remove_data *data = (remove_data *)_data;
- size_t pathlen;
-
- if (git_path_isdir(path->ptr) == true)
- return git_path_direach(path, 0, remove_placeholders_recurs, data);
-
- pathlen = path->size;
-
- if (pathlen < data->filename_len)
- return 0;
-
- /* if path ends in '/'+filename (or equals filename) */
- if (!strcmp(data->filename, path->ptr + pathlen - data->filename_len) &&
- (pathlen == data->filename_len ||
- path->ptr[pathlen - data->filename_len - 1] == '/'))
- return p_unlink(path->ptr);
-
- return 0;
-}
-
-int cl_git_remove_placeholders(const char *directory_path, const char *filename)
-{
- int error;
- remove_data data;
- git_buf buffer = GIT_BUF_INIT;
-
- if (git_path_isdir(directory_path) == false)
- return -1;
-
- if (git_buf_sets(&buffer, directory_path) < 0)
- return -1;
-
- data.filename = filename;
- data.filename_len = strlen(filename);
-
- error = remove_placeholders_recurs(&data, &buffer);
-
- git_buf_dispose(&buffer);
-
- return error;
-}
-
-#define CL_COMMIT_NAME "Libgit2 Tester"
-#define CL_COMMIT_EMAIL "libgit2-test@github.com"
-#define CL_COMMIT_MSG "Test commit of tree "
-
-void cl_repo_commit_from_index(
- git_oid *out,
- git_repository *repo,
- git_signature *sig,
- git_time_t time,
- const char *msg)
-{
- git_index *index;
- git_oid commit_id, tree_id;
- git_object *parent = NULL;
- git_reference *ref = NULL;
- git_tree *tree = NULL;
- char buf[128];
- int free_sig = (sig == NULL);
-
- /* it is fine if looking up HEAD fails - we make this the first commit */
- git_revparse_ext(&parent, &ref, repo, "HEAD");
-
- /* write the index content as a tree */
- cl_git_pass(git_repository_index(&index, repo));
- cl_git_pass(git_index_write_tree(&tree_id, index));
- cl_git_pass(git_index_write(index));
- git_index_free(index);
-
- cl_git_pass(git_tree_lookup(&tree, repo, &tree_id));
-
- if (sig)
- cl_assert(sig->name && sig->email);
- else if (!time)
- cl_git_pass(git_signature_now(&sig, CL_COMMIT_NAME, CL_COMMIT_EMAIL));
- else
- cl_git_pass(git_signature_new(
- &sig, CL_COMMIT_NAME, CL_COMMIT_EMAIL, time, 0));
-
- if (!msg) {
- strcpy(buf, CL_COMMIT_MSG);
- git_oid_tostr(buf + strlen(CL_COMMIT_MSG),
- sizeof(buf) - strlen(CL_COMMIT_MSG), &tree_id);
- msg = buf;
- }
-
- cl_git_pass(git_commit_create_v(
- &commit_id, repo, ref ? git_reference_name(ref) : "HEAD",
- sig, sig, NULL, msg, tree, parent ? 1 : 0, parent));
-
- if (out)
- git_oid_cpy(out, &commit_id);
-
- git_object_free(parent);
- git_reference_free(ref);
- if (free_sig)
- git_signature_free(sig);
- git_tree_free(tree);
-}
-
-void cl_repo_set_bool(git_repository *repo, const char *cfg, int value)
-{
- git_config *config;
- cl_git_pass(git_repository_config(&config, repo));
- cl_git_pass(git_config_set_bool(config, cfg, value != 0));
- git_config_free(config);
-}
-
-int cl_repo_get_bool(git_repository *repo, const char *cfg)
-{
- int val = 0;
- git_config *config;
- cl_git_pass(git_repository_config(&config, repo));
- if (git_config_get_bool(&val, config, cfg) < 0)
- git_error_clear();
- git_config_free(config);
- return val;
-}
-
-void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value)
-{
- git_config *config;
- cl_git_pass(git_repository_config(&config, repo));
- cl_git_pass(git_config_set_string(config, cfg, value));
- git_config_free(config);
-}
-
-/* this is essentially the code from git__unescape modified slightly */
-static size_t strip_cr_from_buf(char *start, size_t len)
-{
- char *scan, *trail, *end = start + len;
-
- for (scan = trail = start; scan < end; trail++, scan++) {
- while (*scan == '\r')
- scan++; /* skip '\r' */
-
- if (trail != scan)
- *trail = *scan;
- }
-
- *trail = '\0';
-
- return (trail - start);
-}
-
-void clar__assert_equal_file(
- const char *expected_data,
- size_t expected_bytes,
- int ignore_cr,
- const char *path,
- const char *file,
- const char *func,
- int line)
-{
- char buf[4000];
- ssize_t bytes, total_bytes = 0;
- int fd = p_open(path, O_RDONLY | O_BINARY);
- cl_assert(fd >= 0);
-
- if (expected_data && !expected_bytes)
- expected_bytes = strlen(expected_data);
-
- while ((bytes = p_read(fd, buf, sizeof(buf))) != 0) {
- clar__assert(
- bytes > 0, file, func, line, "error reading from file", path, 1);
-
- if (ignore_cr)
- bytes = strip_cr_from_buf(buf, bytes);
-
- if (memcmp(expected_data, buf, bytes) != 0) {
- int pos;
- for (pos = 0; pos < bytes && expected_data[pos] == buf[pos]; ++pos)
- /* find differing byte offset */;
- p_snprintf(
- buf, sizeof(buf), "file content mismatch at byte %"PRIdZ,
- (ssize_t)(total_bytes + pos));
- p_close(fd);
- clar__fail(file, func, line, path, buf, 1);
- }
-
- expected_data += bytes;
- total_bytes += bytes;
- }
-
- p_close(fd);
-
- clar__assert(!bytes, file, func, line, "error reading from file", path, 1);
- clar__assert_equal(file, func, line, "mismatched file length", 1, "%"PRIuZ,
- (size_t)expected_bytes, (size_t)total_bytes);
-}
-
-static char *_cl_restore_home = NULL;
-
-void cl_fake_home_cleanup(void *payload)
-{
- char *restore = _cl_restore_home;
- _cl_restore_home = NULL;
-
- GIT_UNUSED(payload);
-
- if (restore) {
- cl_git_pass(git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore));
- git__free(restore);
- }
-}
-
-void cl_fake_home(void)
-{
- git_buf path = GIT_BUF_INIT;
-
- cl_git_pass(git_libgit2_opts(
- GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &path));
-
- _cl_restore_home = git_buf_detach(&path);
- cl_set_cleanup(cl_fake_home_cleanup, NULL);
-
- if (!git_path_exists("home"))
- cl_must_pass(p_mkdir("home", 0777));
- cl_git_pass(git_path_prettify(&path, "home", NULL));
- cl_git_pass(git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
- git_buf_dispose(&path);
-}
-
-void cl_sandbox_set_search_path_defaults(void)
-{
- git_buf path = GIT_BUF_INIT;
-
- git_buf_joinpath(&path, clar_sandbox_path(), "__config");
-
- if (!git_path_exists(path.ptr))
- cl_must_pass(p_mkdir(path.ptr, 0777));
-
- git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr);
- git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr);
- git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr);
- git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_PROGRAMDATA, path.ptr);
-
- git_buf_dispose(&path);
-}
-
-#ifdef GIT_WIN32
-bool cl_sandbox_supports_8dot3(void)
-{
- git_buf longpath = GIT_BUF_INIT;
- char *shortname;
- bool supported;
-
- cl_git_pass(
- git_buf_joinpath(&longpath, clar_sandbox_path(), "longer_than_8dot3"));
-
- cl_git_write2file(longpath.ptr, "", 0, O_RDWR|O_CREAT, 0666);
- shortname = git_win32_path_8dot3_name(longpath.ptr);
-
- supported = (shortname != NULL);
-
- git__free(shortname);
- git_buf_dispose(&longpath);
-
- return supported;
-}
-#endif
-