subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1547045 [4/4] - in /subversion/trunk: ./ subversion/libsvn_fs_fs/ subversion/tests/cmdline/ subversion/tests/cmdline/svntest/ subversion/tests/libsvn_fs_fs/ tools/server-side/
Date Mon, 02 Dec 2013 14:55:21 GMT
Modified: subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py?rev=1547045&r1=1547044&r2=1547045&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py Mon Dec  2 14:55:20 2013
@@ -245,18 +245,77 @@ def load_dumpstream(sbox, dump, *varargs
   return load_and_verify_dumpstream(sbox, None, None, None, False, dump,
                                     *varargs)
 
-def set_changed_path_list(filename, changes):
-  """ Replace the changed paths list in the file given by FILENAME
+def read_l2p(sbox, revision, item):
+  """ For the format 7+ repository in SBOX, return the physical offset
+      of ITEM in REVISION.  This code supports only small, nonpacked revs. """
+
+  filename = fsfs_file(sbox.repo_dir, 'revs', str(revision) + ".l2p")
+
+  fp = open(filename, 'rb')
+  contents = fp.read()
+  length = len(contents)
+  fp.close()
+
+  # decode numbers
+  numbers = []
+  value = 0
+  shift = 0
+  for c in contents:
+    char = ord(c)
+    value += (char & 127) << shift
+    if char < 128:
+      numbers.append(value)
+      shift = 0
+      value = 0
+    else:
+      shift += 7
+
+  # decode offsets
+  numbers[7] = -1
+  for i in range(8, len(numbers)):
+    if numbers[i] & 1 == 1:
+      numbers[i] = - (numbers[i] + 1) / 2
+    else:
+      numbers[i] = numbers[i] / 2
+    numbers[i] += numbers[i-1]
+
+  # we support only small, unpacked rev files
+  if numbers[1] < len(numbers) or numbers[3] != 1 :
+    raise svntest.Failure("More than 1 page in %s" % filename)
+  if numbers[2] != 1:
+    raise svntest.Failure("More than 1 rev in %s" % filename)
+
+  return numbers[item + 7]
+
+def repo_format(sbox):
+  """ Return the repository format number for SBOX."""
+
+  format_file = open(os.path.join(sbox.repo_dir, "db", "format"))
+  format = int(format_file.read()[:1])
+  format_file.close()
+
+  return format
+
+def set_changed_path_list(sbox, revision, changes):
+  """ Replace the changed paths list in the revision file REVISION in SBOX
       with the text CHANGES."""
 
   # read full file
-  fp = open(filename, 'r+b')
+  fp = open(fsfs_file(sbox.repo_dir, 'revs', str(revision)), 'r+b')
   contents = fp.read()
 
-  # replace the changed paths list
-  length = len(contents)
-  header = contents[contents.rfind('\n', length - 64, length - 1):]
-  body_len = long(header.split(' ')[1])
+  if repo_format(sbox) < 7:
+    # replace the changed paths list
+    length = len(contents)
+    header = contents[contents.rfind('\n', length - 64, length - 1):]
+    body_len = long(header.split(' ')[1])
+
+  else:
+    # we will invalidate the l2p index but that's ok for the
+    # kind of tests we run here. The p2l index remains valid
+    # because the offset of the last item does not change
+    body_len = read_l2p(sbox, revision, 1)
+    header = '\n'
 
   contents = contents[:body_len] + changes + header
 
@@ -272,7 +331,7 @@ def set_changed_path_list(filename, chan
 
 #----------------------------------------------------------------------
 
-def test_create(sbox):
+def test_create(sbox, minor_version=None):
   "'svnadmin create'"
 
 
@@ -282,7 +341,7 @@ def test_create(sbox):
   svntest.main.safe_rmtree(repo_dir, 1)
   svntest.main.safe_rmtree(wc_dir)
 
-  svntest.main.create_repos(repo_dir)
+  svntest.main.create_repos(repo_dir, minor_version)
 
   svntest.actions.run_and_verify_svn("Creating rev 0 checkout",
                                      ["Checked out revision 0.\n"], [],
@@ -581,7 +640,9 @@ def verify_windows_paths_in_repos(sbox):
 
   # unfortunately, some backends needs to do more checks than other
   # resulting in different progress output
-  if svntest.main.is_fs_type_fsx():
+  if svntest.main.is_fs_type_fsx() or \
+    (svntest.main.is_fs_type_fsfs() and \
+        svntest.main.options.server_minor_version >= 9):
     svntest.verify.compare_and_display_lines(
       "Error while running 'svnadmin verify'.",
       'STDERR', ["* Verifying metadata at revision 0 ...\n",
@@ -634,7 +695,9 @@ def verify_incremental_fsfs(sbox):
   """svnadmin verify detects corruption dump can't"""
 
   # setup a repo with a directory 'c:hi'
-  sbox.build(create_wc = False)
+  # use physical addressing as this is hard to provoke with logical addressing
+  sbox.build(create_wc = False,
+             minor_version = min(svntest.main.options.server_minor_version,8))
   repo_url = sbox.repo_url
   E_url = sbox.repo_url + '/A/B/E'
 
@@ -1458,7 +1521,11 @@ def verify_non_utf8_paths(sbox):
   "svnadmin verify with non-UTF-8 paths"
 
   dumpfile = clean_dumpfile()
-  test_create(sbox)
+
+  # Corruption only possible in physically addressed revisions created
+  # with pre-1.6 servers.
+  test_create(sbox,
+              minor_version = min(svntest.main.options.server_minor_version,8))
 
   # Load the dumpstream
   load_and_verify_dumpstream(sbox, [], [], dumpfile_revisions, False,
@@ -1476,11 +1543,14 @@ def verify_non_utf8_paths(sbox):
       # replace 'A' with a latin1 character -- the new path is not valid UTF-8
       fp_new.write("\xE6\n")
     elif line == "text: 1 279 32 0 d63ecce65d8c428b86f4f8b0920921fe\n":
-      # fix up the representation checksum
+      # phys, PLAIN directories: fix up the representation checksum
       fp_new.write("text: 1 279 32 0 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
     elif line == "text: 1 292 44 32 a6be7b4cf075fd39e6a99eb69a31232b\n":
-      # fix up the representation checksum
+      # phys, deltified directories: fix up the representation checksum
       fp_new.write("text: 1 292 44 32 f2e93e73272cac0f18fccf16f224eb93\n")
+    elif line == "text: 1 6 31 0 90f306aa9bfd72f456072076a2bd94f7\n":
+      # log addressing: fix up the representation checksum
+      fp_new.write("text: 1 6 31 0 db2d4a0bad5dff0aea9a288dec02f1fb\n")
     elif line == "cpath: /A\n":
       # also fix up the 'created path' field
       fp_new.write("cpath: /\xE6\n")
@@ -1654,9 +1724,13 @@ def hotcopy_incremental_packed(sbox):
   backup_dir, backup_url = sbox.add_repo_path('backup')
   os.mkdir(backup_dir)
   cwd = os.getcwd()
+
   # Configure two files per shard to trigger packing
   format_file = open(os.path.join(sbox.repo_dir, 'db', 'format'), 'wb')
-  format_file.write("6\nlayout sharded 2\n")
+  if svntest.main.options.server_minor_version >= 9:
+    format_file.write("7\nlayout sharded 2\naddressing logical 0\n")
+  else:
+    format_file.write("6\nlayout sharded 2\n")
   format_file.close()
 
   # Pack revisions 0 and 1.
@@ -1890,20 +1964,26 @@ def verify_keep_going(sbox):
                                                         "--keep-going",
                                                         sbox.repo_dir)
 
-  exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
-                                           ".*Verified revision 0.",
-                                           ".*Verified revision 1.",
-                                           ".*Error verifying revision 2.",
-                                           ".*Error verifying revision 3.",
-                                           ".*",
-                                           ".*Summary.*",
-                                           ".*r2: E160004:.*",
-                                           ".*r3: E160004:.*",
-                                           ".*r3: E160004:.*"])
-
-  exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*",
-                                           "svnadmin: E165011:.*"], False)
-
+  if svntest.main.is_fs_log_addressing():
+    exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision 0",
+                                             ".*Verified revision 0.",
+                                             ".*Verified revision 1.",
+                                             ".*Verified revision 2.",
+                                             ".*Verified revision 3."])
+    exp_err = svntest.verify.RegexListOutput(["svnadmin: E165011:.*"], False)
+  else:
+    exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
+                                              ".*Verified revision 0.",
+                                              ".*Verified revision 1.",
+                                              ".*Error verifying revision 2.",
+                                              ".*Error verifying revision 3.",
+                                              ".*",
+                                              ".*Summary.*",
+                                              ".*r2: E160004:.*",
+                                              ".*r3: E160004:.*",
+                                              ".*r3: E160004:.*"])
+    exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*",
+                                              "svnadmin: E165011:.*"], False)
 
   if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
                                    output, errput, exp_out, exp_err):
