/* changes-test.c --- test `changes' interfaces
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#include <apr.h>

#include "../svn_test.h"

#include "svn_pools.h"
#include "svn_error.h"
#include "private/svn_skel.h"

#include "../svn_test_fs.h"
#include "../../libsvn_fs_base/util/fs_skels.h"
#include "../../libsvn_fs_base/bdb/changes-table.h"



/* Helper functions/variables.  */
static const char *standard_txns[]
  = { "0", "1", "2", "3", "4", "5", "6" };
static const char *standard_changes[19][6]
     /* KEY   PATH   NODEREVID  KIND     TEXT PROP */
  = { { "0",  "/foo",  "1.0.0",  "add",     0,  0  },
      { "0",  "/foo",  "1.0.0",  "modify",  0, "1" },
      { "0",  "/bar",  "2.0.0",  "add",     0,  0  },
      { "0",  "/bar",  "2.0.0",  "modify", "1", 0  },
      { "0",  "/bar",  "2.0.0",  "modify",  0, "1" },
      { "0",  "/baz",  "3.0.0",  "add",     0,  0  },
      { "0",  "/baz",  "3.0.0",  "modify", "1", 0  },
      { "1",  "/foo",  "1.0.1",  "modify", "1", 0  },
      { "2",  "/foo",  "1.0.2",  "modify",  0, "1" },
      { "2",  "/bar",  "2.0.2",  "modify", "1", 0  },
      { "3",  "/baz",  "3.0.3",  "modify", "1", 0  },
      { "4",  "/fob",  "4.0.4",  "add",     0,  0  },
      { "4",  "/fob",  "4.0.4",  "modify", "1", 0  },
      { "5",  "/baz",  "3.0.3",  "delete",  0,  0  },
      { "5",  "/baz",  "5.0.5",  "add",     0, "1" },
      { "5",  "/baz",  "5.0.5",  "modify", "1", 0  },
      { "6",  "/fob",  "4.0.6",  "modify", "1", 0  },
      { "6",  "/fob",  "4.0.6",  "reset",   0,  0  },
      { "6",  "/fob",  "4.0.6",  "modify",  0, "1" } };


static svn_fs_path_change_kind_t string_to_kind(const char *str)
{
  if (strcmp(str, "add") == 0)
    return svn_fs_path_change_add;
  if (strcmp(str, "delete") == 0)
    return svn_fs_path_change_delete;
  if (strcmp(str, "replace") == 0)
    return svn_fs_path_change_replace;
  if (strcmp(str, "modify") == 0)
    return svn_fs_path_change_modify;
  if (strcmp(str, "reset") == 0)
    return svn_fs_path_change_reset;
  return 0;
}


/* Common args structure for several different txn_body_* functions. */
struct changes_args
{
  svn_fs_t *fs;
  const char *key;
  change_t *change;
  apr_array_header_t *raw_changes;
  apr_hash_t *changes;
};


static svn_error_t *
txn_body_changes_add(void *baton, trail_t *trail)
{
  struct changes_args *b = baton;
  return svn_fs_bdb__changes_add(b->fs, b->key, b->change,
                                 trail, trail->pool);
}


static svn_error_t *
add_standard_changes(svn_fs_t *fs,
                     apr_pool_t *pool)
{
  int i;
  struct changes_args args;
  int num_changes = sizeof(standard_changes) / sizeof(const char *) / 6;

  for (i = 0; i < num_changes; i++)
    {
      change_t change;

      /* Set up the current change item. */
      change.path = standard_changes[i][1];
      change.noderev_id = svn_fs_parse_id(standard_changes[i][2],
                                          strlen(standard_changes[i][2]),
                                          pool);
      change.kind = string_to_kind(standard_changes[i][3]);
      change.text_mod = standard_changes[i][4] ? 1 : 0;
      change.prop_mod = standard_changes[i][5] ? 1 : 0;

      /* Set up transaction baton. */
      args.fs = fs;
      args.key = standard_changes[i][0];
      args.change = &change;

      /* Write new changes to the changes table. */
      SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_add, &args,
                                     TRUE, pool));
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
txn_body_changes_fetch_raw(void *baton, trail_t *trail)
{
  struct changes_args *b = baton;
  return svn_fs_bdb__changes_fetch_raw(&(b->raw_changes), b->fs, b->key,
                                       trail, trail->pool);
}


