You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/02/04 21:48:13 UTC
svn commit: r1442344 [36/39] - in /subversion/branches/fsfs-format7: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/win32/ contrib/client-side/emacs/
contrib/server-side/fsfsfixer/fixer/ contrib/server-side/svncutter/ doc/...
Modified: subversion/branches/fsfs-format7/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/fsfs-format7/subversion/tests/libsvn_diff/diff-diff3-test.c Mon Feb 4 20:48:05 2013
@@ -76,16 +76,14 @@ make_random_file(const char *filename,
apr_pool_t *pool)
{
apr_file_t *file;
- apr_status_t status;
int num_lines;
num_lines = range_rand(min_lines, max_lines);
- status = apr_file_open(&file, filename,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", filename);
+ SVN_ERR(svn_io_file_open(&file, filename,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT,
+ pool));
while (num_lines--)
{
@@ -100,9 +98,7 @@ make_random_file(const char *filename,
apr_file_printf(file, "line %d line %d line %d", x, x, x);
}
- status = apr_file_close(file);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", filename);
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -117,19 +113,15 @@ make_file(const char *filename,
apr_file_t *file;
apr_status_t status;
- status = apr_file_open(&file, filename,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", filename);
+ SVN_ERR(svn_io_file_open(&file, filename,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
status = apr_file_write_full(file, contents, strlen(contents), NULL);
if (status)
return svn_error_createf(status, NULL, "failed to write '%s'", filename);
- status = apr_file_close(file);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", filename);
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -159,7 +151,6 @@ three_way_merge(const char *filename1,
svn_diff_t *diff;
apr_file_t *output;
svn_stream_t *ostream;
- apr_status_t status;
svn_stringbuf_t *actual;
char *merge_name = apr_psprintf(pool, "merge-%s-%s-%s",
filename1, filename2, filename3);
@@ -199,34 +190,29 @@ three_way_merge(const char *filename1,
SVN_ERR(svn_diff_file_diff3_2(&diff, filename1, filename2, filename3,
options, pool));
- status = apr_file_open(&output, merge_name,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", merge_name);
+ SVN_ERR(svn_io_file_open(&output, merge_name,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
- ostream = svn_stream_from_aprfile(output, pool);
+ ostream = svn_stream_from_aprfile2(output, FALSE, pool);
SVN_ERR(svn_diff_file_output_merge2(ostream, diff,
filename1, filename2, filename3,
NULL, NULL, NULL, NULL,
style,
pool));
SVN_ERR(svn_stream_close(ostream));
- status = apr_file_close(output);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", merge_name);
- SVN_ERR(svn_stringbuf_from_file(&actual, merge_name, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&actual, merge_name, pool));
if (strcmp(actual->data, expected))
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
"failed merging diff '%s' to '%s' into '%s'",
filename1, filename2, filename3);
- SVN_ERR(svn_io_remove_file(filename1, pool));
+ SVN_ERR(svn_io_remove_file2(filename1, TRUE, pool));
if (strcmp(filename1, filename2))
- SVN_ERR(svn_io_remove_file(filename2, pool));
+ SVN_ERR(svn_io_remove_file2(filename2, TRUE, pool));
if (strcmp(filename1, filename3) && strcmp(filename2, filename3))
- SVN_ERR(svn_io_remove_file(filename3, pool));
- SVN_ERR(svn_io_remove_file(merge_name, pool));
+ SVN_ERR(svn_io_remove_file2(filename3, TRUE, pool));
+ SVN_ERR(svn_io_remove_file2(merge_name, TRUE, pool));
return SVN_NO_ERROR;
}
@@ -252,7 +238,6 @@ two_way_diff(const char *filename1,
svn_diff_t *diff;
apr_file_t *output;
svn_stream_t *ostream;
- apr_status_t status;
svn_stringbuf_t *actual;
char *diff_name = apr_psprintf(pool, "diff-%s-%s", filename1, filename2);
@@ -285,27 +270,42 @@ two_way_diff(const char *filename1,
/* Check that two-way diff between contents1 and contents2 produces
expected output. */
SVN_ERR(svn_diff_file_diff_2(&diff, filename1, filename2, options, pool));
- status = apr_file_open(&output, diff_name,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", diff_name);
- ostream = svn_stream_from_aprfile(output, pool);
+ SVN_ERR(svn_io_file_open(&output, diff_name,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
+
+ ostream = svn_stream_from_aprfile2(output, FALSE, pool);
SVN_ERR(svn_diff_file_output_unified2(ostream, diff,
filename1, filename2,
filename1, filename2,
SVN_APR_LOCALE_CHARSET, pool));
SVN_ERR(svn_stream_close(ostream));
- status = apr_file_close(output);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", diff_name);
- SVN_ERR(svn_stringbuf_from_file(&actual, diff_name, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&actual, diff_name, pool));
if (strcmp(actual->data, expected))
- return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
- "failed comparing '%s' and '%s'",
- filename1, filename2);
+ {
+ /*svn_stringbuf_t *dump_actual;
+ svn_stream_t *dump_ostream;
+ dump_actual = svn_stringbuf_create_empty(pool);
+ dump_ostream = svn_stream_from_stringbuf(dump_actual, pool);
+
+ SVN_ERR(svn_diff_mem_string_output_unified(dump_ostream, diff,
+ "expected", "actual",
+ SVN_APR_LOCALE_CHARSET,
+ svn_string_create(expected, pool),
+ svn_string_create(actual->data, pool),
+ pool));
+ SVN_ERR(svn_stream_close(ostream));
+
+ SVN_DBG(("%s\n", dump_actual->data));
+
+ SVN_ERR(make_file("memory", expected, pool));*/
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "failed comparing '%s' and '%s'"
+ " (memory and file results are different)",
+ filename1, filename2);
+ }
/* May as well do the trivial merges while we are here */
SVN_ERR(three_way_merge(filename1, filename2, filename1,
@@ -317,7 +317,7 @@ two_way_diff(const char *filename1,
svn_diff_conflict_display_modified_latest,
pool));
- SVN_ERR(svn_io_remove_file(diff_name, pool));
+ SVN_ERR(svn_io_remove_file2(diff_name, TRUE, pool));
return SVN_NO_ERROR;
}
@@ -373,14 +373,11 @@ make_random_merge_file(const char *filen
apr_pool_t *pool)
{
apr_file_t *file;
- apr_status_t status;
int i;
- status = apr_file_open(&file, filename,
- APR_WRITE | APR_CREATE | APR_TRUNCATE, APR_OS_DEFAULT,
- pool);
- if (status)
- return svn_error_createf(status, NULL, "failed to open '%s'", filename);
+ SVN_ERR(svn_io_file_open(&file, filename,
+ APR_WRITE | APR_CREATE | APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
for (i = 0; i < num_lines; ++i)
{
@@ -413,9 +410,7 @@ make_random_merge_file(const char *filen
}
}
- status = apr_file_close(file);
- if (status)
- return svn_error_createf(status, NULL, "failed to close '%s'", filename);
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -2193,8 +2188,8 @@ random_trivial_merge(apr_pool_t *pool)
min_lines, max_lines, var_lines, block_lines,
i % 2, subpool));
- SVN_ERR(svn_stringbuf_from_file(&contents1, filename1, subpool));
- SVN_ERR(svn_stringbuf_from_file(&contents2, filename2, subpool));
+ SVN_ERR(svn_stringbuf_from_file2(&contents1, filename1, subpool));
+ SVN_ERR(svn_stringbuf_from_file2(&contents2, filename2, subpool));
SVN_ERR(three_way_merge(filename1, filename2, filename1,
contents1->data, contents2->data,
@@ -2262,10 +2257,10 @@ random_three_way_merge(apr_pool_t *pool)
SVN_ERR(make_random_merge_file(filename4, num_lines, mrg_lines,
num_src + num_dst, pool));
- SVN_ERR(svn_stringbuf_from_file(&original, filename1, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified1, filename2, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified2, filename3, pool));
- SVN_ERR(svn_stringbuf_from_file(&combined, filename4, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&original, filename1, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified1, filename2, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified2, filename3, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&combined, filename4, pool));
SVN_ERR(three_way_merge(filename1, filename2, filename3,
original->data, modified1->data,
@@ -2278,7 +2273,7 @@ random_three_way_merge(apr_pool_t *pool)
svn_diff_conflict_display_modified_latest,
subpool));
- SVN_ERR(svn_io_remove_file(filename4, pool));
+ SVN_ERR(svn_io_remove_file2(filename4, TRUE, pool));
svn_pool_clear(subpool);
}
@@ -2335,10 +2330,10 @@ merge_with_part_already_present(apr_pool
SVN_ERR(make_random_merge_file(filename4, num_lines, mrg_lines,
num_src + num_dst / 2, pool));
- SVN_ERR(svn_stringbuf_from_file(&original, filename1, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified1, filename2, pool));
- SVN_ERR(svn_stringbuf_from_file(&modified2, filename3, pool));
- SVN_ERR(svn_stringbuf_from_file(&combined, filename4, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&original, filename1, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified1, filename2, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&modified2, filename3, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&combined, filename4, pool));
SVN_ERR(three_way_merge(filename1, filename2, filename3,
original->data, modified1->data,
@@ -2351,7 +2346,7 @@ merge_with_part_already_present(apr_pool
svn_diff_conflict_display_modified_latest,
subpool));
- SVN_ERR(svn_io_remove_file(filename4, pool));
+ SVN_ERR(svn_io_remove_file2(filename4, TRUE, pool));
svn_pool_clear(subpool);
}
@@ -2394,37 +2389,484 @@ merge_adjacent_changes(apr_pool_t *pool)
return SVN_NO_ERROR;
}
-/* Issue #4133, '"diff -x -w" showing wrong change'.
+/* Issue #4133, 'When sequences of whitespace characters at head of line
+ strides chunk boundary, "diff -x -w" showing wrong change'.
The magic number used in this test, 1<<17, is
CHUNK_SIZE from ../../libsvn_diff/diff_file.c
*/
static svn_error_t *
-test_wrap(apr_pool_t *pool)
+test_norm_offset(apr_pool_t *pool)
{
- char ldata[(1<<17) + 4+4+3+1];
- char rdata[(1<<17) + 4+3+3+1];
- svn_string_t left, right;
+ apr_size_t chunk_size = 1 << 17;
+ const char *pattern1 = " \n";
+ const char *pattern2 = "\n\n\n\n\n\n\n\n";
+ const char *pattern3 = " @@@@@@@\n";
+ const char *pattern4 = " \n";
+ svn_stringbuf_t *original, *modified;
svn_diff_file_options_t *diff_opts = svn_diff_file_options_create(pool);
- diff_opts->ignore_space = svn_diff_file_ignore_space_change;
- /* Two long lines. */
- memset(ldata, '@', 1<<17);
- memset(rdata, '@', 1<<17);
- strcpy(&ldata[1<<17], "foo\n" "ba \n" "x \n");
- strcpy(&rdata[1<<17], "foo\n" "ba\n" "x\t\n");
-
- /* Cast them to svn_string_t. */
- left.data = ldata;
- right.data = rdata;
- left.len = sizeof(ldata)-1;
- right.len = sizeof(rdata)-1;
+ /* The original contents become like this
+
+ $ hexdump -C norm-offset-original
+ 00000000 20 20 20 20 20 20 20 0a 0a 0a 0a 0a 0a 0a 0a 0a | .........|
+ 00000010 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a |................|
+ *
+ 0001fff0 0a 0a 0a 0a 0a 0a 0a 0a 20 20 20 20 20 20 20 20 |........ |
+ 00020000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
+ 00020010 40 40 40 40 40 40 40 0a 0a 0a 0a 0a 0a 0a 0a 0a |@@@@@@@.........|
+ 00020020 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a |................|
+ *
+ 000203f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0a | .|
+ 00020400
+ */
+ original = svn_stringbuf_create_ensure(chunk_size + 1024, pool);
+ svn_stringbuf_appendcstr(original, pattern1);
+ while (original->len < chunk_size - 8)
+ {
+ svn_stringbuf_appendcstr(original, pattern2);
+ }
+ svn_stringbuf_appendcstr(original, pattern3);
+ while (original->len < chunk_size +1024 - 16)
+ {
+ svn_stringbuf_appendcstr(original, pattern2);
+ }
+ svn_stringbuf_appendcstr(original, pattern4);
+
+ /* The modified contents become like this.
+
+ $ hexdump -C norm-offset-modified
+ 00000000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0a | .|
+ 00000010 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a |................|
+ *
+ 00020000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
+ 00020010 20 20 20 20 20 20 20 20 40 40 40 40 40 40 40 0a | @@@@@@@.|
+ 00020020 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a |................|
+ *
+ 000203f0 0a 0a 0a 0a 0a 0a 0a 0a 20 20 20 20 20 20 20 0a |........ .|
+ 00020400
+ */
+ modified = svn_stringbuf_create_ensure(chunk_size + 1024, pool);
+ svn_stringbuf_appendcstr(modified, pattern4);
+ while (modified->len < chunk_size)
+ {
+ svn_stringbuf_appendcstr(modified, pattern2);
+ }
+ svn_stringbuf_appendcstr(modified, pattern3);
+ while (modified->len < chunk_size +1024 - 8)
+ {
+ svn_stringbuf_appendcstr(modified, pattern2);
+ }
+ svn_stringbuf_appendcstr(modified, pattern1);
/* Diff them. Modulo whitespace, they are identical. */
- {
- svn_diff_t *diff;
- SVN_ERR(svn_diff_mem_string_diff(&diff, &left, &right, diff_opts, pool));
- SVN_TEST_ASSERT(FALSE == svn_diff_contains_diffs(diff));
- }
+ diff_opts->ignore_space = svn_diff_file_ignore_space_all;
+ SVN_ERR(two_way_diff("norm-offset-original", "norm-offset-modified",
+ original->data, modified->data, "",
+ diff_opts, pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Issue #4283, 'When identical suffix started at a chunk boundary,
+ incorrect diff was generated'.
+ The magic number used in this test, (1<<17) and 50 are CHUNK_SIZE
+ and SUFFIX_LINES_TO_KEEP from ../../libsvn_diff/diff_file.c, respectively.
+ */
+#define ORIGINAL_CONTENTS_PATTERN "0123456789abcde\n"
+#define INSERTED_LINE "0123456789ABCDE\n"
+static svn_error_t *
+test_identical_suffix(apr_pool_t *pool)
+{
+ apr_size_t lines_in_chunk = (1 << 17)
+ / (sizeof(ORIGINAL_CONTENTS_PATTERN) - 1);
+ /* To let identical suffix start at a chunk boundary,
+ insert a line at before (SUFFIX_LINES_TO_KEEP + 1) lines
+ from tail of the previous chunk. */
+ apr_size_t insert_pos = lines_in_chunk
+#ifdef SUFFIX_LINES_TO_KEEP
+ - SUFFIX_LINES_TO_KEEP
+#else
+ - 50
+#endif
+ - 1;
+ apr_size_t i;
+ svn_stringbuf_t *original, *modified;
+
+ /* The original contents become like this.
+
+ $ hexdump -C identical-suffix-original
+ 00000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 0a |0123456789abcde.|
+ *
+ 00020400
+ */
+ original = svn_stringbuf_create_ensure((1 << 17) + 1024, pool);
+ for (i = 0; i < lines_in_chunk + 64; i++)
+ {
+ svn_stringbuf_appendbytes(original, ORIGINAL_CONTENTS_PATTERN,
+ sizeof(ORIGINAL_CONTENTS_PATTERN) - 1);
+ }
+
+ /* The modified contents become like this.
+
+ $ hexdump -C identical-suffix-modified
+ 00000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 0a |0123456789abcde.|
+ *
+ 00000400 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 0a |0123456789ABCDE.|
+ 00000410 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 0a |0123456789abcde.|
+ *
+ 0001fcd0 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 0a |0123456789ABCDE.|
+ 0001fce0 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 0a |0123456789abcde.|
+ *
+ 00020420
+ */
+ modified = svn_stringbuf_dup(original, pool);
+ svn_stringbuf_insert(modified,
+ 64 * (sizeof(ORIGINAL_CONTENTS_PATTERN) - 1),
+ INSERTED_LINE, sizeof(INSERTED_LINE) - 1);
+ svn_stringbuf_insert(modified,
+ insert_pos * (sizeof(ORIGINAL_CONTENTS_PATTERN) - 1),
+ INSERTED_LINE, sizeof(INSERTED_LINE) - 1);
+
+ SVN_ERR(two_way_diff("identical-suffix-original",
+ "identical-suffix-modified",
+ original->data, modified->data,
+ apr_psprintf(pool,
+ "--- identical-suffix-original" NL
+ "+++ identical-suffix-modified" NL
+ "@@ -62,6 +62,7 @@" NL
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN
+ "+" INSERTED_LINE
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN
+ "@@ -%u,6 +%u,7 @@" NL
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN
+ "+" INSERTED_LINE
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN
+ " " ORIGINAL_CONTENTS_PATTERN,
+ 1 + (unsigned int)insert_pos - 3 - 1,
+ 1 + (unsigned int)insert_pos - 3),
+ NULL, pool));
+
+ return SVN_NO_ERROR;
+}
+#undef ORIGINAL_CONTENTS_PATTERN
+#undef INSERTED_LINE
+
+/* The magic number used in this test, 1<<17, is
+ CHUNK_SIZE from ../../libsvn_diff/diff_file.c
+ */
+static svn_error_t *
+test_token_compare(apr_pool_t *pool)
+{
+ apr_size_t chunk_size = 1 << 17;
+ const char *pattern = "\n\n\n\n\n\n\n\n";
+ svn_stringbuf_t *original, *modified;
+ svn_diff_file_options_t *diff_opts = svn_diff_file_options_create(pool);
+
+ diff_opts->ignore_space = svn_diff_file_ignore_space_all;
+
+ original = svn_stringbuf_create_ensure(chunk_size, pool);
+ while (original->len < chunk_size - 8)
+ {
+ svn_stringbuf_appendcstr(original, pattern);
+ }
+ svn_stringbuf_appendcstr(original, " @@@\n");
+
+ modified = svn_stringbuf_create_ensure(chunk_size, pool);
+ while (modified->len < chunk_size - 8)
+ {
+ svn_stringbuf_appendcstr(modified, pattern);
+ }
+ svn_stringbuf_appendcstr(modified, " @@@\n");
+
+ /* regression test for reading exceeding the file size */
+ SVN_ERR(two_way_diff("token-compare-original1", "token-compare-modified1",
+ original->data, modified->data, "",
+ diff_opts, pool));
+
+ svn_stringbuf_appendcstr(original, "aaaaaaa\n");
+ svn_stringbuf_appendcstr(modified, "bbbbbbb\n");
+
+ /* regression test for comparison beyond the end-of-line */
+ SVN_ERR(two_way_diff("token-compare-original2", "token-compare-modified2",
+ original->data, modified->data,
+ apr_psprintf(pool,
+ "--- token-compare-original2" NL
+ "+++ token-compare-modified2" NL
+ "@@ -%u,4 +%u,4 @@" NL
+ " \n"
+ " \n"
+ " @@@\n"
+ "-aaaaaaa\n"
+ "+bbbbbbb\n",
+ 1 +(unsigned int)chunk_size - 8 + 1 - 3,
+ 1 +(unsigned int)chunk_size - 8 + 1 - 3),
+ diff_opts, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+two_way_issue_3362_v1(apr_pool_t *pool)
+{
+ svn_diff_file_options_t *diff_opts = svn_diff_file_options_create(pool);
+
+ SVN_ERR(two_way_diff("issue-3362-1-v1",
+ "issue-3362-2-v1",
+ /* File 1 */
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5\n"
+ "line_6\n"
+ "line_7\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27\n"
+ "line_28\n"
+ "line_29\n"
+ "line_30\n",
+ /* File 2 */
+ "line_1a\n"
+ "line_2a\n"
+ "line_3a\n"
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5a\n"
+ "line_6b\n"
+ "line_7c\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11a\n"
+ "line_11b\n"
+ "line_11c\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19a\n"
+ "line_19b\n"
+ "line_19c\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27\n"
+ "line_27a\n",
+ /* Expected */
+ "--- issue-3362-1-v1" APR_EOL_STR
+ "+++ issue-3362-2-v1" APR_EOL_STR
+ "@@ -1,14 +1,19 @@" APR_EOL_STR
+ "+line_1a\n"
+ "+line_2a\n"
+ "+line_3a\n"
+ " line_1\n" /* 1.7 mem diff: line missing */
+ " line_2\n"
+ " line_3\n"
+ " line_4\n"
+ "-line_5\n"
+ "-line_6\n"
+ "-line_7\n"
+ "+line_5a\n"
+ "+line_6b\n"
+ "+line_7c\n"
+ " line_8\n"
+ " line_9\n"
+ " line_10\n"
+ "-line_11\n"
+ "+line_11a\n"
+ "+line_11b\n"
+ "+line_11c\n"
+ " line_12\n"
+ " line_13\n"
+ " line_14\n" /* 1.7 mem diff: line missing */
+ "@@ -16,7 +21,9 @@" APR_EOL_STR
+ " line_16\n"
+ " line_17\n"
+ " line_18\n"
+ "-line_19\n"
+ "+line_19a\n"
+ "+line_19b\n"
+ "+line_19c\n"
+ " line_20\n"
+ " line_21\n"
+ " line_22\n"
+ "@@ -25,6 +32,4 @@" APR_EOL_STR
+ " line_25\n"
+ " line_26\n"
+ " line_27\n"
+ "-line_28\n"
+ "-line_29\n"
+ "-line_30\n"
+ "+line_27a\n",
+ diff_opts, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+two_way_issue_3362_v2(apr_pool_t *pool)
+{
+ svn_diff_file_options_t *diff_opts = svn_diff_file_options_create(pool);
+
+ SVN_ERR(two_way_diff("issue-3362-1-v2",
+ "issue-3362-2-v2",
+ /* File 1 */
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5\n"
+ "line_6\n"
+ "line_7\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27\n"
+ "line_28\n"
+ "line_29\n"
+ "line_30\n",
+ /* File 2 */
+ "line_1a\n"
+ "line_1b\n"
+ "line_1c\n"
+ "line_1\n"
+ "line_2\n"
+ "line_3\n"
+ "line_4\n"
+ "line_5a\n"
+ "line_5b\n"
+ "line_5c\n"
+ "line_6\n"
+ "line_7\n"
+ "line_8\n"
+ "line_9\n"
+ "line_10\n"
+ "line_11a\n"
+ "line_11b\n"
+ "line_11c\n"
+ "line_12\n"
+ "line_13\n"
+ "line_14\n"
+ "line_15\n"
+ "line_16\n"
+ "line_17\n"
+ "line_18\n"
+ "line_19a\n"
+ "line_19b\n"
+ "line_19c\n"
+ "line_20\n"
+ "line_21\n"
+ "line_22\n"
+ "line_23\n"
+ "line_24\n"
+ "line_25\n"
+ "line_26\n"
+ "line_27a\n"
+ "line_27b\n"
+ "line_27c\n"
+ "line_28\n"
+ "line_29\n"
+ "line_30\n",
+ /* Expected */
+ "--- issue-3362-1-v2" APR_EOL_STR
+ "+++ issue-3362-2-v2" APR_EOL_STR
+ "@@ -1,14 +1,21 @@" APR_EOL_STR
+ "+line_1a\n"
+ "+line_1b\n"
+ "+line_1c\n"
+ " line_1\n" /* 1.7 mem diff: line missing */
+ " line_2\n"
+ " line_3\n"
+ " line_4\n"
+ "-line_5\n"
+ "+line_5a\n"
+ "+line_5b\n"
+ "+line_5c\n"
+ " line_6\n"
+ " line_7\n"
+ " line_8\n"
+ " line_9\n"
+ " line_10\n"
+ "-line_11\n"
+ "+line_11a\n"
+ "+line_11b\n"
+ "+line_11c\n"
+ " line_12\n"
+ " line_13\n"
+ " line_14\n" /* 1.7 mem diff: line missing */
+ "@@ -16,7 +23,9 @@" APR_EOL_STR
+ " line_16\n"
+ " line_17\n"
+ " line_18\n"
+ "-line_19\n"
+ "+line_19a\n"
+ "+line_19b\n"
+ "+line_19c\n"
+ " line_20\n"
+ " line_21\n"
+ " line_22\n"
+ "@@ -24,7 +33,9 @@" APR_EOL_STR
+ " line_24\n"
+ " line_25\n"
+ " line_26\n"
+ "-line_27\n"
+ "+line_27a\n"
+ "+line_27b\n"
+ "+line_27c\n"
+ " line_28\n"
+ " line_29\n"
+ " line_30\n",
+ diff_opts, pool));
return SVN_NO_ERROR;
}
@@ -2458,7 +2900,15 @@ struct svn_test_descriptor_t test_funcs[
"3-way merge with conflict styles"),
SVN_TEST_PASS2(test_diff4,
"4-way merge; see variance-adjusted-patching.html"),
- SVN_TEST_XFAIL2(test_wrap,
- "difference at the start of a 128KB window"),
+ SVN_TEST_PASS2(test_norm_offset,
+ "offset of the normalized token"),
+ SVN_TEST_PASS2(test_identical_suffix,
+ "identical suffix starts at the boundary of a chunk"),
+ SVN_TEST_PASS2(test_token_compare,
+ "compare tokes at the chunk boundary"),
+ SVN_TEST_PASS2(two_way_issue_3362_v1,
+ "2-way issue #3362 test v1"),
+ SVN_TEST_PASS2(two_way_issue_3362_v2,
+ "2-way issue #3362 test v2"),
SVN_TEST_NULL
};
Modified: subversion/branches/fsfs-format7/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/libsvn_fs/fs-test.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/fsfs-format7/subversion/tests/libsvn_fs/fs-test.c Mon Feb 4 20:48:05 2013
@@ -1566,6 +1566,7 @@ merging_commit(const svn_test_opts_t *op
/* (5) E doesn't exist in ANCESTOR, and has been added to A. */
{
+ svn_revnum_t failed_rev;
/* (1) E doesn't exist in ANCESTOR, and has been added to B.
Conflict. */
SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[4], pool));
@@ -1573,7 +1574,7 @@ merging_commit(const svn_test_opts_t *op
SVN_ERR(svn_fs_make_file(txn_root, "theta", pool));
SVN_ERR(svn_test__set_file_contents
(txn_root, "theta", "This is another file 'theta'.\n", pool));
- SVN_ERR(test_commit_txn(&after_rev, txn, "/theta", pool));
+ SVN_ERR(test_commit_txn(&failed_rev, txn, "/theta", pool));
SVN_ERR(svn_fs_abort_txn(txn, pool));
/* (1) E exists in ANCESTOR, but has been deleted from B. Can't
@@ -1581,6 +1582,8 @@ merging_commit(const svn_test_opts_t *op
/* (3) E exists in both ANCESTOR and B. Can't occur, by assumption
that E doesn't exist in ANCESTOR. */
+
+ SVN_TEST_ASSERT(failed_rev == SVN_INVALID_REVNUM);
}
/* (4) E exists in ANCESTOR, but has been deleted from A */
@@ -1594,15 +1597,16 @@ merging_commit(const svn_test_opts_t *op
SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
SVN_ERR(svn_fs_delete(txn_root, "A/D/H", pool));
- /* ### FIXME: It is at this point that our test stops being valid,
- ### hence its expected failure. The following call will now
- ### conflict on /A/D/H, causing revision 6 *not* to be created,
- ### and the remainer of this test (which was written long ago)
- ### to suffer from a shift in the expected state and behavior
- ### of the filesystem as a result of this commit not happening.
- */
+ /* We used to create the revision like this before fixing issue
+ #2751 -- Directory prop mods reverted in overlapping commits scenario.
- SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
+ But we now expect that to fail as out of date */
+ {
+ svn_revnum_t failed_rev;
+ SVN_ERR(test_commit_txn(&failed_rev, txn, "/A/D/H", pool));
+
+ SVN_TEST_ASSERT(failed_rev == SVN_INVALID_REVNUM);
+ }
/*********************************************************************/
/* REVISION 6 */
/*********************************************************************/
@@ -1640,18 +1644,22 @@ merging_commit(const svn_test_opts_t *op
/* Try deleting a file F inside a subtree S where S does not exist
in the most recent revision, but does exist in the ancestor
tree. This should conflict. */
- SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
- SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
- SVN_ERR(svn_fs_delete(txn_root, "A/D/H/omega", pool));
- SVN_ERR(test_commit_txn(&after_rev, txn, "/A/D/H", pool));
- SVN_ERR(svn_fs_abort_txn(txn, pool));
+ {
+ svn_revnum_t failed_rev;
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_delete(txn_root, "A/D/H/omega", pool));
+ SVN_ERR(test_commit_txn(&failed_rev, txn, "/A/D/H", pool));
+ SVN_ERR(svn_fs_abort_txn(txn, pool));
+
+ SVN_TEST_ASSERT(failed_rev == SVN_INVALID_REVNUM);
+ }
/* E exists in both ANCESTOR and B ... */
{
/* (1) but refers to different nodes. Conflict. */
- SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
- SVN_ERR(svn_fs_delete(txn_root, "A/D/H", pool));
SVN_ERR(svn_fs_make_dir(txn_root, "A/D/H", pool));
SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
revisions[revision_count++] = after_rev;
@@ -4969,10 +4977,7 @@ struct svn_test_descriptor_t test_funcs[
"basic commit"),
SVN_TEST_OPTS_PASS(test_tree_node_validation,
"testing tree validation helper"),
- SVN_TEST_OPTS_WIMP(merging_commit,
- "merging commit",
- "needs to be written to match new"
- " merge() algorithm expectations"),
+ SVN_TEST_OPTS_PASS(merging_commit, "merging commit"),
SVN_TEST_OPTS_PASS(copy_test,
"copying and tracking copy history"),
SVN_TEST_OPTS_PASS(commit_date,
Propchange: subversion/branches/fsfs-format7/subversion/tests/libsvn_ra/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Feb 4 20:48:05 2013
@@ -0,0 +1,4 @@
+*.lo
+.libs
+ra-test
+test-repo-*
Modified: subversion/branches/fsfs-format7/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/libsvn_repos/repos-test.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/fsfs-format7/subversion/tests/libsvn_repos/repos-test.c Mon Feb 4 20:48:05 2013
@@ -1123,30 +1123,104 @@ rmlocks(const svn_test_opts_t *opts,
/* Helper for the authz test. Set *AUTHZ_P to a representation of
- AUTHZ_CONTENTS, using POOL for temporary allocation. */
+ AUTHZ_CONTENTS, using POOL for temporary allocation. If DISK
+ is TRUE then write the contents to a temp file and use
+ svn_repos_authz_read() to get the data if FALSE write the
+ data to a buffered stream and use svn_repos_authz_parse(). */
static svn_error_t *
authz_get_handle(svn_authz_t **authz_p, const char *authz_contents,
- apr_pool_t *pool)
+ svn_boolean_t disk, apr_pool_t *pool)
{
- const char *authz_file_path;
+ if (disk)
+ {
+ const char *authz_file_path;
+
+ /* Create a temporary file. */
+ SVN_ERR_W(svn_io_write_unique(&authz_file_path, NULL,
+ authz_contents, strlen(authz_contents),
+ svn_io_file_del_on_pool_cleanup, pool),
+ "Writing temporary authz file");
+
+ /* Read the authz configuration back and start testing. */
+ SVN_ERR_W(svn_repos_authz_read(authz_p, authz_file_path, TRUE, pool),
+ "Opening test authz file");
+
+ /* Done with the file. */
+ SVN_ERR_W(svn_io_remove_file(authz_file_path, pool),
+ "Removing test authz file");
+ }
+ else
+ {
+ svn_stream_t *stream;
- /* Create a temporary file. */
- SVN_ERR_W(svn_io_write_unique(&authz_file_path, NULL,
- authz_contents, strlen(authz_contents),
- svn_io_file_del_on_pool_cleanup, pool),
- "Writing temporary authz file");
-
- /* Read the authz configuration back and start testing. */
- SVN_ERR_W(svn_repos_authz_read(authz_p, authz_file_path, TRUE, pool),
- "Opening test authz file");
-
- /* Done with the file. */
- SVN_ERR_W(svn_io_remove_file(authz_file_path, pool),
- "Removing test authz file");
+ stream = svn_stream_buffered(pool);
+ SVN_ERR_W(svn_stream_puts(stream, authz_contents),
+ "Writing authz contents to stream");
+
+ SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, NULL, pool),
+ "Parsing the authz contents");
+
+ SVN_ERR_W(svn_stream_close(stream),
+ "Closing the stream");
+ }
return SVN_NO_ERROR;
}
+struct check_access_tests {
+ const char *path;
+ const char *repo_name;
+ const char *user;
+ const svn_repos_authz_access_t required;
+ const svn_boolean_t expected;
+};
+
+/* Helper for the authz test. Runs a set of tests against AUTHZ_CFG
+ * as defined in TESTS. */
+static svn_error_t *
+authz_check_access(svn_authz_t *authz_cfg,
+ const struct check_access_tests *tests,
+ apr_pool_t *pool)
+{
+ int i;
+ svn_boolean_t access_granted;
+
+ /* Loop over the test array and test each case. */
+ for (i = 0; !(tests[i].path == NULL
+ && tests[i].required == svn_authz_none); i++)
+ {
+ SVN_ERR(svn_repos_authz_check_access(authz_cfg,
+ tests[i].repo_name,
+ tests[i].path,
+ tests[i].user,
+ tests[i].required,
+ &access_granted, pool));
+
+ if (access_granted != tests[i].expected)
+ {
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Authz incorrectly %s %s%s access "
+ "to %s%s%s for user %s",
+ access_granted ?
+ "grants" : "denies",
+ tests[i].required
+ & svn_authz_recursive ?
+ "recursive " : "",
+ tests[i].required
+ & svn_authz_read ?
+ "read" : "write",
+ tests[i].repo_name ?
+ tests[i].repo_name : "",
+ tests[i].repo_name ?
+ ":" : "",
+ tests[i].path,
+ tests[i].user ?
+ tests[i].user : "-");
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
/* Test that authz is giving out the right authorizations. */
@@ -1158,36 +1232,30 @@ authz(apr_pool_t *pool)
svn_error_t *err;
svn_boolean_t access_granted;
apr_pool_t *subpool = svn_pool_create(pool);
- int i;
+
/* Definition of the paths to test and expected replies for each. */
- struct
- {
- const char *path;
- const char *user;
- const svn_repos_authz_access_t required;
- const svn_boolean_t expected;
- } test_set[] = {
+ struct check_access_tests test_set[] = {
/* Test that read rules are correctly used. */
- { "/A", NULL, svn_authz_read, TRUE },
- { "/iota", NULL, svn_authz_read, FALSE },
+ { "/A", "greek", NULL, svn_authz_read, TRUE },
+ { "/iota", "greek", NULL, svn_authz_read, FALSE },
/* Test that write rules are correctly used. */
- { "/A", "plato", svn_authz_write, TRUE },
- { "/A", NULL, svn_authz_write, FALSE },
+ { "/A", "greek", "plato", svn_authz_write, TRUE },
+ { "/A", "greek", NULL, svn_authz_write, FALSE },
/* Test that pan-repository rules are found and used. */
- { "/A/B/lambda", "plato", svn_authz_read, TRUE },
- { "/A/B/lambda", NULL, svn_authz_read, FALSE },
+ { "/A/B/lambda", "greek", "plato", svn_authz_read, TRUE },
+ { "/A/B/lambda", "greek", NULL, svn_authz_read, FALSE },
/* Test that authz uses parent path ACLs if no rule for the path
exists. */
- { "/A/C", NULL, svn_authz_read, TRUE },
+ { "/A/C", "greek", NULL, svn_authz_read, TRUE },
/* Test that recursive access requests take into account the rules
of subpaths. */
- { "/A/D", "plato", svn_authz_read | svn_authz_recursive, TRUE },
- { "/A/D", NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D", "greek", "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/A/D", "greek", NULL, svn_authz_read | svn_authz_recursive, FALSE },
/* Test global write access lookups. */
- { NULL, "plato", svn_authz_read, TRUE },
- { NULL, NULL, svn_authz_write, FALSE },
+ { NULL, "greek", "plato", svn_authz_read, TRUE },
+ { NULL, "greek", NULL, svn_authz_write, FALSE },
/* Sentinel */
- { NULL, NULL, svn_authz_none, FALSE }
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
};
/* The test logic:
@@ -1239,37 +1307,14 @@ authz(apr_pool_t *pool)
"" NL;
/* Load the test authz rules. */
- SVN_ERR(authz_get_handle(&authz_cfg, contents, subpool));
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, FALSE, subpool));
/* Loop over the test array and test each case. */
- for (i = 0; !(test_set[i].path == NULL
- && test_set[i].required == svn_authz_none); i++)
- {
- SVN_ERR(svn_repos_authz_check_access(authz_cfg, "greek",
- test_set[i].path,
- test_set[i].user,
- test_set[i].required,
- &access_granted, subpool));
-
- if (access_granted != test_set[i].expected)
- {
- return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
- "Authz incorrectly %s %s%s access "
- "to greek:%s for user %s",
- access_granted ?
- "grants" : "denies",
- test_set[i].required
- & svn_authz_recursive ?
- "recursive " : "",
- test_set[i].required
- & svn_authz_read ?
- "read" : "write",
- test_set[i].path,
- test_set[i].user ?
- test_set[i].user : "-");
- }
- }
+ SVN_ERR(authz_check_access(authz_cfg, test_set, subpool));
+ /* Repeat the previous test on disk */
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, TRUE, subpool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, subpool));
/* The authz rules for the phase 2 tests, first case (cyclic
dependency). */
@@ -1283,7 +1328,7 @@ authz(apr_pool_t *pool)
/* Load the test authz rules and check that group cycles are
reported. */
- err = authz_get_handle(&authz_cfg, contents, subpool);
+ err = authz_get_handle(&authz_cfg, contents, FALSE, subpool);
if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
return svn_error_createf(SVN_ERR_TEST_FAILED, err,
"Got %s error instead of expected "
@@ -1298,7 +1343,7 @@ authz(apr_pool_t *pool)
"@senate = r" NL;
/* Check that references to undefined groups are reported. */
- err = authz_get_handle(&authz_cfg, contents, subpool);
+ err = authz_get_handle(&authz_cfg, contents, FALSE, subpool);
if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
return svn_error_createf(SVN_ERR_TEST_FAILED, err,
"Got %s error instead of expected "
@@ -1315,7 +1360,7 @@ authz(apr_pool_t *pool)
"* =" NL;
/* Load the test authz rules. */
- SVN_ERR(authz_get_handle(&authz_cfg, contents, subpool));
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, FALSE, subpool));
/* Verify that the rule on /dir2/secret doesn't affect this
request */
@@ -1333,7 +1378,7 @@ authz(apr_pool_t *pool)
contents =
"[greek:/dir2//secret]" NL
"* =" NL;
- SVN_TEST_ASSERT_ERROR(authz_get_handle(&authz_cfg, contents, subpool),
+ SVN_TEST_ASSERT_ERROR(authz_get_handle(&authz_cfg, contents, FALSE, subpool),
SVN_ERR_AUTHZ_INVALID_CONFIG);
/* That's a wrap! */
@@ -1341,7 +1386,518 @@ authz(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+
+/* Test in-repo authz paths */
+static svn_error_t *
+in_repo_authz(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos;
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_revnum_t youngest_rev;
+ svn_authz_t *authz_cfg;
+ const char *authz_contents;
+ const char *repos_root;
+ const char *repos_url;
+ const char *authz_url;
+ svn_error_t *err;
+ struct check_access_tests test_set[] = {
+ /* reads */
+ { "/A", NULL, NULL, svn_authz_read, FALSE },
+ { "/A", NULL, "plato", svn_authz_read, TRUE },
+ { "/A", NULL, "socrates", svn_authz_read, TRUE },
+ /* writes */
+ { "/A", NULL, NULL, svn_authz_write, FALSE },
+ { "/A", NULL, "socrates", svn_authz_write, FALSE },
+ { "/A", NULL, "plato", svn_authz_write, TRUE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Test plan:
+ * Create an authz file and put it in the repository.
+ * Verify it can be read with an relative URL.
+ * Verify it can be read with an absolute URL.
+ * Verify non-existant path does not error out when must_exist is FALSE.
+ * Verify non-existant path does error out when must_exist is TRUE.
+ * Verify that an http:// URL produces an error.
+ * Verify that an svn:// URL produces an error.
+ */
+
+ /* What we'll put in the authz file, it's simple since we're not testing
+ * the parsing, just that we got what we expected. */
+ authz_contents =
+ "" NL
+ "" NL
+ "[/]" NL
+ "plato = rw" NL
+ "socrates = r";
+
+ /* Create a filesystem and repository. */
+ SVN_ERR(svn_test__create_repos(&repos, "test-repo-in-repo-authz",
+ opts, pool));
+ fs = svn_repos_fs(repos);
+
+ /* Commit the authz file to the repo. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "authz", pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "authz", authz_contents,
+ pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+ SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+
+ /* repos relative URL */
+ repos_root = svn_repos_path(repos, pool);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", NULL, TRUE,
+ repos_root, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* absolute file URL, repos_root is NULL to validate the contract that it
+ * is not needed except when a repos relative URL is passed. */
+ SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_root, pool));
+ authz_url = apr_pstrcat(pool, repos_url, "/authz", (char *)NULL);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, NULL, TRUE,
+ NULL, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* Non-existant path in the repo with must_exist set to FALSE */
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz", NULL, FALSE,
+ repos_root, pool));
+
+ /* Non-existant path in the repo with must_exist set to TRUE */
+ err = svn_repos_authz_read2(&authz_cfg, "^/A/authz", NULL, TRUE,
+ repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_ILLEGAL_TARGET)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_ILLEGAL_TARGET",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* http:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "http://example.com/repo/authz",
+ NULL, TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_RA_ILLEGAL_URL",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* svn:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "svn://example.com/repo/authz",
+ NULL, TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_RA_ILLEGAL_URL",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Test in-repo authz with global groups. */
+static svn_error_t *
+in_repo_groups_authz(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos;
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_revnum_t youngest_rev;
+ svn_authz_t *authz_cfg;
+ const char *groups_contents;
+ const char *authz_contents;
+ const char *repos_root;
+ const char *repos_url;
+ const char *groups_url;
+ const char *authz_url;
+ svn_error_t *err;
+ struct check_access_tests test_set[] = {
+ /* reads */
+ { "/A", NULL, NULL, svn_authz_read, FALSE },
+ { "/A", NULL, "plato", svn_authz_read, TRUE },
+ { "/A", NULL, "socrates", svn_authz_read, TRUE },
+ { "/A", NULL, "solon", svn_authz_read, TRUE },
+ { "/A", NULL, "ephialtes", svn_authz_read, TRUE },
+ /* writes */
+ { "/A", NULL, NULL, svn_authz_write, FALSE },
+ { "/A", NULL, "plato", svn_authz_write, FALSE },
+ { "/A", NULL, "socrates", svn_authz_write, FALSE },
+ { "/A", NULL, "solon", svn_authz_write, TRUE },
+ { "/A", NULL, "ephialtes", svn_authz_write, TRUE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Test plan:
+ * 1. Create an authz file, a global groups file and an empty authz file,
+ * put all these files in the repository. The empty authz file is
+ * required to perform the non-existent path checks (4-7) --
+ * otherwise we would get the authz validation error due to undefined
+ * groups.
+ * 2. Verify that the groups file can be read with an relative URL.
+ * 3. Verify that the groups file can be read with an absolute URL.
+ * 4. Verify that non-existent groups file path does not error out when
+ * must_exist is FALSE.
+ * 5. Same as (4), but when both authz and groups file paths do
+ * not exist.
+ * 6. Verify that non-existent path for the groups file does error out when
+ * must_exist is TRUE.
+ * 7. Verify that an http:// URL produces an error.
+ * 8. Verify that an svn:// URL produces an error.
+ */
+
+ /* What we'll put in the authz and groups files, it's simple since
+ * we're not testing the parsing, just that we got what we expected. */
+
+ groups_contents =
+ "[groups]" NL
+ "philosophers = plato, socrates" NL
+ "senate = solon, ephialtes" NL
+ "" NL;
+
+ authz_contents =
+ "[/]" NL
+ "@senate = rw" NL
+ "@philosophers = r" NL
+ "" NL;
+
+ /* Create a filesystem and repository. */
+ SVN_ERR(svn_test__create_repos(&repos,
+ "test-repo-in-repo-global-groups-authz",
+ opts, pool));
+ fs = svn_repos_fs(repos);
+
+ /* Commit the authz, empty authz and groups files to the repo. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "groups", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "authz", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "empty-authz", pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "groups",
+ groups_contents, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "authz",
+ authz_contents, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "empty-authz", "", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+ SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+
+ /* repos relative URLs */
+ repos_root = svn_repos_path(repos, pool);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", "^/groups",
+ TRUE, repos_root, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* absolute file URLs, repos_root is NULL to validate the contract that it
+ * is not needed except when a repos relative URLs are passed. */
+ SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_root, pool));
+ authz_url = apr_pstrcat(pool, repos_url, "/authz", (char *)NULL);
+ groups_url = apr_pstrcat(pool, repos_url, "/groups", (char *)NULL);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, groups_url,
+ TRUE, NULL, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* Non-existent path for the groups file with must_exist
+ * set to TRUE */
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "^/A/groups", FALSE,
+ repos_root, pool));
+
+ /* Non-existent paths for both the authz and the groups files
+ * with must_exist set to TRUE */
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz",
+ "^/A/groups", FALSE,
+ repos_root, pool));
+
+ /* Non-existent path for the groups file with must_exist
+ * set to TRUE */
+ err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "^/A/groups", TRUE,
+ repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_ILLEGAL_TARGET)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_ILLEGAL_TARGET",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* http:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "http://example.com/repo/groups",
+ TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_RA_ILLEGAL_URL",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* svn:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz",
+ "http://example.com/repo/groups",
+ TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_RA_ILLEGAL_URL",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Helper for the groups_authz test. Set *AUTHZ_P to a representation of
+ AUTHZ_CONTENTS in conjuction with GROUPS_CONTENTS, using POOL for
+ temporary allocation. If DISK is TRUE then write the contents to
+ temporary files and use svn_repos_authz_read2() to get the data if FALSE
+ write the data to a buffered stream and use svn_repos_authz_parse(). */
+static svn_error_t *
+authz_groups_get_handle(svn_authz_t **authz_p,
+ const char *authz_contents,
+ const char *groups_contents,
+ svn_boolean_t disk,
+ apr_pool_t *pool)
+{
+ if (disk)
+ {
+ const char *authz_file_path;
+ const char *groups_file_path;
+
+ /* Create temporary files. */
+ SVN_ERR_W(svn_io_write_unique(&authz_file_path, NULL,
+ authz_contents,
+ strlen(authz_contents),
+ svn_io_file_del_on_pool_cleanup, pool),
+ "Writing temporary authz file");
+ SVN_ERR_W(svn_io_write_unique(&groups_file_path, NULL,
+ groups_contents,
+ strlen(groups_contents),
+ svn_io_file_del_on_pool_cleanup, pool),
+ "Writing temporary groups file");
+
+ /* Read the authz configuration back and start testing. */
+ SVN_ERR_W(svn_repos_authz_read2(authz_p, authz_file_path,
+ groups_file_path, TRUE, NULL, pool),
+ "Opening test authz and groups files");
+
+ /* Done with the files. */
+ SVN_ERR_W(svn_io_remove_file(authz_file_path, pool),
+ "Removing test authz file");
+ SVN_ERR_W(svn_io_remove_file(groups_file_path, pool),
+ "Removing test groups file");
+ }
+ else
+ {
+ svn_stream_t *stream;
+ svn_stream_t *groups_stream;
+
+ /* Create the streams. */
+ stream = svn_stream_buffered(pool);
+ groups_stream = svn_stream_buffered(pool);
+
+ SVN_ERR_W(svn_stream_puts(stream, authz_contents),
+ "Writing authz contents to stream");
+ SVN_ERR_W(svn_stream_puts(groups_stream, groups_contents),
+ "Writing groups contents to stream");
+
+ /* Read the authz configuration from the streams and start testing. */
+ SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, groups_stream, pool),
+ "Parsing the authz and groups contents");
+
+ /* Done with the streams. */
+ SVN_ERR_W(svn_stream_close(stream),
+ "Closing the authz stream");
+ SVN_ERR_W(svn_stream_close(groups_stream),
+ "Closing the groups stream");
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Test authz with global groups. */
+static svn_error_t *
+groups_authz(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_authz_t *authz_cfg;
+ const char *authz_contents;
+ const char *groups_contents;
+ svn_error_t *err;
+
+ struct check_access_tests test_set1[] = {
+ /* reads */
+ { "/A", "greek", NULL, svn_authz_read, FALSE },
+ { "/A", "greek", "plato", svn_authz_read, TRUE },
+ { "/A", "greek", "demetrius", svn_authz_read, TRUE },
+ { "/A", "greek", "galenos", svn_authz_read, TRUE },
+ { "/A", "greek", "pamphilos", svn_authz_read, FALSE },
+ /* writes */
+ { "/A", "greek", NULL, svn_authz_write, FALSE },
+ { "/A", "greek", "plato", svn_authz_write, TRUE },
+ { "/A", "greek", "demetrius", svn_authz_write, FALSE },
+ { "/A", "greek", "galenos", svn_authz_write, FALSE },
+ { "/A", "greek", "pamphilos", svn_authz_write, FALSE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+ struct check_access_tests test_set2[] = {
+ /* reads */
+ { "/A", "greek", NULL, svn_authz_read, FALSE },
+ { "/A", "greek", "socrates", svn_authz_read, FALSE },
+ { "/B", "greek", NULL, svn_authz_read, FALSE},
+ { "/B", "greek", "socrates", svn_authz_read, TRUE },
+ /* writes */
+ { "/A", "greek", NULL, svn_authz_write, FALSE },
+ { "/A", "greek", "socrates", svn_authz_write, FALSE },
+ { "/B", "greek", NULL, svn_authz_write, FALSE},
+ { "/B", "greek", "socrates", svn_authz_write, TRUE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Test plan:
+ * 1. Ensure that a simple setup with global groups and access rights in
+ * two separate files works as expected.
+ * 2. Verify that access rights written in the global groups file are
+ * discarded and affect nothing in authorization terms.
+ * 3. Verify that local groups in the authz file are prohibited in
+ * conjuction with global groups (and that a configuration error is
+ * reported in this scenario).
+ * 4. Ensure that group cycles in the global groups file are reported.
+ *
+ * All checks are performed twice -- for the configurations stored on disk
+ * and in memory. See authz_groups_get_handle.
+ */
+
+ groups_contents =
+ "[groups]" NL
+ "slaves = pamphilos,@gladiators" NL
+ "gladiators = demetrius,galenos" NL
+ "philosophers = plato" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/A]" NL
+ "@slaves = " NL
+ "@gladiators = r" NL
+ "@philosophers = rw" NL
+ "" NL;
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set1, pool));
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set1, pool));
+
+ /* Access rights in the global groups file are discarded. */
+ groups_contents =
+ "[groups]" NL
+ "philosophers = socrates" NL
+ "" NL
+ "[greek:/A]" NL
+ "@philosophers = rw" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/B]" NL
+ "@philosophers = rw" NL
+ "" NL;
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set2, pool));
+
+ SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool));
+
+ SVN_ERR(authz_check_access(authz_cfg, test_set2, pool));
+
+ /* Local groups cannot be used in conjuction with global groups. */
+ groups_contents =
+ "[groups]" NL
+ "slaves = maximus" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/A]" NL
+ "@slaves = " NL
+ "@kings = rw" NL
+ "" NL
+ "[groups]" NL
+ /* That's an epic story of the slave who tried to become a king. */
+ "kings = maximus" NL
+ "" NL;
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* Ensure that group cycles are reported. */
+ groups_contents =
+ "[groups]" NL
+ "slaves = cooks,scribes,@gladiators" NL
+ "gladiators = equites,thraces,@slaves" NL
+ "" NL;
+
+ authz_contents =
+ "[greek:/A]" NL
+ "@slaves = r" NL
+ "" NL;
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ err = authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool);
+
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ return SVN_NO_ERROR;
+}
/* Callback for the commit editor tests that relays requests to
authz. */
@@ -1585,7 +2141,7 @@ commit_editor_authz(const svn_test_opts_
"[/A/D/G]" NL
"plato = r"; /* No newline at end of file. */
- SVN_ERR(authz_get_handle(&authz_file, authz_contents, pool));
+ SVN_ERR(authz_get_handle(&authz_file, authz_contents, FALSE, pool));
iterpool = svn_pool_create(pool);
for (i = 0; i < (sizeof(path_actions) / sizeof(struct authz_path_action_t));
@@ -1720,15 +2276,17 @@ commit_continue_txn(const svn_test_opts_
}
+
+/* A baton for check_location_segments(). */
struct nls_receiver_baton
{
int count;
- svn_location_segment_t *expected_segments;
+ const svn_location_segment_t *expected_segments;
};
-
+/* Return a pretty-printed string representing SEGMENT. */
static const char *
-format_segment(svn_location_segment_t *segment,
+format_segment(const svn_location_segment_t *segment,
apr_pool_t *pool)
{
return apr_psprintf(pool, "[r%ld-r%ld: /%s]",
@@ -1737,14 +2295,15 @@ format_segment(svn_location_segment_t *s
segment->path ? segment->path : "(null)");
}
-
+/* A location segment receiver for check_location_segments().
+ * Implements svn_location_segment_receiver_t. */
static svn_error_t *
nls_receiver(svn_location_segment_t *segment,
void *baton,
apr_pool_t *pool)
{
struct nls_receiver_baton *b = baton;
- svn_location_segment_t *expected_segment = b->expected_segments + b->count;
+ const svn_location_segment_t *expected_segment = b->expected_segments + b->count;
/* expected_segments->range_end can't be 0, so if we see that, it's
our end-of-the-list sentry. */
@@ -1766,18 +2325,22 @@ nls_receiver(svn_location_segment_t *seg
return SVN_NO_ERROR;
}
-
+/* Run a svn_repos_node_location_segments() query with REPOS, PATH, PEG_REV,
+ * START_REV, END_REV. Check that the result exactly matches the list of
+ * segments EXPECTED_SEGMENTS, which is terminated by an entry with
+ * 'range_end'==0.
+ */
static svn_error_t *
check_location_segments(svn_repos_t *repos,
const char *path,
svn_revnum_t peg_rev,
svn_revnum_t start_rev,
svn_revnum_t end_rev,
- svn_location_segment_t *expected_segments,
+ const svn_location_segment_t *expected_segments,
apr_pool_t *pool)
{
struct nls_receiver_baton b;
- svn_location_segment_t *segment;
+ const svn_location_segment_t *segment;
/* Run svn_repos_node_location_segments() with a receiver that
validates against EXPECTED_SEGMENTS. */
@@ -1799,6 +2362,21 @@ check_location_segments(svn_repos_t *rep
return SVN_NO_ERROR;
}
+/* Inputs and expected outputs for svn_repos_node_location_segments() tests.
+ */
+typedef struct location_segment_test_t
+{
+ /* Path and peg revision to query */
+ const char *path;
+ svn_revnum_t peg;
+ /* Start (youngest) and end (oldest) revisions to query */
+ svn_revnum_t start;
+ svn_revnum_t end;
+
+ /* Expected segments */
+ svn_location_segment_t segments[10];
+
+} location_segment_test_t;
static svn_error_t *
node_location_segments(const svn_test_opts_t *opts,
@@ -1811,6 +2389,72 @@ node_location_segments(const svn_test_op
svn_fs_root_t *txn_root, *root;
svn_revnum_t youngest_rev = 0;
+ static const location_segment_test_t subtests[] =
+ {
+ { /* Check locations for /@HEAD. */
+ "", SVN_INVALID_REVNUM, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+ {
+ { 0, 7, "" },
+ { 0 }
+ }
+ },
+ { /* Check locations for A/D@HEAD. */
+ "A/D", SVN_INVALID_REVNUM, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+ {
+ { 7, 7, "A/D" },
+ { 3, 6, "A/D2" },
+ { 1, 2, "A/D" },
+ { 0 }
+ }
+ },
+ { /* Check a subset of the locations for A/D@HEAD. */
+ "A/D", SVN_INVALID_REVNUM, 5, 2,
+ {
+ { 3, 5, "A/D2" },
+ { 2, 2, "A/D" },
+ { 0 }
+ },
+ },
+ { /* Check a subset of locations for A/D2@5. */
+ "A/D2", 5, 3, 2,
+ {
+ { 3, 3, "A/D2" },
+ { 2, 2, "A/D" },
+ { 0 }
+ },
+ },
+ { /* Check locations for A/D@6. */
+ "A/D", 6, 6, SVN_INVALID_REVNUM,
+ {
+ { 1, 6, "A/D" },
+ { 0 }
+ },
+ },
+ { /* Check locations for A/D/G@HEAD. */
+ "A/D/G", SVN_INVALID_REVNUM, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+ {
+ { 7, 7, "A/D/G" },
+ { 6, 6, "A/D2/G" },
+ { 5, 5, NULL },
+ { 3, 4, "A/D2/G" },
+ { 1, 2, "A/D/G" },
+ { 0 }
+ },
+ },
+ { /* Check a subset of the locations for A/D/G@HEAD. */
+ "A/D/G", SVN_INVALID_REVNUM, 3, 2,
+ {
+ { 3, 3, "A/D2/G" },
+ { 2, 2, "A/D/G" },
+ { 0 }
+ },
+ },
+ {
+ NULL
+ },
+ };
+ const location_segment_test_t *subtest;
+
/* Bail (with success) on known-untestable scenarios */
if ((strcmp(opts->fs_type, "bdb") == 0)
&& (opts->server_minor_version == 4))
@@ -1884,117 +2528,19 @@ node_location_segments(const svn_test_op
SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
svn_pool_clear(subpool);
- /* Check locations for /@HEAD. */
- {
- svn_location_segment_t expected_segments[] =
- {
- { 0, 7, "" },
- { 0 }
- };
- SVN_ERR(check_location_segments(repos, "",
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- expected_segments, pool));
- }
-
- /* Check locations for A/D@HEAD. */
- {
- svn_location_segment_t expected_segments[] =
- {
- { 7, 7, "A/D" },
- { 3, 6, "A/D2" },
- { 1, 2, "A/D" },
- { 0 }
- };
- SVN_ERR(check_location_segments(repos, "A/D",
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- expected_segments, pool));
- }
-
- /* Check a subset of the locations for A/D@HEAD. */
- {
- svn_location_segment_t expected_segments[] =
- {
- { 3, 5, "A/D2" },
- { 2, 2, "A/D" },
- { 0 }
- };
- SVN_ERR(check_location_segments(repos, "A/D",
- SVN_INVALID_REVNUM,
- 5,
- 2,
- expected_segments, pool));
- }
-
- /* Check a subset of locations for A/D2@5. */
- {
- svn_location_segment_t expected_segments[] =
- {
- { 3, 3, "A/D2" },
- { 2, 2, "A/D" },
- { 0 }
- };
- SVN_ERR(check_location_segments(repos, "A/D2",
- 5,
- 3,
- 2,
- expected_segments, pool));
- }
-
- /* Check locations for A/D@6. */
- {
- svn_location_segment_t expected_segments[] =
- {
- { 1, 6, "A/D" },
- { 0 }
- };
- SVN_ERR(check_location_segments(repos, "A/D",
- 6,
- 6,
- SVN_INVALID_REVNUM,
- expected_segments, pool));
- }
-
- /* Check locations for A/D/G@HEAD. */
- {
- svn_location_segment_t expected_segments[] =
- {
- { 7, 7, "A/D/G" },
- { 6, 6, "A/D2/G" },
- { 5, 5, NULL },
- { 3, 4, "A/D2/G" },
- { 1, 2, "A/D/G" },
- { 0 }
- };
- SVN_ERR(check_location_segments(repos, "A/D/G",
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- expected_segments, pool));
- }
-
- /* Check a subset of the locations for A/D/G@HEAD. */
- {
- svn_location_segment_t expected_segments[] =
- {
- { 3, 3, "A/D2/G" },
- { 2, 2, "A/D/G" },
- { 0 }
- };
- SVN_ERR(check_location_segments(repos, "A/D/G",
- SVN_INVALID_REVNUM,
- 3,
- 2,
- expected_segments, pool));
- }
+ /* */
+ for (subtest = subtests; subtest->path; subtest++)
+ {
+ SVN_ERR(check_location_segments(repos, subtest->path, subtest->peg,
+ subtest->start, subtest->end,
+ subtest->segments, pool));
+ }
return SVN_NO_ERROR;
}
+
/* Test that the reporter doesn't send deltas under excluded paths. */
static svn_error_t *
reporter_depth_exclude(const svn_test_opts_t *opts,
@@ -2275,7 +2821,7 @@ prop_validation(const svn_test_opts_t *o
{
svn_error_t *err;
svn_repos_t *repos;
- const char non_utf8_string[5] = { 'a', (char)0xff, 'b', '\n', 0 };
+ const char non_utf8_string[5] = { 'a', '\xff', 'b', '\n', 0 };
const char *non_lf_string = "a\r\nb\n\rc\rd\n";
apr_pool_t *subpool = svn_pool_create(pool);
@@ -2550,7 +3096,7 @@ issue_4060(const svn_test_opts_t *opts,
"ozymandias = r" NL
"" NL;
- SVN_ERR(authz_get_handle(&authz_cfg, authz_contents, subpool));
+ SVN_ERR(authz_get_handle(&authz_cfg, authz_contents, FALSE, subpool));
SVN_ERR(svn_repos_authz_check_access(authz_cfg, "babylon",
"/A/B/C", "ozymandias",
@@ -2575,6 +3121,36 @@ issue_4060(const svn_test_opts_t *opts,
return SVN_NO_ERROR;
}
+/* Test svn_repos_delete(). */
+static svn_error_t *
+test_delete_repos(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ const char *path;
+ svn_node_kind_t kind;
+
+ /* We have to use a subpool to close the svn_repos_t before calling
+ svn_repos_delete. */
+ {
+ svn_repos_t *repos;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ SVN_ERR(svn_test__create_repos(&repos, "test-repo-delete-repos", opts,
+ subpool));
+ path = svn_repos_path(repos, pool);
+ svn_pool_destroy(subpool);
+ }
+
+ SVN_ERR(svn_io_check_path(path, &kind, pool));
+ SVN_TEST_ASSERT(kind != svn_node_none);
+ SVN_ERR(svn_repos_delete(path, pool));
+ SVN_ERR(svn_io_check_path(path, &kind, pool));
+ SVN_TEST_ASSERT(kind == svn_node_none);
+
+ /* Recreate dir so that test cleanup doesn't fail. */
+ SVN_ERR(svn_io_dir_make(path, APR_OS_DEFAULT, pool));
+
+ return SVN_NO_ERROR;
+}
/* The test table. */
@@ -2595,6 +3171,12 @@ struct svn_test_descriptor_t test_funcs[
"test removal of defunct locks"),
SVN_TEST_PASS2(authz,
"test authz access control"),
+ SVN_TEST_OPTS_PASS(in_repo_authz,
+ "test authz stored in the repo"),
+ SVN_TEST_OPTS_PASS(in_repo_groups_authz,
+ "test authz and global groups stored in the repo"),
+ SVN_TEST_OPTS_PASS(groups_authz,
+ "test authz with global groups"),
SVN_TEST_OPTS_PASS(commit_editor_authz,
"test authz in the commit editor"),
SVN_TEST_OPTS_PASS(commit_continue_txn,
@@ -2611,5 +3193,7 @@ struct svn_test_descriptor_t test_funcs[
"test svn_repos_get_file_revsN"),
SVN_TEST_OPTS_PASS(issue_4060,
"test issue 4060"),
+ SVN_TEST_OPTS_PASS(test_delete_repos,
+ "test svn_repos_delete"),
SVN_TEST_NULL
};
Modified: subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/config-test.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/config-test.c Mon Feb 4 20:48:05 2013
@@ -269,6 +269,31 @@ test_has_section_case_sensitive(apr_pool
return SVN_NO_ERROR;
}
+
+static svn_error_t *
+test_stream_interface(apr_pool_t *pool)
+{
+ svn_config_t *cfg;
+ const char *cfg_file;
+ svn_stream_t *stream;
+
+ if (!srcdir)
+ SVN_ERR(init_params(pool));
+
+ cfg_file = apr_pstrcat(pool, srcdir, "/", "config-test.cfg", (char *)NULL);
+ SVN_ERR(svn_stream_open_readonly(&stream, cfg_file, pool, pool));
+
+ SVN_ERR(svn_config_parse(&cfg, stream, TRUE, pool));
+
+ /* nominal test to make sure cfg is populated with something since
+ * svn_config_parse will happily return an empty cfg if the stream is
+ * empty. */
+ if (! svn_config_has_section(cfg, "section1"))
+ return fail(pool, "Failed to find section1");
+
+ return SVN_NO_ERROR;
+}
+
/*
====================================================================
If you add a new test to this file, update this array.
@@ -288,5 +313,7 @@ struct svn_test_descriptor_t test_funcs[
"test svn_config_has_section (case insensitive)"),
SVN_TEST_PASS2(test_has_section_case_sensitive,
"test svn_config_has_section (case sensitive)"),
+ SVN_TEST_PASS2(test_stream_interface,
+ "test svn_config_parse"),
SVN_TEST_NULL
};
Modified: subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/error-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/error-test.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/error-test.c (original)
+++ subversion/branches/fsfs-format7/subversion/tests/libsvn_subr/error-test.c Mon Feb 4 20:48:05 2013
@@ -125,8 +125,9 @@ test_error_purge_tracing(apr_pool_t *poo
svn_error_malfunction_handler_t orig_handler;
/* For this test, use a random error status. */
- err = svn_error_create(SVN_ERR_BAD_UUID, NULL, SVN_ERR__TRACED);
+ err = svn_error_create(SVN_ERR_BAD_UUID, NULL, "");
err = svn_error_trace(err);
+ err->child->message = err->message;
/* Register a malfunction handler that doesn't call abort() to
check that a new error chain with an assertion error is