@@ -1912,10 +1992,13 @@ def verify_keep_going(sbox):
   exit_code, output, errput = svntest.main.run_svnadmin("verify",
                                                         sbox.repo_dir)
 
-  exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
-                                           ".*Verified revision 0.",
-                                           ".*Verified revision 1.",
-                                           ".*Error verifying revision 2."])
+  if (svntest.main.options.server_minor_version < 9):
+    exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
+                                             ".*Verified revision 0.",
+                                             ".*Verified revision 1.",
+                                             ".*Error verifying revision 2."])
+  else:
+    exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision 0"])
 
   if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
                                    output, errput, exp_out, exp_err):
@@ -1947,43 +2030,44 @@ def verify_invalid_path_changes(sbox):
   # "carried over" but that all corrupts we get detected independently
 
   # add existing node
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '2'),
+  set_changed_path_list(sbox, 2,
                         "_0.0.t1-1 add-dir false false /A\n\n")
 
   # add into non-existent parent
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '4'),
+  set_changed_path_list(sbox, 4,
                         "_0.0.t3-2 add-dir false false /C/X\n\n")
 
   # del non-existent node
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '6'),
+  set_changed_path_list(sbox, 6,
                         "_0.0.t5-2 delete-dir false false /C\n\n")
 
   # del existent node of the wrong kind
