summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-06-17 08:15:49 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-06-17 08:15:49 +0200
commita56db99234017eb7814258dfe8bcdec365417a3b (patch)
treeba49074368a7d9b6dff87e8a6540e8137b29d4b9 /tests
parent5f83758fa35a7942457d676e41240dbfbda598b5 (diff)
parent892abf93157ea576fc3f2ccac118045a6a47247c (diff)
downloadlibgit2-a56db99234017eb7814258dfe8bcdec365417a3b.tar.gz
Merge pull request #3219 from libgit2/cmn/racy-diff
Zero out racily-clean entries' file_size
Diffstat (limited to 'tests')
-rw-r--r--tests/checkout/checkout_helpers.c22
-rw-r--r--tests/checkout/checkout_helpers.h2
-rw-r--r--tests/checkout/crlf.c11
-rw-r--r--tests/core/posix.c49
-rw-r--r--tests/diff/racy.c39
-rw-r--r--tests/diff/workdir.c6
-rw-r--r--tests/merge/workdir/dirty.c12
-rw-r--r--tests/status/worktree.c6
8 files changed, 143 insertions, 4 deletions
diff --git a/tests/checkout/checkout_helpers.c b/tests/checkout/checkout_helpers.c
index 06b4e0682..f6e36d39b 100644
--- a/tests/checkout/checkout_helpers.c
+++ b/tests/checkout/checkout_helpers.c
@@ -2,6 +2,7 @@
#include "checkout_helpers.h"
#include "refs.h"
#include "fileops.h"
+#include "index.h"
void assert_on_branch(git_repository *repo, const char *branch)
{
@@ -128,3 +129,24 @@ int checkout_count_callback(
return 0;
}
+
+void tick_index(git_index *index)
+{
+ int index_fd;
+ git_time_t ts;
+ struct timeval times[2];
+
+ cl_assert(index->on_disk);
+ cl_assert(git_index_path(index));
+
+ cl_git_pass(git_index_read(index, true));
+ ts = index->stamp.mtime;
+
+ times[0].tv_sec = ts;
+ times[0].tv_usec = 0;
+ times[1].tv_sec = ts + 1;
+ times[1].tv_usec = 0;
+
+ cl_git_pass(p_utimes(git_index_path(index), times));
+ cl_git_pass(git_index_read(index, true));
+}
diff --git a/tests/checkout/checkout_helpers.h b/tests/checkout/checkout_helpers.h
index 705ee903d..6058a196c 100644
--- a/tests/checkout/checkout_helpers.h
+++ b/tests/checkout/checkout_helpers.h
@@ -27,3 +27,5 @@ extern int checkout_count_callback(
const git_diff_file *target,
const git_diff_file *workdir,
void *payload);
+
+extern void tick_index(git_index *index);
diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c
index 381b04013..61459b3a4 100644
--- a/tests/checkout/crlf.c
+++ b/tests/checkout/crlf.c
@@ -4,6 +4,7 @@
#include "git2/checkout.h"
#include "repository.h"
+#include "index.h"
#include "posix.h"
static git_repository *g_repo;
@@ -40,9 +41,10 @@ void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void)
cl_repo_set_bool(g_repo, "core.autocrlf", false);
- git_checkout_head(g_repo, &opts);
-
git_repository_index(&index, g_repo);
+ tick_index(index);
+
+ git_checkout_head(g_repo, &opts);
cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL);
cl_assert(entry->file_size == strlen(ALL_LF_TEXT_RAW));
@@ -140,9 +142,10 @@ void test_checkout_crlf__autocrlf_true_index_size_is_filtered_size(void)
cl_repo_set_bool(g_repo, "core.autocrlf", true);
- git_checkout_head(g_repo, &opts);
-
git_repository_index(&index, g_repo);
+ tick_index(index);
+
+ git_checkout_head(g_repo, &opts);
cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL);
diff --git a/tests/core/posix.c b/tests/core/posix.c
index 1cef937cd..5a9e24899 100644
--- a/tests/core/posix.c
+++ b/tests/core/posix.c
@@ -97,3 +97,52 @@ void test_core_posix__inet_pton(void)
cl_git_fail(p_inet_pton(5, "315.124", NULL)); /* AF_CHAOS */
cl_assert_equal_i(EAFNOSUPPORT, errno);
}
+
+void test_core_posix__utimes(void)
+{
+ struct timeval times[2];
+ struct stat st;
+ time_t curtime;
+ int fd;
+
+ /* test p_utimes */
+ times[0].tv_sec = 1234567890;
+ times[0].tv_usec = 0;
+ times[1].tv_sec = 1234567890;
+ times[1].tv_usec = 0;
+
+ cl_git_mkfile("foo", "Dummy file.");
+ cl_must_pass(p_utimes("foo", times));
+
+ p_stat("foo", &st);
+ cl_assert_equal_i(1234567890, st.st_atime);
+ cl_assert_equal_i(1234567890, st.st_mtime);
+
+
+ /* test p_futimes */
+ times[0].tv_sec = 1414141414;
+ times[0].tv_usec = 0;
+ times[1].tv_sec = 1414141414;
+ times[1].tv_usec = 0;
+
+ cl_must_pass(fd = p_open("foo", O_RDWR));
+ cl_must_pass(p_futimes(fd, times));
+ p_close(fd);
+
+ p_stat("foo", &st);
+ cl_assert_equal_i(1414141414, st.st_atime);
+ cl_assert_equal_i(1414141414, st.st_mtime);
+
+
+ /* test p_utimes with current time, assume that
+ * it takes < 5 seconds to get the time...!
+ */
+ cl_must_pass(p_utimes("foo", NULL));
+
+ curtime = time(NULL);
+ p_stat("foo", &st);
+ cl_assert((st.st_atime - curtime) < 5);
+ cl_assert((st.st_mtime - curtime) < 5);
+
+ p_unlink("foo");
+}
diff --git a/tests/diff/racy.c b/tests/diff/racy.c
new file mode 100644
index 000000000..a109f8c3b
--- /dev/null
+++ b/tests/diff/racy.c
@@ -0,0 +1,39 @@
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+
+static git_repository *g_repo;
+
+void test_diff_racy__initialize(void)
+{
+ cl_git_pass(git_repository_init(&g_repo, "diff_racy", false));
+}
+
+void test_diff_racy__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+void test_diff_racy__diff(void)
+{
+ git_index *index;
+ git_diff *diff;
+ git_buf path = GIT_BUF_INIT;
+
+ cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));
+ cl_git_mkfile(path.ptr, "A");
+
+ /* Put 'A' into the index */
+ cl_git_pass(git_repository_index(&index, g_repo));
+ cl_git_pass(git_index_add_bypath(index, "A"));
+ cl_git_pass(git_index_write(index));
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
+ cl_assert_equal_i(0, git_diff_num_deltas(diff));
+
+ /* Change its contents quickly, so we get the same timestamp */
+ cl_git_mkfile(path.ptr, "B");
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
+ cl_assert_equal_i(1, git_diff_num_deltas(diff));
+}
diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c
index 5d6ebed95..6b72f3286 100644
--- a/tests/diff/workdir.c
+++ b/tests/diff/workdir.c
@@ -2,6 +2,7 @@
#include "diff_helpers.h"
#include "repository.h"
#include "git2/sys/diff.h"
+#include "../checkout/checkout_helpers.h"
static git_repository *g_repo = NULL;
@@ -1583,6 +1584,7 @@ void test_diff_workdir__can_update_index(void)
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff *diff = NULL;
git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT;
+ git_index *index;
g_repo = cl_git_sandbox_init("status");
@@ -1607,6 +1609,10 @@ void test_diff_workdir__can_update_index(void)
/* now allow diff to update stat cache */
opts.flags |= GIT_DIFF_UPDATE_INDEX;
+ /* advance a tick for the index so we don't re-calculate racily-clean entries */
+ cl_git_pass(git_repository_index__weakptr(&index, g_repo));
+ tick_index(index);
+
basic_diff_status(&diff, &opts);
cl_git_pass(git_diff_get_perfdata(&perf, diff));
diff --git a/tests/merge/workdir/dirty.c b/tests/merge/workdir/dirty.c
index b66225d1f..30c404b70 100644
--- a/tests/merge/workdir/dirty.c
+++ b/tests/merge/workdir/dirty.c
@@ -2,6 +2,7 @@
#include "git2/merge.h"
#include "buffer.h"
#include "merge.h"
+#include "index.h"
#include "../merge_helpers.h"
#include "posix.h"
@@ -231,9 +232,20 @@ static int merge_differently_filtered_files(char *files[])
cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL));
+ /* Emulate checkout with a broken or misconfigured filter: modify some
+ * files on-disk and then update the index with the updated file size
+ * and time, as if some filter applied them. These files should not be
+ * treated as dirty since we created them.
+ *
+ * (Make sure to update the index stamp to defeat racy-git protections
+ * trying to sanity check the files in the index; those would rehash the
+ * files, showing them as dirty, the exact mechanism we're trying to avoid.)
+ */
+
write_files(files);
hack_index(files);
+ repo_index->stamp.mtime = time(NULL) + 1;
cl_git_pass(git_index_write(repo_index));
error = merge_branch();
diff --git a/tests/status/worktree.c b/tests/status/worktree.c
index 3b18ae6c0..f8d1f7f54 100644
--- a/tests/status/worktree.c
+++ b/tests/status/worktree.c
@@ -6,6 +6,7 @@
#include "util.h"
#include "path.h"
#include "../diff/diff_helpers.h"
+#include "../checkout/checkout_helpers.h"
#include "git2/sys/diff.h"
/**
@@ -956,6 +957,7 @@ void test_status_worktree__update_stat_cache_0(void)
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
git_status_list *status;
git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT;
+ git_index *index;
opts.flags = GIT_STATUS_OPT_DEFAULTS;
@@ -967,6 +969,10 @@ void test_status_worktree__update_stat_cache_0(void)
git_status_list_free(status);
+ /* tick the index so we avoid recalculating racily-clean entries */
+ cl_git_pass(git_repository_index__weakptr(&index, repo));
+ tick_index(index);
+
opts.flags |= GIT_STATUS_OPT_UPDATE_INDEX;
cl_git_pass(git_status_list_new(&status, repo, &opts));