static svn_error_t *
txn_body_changes_fetch(void *baton, trail_t *trail)
{
  struct changes_args *b = baton;
  return svn_fs_bdb__changes_fetch(&(b->changes), b->fs, b->key,
                                   trail, trail->pool);
}


static svn_error_t *
txn_body_changes_delete(void *baton, trail_t *trail)
{
  struct changes_args *b = baton;
  return svn_fs_bdb__changes_delete(b->fs, b->key, trail, trail->pool);
}



/* The tests.  */

static svn_error_t *
changes_add(const svn_test_opts_t *opts,
            apr_pool_t *pool)
{
  svn_fs_t *fs;

  /* Create a new fs and repos */
  SVN_ERR(svn_test__create_bdb_fs(&fs, "test-repo-changes-add", opts,
                                  pool));

  /* Add the standard slew of changes. */
  SVN_ERR(add_standard_changes(fs, pool));

  return SVN_NO_ERROR;
}


static svn_error_t *
changes_fetch_raw(const svn_test_opts_t *opts,
                  apr_pool_t *pool)
{
  svn_fs_t *fs;
  int i;
  int num_txns = sizeof(standard_txns) / sizeof(const char *);
  int cur_change_index = 0;
  struct changes_args args;

  /* Create a new fs and repos */
  SVN_ERR(svn_test__create_bdb_fs(&fs, "test-repo-changes-fetch-raw", opts,
                                  pool));

  /* First, verify that we can request changes for an arbitrary key
     without error. */
  args.fs = fs;
  args.key = "blahbliggityblah";
  SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch_raw, &args,
                                 FALSE, pool));
  if ((! args.raw_changes) || (args.raw_changes->nelts))
    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
                            "expected empty changes array");

  /* Add the standard slew of changes. */
  SVN_ERR(add_standard_changes(fs, pool));

  /* For each transaction, fetch that transaction's changes, and
     compare those changes against the standard changes list.  Order
     matters throughout all the changes code, so we shouldn't have to
     worry about ordering of the arrays.  */
  for (i = 0; i < num_txns; i++)
    {
      const char *txn_id = standard_txns[i];
      int j;

      /* Setup the trail baton. */
      args.fs = fs;
      args.key = txn_id;

      /* And get those changes. */
      SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch_raw,
                                     &args, FALSE, pool));
      if (! args.raw_changes)
        return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
                                 "got no changes for key '%s'", txn_id);

      for (j = 0; j < args.raw_changes->nelts; j++)
        {
          svn_string_t *noderev_id;
          svn_fs_path_change_kind_t kind;
          change_t *change = APR_ARRAY_IDX(args.raw_changes, j, change_t *);
          int mod_bit = 0;

          /* Verify that the TXN_ID matches. */
          if (strcmp(standard_changes[cur_change_index][0], txn_id))
            return svn_error_createf
              (SVN_ERR_TEST_FAILED, NULL,
               "missing some changes for key '%s'", txn_id);

          /* Verify that the PATH matches. */
          if (strcmp(standard_changes[cur_change_index][1], change->path))
            return svn_error_createf
              (SVN_ERR_TEST_FAILED, NULL,
               "paths differ in change for key '%s'", txn_id);

          /* Verify that the NODE-REV-ID matches. */
          noderev_id = svn_fs_unparse_id(change->noderev_id, pool);
          if (strcmp(standard_changes[cur_change_index][2], noderev_id->data))
            return svn_error_createf
              (SVN_ERR_TEST_FAILED, NULL,
               "node revision ids differ in change for key '%s'", txn_id);

          /* Verify that the change KIND matches. */
          kind = string_to_kind(standard_changes[cur_change_index][3]);
          if (kind != change->kind)
            return svn_error_createf
              (SVN_ERR_TEST_FAILED, NULL,
               "change kinds differ in change for key '%s'", txn_id);

          /* Verify that the change TEXT-MOD bit matches. */
          mod_bit = standard_changes[cur_change_index][4] ? 1 : 0;
          if (mod_bit != change->text_mod)
            return svn_error_createf
              (SVN_ERR_TEST_FAILED, NULL,
               "change text-mod bits differ in change for key '%s'", txn_id);

          /* Verify that the change PROP-MOD bit matches. */
          mod_bit = standard_changes[cur_change_index][5] ? 1 : 0;
          if (mod_bit != change->prop_mod)
            return svn_error_createf
              (SVN_ERR_TEST_FAILED, NULL,
               "change prop-mod bits differ in change for key '%s'", txn_id);

          cur_change_index++;
        }
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
changes_delete(const svn_test_opts_t *opts,
               apr_pool_t *pool)
{
  svn_fs_t *fs;
  int i;
  int num_txns = sizeof(standard_txns) / sizeof(const char *);
  struct changes_args args;

  /* Create a new fs and repos */
  SVN_ERR(svn_test__create_bdb_fs(&fs, "test-repo-changes-delete", opts,
                                  pool));

  /* Add the standard slew of changes. */
  SVN_ERR(add_standard_changes(fs, pool));

  /* Now, delete all the changes we know about, verifying their removal. */
  for (i = 0; i < num_txns; i++)
    {
      args.fs = fs;
      args.key = standard_txns[i];
      SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_delete,
                                     &args, FALSE, pool));
      args.changes = 0;
      SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch_raw,
                                     &args, FALSE, pool));
      if ((! args.raw_changes) || (args.raw_changes->nelts))
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "expected empty changes array for txn '%s'", args.key);
    }

  return SVN_NO_ERROR;
}