+  #
   # THIS WILL NOT BE DETECTED
   # since dump mechanism and file don't care about the types of deleted nodes
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '8'),
+  set_changed_path_list(sbox, 8,
                         "_0.0.t7-2 delete-file false false /B3\n\n")
 
   # copy from non-existent node
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '10'),
+  set_changed_path_list(sbox, 10,
                         "_0.0.t9-2 add-dir false false /B10\n"
                         "6 /B8\n")
 
   # copy from existing node of the wrong kind
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '12'),
+  set_changed_path_list(sbox, 12,
                         "_0.0.t11-2 add-file false false /B12\n"
                         "9 /B8\n")
 
   # modify non-existent node
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '14'),
+  set_changed_path_list(sbox, 14,
                         "_0.0.t13-2 modify-file false false /A/D/H/foo\n\n")
 
   # modify existent node of the wrong kind
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '16'),
+  set_changed_path_list(sbox, 16,
                         "_0.0.t15-2 modify-file false false /B12\n\n")
 
   # replace non-existent node
-  set_changed_path_list(fsfs_file(sbox.repo_dir, 'revs', '18'),
+  set_changed_path_list(sbox, 18,
                         "_0.0.t17-2 replace-file false false /A/D/H/foo\n\n")
 
   # find corruptions
@@ -1991,7 +2075,12 @@ def verify_invalid_path_changes(sbox):
                                                         "--keep-going",
                                                         sbox.repo_dir)
 
-  exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
+  if repo_format(sbox) < 7:
+    first_line = ".*Verifying repository metadata"
+  else:
+    first_line = ".*Verifying metadata at revision 0"
+
+  exp_out = svntest.verify.RegexListOutput([first_line,
                                            ".*Verified revision 0.",
                                            ".*Verified revision 1.",
                                            ".*Error verifying revision 2.",
@@ -2042,13 +2131,17 @@ def verify_invalid_path_changes(sbox):
   exit_code, output, errput = svntest.main.run_svnadmin("verify",
                                                         sbox.repo_dir)
 
-  exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
-                                           ".*Verified revision 0.",
-                                           ".*Verified revision 1.",
-                                           ".*Error verifying revision 2."])
-
-  exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*",
-                                            "svnadmin: E165011:.*"], False)
+  if svntest.main.is_fs_log_addressing():
+    exp_out = svntest.verify.RegexListOutput([first_line])
+    exp_err = svntest.verify.RegexListOutput(["svnadmin: E160058:.*",
+                                              "svnadmin: E165011:.*"], False)
+  else:
+    exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
+                                              ".*Verified revision 0.",
+                                              ".*Verified revision 1.",
+                                              ".*Error verifying revision 2."])
+    exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*",
+                                              "svnadmin: E165011:.*"], False)
 
   if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
                                    output, errput, exp_out, exp_err):

