summaryrefslogtreecommitdiff
path: root/tests-clar
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2012-06-19 15:17:35 -0700
committerVicent Martí <vicent@github.com>2012-06-19 15:17:35 -0700
commitc3ce8d0c9a8c9510e713babf1110b2df84f0aa88 (patch)
tree10e30e40f64f7008ac49b0a557b9cb2a164ba8e1 /tests-clar
parent5232994072862de1358a2a0b14dda14e018f02e6 (diff)
parent77d65af4398c6e2b7b7d54cbc10857f02132740e (diff)
downloadlibgit2-c3ce8d0c9a8c9510e713babf1110b2df84f0aa88.tar.gz
Merge pull request #775 from arrbee/fix-index-filemodes
Make index add/append support core.filemode flag
Diffstat (limited to 'tests-clar')
-rw-r--r--tests-clar/clar_helpers.c9
-rw-r--r--tests-clar/clar_libgit2.h2
-rw-r--r--tests-clar/index/filemodes.c212
3 files changed, 218 insertions, 5 deletions
diff --git a/tests-clar/clar_helpers.c b/tests-clar/clar_helpers.c
index 1275d1620..c91479438 100644
--- a/tests-clar/clar_helpers.c
+++ b/tests-clar/clar_helpers.c
@@ -28,9 +28,10 @@ void cl_git_mkfile(const char *filename, const char *content)
cl_must_pass(p_close(fd));
}
-void cl_git_write2file(const char *filename, const char *new_content, int flags)
+void cl_git_write2file(
+ const char *filename, const char *new_content, int flags, unsigned int mode)
{
- int fd = p_open(filename, flags, 0644);
+ int fd = p_open(filename, flags, mode);
cl_assert(fd >= 0);
if (!new_content)
new_content = "\n";
@@ -40,12 +41,12 @@ void cl_git_write2file(const char *filename, const char *new_content, int flags)
void cl_git_append2file(const char *filename, const char *new_content)
{
- cl_git_write2file(filename, new_content, O_WRONLY | O_CREAT | O_APPEND);
+ cl_git_write2file(filename, new_content, O_WRONLY | O_CREAT | O_APPEND, 0644);
}
void cl_git_rewritefile(const char *filename, const char *new_content)
{
- cl_git_write2file(filename, new_content, O_WRONLY | O_CREAT | O_TRUNC);
+ cl_git_write2file(filename, new_content, O_WRONLY | O_CREAT | O_TRUNC, 0644);
}
#ifdef GIT_WIN32
diff --git a/tests-clar/clar_libgit2.h b/tests-clar/clar_libgit2.h
index a3b03bbb3..eab6c3d3e 100644
--- a/tests-clar/clar_libgit2.h
+++ b/tests-clar/clar_libgit2.h
@@ -38,7 +38,7 @@
void cl_git_mkfile(const char *filename, const char *content);
void cl_git_append2file(const char *filename, const char *new_content);
void cl_git_rewritefile(const char *filename, const char *new_content);
-void cl_git_write2file(const char *filename, const char *new_content, int mode);
+void cl_git_write2file(const char *filename, const char *new_content, int flags, unsigned int mode);
bool cl_toggle_filemode(const char *filename);
bool cl_is_chmod_supported(void);
diff --git a/tests-clar/index/filemodes.c b/tests-clar/index/filemodes.c
new file mode 100644
index 000000000..8bd35ddab
--- /dev/null
+++ b/tests-clar/index/filemodes.c
@@ -0,0 +1,212 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "posix.h"
+#include "index.h"
+
+static git_repository *g_repo = NULL;
+
+void test_index_filemodes__initialize(void)
+{
+ g_repo = cl_git_sandbox_init("filemodes");
+}
+
+void test_index_filemodes__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+void test_index_filemodes__read(void)
+{
+ git_index *index;
+ unsigned int i;
+ static bool expected[6] = { 0, 1, 0, 1, 0, 1 };
+
+ cl_git_pass(git_repository_index(&index, g_repo));
+ cl_assert_equal_i(6, git_index_entrycount(index));
+
+ for (i = 0; i < 6; ++i) {
+ git_index_entry *entry = git_index_get(index, i);
+ cl_assert(entry != NULL);
+ cl_assert(((entry->mode & 0100) ? 1 : 0) == expected[i]);
+ }
+
+ git_index_free(index);
+}
+
+static void replace_file_with_mode(
+ const char *filename, const char *backup, unsigned int create_mode)
+{
+ git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT;
+
+ cl_git_pass(git_buf_joinpath(&path, "filemodes", filename));
+ cl_git_pass(git_buf_printf(&content, "%s as %08u (%d)",
+ filename, create_mode, rand()));
+
+ cl_git_pass(p_rename(path.ptr, backup));
+ cl_git_write2file(
+ path.ptr, content.ptr, O_WRONLY|O_CREAT|O_TRUNC, create_mode);
+
+ git_buf_free(&path);
+ git_buf_free(&content);
+}
+
+static void add_and_check_mode(
+ git_index *index, const char *filename, unsigned int expect_mode)
+{
+ int pos;
+ git_index_entry *entry;
+
+ cl_git_pass(git_index_add(index, filename, 0));
+
+ pos = git_index_find(index, filename);
+ cl_assert(pos >= 0);
+
+ entry = git_index_get(index, pos);
+ cl_assert(entry->mode == expect_mode);
+}
+
+static void append_and_check_mode(
+ git_index *index, const char *filename, unsigned int expect_mode)
+{
+ unsigned int before, after;
+ git_index_entry *entry;
+
+ before = git_index_entrycount(index);
+
+ cl_git_pass(git_index_append(index, filename, 0));
+
+ after = git_index_entrycount(index);
+ cl_assert_equal_i(before + 1, after);
+
+ /* bypass git_index_get since that resorts the index */
+ entry = (git_index_entry *)git_vector_get(&index->entries, after - 1);
+
+ cl_assert_equal_s(entry->path, filename);
+ cl_assert(expect_mode == entry->mode);
+}
+
+void test_index_filemodes__untrusted(void)
+{
+ git_config *cfg;
+ git_index *index;
+ bool can_filemode = cl_is_chmod_supported();
+
+ cl_git_pass(git_repository_config(&cfg, g_repo));
+ cl_git_pass(git_config_set_bool(cfg, "core.filemode", false));
+ git_config_free(cfg);
+
+ cl_git_pass(git_repository_index(&index, g_repo));
+ cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) != 0);
+
+ /* 1 - add 0644 over existing 0644 -> expect 0644 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644);
+ add_and_check_mode(index, "exec_off", 0100644);
+
+ /* 2 - add 0644 over existing 0755 -> expect 0755 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644);
+ add_and_check_mode(index, "exec_on", 0100755);
+
+ /* 3 - add 0755 over existing 0644 -> expect 0644 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755);
+ add_and_check_mode(index, "exec_off", 0100644);
+
+ /* 4 - add 0755 over existing 0755 -> expect 0755 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
+ add_and_check_mode(index, "exec_on", 0100755);
+
+ /* 5 - append 0644 over existing 0644 -> expect 0644 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.2", 0644);
+ append_and_check_mode(index, "exec_off", 0100644);
+
+ /* 6 - append 0644 over existing 0755 -> expect 0755 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.2", 0644);
+ append_and_check_mode(index, "exec_on", 0100755);
+
+ /* 7 - append 0755 over existing 0644 -> expect 0644 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.3", 0755);
+ append_and_check_mode(index, "exec_off", 0100644);
+
+ /* 8 - append 0755 over existing 0755 -> expect 0755 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.3", 0755);
+ append_and_check_mode(index, "exec_on", 0100755);
+
+ /* 9 - add new 0644 -> expect 0644 */
+ cl_git_write2file("filemodes/new_off", "blah",
+ O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ add_and_check_mode(index, "new_off", 0100644);
+
+ /* this test won't give predictable results on a platform
+ * that doesn't support filemodes correctly, so skip it.
+ */
+ if (can_filemode) {
+ /* 10 - add 0755 -> expect 0755 */
+ cl_git_write2file("filemodes/new_on", "blah",
+ O_WRONLY | O_CREAT | O_TRUNC, 0755);
+ add_and_check_mode(index, "new_on", 0100755);
+ }
+
+ git_index_free(index);
+}
+
+void test_index_filemodes__trusted(void)
+{
+ git_config *cfg;
+ git_index *index;
+
+ /* Only run these tests on platforms where I can actually
+ * chmod a file and get the stat results I expect!
+ */
+ if (!cl_is_chmod_supported())
+ return;
+
+ cl_git_pass(git_repository_config(&cfg, g_repo));
+ cl_git_pass(git_config_set_bool(cfg, "core.filemode", true));
+ git_config_free(cfg);
+
+ cl_git_pass(git_repository_index(&index, g_repo));
+ cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) == 0);
+
+ /* 1 - add 0644 over existing 0644 -> expect 0644 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644);
+ add_and_check_mode(index, "exec_off", 0100644);
+
+ /* 2 - add 0644 over existing 0755 -> expect 0644 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644);
+ add_and_check_mode(index, "exec_on", 0100644);
+
+ /* 3 - add 0755 over existing 0644 -> expect 0755 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755);
+ add_and_check_mode(index, "exec_off", 0100755);
+
+ /* 4 - add 0755 over existing 0755 -> expect 0755 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
+ add_and_check_mode(index, "exec_on", 0100755);
+
+ /* 5 - append 0644 over existing 0644 -> expect 0644 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.2", 0644);
+ append_and_check_mode(index, "exec_off", 0100644);
+
+ /* 6 - append 0644 over existing 0755 -> expect 0644 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.2", 0644);
+ append_and_check_mode(index, "exec_on", 0100644);
+
+ /* 7 - append 0755 over existing 0644 -> expect 0755 */
+ replace_file_with_mode("exec_off", "filemodes/exec_off.3", 0755);
+ append_and_check_mode(index, "exec_off", 0100755);
+
+ /* 8 - append 0755 over existing 0755 -> expect 0755 */
+ replace_file_with_mode("exec_on", "filemodes/exec_on.3", 0755);
+ append_and_check_mode(index, "exec_on", 0100755);
+
+ /* 9 - add new 0644 -> expect 0644 */
+ cl_git_write2file("filemodes/new_off", "blah",
+ O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ add_and_check_mode(index, "new_off", 0100644);
+
+ /* 10 - add 0755 -> expect 0755 */
+ cl_git_write2file("filemodes/new_on", "blah",
+ O_WRONLY | O_CREAT | O_TRUNC, 0755);
+ add_and_check_mode(index, "new_on", 0100755);
+
+ git_index_free(index);
+}