You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/11/05 16:29:46 UTC

svn commit: r1539032 - /subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c

Author: rhuijben
Date: Tue Nov  5 15:29:45 2013
New Revision: 1539032

URL: http://svn.apache.org/r1539032
Log:
Extend the op-depth test framework with some helper code to verify which
conflicts are installed in a specific part of the working copy.

* subversion/tests/libsvn_wc/op-depth-test.c
  (includes): Add svn_hash.h.
  (conflict_info_t): New struct.
  (print_conflict,
   compare_conflict_info,
   check_db_conflicts): New functions.

  (update_prop_mod_into_moved,
   nested_move_update): Extend test with conflict verification.

Modified:
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c

Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1539032&r1=1539031&r2=1539032&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Tue Nov  5 15:29:45 2013
@@ -29,6 +29,7 @@
 
 #include "svn_private_config.h"
 #include "svn_types.h"
+#include "svn_hash.h"
 #include "svn_io.h"
 #include "svn_dirent_uri.h"
 #include "svn_pools.h"
@@ -104,6 +105,14 @@ typedef struct nodes_row_t {
     const char *props;  /* comma-separated list of prop names */
 } nodes_row_t;
 
+/* What conflicts are on a path. */
+typedef struct conflict_info_t {
+    const char *local_relpath;
+    svn_boolean_t text_conflicted;
+    svn_boolean_t prop_conflicted;
+    svn_boolean_t tree_conflicted;
+} conflict_info_t;
+
 /* Macro for filling in the REPO_* fields of a non-base NODES_ROW_T
  * that has no copy-from info. */
 #define NO_COPY_FROM SVN_INVALID_REVNUM, NULL, FALSE
@@ -332,6 +341,146 @@ check_db_rows(svn_test__sandbox_t *b,
 }
 
 
