diff options
| author | Carlos Martín Nieto <cmn@dwim.me> | 2015-06-17 08:15:49 +0200 |
|---|---|---|
| committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-06-17 08:15:49 +0200 |
| commit | a56db99234017eb7814258dfe8bcdec365417a3b (patch) | |
| tree | ba49074368a7d9b6dff87e8a6540e8137b29d4b9 /tests | |
| parent | 5f83758fa35a7942457d676e41240dbfbda598b5 (diff) | |
| parent | 892abf93157ea576fc3f2ccac118045a6a47247c (diff) | |
| download | libgit2-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.c | 22 | ||||
| -rw-r--r-- | tests/checkout/checkout_helpers.h | 2 | ||||
| -rw-r--r-- | tests/checkout/crlf.c | 11 | ||||
| -rw-r--r-- | tests/core/posix.c | 49 | ||||
| -rw-r--r-- | tests/diff/racy.c | 39 | ||||
| -rw-r--r-- | tests/diff/workdir.c | 6 | ||||
| -rw-r--r-- | tests/merge/workdir/dirty.c | 12 | ||||
| -rw-r--r-- | tests/status/worktree.c | 6 |
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)); |
