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