static apr_hash_t *
get_ideal_changes(const char *txn_id,
                  apr_pool_t *pool)
{
  apr_hash_t *ideal = apr_hash_make(pool);
  svn_fs_path_change_t *change;
  if (strcmp(txn_id, "0") == 0)
    {
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("1.0.0", 5, pool);
      change->change_kind = svn_fs_path_change_add;
      change->text_mod = 0;
      change->prop_mod = 1;
      apr_hash_set(ideal, "/foo", APR_HASH_KEY_STRING, change);

      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("2.0.0", 5, pool);
      change->change_kind = svn_fs_path_change_add;
      change->text_mod = 1;
      change->prop_mod = 1;
      apr_hash_set(ideal, "/bar", APR_HASH_KEY_STRING, change);

      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("3.0.0", 5, pool);
      change->change_kind = svn_fs_path_change_add;
      change->text_mod = 1;
      change->prop_mod = 0;
      apr_hash_set(ideal, "/baz", APR_HASH_KEY_STRING, change);
    }
  if (strcmp(txn_id, "1") == 0)
    {
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("1.0.1", 5, pool);
      change->change_kind = svn_fs_path_change_modify;
      change->text_mod = 1;
      change->prop_mod = 0;
      apr_hash_set(ideal, "/foo", APR_HASH_KEY_STRING, change);
    }
  if (strcmp(txn_id, "2") == 0)
    {
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("1.0.2", 5, pool);
      change->change_kind = svn_fs_path_change_modify;
      change->text_mod = 0;
      change->prop_mod = 1;
      apr_hash_set(ideal, "/foo", APR_HASH_KEY_STRING, change);

      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("2.0.2", 5, pool);
      change->change_kind = svn_fs_path_change_modify;
      change->text_mod = 1;
      change->prop_mod = 0;
      apr_hash_set(ideal, "/bar", APR_HASH_KEY_STRING, change);
    }
  if (strcmp(txn_id, "3") == 0)
    {
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("3.0.3", 5, pool);
      change->change_kind = svn_fs_path_change_modify;
      change->text_mod = 1;
      change->prop_mod = 0;
      apr_hash_set(ideal, "/baz", APR_HASH_KEY_STRING, change);
    }
  if (strcmp(txn_id, "4") == 0)
    {
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("4.0.4", 5, pool);
      change->change_kind = svn_fs_path_change_add;
      change->text_mod = 1;
      change->prop_mod = 0;
      apr_hash_set(ideal, "/fob", APR_HASH_KEY_STRING, change);
    }
  if (strcmp(txn_id, "5") == 0)
    {
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("5.0.5", 5, pool);
      change->change_kind = svn_fs_path_change_replace;
      change->text_mod = 1;
      change->prop_mod = 1;
      apr_hash_set(ideal, "/baz", APR_HASH_KEY_STRING, change);
    }
  if (strcmp(txn_id, "6") == 0)
    {
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = svn_fs_parse_id("4.0.6", 5, pool);
      change->change_kind = svn_fs_path_change_modify;
      change->text_mod = 0;
      change->prop_mod = 1;
      apr_hash_set(ideal, "/fob", APR_HASH_KEY_STRING, change);
    }
  return ideal;
}