Modified: subversion/trunk/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/main.py?rev=1547045&r1=1547044&r2=1547045&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/main.py Mon Dec  2 14:55:20 2013
@@ -1337,7 +1337,8 @@ def is_fs_type_bdb():
   return options.fs_type == 'bdb'
 
 def is_fs_log_addressing():
-  return is_fs_type_fsx()
+  return is_fs_type_fsx() or \
+        (is_fs_type_fsfs() and options.server_minor_version >= 9)
 
 def is_os_windows():
   return os.name == 'nt'

Propchange: subversion/trunk/subversion/tests/libsvn_fs_fs/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Dec  2 14:55:20 2013
@@ -2,6 +2,7 @@ Debug
 Release
 .libs
 test-repo-*
+upgrade_*
 fs-pack-test
 fs-fs-pack-test
 test-get-set-revprop-packed-fs

Modified: subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c?rev=1547045&r1=1547044&r2=1547045&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c Mon Dec  2 14:55:20 2013
@@ -55,16 +55,35 @@ write_format(const char *path,
 
   if (format >= SVN_FS_FS__MIN_LAYOUT_FORMAT_OPTION_FORMAT)
     {
-      if (max_files_per_dir)
-        contents = apr_psprintf(pool,
-                                "%d\n"
-                                "layout sharded %d\n",
-                                format, max_files_per_dir);
+      if (format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+        {
+          if (max_files_per_dir)
+            contents = apr_psprintf(pool,
+                                    "%d\n"
+                                    "layout sharded %d\n"
+                                    "addressing logical 0\n",
+                                    format, max_files_per_dir);
+          else
+            /* linear layouts never use logical addressing */
+            contents = apr_psprintf(pool,
+                                    "%d\n"
+                                    "layout linear\n"
+                                    "addressing physical\n",
+                                    format);
+        }
       else
-        contents = apr_psprintf(pool,
-                                "%d\n"
-                                "layout linear",
-                                format);
+        {
+          if (max_files_per_dir)
+            contents = apr_psprintf(pool,
+                                    "%d\n"
+                                    "layout sharded %d\n",
+                                    format, max_files_per_dir);
+          else
+            contents = apr_psprintf(pool,
+                                    "%d\n"
+                                    "layout linear\n",
+                                    format);
+        }
     }
   else
     {
@@ -312,14 +331,37 @@ pack_filesystem(const svn_test_opts_t *o
         return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
                                  "Expected pack file '%s' not found", path);
 
-      path = svn_dirent_join_many(pool, REPO_NAME, "revs",
-                                  apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
-                                  "manifest", SVN_VA_NULL);
-      SVN_ERR(svn_io_check_path(path, &kind, pool));
-      if (kind != svn_node_file)
-        return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
-                                 "Expected manifest file '%s' not found",
-                                 path);
+      if (opts->server_minor_version && (opts->server_minor_version < 9))
+        {
+          path = svn_dirent_join_many(pool, REPO_NAME, "revs",
+                                      apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
+                                      "manifest", SVN_VA_NULL);
+          SVN_ERR(svn_io_check_path(path, &kind, pool));
+          if (kind != svn_node_file)
+            return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
+                                     "Expected manifest file '%s' not found",
+                                     path);
+        }
+      else
+        {
+          path = svn_dirent_join_many(pool, REPO_NAME, "revs",
+                                      apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
+                                      "pack.l2p", SVN_VA_NULL);
+          SVN_ERR(svn_io_check_path(path, &kind, pool));
+          if (kind != svn_node_file)
+            return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
+                                     "Expected log-to-phys index file '%s' not found",
+                                     path);
+
+          path = svn_dirent_join_many(pool, REPO_NAME, "revs",
+                                      apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
+                                      "pack.p2l", NULL);
+          SVN_ERR(svn_io_check_path(path, &kind, pool));
+          if (kind != svn_node_file)
+            return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
+                                     "Expected phys-to-log index file '%s' not found",
+                                     path);
+        }
 
       /* This directory should not exist. */
       path = svn_dirent_join_many(pool, REPO_NAME, "revs",
@@ -891,6 +933,191 @@ get_set_multiple_huge_revprops_packed_fs
 #undef SHARD_SIZE
 
 /* ------------------------------------------------------------------------ */
+#define SHARD_SIZE 4
+static svn_error_t *
+upgrade_txns_to_log_addressing(const svn_test_opts_t *opts,
+                               const char *repo_name,
+                               svn_revnum_t max_rev,
+                               svn_boolean_t upgrade_before_txns,
+                               apr_pool_t *pool)
+{
+  svn_fs_t *fs;
+  svn_revnum_t rev;
+  apr_array_header_t *txns;
+  apr_array_header_t *txn_names;
+  int i, k;
+  svn_test_opts_t temp_opts;
+  svn_fs_root_t *root;
+  static const char * const paths[SHARD_SIZE][2]
+    = {
+        { "A/mu",        "A/B/lambda" },
+        { "A/B/E/alpha", "A/D/H/psi"  },
+        { "A/D/gamma",   "A/B/E/beta" },
+        { "A/D/G/pi",    "A/D/G/rho"  }
+      };
+
+  /* Bail (with success) on known-untestable scenarios */
+  if ((strcmp(opts->fs_type, "fsfs") != 0)
+      || (opts->server_minor_version && (opts->server_minor_version < 9)))
+    return SVN_NO_ERROR;
+
+  /* Create the packed FS in phys addressing format and open it. */
+  temp_opts = *opts;
+  temp_opts.server_minor_version = 8;
+  SVN_ERR(prepare_revprop_repo(&fs, repo_name, max_rev, SHARD_SIZE,
+                               &temp_opts, pool));
+
+  if (upgrade_before_txns)
+    {
+      /* upgrade to final repo format (using log addressing) and re-open */
+      SVN_ERR(svn_fs_upgrade2(repo_name, NULL, NULL, NULL, NULL, pool));
+      SVN_ERR(svn_fs_open(&fs, repo_name, svn_fs_config(fs, pool), pool));
+    }
+
+  /* Create 4 concurrent transactions */
+  txns = apr_array_make(pool, SHARD_SIZE, sizeof(svn_fs_txn_t *));
+  txn_names = apr_array_make(pool, SHARD_SIZE, sizeof(const char *));
+  for (i = 0; i < SHARD_SIZE; ++i)
+    {
+      svn_fs_txn_t *txn;
+      const char *txn_name;
+
+      SVN_ERR(svn_fs_begin_txn(&txn, fs, max_rev, pool));
+      APR_ARRAY_PUSH(txns, svn_fs_txn_t *) = txn;
+
+      SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
+      APR_ARRAY_PUSH(txn_names, const char *) = txn_name;
+    }
+
+  /* Let all txns touch at least 2 files.
+   * Thus, the addressing data of at least one representation in the txn
+   * will differ between addressing modes. */
+  for (i = 0; i < SHARD_SIZE; ++i)
+    {
+      svn_fs_txn_t *txn = APR_ARRAY_IDX(txns, i, svn_fs_txn_t *);
+      SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+
+      for (k = 0; k < 2; ++k)
+        {
+          svn_stream_t *stream;
+          const char *file_path = paths[i][k];
+
+          SVN_ERR(svn_fs_apply_text(&stream, root, file_path, NULL, pool));
+          SVN_ERR(svn_stream_printf(stream, pool,
+                                    "This is file %s in txn %d",
+                                    file_path, i));
+          SVN_ERR(svn_stream_close(stream));
+        }
+    }
+
+  if (!upgrade_before_txns)
+    {
+      /* upgrade to final repo format (using log addressing) and re-open */
+      SVN_ERR(svn_fs_upgrade2(repo_name, NULL, NULL, NULL, NULL, pool));
+      SVN_ERR(svn_fs_open(&fs, repo_name, svn_fs_config(fs, pool), pool));
+    }
+
+  /* Commit all transactions
+   * (in reverse order to make things more interesting) */
+  for (i = SHARD_SIZE - 1; i >= 0; --i)
+    {
+      svn_fs_txn_t *txn;
+      const char *txn_name = APR_ARRAY_IDX(txn_names, i, const char *);
+      SVN_ERR(svn_fs_open_txn(&txn, fs, txn_name, pool));
+      SVN_ERR(svn_fs_commit_txn2(NULL, &rev, txn, TRUE, pool));
+    }
+
+  /* Further changes to fill the shard */
+
+  SVN_ERR(svn_fs_youngest_rev(&rev, fs, pool));
+  SVN_TEST_ASSERT(rev == SHARD_SIZE + max_rev + 1);
+
+  while ((rev + 1) % SHARD_SIZE)
+    {
+      svn_fs_txn_t *txn;
+      if (rev % SHARD_SIZE == 0)
+        break;
+
+      SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+      SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+      SVN_ERR(svn_test__set_file_contents(root, "iota",
+                                          get_rev_contents(rev + 1, pool),
+                                          pool));
+      SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+    }
+
+  /* Pack repo to verify that old and new shard get packed according to
+     their respective addressing mode */
+
+  SVN_ERR(svn_fs_pack(repo_name, NULL, NULL, NULL, NULL, pool));
+
+  /* verify that our changes got in */
+
+  SVN_ERR(svn_fs_revision_root(&root, fs, rev, pool));
+  for (i = 0; i < SHARD_SIZE; ++i)
+    {
+      for (k = 0; k < 2; ++k)
+        {
+          svn_stream_t *stream;
+          const char *file_path = paths[i][k];
+          svn_string_t *string;
+          const char *expected;
+
+          SVN_ERR(svn_fs_file_contents(&stream, root, file_path, pool));
+          SVN_ERR(svn_string_from_stream(&string, stream, pool, pool));
+
+          expected = apr_psprintf(pool,"This is file %s in txn %d",
+                                  file_path, i);
+          SVN_TEST_STRING_ASSERT(string->data, expected);
+        }
+    }
+
+  /* verify that the indexes are consistent, we calculated the correct
+     low-level checksums etc. */
+  SVN_ERR(svn_fs_verify(repo_name, NULL,
+                        SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+                        NULL, NULL, NULL, NULL, pool));
+  for (; rev >= 0; --rev)
+    {
+      SVN_ERR(svn_fs_revision_root(&root, fs, rev, pool));
+      SVN_ERR(svn_fs_verify_root(root, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+#undef SHARD_SIZE
+
+#define REPO_NAME "upgrade_new_txns_to_log_addressing"
+#define MAX_REV 8
+static svn_error_t *
+upgrade_new_txns_to_log_addressing(const svn_test_opts_t *opts,
+                                   apr_pool_t *pool)
+{
+  SVN_ERR(upgrade_txns_to_log_addressing(opts, REPO_NAME, MAX_REV, TRUE,
+                                         pool));
+
+  return SVN_NO_ERROR;
+}
+#undef REPO_NAME
+#undef MAX_REV
+
+/* ------------------------------------------------------------------------ */
+#define REPO_NAME "upgrade_old_txns_to_log_addressing"
+#define MAX_REV 8
+static svn_error_t *
+upgrade_old_txns_to_log_addressing(const svn_test_opts_t *opts,
+                                   apr_pool_t *pool)
+{
+  SVN_ERR(upgrade_txns_to_log_addressing(opts, REPO_NAME, MAX_REV, FALSE,
+                                         pool));
+
+  return SVN_NO_ERROR;
+}
+
+#undef REPO_NAME
+#undef MAX_REV
+
+/* ------------------------------------------------------------------------ */
 
 /* The test table.  */
 
@@ -923,5 +1150,9 @@ struct svn_test_descriptor_t test_funcs[
                        "test packing with shard size = 1"),
     SVN_TEST_OPTS_PASS(get_set_multiple_huge_revprops_packed_fs,
                        "set multiple huge revprops in packed FSFS"),
+    SVN_TEST_OPTS_PASS(upgrade_new_txns_to_log_addressing,
+                       "upgrade txns to log addressing in shared FSFS"),
+    SVN_TEST_OPTS_PASS(upgrade_old_txns_to_log_addressing,
+                       "upgrade txns started before svnadmin upgrade"),
     SVN_TEST_NULL
   };

Modified: subversion/trunk/tools/server-side/svn-rep-sharing-stats.c
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/server-side/svn-rep-sharing-stats.c?rev=1547045&r1=1547044&r2=1547045&view=diff
==============================================================================
--- subversion/trunk/tools/server-side/svn-rep-sharing-stats.c (original)
+++ subversion/trunk/tools/server-side/svn-rep-sharing-stats.c Mon Dec  2 14:55:20 2013
@@ -211,7 +211,7 @@ static svn_error_t *record(apr_hash_t *r
    */
   key = apr_pcalloc(result_pool, sizeof(*key));
   key->revision = rep->revision;
-  key->offset = rep->offset;
+  key->offset = rep->item_index;
 
   /* Update or create the value. */
   if ((value = apr_hash_get(records, key, sizeof(*key))))



Mime
View raw message