+static const char *
+print_conflict(const conflict_info_t *row,
+               apr_pool_t *result_pool)
+{
+  return apr_psprintf(result_pool, "\"%s\", %s, %s, %s",
+                      row->local_relpath,
+                      row->text_conflicted ? "TRUE" : "FALSE",
+                      row->prop_conflicted ? "TRUE" : "FALSE",
+                      row->tree_conflicted ? "TRUE" : "FALSE");
+}
+
+static svn_error_t *
+compare_conflict_info(const void *key, apr_ssize_t klen,
+                      enum svn_hash_diff_key_status status,
+                      void *baton)
+{
+  comparison_baton_t *b = baton;
+  conflict_info_t *expected = apr_hash_get(b->expected_hash, key, klen);
+  conflict_info_t *found = apr_hash_get(b->found_hash, key, klen);
+
+  if (! expected)
+    {
+      b->errors = svn_error_createf(
+                    SVN_ERR_TEST_FAILED, b->errors,
+                    "found   {%s}",
+                    print_conflict(found, b->scratch_pool));
+    }
+  else if (! found)
+    {
+      b->errors = svn_error_createf(
+                    SVN_ERR_TEST_FAILED, b->errors,
+                    "expected {%s}",
+                    print_conflict(expected, b->scratch_pool));
+    }
+  else if (expected->text_conflicted != found->text_conflicted
+           || expected->prop_conflicted != found->prop_conflicted
+           || expected->tree_conflicted != found->tree_conflicted)
+    {
+      b->errors = svn_error_createf(
+                    SVN_ERR_TEST_FAILED, b->errors,
+                    "expected {%s}; found {%s}",
+                    print_conflict(expected, b->scratch_pool),
+                    print_conflict(found, b->scratch_pool));
+    }
+
+  /* Don't terminate the comparison: accumulate all differences. */
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+check_db_conflicts(svn_test__sandbox_t *b,
+                   const char *root_path,
+                   const conflict_info_t *expected_conflicts)
+{
+  const char *base_relpath = root_path;
+  svn_sqlite__db_t *sdb;
+  int i;
+  svn_sqlite__stmt_t *stmt;
+  static const char *const statements[] = {
+    "SELECT local_relpath"
+    " FROM actual_node "
+    " WHERE conflict_data is NOT NULL "
+    "   AND local_relpath = ?1 OR local_relpath LIKE ?2",
+    NULL };
+#define STMT_SELECT_ACTUAL_INFO 0
+
+  svn_boolean_t have_row;
+  apr_hash_t *found_hash = apr_hash_make(b->pool);
+  apr_hash_t *expected_hash = apr_hash_make(b->pool);
+  apr_pool_t *iterpool = svn_pool_create(b->pool);
+  apr_hash_index_t *hi;
+  comparison_baton_t comparison_baton;
+
+  comparison_baton.expected_hash = expected_hash;
+  comparison_baton.found_hash = found_hash;
+  comparison_baton.scratch_pool = b->pool;
+  comparison_baton.errors = NULL;
+
+  /* Fill ACTUAL_HASH with data from the WC DB. */
+  SVN_ERR(open_wc_db(&sdb, b->wc_abspath, statements, b->pool, b->pool));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ACTUAL_INFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "ss", base_relpath,
+                            (base_relpath[0]
+                             ? apr_psprintf(b->pool, "%s/%%", base_relpath)
+                             : "_%")));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  while (have_row)
+    {
+      conflict_info_t *row = apr_palloc(b->pool, sizeof(*row));
+
+      row->local_relpath = svn_sqlite__column_text(stmt, 0, b->pool);
+
+      svn_hash_sets(found_hash, row->local_relpath, row);
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(svn_sqlite__close(sdb));
+
+  for (hi = apr_hash_first(b->pool, found_hash); hi; hi = apr_hash_next(hi))
+    {
+      svn_skel_t *conflict;
+      conflict_info_t *info = svn__apr_hash_index_val(hi);
+      const char *local_abspath;
+
+      svn_pool_clear(iterpool);
+
+      local_abspath = svn_dirent_join(b->wc_abspath, info->local_relpath,
+                                      iterpool);
+
+      SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db, local_abspath,
+                                       iterpool, iterpool));
+
+      SVN_TEST_ASSERT(conflict != NULL);
+
+      SVN_ERR(svn_wc__conflict_read_info(NULL, NULL,
+                                         &info->text_conflicted,
+                                         &info->prop_conflicted,
+                                         &info->tree_conflicted,
+                                         b->wc_ctx->db, local_abspath,
+                                         conflict,
+                                         iterpool, iterpool));
+    }
+
+  /* Fill EXPECTED_HASH with data from EXPECTED_ROWS. */
+  if (expected_conflicts)
+    for (i = 0; expected_conflicts[i].local_relpath != NULL; i++)
+      {
+        const conflict_info_t *row = &expected_conflicts[i];
+
+        svn_hash_sets(expected_hash, row->local_relpath, row);
+      }
+
+  /* Compare EXPECTED_HASH with ACTUAL_HASH and return any errors. */
+  SVN_ERR(svn_hash_diff(expected_hash, found_hash,
+                        compare_conflict_info, &comparison_baton, b->pool));
+  return comparison_baton.errors;
+}
+
+
 /* ---------------------------------------------------------------------- */
 /* The test functions */
 
@@ -5215,9 +5364,21 @@ update_prop_mod_into_moved(const svn_tes
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
 
+  {
+    conflict_info_t conflicts[] = {
+      { "A", FALSE, FALSE, TRUE },
+      {0}
+    };
+
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
+
   /* Resolve should update the move. */
   SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
                           svn_wc_conflict_choose_mine_conflict));
+
+  SVN_ERR(check_db_conflicts(&b, "", NULL));
+
   {
     nodes_row_t nodes[] = {
       {0, "",         "normal",       2, ""},
@@ -5326,6 +5487,8 @@ nested_move_update(const svn_test_opts_t
 
   /* Update A to r3 brings no changes but updates the revisions. */
   SVN_ERR(sbox_wc_update(&b, "A", 3));
+  SVN_ERR(check_db_conflicts(&b, "", NULL /* no conflicts */));
+
   {
     nodes_row_t nodes[] = {
       {0, "",          "normal",       2, ""},