static svn_error_t *
compare_changes(apr_hash_t *ideals,
                apr_hash_t *changes,
                const svn_test_opts_t *opts,
                const char *txn_id,
                apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(pool, ideals); hi; hi = apr_hash_next(hi))
    {
      const void *key;
      void *val;
      svn_fs_path_change_t *ideal_change, *change;
      const char *path;

      /* KEY will be the path, VAL the change. */
      apr_hash_this(hi, &key, NULL, &val);
      path = (const char *) key;
      ideal_change = val;

      /* Now get the change that refers to PATH in the actual
         changes hash. */
      change = apr_hash_get(changes, path, APR_HASH_KEY_STRING);
      if (! change)
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "missing expected change for path '%s' in txn_id '%s'",
           path, txn_id);

      /* Verify that the NODE-REV-ID matches. */
      if (svn_fs_compare_ids(change->node_rev_id,
                             ideal_change->node_rev_id))
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "node revision ids differ in change for key '%s'", txn_id);

      /* Verify that the change KIND matches. */
      if (change->change_kind != ideal_change->change_kind)
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "change kinds differ in change for key '%s'", txn_id);

      /* Verify that the change TEXT-MOD bit matches. */
      if (change->text_mod != ideal_change->text_mod)
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "change text-mod bits differ in change for key '%s'", txn_id);

      /* Verify that the change PROP-MOD bit matches. */
      if (change->prop_mod != ideal_change->prop_mod)
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "change prop-mod bits differ in change for key '%s'", txn_id);
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
changes_fetch(const svn_test_opts_t *opts,
              apr_pool_t *pool)
{
  svn_fs_t *fs;
  int i;
  int num_txns = sizeof(standard_txns) / sizeof(const char *);
  struct changes_args args;

  /* Create a new fs and repos */
  SVN_ERR(svn_test__create_bdb_fs(&fs, "test-repo-changes-fetch", opts,
                                  pool));

  /* First, verify that we can request changes for an arbitrary key
     without error. */
  args.fs = fs;
  args.key = "blahbliggityblah";
  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_changes_fetch, &args,
                                 FALSE, pool));
  if ((! args.changes) || (apr_hash_count(args.changes)))
    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
                            "expected empty changes hash");

  /* Add the standard slew of changes. */
  SVN_ERR(add_standard_changes(fs, pool));

  /* For each transaction, fetch that transaction's changes, and
     compare those changes against our ideal compressed changes
     hash. */
  for (i = 0; i < num_txns; i++)
    {
      const char *txn_id = standard_txns[i];
      apr_hash_t *ideals;

      /* Get the ideal changes hash. */
      ideals = get_ideal_changes(txn_id, pool);

      /* Setup the trail baton. */
      args.fs = fs;
      args.key = txn_id;

      /* And get those changes via in the internal interface, and
         verify that they are accurate. */
      SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_changes_fetch, &args,
                                     FALSE, pool));
      if (! args.changes)
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "got no changes for key '%s'", txn_id);
      if (apr_hash_count(ideals) != apr_hash_count(args.changes))
        return svn_error_createf
          (SVN_ERR_TEST_FAILED, NULL,
           "unexpected number of changes for key '%s'", txn_id);
      SVN_ERR(compare_changes(ideals, args.changes, opts, txn_id, pool));
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
changes_fetch_ordering(const svn_test_opts_t *opts,
                       apr_pool_t *pool)
{
  svn_fs_t *fs;
  svn_revnum_t youngest_rev = 0;
  const char *txn_name;
  svn_fs_txn_t *txn;
  svn_fs_root_t *txn_root, *rev_root;
  struct changes_args args;
  apr_pool_t *subpool = svn_pool_create(pool);
  apr_hash_index_t *hi;

  /* Create a new fs and repos */
  SVN_ERR(svn_test__create_bdb_fs
          (&fs, "test-repo-changes-fetch-ordering", opts,
           pool));

  /*** REVISION 1: Make some files and dirs. ***/
  SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool));
  SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
  {
    static svn_test__txn_script_command_t script_entries[] = {
      { 'a', "dir1",        0 },
      { 'a', "file1",       "This is the file 'file1'.\n" },
      { 'a', "dir1/file2",  "This is the file 'file2'.\n" },
      { 'a', "dir1/file3",  "This is the file 'file3'.\n" },
      { 'a', "dir1/file4",  "This is the file 'file4'.\n" },
    };
    SVN_ERR(svn_test__txn_script_exec(txn_root, script_entries, 5, subpool));
  }
  SVN_ERR(svn_fs_commit_txn(NULL, &youngest_rev, txn, subpool));
  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
  svn_pool_clear(subpool);

  /*** REVISION 2: Delete and add some stuff, non-depth-first. ***/
  SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool));
  /* Don't use subpool, txn_name is used after subpool is cleared */
  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
  SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
  {
    static svn_test__txn_script_command_t script_entries[] = {
      { 'd', "file1",       "This is the file 'file1'.\n" },
      { 'd', "dir1/file2",  "This is the file 'file2'.\n" },
      { 'd', "dir1/file3",  "This is the file 'file3'.\n" },
      { 'a', "dir1/file5",  "This is the file 'file4'.\n" },
      { 'a', "dir1/dir2",   0 },
      { 'd', "dir1",        0 },
      { 'a', "dir3",        0 },
    };
    SVN_ERR(svn_test__txn_script_exec(txn_root, script_entries, 7, subpool));
  }
  SVN_ERR(svn_fs_commit_txn(NULL, &youngest_rev, txn, subpool));
  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
  svn_pool_clear(subpool);

  /*** TEST:  We should have only three changes, the deletion of 'file1'
       the deletion of 'dir1', and the addition of 'dir3'. ***/
  args.fs = fs;
  args.key = txn_name;
  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_changes_fetch, &args,
                                 FALSE, subpool));
  if ((! args.changes) || (apr_hash_count(args.changes) != 3))
    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
                            "expected changes");
  for (hi = apr_hash_first(subpool, args.changes);
       hi; hi = apr_hash_next(hi))
    {
      const void *key;
      void *val;
      svn_fs_path_change_t *change;

      /* KEY will be the path, VAL the change. */
      apr_hash_this(hi, &key, NULL, &val);
      change = val;

      if ((change->change_kind == svn_fs_path_change_add)
          && (strcmp(key, "/dir3") == 0))
        ;
      else if ((change->change_kind == svn_fs_path_change_delete)
               && ((strcmp(key, "/dir1") == 0)
                   || (strcmp(key, "/file1") == 0)))
        ;
      else
        return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
                                "got wrong changes");
    }

  /*** REVISION 3: Do the same stuff as in revision 1. ***/
  SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool));
  SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
  {
    static svn_test__txn_script_command_t script_entries[] = {
      { 'a', "dir1",        0 },
      { 'a', "file1",       "This is the file 'file1'.\n" },
      { 'a', "dir1/file2",  "This is the file 'file2'.\n" },
      { 'a', "dir1/file3",  "This is the file 'file3'.\n" },
      { 'a', "dir1/file4",  "This is the file 'file4'.\n" },
    };
    SVN_ERR(svn_test__txn_script_exec(txn_root, script_entries, 5, subpool));
  }
  SVN_ERR(svn_fs_commit_txn(NULL, &youngest_rev, txn, subpool));
  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
  svn_pool_clear(subpool);

  /*** REVISION 4: Do the same stuff as in revision 2, but use a copy
       overwrite of the top directory (instead of a delete) to test
       that the 'replace' change type works, too.  (And add 'dir4'
       instead of 'dir3', since 'dir3' still exists).  ***/
  SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool));
  /* Don't use subpool, txn_name is used after subpool is cleared */
  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
  SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
  SVN_ERR(svn_fs_revision_root(&rev_root, fs, 1, subpool));
  {
    static svn_test__txn_script_command_t script_entries[] = {
      { 'd', "file1",       "This is the file 'file1'.\n" },
      { 'd', "dir1/file2",  "This is the file 'file2'.\n" },
      { 'd', "dir1/file3",  "This is the file 'file3'.\n" },
      { 'a', "dir1/file5",  "This is the file 'file4'.\n" },
      { 'a', "dir1/dir2",   0 },
    };
    SVN_ERR(svn_test__txn_script_exec(txn_root, script_entries, 5, subpool));
    SVN_ERR(svn_fs_copy(rev_root, "dir1", txn_root, "dir1", subpool));
    SVN_ERR(svn_fs_make_dir(txn_root, "dir4", subpool));
  }
  SVN_ERR(svn_fs_commit_txn(NULL, &youngest_rev, txn, subpool));
  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
  svn_pool_clear(subpool);

  /*** TEST:  We should have only three changes, the deletion of 'file1'
       the replacement of 'dir1', and the addition of 'dir4'. ***/
  args.fs = fs;
  args.key = txn_name;
  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_changes_fetch, &args,
                                 FALSE, subpool));
  if ((! args.changes) || (apr_hash_count(args.changes) != 3))
    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
                            "expected changes");
  for (hi = apr_hash_first(subpool, args.changes);
       hi; hi = apr_hash_next(hi))
    {
      const void *key;
      void *val;
      svn_fs_path_change_t *change;

      /* KEY will be the path, VAL the change. */
      apr_hash_this(hi, &key, NULL, &val);
      change = val;

      if ((change->change_kind == svn_fs_path_change_add)
          && (strcmp(key, "/dir4") == 0))
        ;
      else if ((change->change_kind == svn_fs_path_change_replace)
               && (strcmp(key, "/dir1") == 0))
        ;
      else if ((change->change_kind == svn_fs_path_change_delete)
               && (strcmp(key, "/file1") == 0))
        ;
      else
        return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
                                "got wrong changes");
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
changes_bad_sequences(const svn_test_opts_t *opts,
                      apr_pool_t *pool)
{
  svn_fs_t *fs;
  apr_pool_t *subpool = svn_pool_create(pool);
  svn_error_t *err;

  /* Create a new fs and repos */
  SVN_ERR(svn_test__create_bdb_fs
          (&fs, "test-repo-changes-bad-sequences", opts,
           pool));

  /* Test changes bogus because a path's node-rev-ID changed
     unexpectedly. */
  svn_pool_clear(subpool);
  {
    static const char *bogus_changes[][6]
         /* KEY   PATH   NODEREVID  KIND       TEXT PROP */
      = { { "x",  "/foo",  "1.0.0",  "add",     0 ,  0  },
          { "x",  "/foo",  "1.0.0",  "modify",  0 , "1" },
          { "x",  "/foo",  "2.0.0",  "modify", "1", "1" } };
    int num_changes = sizeof(bogus_changes) / sizeof(const char *) / 6;
    struct changes_args args;
    int i;

    for (i = 0; i < num_changes; i++)
      {
        change_t change;

        /* Set up the current change item. */
        change.path = bogus_changes[i][1];
        change.noderev_id = svn_fs_parse_id(bogus_changes[i][2],
                                            strlen(bogus_changes[i][2]),
                                            subpool);
        change.kind = string_to_kind(bogus_changes[i][3]);
        change.text_mod = bogus_changes[i][4] ? 1 : 0;
        change.prop_mod = bogus_changes[i][5] ? 1 : 0;

        /* Set up transaction baton. */
        args.fs = fs;
        args.key = "x";
        args.change = &change;

        /* Write new changes to the changes table. */
        SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_add, &args,
                                       TRUE, subpool));
      }

    /* Now read 'em back, looking for an error. */
    args.fs = fs;
    args.key = "x";
    err = svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch, &args,
                                 TRUE, subpool);
    if (!err)
      {
        return svn_error_create(SVN_ERR_TEST_FAILED, 0,
                                "Expected SVN_ERR_FS_CORRUPT, got no error.");
      }
    else if (err->apr_err != SVN_ERR_FS_CORRUPT)
      {
        return svn_error_create(SVN_ERR_TEST_FAILED, err,
                                "Expected SVN_ERR_FS_CORRUPT, got a different error.");
      }
    else
      {
        svn_error_clear(err);
      }

    /* Post-test cleanup. */
    SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_delete, &args,
                                   TRUE, subpool));
  }

  /* Test changes bogus because there's a change other than an
     add-type changes on a deleted path. */
  svn_pool_clear(subpool);
  {
    static const char *bogus_changes[][6]
         /* KEY   PATH   NODEREVID  KIND       TEXT PROP */
      = { { "x",  "/foo",  "1.0.0",  "delete",  0 ,  0  },
          { "x",  "/foo",  "1.0.0",  "modify", "1",  0  } };
    int num_changes = sizeof(bogus_changes) / sizeof(const char *) / 6;
    struct changes_args args;
    int i;

    for (i = 0; i < num_changes; i++)
      {
        change_t change;

        /* Set up the current change item. */
        change.path = bogus_changes[i][1];
        change.noderev_id = svn_fs_parse_id(bogus_changes[i][2],
                                            strlen(bogus_changes[i][2]),
                                            subpool);
        change.kind = string_to_kind(bogus_changes[i][3]);
        change.text_mod = bogus_changes[i][4] ? 1 : 0;
        change.prop_mod = bogus_changes[i][5] ? 1 : 0;

        /* Set up transaction baton. */
        args.fs = fs;
        args.key = "x";
        args.change = &change;

        /* Write new changes to the changes table. */
        SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_add, &args,
                                       TRUE, subpool));
      }

    /* Now read 'em back, looking for an error. */
    args.fs = fs;
    args.key = "x";
    err = svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch, &args,
                                 TRUE, subpool);
    if (!err)
      {
        return svn_error_create(SVN_ERR_TEST_FAILED, 0,
                                "Expected SVN_ERR_FS_CORRUPT, got no error.");
      }
    else if (err->apr_err != SVN_ERR_FS_CORRUPT)
      {
        return svn_error_create(SVN_ERR_TEST_FAILED, err,
                                "Expected SVN_ERR_FS_CORRUPT, got a different error.");
      }
    else
      {
        svn_error_clear(err);
      }

    /* Post-test cleanup. */
    SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_delete, &args,
                                   TRUE, subpool));
  }

  /* Test changes bogus because there's an add on a path that's got
     previous non-delete changes on it. */
  svn_pool_clear(subpool);
  {
    static const char *bogus_changes[][6]
         /* KEY   PATH   NODEREVID  KIND       TEXT PROP */
      = { { "x",  "/foo",  "1.0.0",  "modify", "1",  0  },
          { "x",  "/foo",  "1.0.0",  "add",    "1",  0  } };
    int num_changes = sizeof(bogus_changes) / sizeof(const char *) / 6;
    struct changes_args args;
    int i;

    for (i = 0; i < num_changes; i++)
      {
        change_t change;

        /* Set up the current change item. */
        change.path = bogus_changes[i][1];
        change.noderev_id = svn_fs_parse_id(bogus_changes[i][2],
                                            strlen(bogus_changes[i][2]),
                                            subpool);
        change.kind = string_to_kind(bogus_changes[i][3]);
        change.text_mod = bogus_changes[i][4] ? 1 : 0;
        change.prop_mod = bogus_changes[i][5] ? 1 : 0;

        /* Set up transaction baton. */
        args.fs = fs;
        args.key = "x";
        args.change = &change;

        /* Write new changes to the changes table. */
        SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_add, &args,
                                       TRUE, subpool));
      }

    /* Now read 'em back, looking for an error. */
    args.fs = fs;
    args.key = "x";
    err = svn_fs_base__retry_txn(args.fs, txn_body_changes_fetch, &args,
                                 TRUE, subpool);
    if (!err)
      {
        return svn_error_create(SVN_ERR_TEST_FAILED, 0,
                                "Expected SVN_ERR_FS_CORRUPT, got no error.");
      }
    else if (err->apr_err != SVN_ERR_FS_CORRUPT)
      {
        return svn_error_create(SVN_ERR_TEST_FAILED, err,
                                "Expected SVN_ERR_FS_CORRUPT, got a different error.");
      }
    else
      {
        svn_error_clear(err);
      }

    /* Post-test cleanup. */
    SVN_ERR(svn_fs_base__retry_txn(args.fs, txn_body_changes_delete, &args,
                                   TRUE, subpool));
  }

  return SVN_NO_ERROR;
}



/* The test table.  */

static int max_threads = 4;

static struct svn_test_descriptor_t test_funcs[] =
  {
    SVN_TEST_NULL,
    SVN_TEST_OPTS_PASS(changes_add,
                       "add changes to the changes table"),
    SVN_TEST_OPTS_PASS(changes_fetch_raw,
                       "fetch raw changes from the changes table"),
    SVN_TEST_OPTS_PASS(changes_delete,
                       "delete changes from the changes table"),
    SVN_TEST_OPTS_PASS(changes_fetch,
                       "fetch compressed changes from the changes table"),
    SVN_TEST_OPTS_PASS(changes_fetch_ordering,
                       "verify ordered-ness of fetched compressed changes"),
    SVN_TEST_OPTS_PASS(changes_bad_sequences,
                       "verify that bad change sequences raise errors"),
    SVN_TEST_NULL
  };

SVN_TEST_MAIN
