Commit 956f4da897aa0eec3f66f00cb7a4a47914c24059

Edward Thomson 2015-11-13T16:30:39

index: test for smudged entries on write only Test that entries are only smudged when we write the index: the entry smudging is to prevent us from updating an index in a way that it would be impossible to tell that an item was racy. Consider when we load an index: any entries that have the same (or newer) timestamp than the index itself are considered racy, and are subject to further scrutiny. If we *save* that index with the same entries that we loaded, then the index would now have a newer timestamp than the entries, and they would no longer be given that additional scrutiny, failing our racy detection! So test that we smudge those entries only on writing the new index, but that we can detect them (in diff) without having to write.

diff --git a/tests/index/racy.c b/tests/index/racy.c
index 6ff12a3..fc48f07 100644
--- a/tests/index/racy.c
+++ b/tests/index/racy.c
@@ -100,13 +100,13 @@ void test_index_racy__write_index_just_after_file(void)
 	git_index_free(index);
 }
 
-void test_index_racy__empty_file_after_smudge(void)
+
+static void setup_race(void)
 {
-	git_index *index;
-	git_diff *diff;
 	git_buf path = GIT_BUF_INIT;
-	int i, found_race = 0;
+	git_index *index;
 	const git_index_entry *entry;
+	int i, found_race = 0;
 
 	/* Make sure we do have a timestamp */
 	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
@@ -131,18 +131,46 @@ void test_index_racy__empty_file_after_smudge(void)
 			found_race = 1;
 			break;
 		}
-
 	}
 
 	if (!found_race)
 		cl_fail("failed to find race after 10 attempts");
 
+	git_buf_free(&path);
+}
+
+void test_index_racy__smudges_index_entry_on_save(void)
+{
+	git_index *index;
+	const git_index_entry *entry;
+
+	setup_race();
+
+	/* write the index, which will smudge anything that had the same timestamp
+	 * as the index when the index was loaded.  that way future loads of the
+	 * index (with the new timestamp) will know that these files were not
+	 * clean.
+	 */
+
+	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
+	cl_git_pass(git_index_write(index));
+
+	cl_assert(entry = git_index_get_bypath(index, "A", 0));
 	cl_assert_equal_i(0, entry->file_size);
+}
+
+void test_index_racy__detects_diff_of_change_in_identical_timestamp(void)
+{
+	git_index *index;
+	git_diff *diff;
+
+	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
+
+	setup_race();
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
 	cl_assert_equal_i(1, git_diff_num_deltas(diff));
 
-	git_buf_free(&path);
 	git_diff_free(diff);
 }
 
@@ -204,7 +232,7 @@ void test_index_racy__reading_clears_uptodate_bit(void)
 	const git_index_entry *entry;
 
 	setup_uptodate_files();
-	
+
 	cl_git_pass(git_repository_index(&index, g_repo));
 	cl_git_pass(git_index_write(index));