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 2015/02/12 17:14:29 UTC
svn commit: r1659301 [3/3] - in /subversion/branches/pin-externals: ./
subversion/include/private/ subversion/libsvn_delta/
subversion/libsvn_fs_base/ subversion/libsvn_fs_fs/
subversion/libsvn_repos/ subversion/libsvn_subr/ subversion/libsvn_wc/
subve...
Modified: subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c?rev=1659301&r1=1659300&r2=1659301&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c Thu Feb 12 16:14:28 2015
@@ -41,8 +41,6 @@
#include "../svn_test_fs.h"
#include "../../libsvn_ra_local/ra_local.h"
-static const char tunnel_repos_name[] = "test-repo-tunnel";
-
/*-------------------------------------------------------------------*/
/** Helper routines. **/
@@ -136,18 +134,36 @@ commit_tree(svn_ra_session_t *session,
return SVN_NO_ERROR;
}
-static svn_boolean_t last_tunnel_check;
-static int tunnel_open_count;
-static void *check_tunnel_baton;
-static void *open_tunnel_context;
+/* Baton for opening tunnels */
+typedef struct tunnel_baton_t
+{
+ int magic; /* TUNNEL_MAGIC */
+ int open_count;
+ svn_boolean_t last_check;
+} tunnel_baton_t;
+
+#define TUNNEL_MAGIC 0xF00DF00F
+
+/* Baton for closing a specific tunnel */
+typedef struct close_baton_t
+{
+ int magic;
+ tunnel_baton_t *tb;
+ apr_proc_t *proc;
+} close_baton_t;
+
+#define CLOSE_MAGIC 0x1BADBAD1
static svn_boolean_t
check_tunnel(void *tunnel_baton, const char *tunnel_name)
{
- if (tunnel_baton != check_tunnel_baton)
+ tunnel_baton_t *b = tunnel_baton;
+
+ if (b->magic != TUNNEL_MAGIC)
abort();
- last_tunnel_check = (0 == strcmp(tunnel_name, "test"));
- return last_tunnel_check;
+
+ b->last_check = (0 == strcmp(tunnel_name, "test"));
+ return b->last_check;
}
static void
@@ -168,8 +184,10 @@ open_tunnel(svn_stream_t **request, svn_
apr_status_t status;
const char *args[] = { "svnserve", "-t", "-r", ".", NULL };
const char *svnserve;
+ tunnel_baton_t *b = tunnel_baton;
+ close_baton_t *cb;
- SVN_TEST_ASSERT(tunnel_baton == check_tunnel_baton);
+ SVN_TEST_ASSERT(b->magic == TUNNEL_MAGIC);
SVN_ERR(svn_dirent_get_absolute(&svnserve, "../../svnserve/svnserve", pool));
#ifdef WIN32
@@ -193,11 +211,7 @@ open_tunnel(svn_stream_t **request, svn_
args, NULL, attr, pool);
if (status != APR_SUCCESS)
return svn_error_wrap_apr(status, "Could not run svnserve");
-#ifdef WIN32
apr_pool_note_subprocess(pool, proc, APR_KILL_NEVER);
-#else
- apr_pool_note_subprocess(pool, proc, APR_KILL_ONLY_ONCE);
-#endif
/* APR pipe objects inherit by default. But we don't want the
* tunnel agent's pipes held open by future child processes
@@ -205,20 +219,42 @@ open_tunnel(svn_stream_t **request, svn_
apr_file_inherit_unset(proc->in);
apr_file_inherit_unset(proc->out);
+ cb = apr_pcalloc(pool, sizeof(*cb));
+ cb->magic = CLOSE_MAGIC;
+ cb->tb = b;
+ cb->proc = proc;
+
*request = svn_stream_from_aprfile2(proc->in, FALSE, pool);
*response = svn_stream_from_aprfile2(proc->out, FALSE, pool);
*close_func = close_tunnel;
- open_tunnel_context = *close_baton = &last_tunnel_check;
- ++tunnel_open_count;
+ *close_baton = cb;
+ ++b->open_count;
return SVN_NO_ERROR;
}
static void
close_tunnel(void *tunnel_context, void *tunnel_baton)
{
- assert(tunnel_context == open_tunnel_context);
- assert(tunnel_baton == check_tunnel_baton);
- --tunnel_open_count;
+ close_baton_t *b = tunnel_context;
+
+ if (b->magic != CLOSE_MAGIC)
+ abort();
+ if (--b->tb->open_count == 0)
+ {
+ apr_status_t child_exit_status;
+ int child_exit_code;
+ apr_exit_why_e child_exit_why;
+
+ SVN_TEST_ASSERT_NO_RETURN(0 == apr_file_close(b->proc->in));
+ SVN_TEST_ASSERT_NO_RETURN(0 == apr_file_close(b->proc->out));
+
+ child_exit_status =
+ apr_proc_wait(b->proc, &child_exit_code, &child_exit_why, APR_WAIT);
+
+ SVN_TEST_ASSERT_NO_RETURN(child_exit_status == APR_CHILD_DONE);
+ SVN_TEST_ASSERT_NO_RETURN(child_exit_code == 0);
+ SVN_TEST_ASSERT_NO_RETURN(child_exit_why == APR_PROC_EXIT);
+ }
}
@@ -293,6 +329,7 @@ static svn_error_t *
check_tunnel_callback_test(const svn_test_opts_t *opts,
apr_pool_t *pool)
{
+ tunnel_baton_t b = { TUNNEL_MAGIC };
svn_ra_callbacks2_t *cbtable;
svn_ra_session_t *session;
svn_error_t *err;
@@ -300,7 +337,7 @@ check_tunnel_callback_test(const svn_tes
SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
cbtable->check_tunnel_func = check_tunnel;
cbtable->open_tunnel_func = open_tunnel;
- cbtable->tunnel_baton = check_tunnel_baton = &cbtable;
+ cbtable->tunnel_baton = &b;
SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton,
TRUE /* non_interactive */,
"jrandom", "rayjandom",
@@ -309,13 +346,12 @@ check_tunnel_callback_test(const svn_tes
FALSE /* trust_server_cert */,
NULL, NULL, NULL, pool));
- last_tunnel_check = TRUE;
- open_tunnel_context = NULL;
+ b.last_check = TRUE;
err = svn_ra_open4(&session, NULL, "svn+foo://localhost/no-repo",
NULL, cbtable, NULL, NULL, pool);
svn_error_clear(err);
SVN_TEST_ASSERT(err);
- SVN_TEST_ASSERT(!last_tunnel_check);
+ SVN_TEST_ASSERT(!b.last_check);
return SVN_NO_ERROR;
}
@@ -323,21 +359,26 @@ static svn_error_t *
tunnel_callback_test(const svn_test_opts_t *opts,
apr_pool_t *pool)
{
- apr_pool_t *connection_pool;
- svn_repos_t *repos;
+ tunnel_baton_t b = { TUNNEL_MAGIC };
+ apr_pool_t *scratch_pool = svn_pool_create(pool);
const char *url;
svn_ra_callbacks2_t *cbtable;
svn_ra_session_t *session;
svn_error_t *err;
+ const char tunnel_repos_name[] = "test-repo-tunnel";
+
+ SVN_ERR(svn_test__create_repos(NULL, tunnel_repos_name, opts, scratch_pool));
- SVN_ERR(svn_test__create_repos(&repos, tunnel_repos_name, opts, pool));
+ /* Immediately close the repository to avoid race condition with svnserve
+ (and then the cleanup code) with BDB when our pool is cleared. */
+ svn_pool_clear(scratch_pool);
url = apr_pstrcat(pool, "svn+test://localhost/", tunnel_repos_name,
SVN_VA_NULL);
SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
cbtable->check_tunnel_func = check_tunnel;
cbtable->open_tunnel_func = open_tunnel;
- cbtable->tunnel_baton = check_tunnel_baton = &cbtable;
+ cbtable->tunnel_baton = &b;
SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton,
TRUE /* non_interactive */,
"jrandom", "rayjandom",
@@ -346,12 +387,9 @@ tunnel_callback_test(const svn_test_opts
FALSE /* trust_server_cert */,
NULL, NULL, NULL, pool));
- last_tunnel_check = FALSE;
- open_tunnel_context = NULL;
- tunnel_open_count = 0;
- connection_pool = svn_pool_create(pool);
+ b.last_check = FALSE;
err = svn_ra_open4(&session, NULL, url, NULL, cbtable, NULL, NULL,
- connection_pool);
+ scratch_pool);
if (err && err->apr_err == SVN_ERR_TEST_FAILED)
{
svn_handle_error2(err, stderr, FALSE, "svn_tests: ");
@@ -359,10 +397,10 @@ tunnel_callback_test(const svn_test_opts
return SVN_NO_ERROR;
}
SVN_ERR(err);
- SVN_TEST_ASSERT(last_tunnel_check);
- SVN_TEST_ASSERT(tunnel_open_count > 0);
- svn_pool_destroy(connection_pool);
- SVN_TEST_ASSERT(tunnel_open_count == 0);
+ SVN_TEST_ASSERT(b.last_check);
+ SVN_TEST_ASSERT(b.open_count > 0);
+ svn_pool_destroy(scratch_pool);
+ SVN_TEST_ASSERT(b.open_count == 0);
return SVN_NO_ERROR;
}
Modified: subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c?rev=1659301&r1=1659300&r2=1659301&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c Thu Feb 12 16:14:28 2015
@@ -105,12 +105,22 @@ typedef struct nodes_row_t {
const char *props; /* comma-separated list of prop names */
} nodes_row_t;
+/* Tree conflict details */
+typedef struct tree_conflict_info
+{
+ svn_wc_conflict_action_t action;
+ svn_wc_conflict_reason_t reason;
+ const char *delete_path;
+ svn_boolean_t conflicted_fb; /* fallback for reason, action and path 0 */
+} tree_conflict_info;
+
/* 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;
+
+ tree_conflict_info tc;
} conflict_info_t;
/* Macro for filling in the REPO_* fields of a non-base NODES_ROW_T
@@ -263,7 +273,6 @@ check_db_rows(svn_test__sandbox_t *b,
const char *root_path,
const nodes_row_t *expected_rows)
{
- const char *base_relpath = root_path;
svn_sqlite__db_t *sdb;
int i;
svn_sqlite__stmt_t *stmt;
@@ -281,10 +290,8 @@ check_db_rows(svn_test__sandbox_t *b,
/* Fill ACTUAL_HASH with data from the WC DB. */
SVN_ERR(open_wc_db(&sdb, b->wc_abspath, b->pool, b->pool));
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_NODES_INFO));
- SVN_ERR(svn_sqlite__bindf(stmt, "ss", base_relpath,
- (base_relpath[0]
- ? apr_psprintf(b->pool, "%s/%%", base_relpath)
- : "_%")));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", (apr_int64_t)1 /* wc_id */,
+ root_path));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while (have_row)
{
@@ -332,16 +339,84 @@ check_db_rows(svn_test__sandbox_t *b,
return comparison_baton.errors;
}
-
+#define EDIT_EDIT_TC {svn_wc_conflict_reason_edited, \
+ svn_wc_conflict_action_edit, \
+ NULL, TRUE}
+#define NO_TC { 0 }
static const char *
print_conflict(const conflict_info_t *row,
apr_pool_t *result_pool)
{
+ const char *tc_text;
+
+ if (!row->tc.reason && !row->tc.action && !row->tc.delete_path)
+ {
+ if (row->tc.conflicted_fb)
+ tc_text = "EDIT_EDIT_TC";
+ else
+ tc_text = "NO_TC";
+ }
+ else
+ {
+ const char *action;
+ const char *reason;
+ const char *path;
+
+#define CASE_ENUM_STRVAL(x, y) case y: x = #y; break
+ switch(row->tc.action)
+ {
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_edit);
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_add);
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_delete);
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_replace);
+ default:
+ SVN_ERR_MALFUNCTION_NO_RETURN();
+ }
+ switch(row->tc.reason)
+ {
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_edited);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_obstructed);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_deleted);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_missing);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_unversioned);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_added);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_replaced);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_moved_away);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_moved_here);
+ default:
+ SVN_ERR_MALFUNCTION_NO_RETURN();
+ }
+
+ if (row->tc.delete_path)
+ path = apr_psprintf(result_pool, ", \"%s\"", row->tc.delete_path);
+ else
+ path = "";
+
+ tc_text = apr_psprintf(result_pool, "{%s, %s%s}", action,
+ reason, path);
+ }
+
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");
+ tc_text);
+}
+
+static svn_boolean_t
+tree_conflicts_match(const tree_conflict_info *expected,
+ const tree_conflict_info *actual)
+{
+ if (expected->action != actual->action)
+ return FALSE;
+ else if (expected->reason != actual->reason)
+ return FALSE;
+ else if (strcmp_null(expected->delete_path, actual->delete_path) != 0)
+ return FALSE;
+ else if (expected->conflicted_fb != actual->conflicted_fb)
+ return FALSE;
+
+ return TRUE;
}
static svn_error_t *
@@ -369,7 +444,7 @@ compare_conflict_info(const void *key, a
}
else if (expected->text_conflicted != found->text_conflicted
|| expected->prop_conflicted != found->prop_conflicted
- || expected->tree_conflicted != found->tree_conflicted)
+ || !tree_conflicts_match(&expected->tc, &found->tc))
{
b->errors = svn_error_createf(
SVN_ERR_TEST_FAILED, b->errors,
@@ -387,7 +462,6 @@ check_db_conflicts(svn_test__sandbox_t *
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;
@@ -407,14 +481,12 @@ check_db_conflicts(svn_test__sandbox_t *
/* Fill ACTUAL_HASH with data from the WC DB. */
SVN_ERR(open_wc_db(&sdb, b->wc_abspath, 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__bindf(stmt, "is", (apr_int64_t)1 /* wc_id */,
+ root_path));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while (have_row)
{
- conflict_info_t *row = apr_palloc(b->pool, sizeof(*row));
+ conflict_info_t *row = apr_pcalloc(b->pool, sizeof(*row));
row->local_relpath = svn_sqlite__column_text(stmt, 0, b->pool);
@@ -430,6 +502,7 @@ check_db_conflicts(svn_test__sandbox_t *
svn_skel_t *conflict;
conflict_info_t *info = apr_hash_this_val(hi);
const char *local_abspath;
+ svn_boolean_t tree_conflicted;
svn_pool_clear(iterpool);
@@ -444,10 +517,33 @@ check_db_conflicts(svn_test__sandbox_t *
SVN_ERR(svn_wc__conflict_read_info(NULL, NULL,
&info->text_conflicted,
&info->prop_conflicted,
- &info->tree_conflicted,
+ &tree_conflicted,
b->wc_ctx->db, local_abspath,
conflict,
iterpool, iterpool));
+
+ if (tree_conflicted)
+ {
+ const char *move_src_abspath;
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(&info->tc.reason,
+ &info->tc.action,
+ &move_src_abspath,
+ b->wc_ctx->db,
+ local_abspath,
+ conflict,
+ b->pool, iterpool));
+
+ if (move_src_abspath)
+ info->tc.delete_path =
+ svn_dirent_skip_ancestor(b->wc_abspath, move_src_abspath);
+
+ if (!info->tc.reason
+ && !info->tc.action
+ && !info->tc.delete_path)
+ {
+ info->tc.conflicted_fb = TRUE;
+ }
+ }
}
/* Fill EXPECTED_HASH with data from EXPECTED_ROWS. */
@@ -1159,29 +1255,17 @@ insert_dirs(svn_test__sandbox_t *b,
while(nodes->local_relpath)
{
- if (nodes->local_relpath[0])
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "sdssrs",
- nodes->local_relpath,
- nodes->op_depth,
- nodes->presence,
- nodes->repo_relpath,
- nodes->repo_revnum,
- svn_relpath_dirname(nodes->local_relpath,
- b->pool)));
- }
- else
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE_ROOT));
- SVN_ERR(svn_sqlite__bindf(stmt, "sdssr",
- nodes->local_relpath,
- nodes->op_depth,
- nodes->presence,
- nodes->repo_relpath,
- nodes->repo_revnum));
- }
-
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "sdssrs",
+ nodes->local_relpath,
+ nodes->op_depth,
+ nodes->presence,
+ nodes->repo_relpath,
+ nodes->repo_revnum,
+ nodes->local_relpath[0]
+ ? svn_relpath_dirname(nodes->local_relpath,
+ b->pool)
+ : NULL));
SVN_ERR(svn_sqlite__step_done(stmt));
++nodes;
}
@@ -1949,22 +2033,14 @@ insert_actual(svn_test__sandbox_t *b,
while(actual->local_relpath)
{
- if (actual->local_relpath[0])
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL));
- SVN_ERR(svn_sqlite__bindf(stmt, "sss",
- actual->local_relpath,
- svn_relpath_dirname(actual->local_relpath,
- b->pool),
- actual->changelist));
- }
- else
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL_ROOT));
- SVN_ERR(svn_sqlite__bindf(stmt, "ss",
- actual->local_relpath,
- actual->changelist));
- }
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL));
+ SVN_ERR(svn_sqlite__bindf(stmt, "sss",
+ actual->local_relpath,
+ actual->local_relpath[0]
+ ? svn_relpath_dirname(actual->local_relpath,
+ b->pool)
+ : NULL,
+ actual->changelist));
SVN_ERR(svn_sqlite__step_done(stmt));
if (actual->changelist)
{
@@ -5315,7 +5391,7 @@ mixed_rev_move(const svn_test_opts_t *op
{
conflict_info_t conflicts[] = {
- { "X/D", FALSE, FALSE, TRUE },
+ { "X/D", FALSE, FALSE, {0 /* ### Needs fixing */} },
{0}
};
@@ -5421,7 +5497,8 @@ update_prop_mod_into_moved(const svn_tes
{
conflict_info_t conflicts[] = {
- { "A", FALSE, FALSE, TRUE },
+ { "A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A"}},
{0}
};
@@ -6191,6 +6268,34 @@ move_in_delete(const svn_test_opts_t *op
}
SVN_ERR(sbox_wc_update(&b, "", 3));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, ""},
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/D", "normal", 3, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 3, "A/B/C/D/E"},
+
+ {1, "C2", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "C2/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+
+ {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+
+ {0}
+ };
+ conflict_info_t conflicts[] = {
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
SVN_ERR(sbox_wc_revert(&b, "A/B", svn_depth_empty));
{
nodes_row_t nodes[] = {
@@ -6207,7 +6312,14 @@ move_in_delete(const svn_test_opts_t *op
{1, "C2/D", "normal", 2, "A/B/C/D", MOVED_HERE},
{0}
};
+ conflict_info_t conflicts[] = {
+ {"A/B/C", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B/C"}},
+ {0}
+ };
SVN_ERR(check_db_rows(&b, "", nodes));
+ /* Where did this conflict come from? */
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
}
/* Revert should have left a tree-conflict (or broken the move). */
@@ -6230,6 +6342,7 @@ move_in_delete(const svn_test_opts_t *op
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
}
return SVN_NO_ERROR;
@@ -6889,8 +7002,10 @@ finite_move_update_bump(const svn_test_o
SVN_ERR(sbox_wc_update_depth(&b, "P/Q", 2, svn_depth_files, FALSE));
{
conflict_info_t conflicts[] = {
- {"A/B", FALSE, FALSE, TRUE},
- {"P/Q", FALSE, FALSE, TRUE},
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B"}},
+ {"P/Q", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "P/Q"}},
{0}
};
SVN_ERR(check_db_conflicts(&b, "", conflicts));
@@ -6936,8 +7051,10 @@ finite_move_update_bump(const svn_test_o
SVN_ERR(sbox_wc_update_depth(&b, "P", 2, svn_depth_immediates, FALSE));
{
conflict_info_t conflicts[] = {
- {"A/B", FALSE, FALSE, TRUE},
- {"P", FALSE, FALSE, TRUE},
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B"}},
+ {"P", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "P"}},
{0}
};
SVN_ERR(check_db_conflicts(&b, "", conflicts));
@@ -6981,8 +7098,11 @@ finite_move_update_bump(const svn_test_o
SVN_ERR(sbox_wc_update_depth(&b, "P/Q", 2, svn_depth_empty, FALSE));
{
conflict_info_t conflicts[] = {
- {"A/B/C", FALSE, FALSE, TRUE},
- {"P/Q", FALSE, FALSE, TRUE},
+ {"A/B/C", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B/C"}},
+ {"P/Q", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "P/Q"}},
+
{0}
};
SVN_ERR(check_db_conflicts(&b, "", conflicts));
@@ -9342,11 +9462,14 @@ del4_update_edit_AAA(const svn_test_opts
SVN_ERR(sbox_wc_update(&b, "", 2));
{
conflict_info_t conflicts[] = {
- {"A", FALSE, FALSE, TRUE},
- {"B", FALSE, FALSE, TRUE},
- {"C/A", FALSE, FALSE, TRUE},
- {"D/A/A", FALSE, FALSE, TRUE},
-
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
{0},
};
@@ -9481,10 +9604,14 @@ del4_update_delself_AAA(const svn_test_o
{
conflict_info_t conflicts[] = {
- {"A", FALSE, FALSE, TRUE},
- {"B", FALSE, FALSE, TRUE},
- {"C/A", FALSE, FALSE, TRUE},
- {"D/A/A", FALSE, FALSE, TRUE},
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
{0}
};
@@ -9534,11 +9661,14 @@ del4_update_delself_AAA(const svn_test_o
{
conflict_info_t conflicts[] = {
/* Not resolved yet */
- {"D/A/A", FALSE, FALSE, TRUE},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
/* New */
- {"A/A", FALSE, FALSE, TRUE},
- {"A/A/A", FALSE, FALSE, TRUE},
+ {"A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {"A/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "A/A/A"}},
{0}
};
@@ -9556,7 +9686,40 @@ del4_update_delself_AAA(const svn_test_o
SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
/* Go back to start position */
SVN_ERR(sbox_wc_update(&b, "", 1));
- SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ conflict_info_t conflicts[] = {
+ {"A/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {"A/A/A", FALSE, FALSE, { svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
+ svn_wc_conflict_choose_mine_conflict));
/* Update and resolve via their strategy */
SVN_ERR(sbox_wc_update(&b, "", 2));
SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
@@ -9859,14 +10022,46 @@ move4_update_delself_AAA(const svn_test_
{ 0 },
};
- SVN_ERR(check_db_rows(&b, "", nodes));
+
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A"}},
+ {"B", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
}
- SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
- /* Update and resolve via their strategy */
- SVN_ERR(sbox_wc_update(&b, "", 2));
- SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
- return SVN_NO_ERROR;
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ conflict_info_t conflicts[] = {
+ {"A/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/A"}},
+ {"A/A/A", FALSE, FALSE, { svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -10061,8 +10256,35 @@ movedhere_extract_retract(const svn_test
SVN_ERR(sbox_wc_mkdir(&b, "Z/E2"));
SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
svn_wc_conflict_choose_mine_conflict));
+ {
+ conflict_info_t conflicts[] = {
+ {"Z/B1", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {"Z/B2", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "Z/B2"}},
+ {"Z/C1", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_deleted}},
+ {"Z/C2", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "Z/C2"}},
+ {"Z/E2", FALSE, FALSE, {svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added}},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
SVN_ERR(sbox_wc_resolve(&b, "Z/B1", svn_depth_empty,
svn_wc_conflict_choose_mine_conflict));
SVN_ERR(sbox_wc_resolve(&b, "Z/B2", svn_depth_empty,
@@ -10073,8 +10295,10 @@ movedhere_extract_retract(const svn_test
SVN_ERR(sbox_wc_resolve(&b, "Z/C2", svn_depth_empty,
svn_wc_conflict_choose_merged));
- SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
- svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "Z/E2", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
{
nodes_row_t nodes[] = {
@@ -10129,6 +10353,8 @@ movedhere_extract_retract(const svn_test
{ 0 },
};
SVN_ERR(check_db_rows(&b, "", nodes));
+
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
}
return SVN_NO_ERROR;
@@ -10255,11 +10481,13 @@ break_move_in_delete(const svn_test_opts
{0}
};
conflict_info_t conflicts1[] = {
- {"X", FALSE, FALSE, TRUE},
+ {"X", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
{0}
};
conflict_info_t conflicts2[] = {
- {"X/Y/Z", FALSE, FALSE, TRUE},
+ {"X/Y/Z", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "X"}},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
@@ -10286,6 +10514,7 @@ break_move_in_delete(const svn_test_opts
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
}
return SVN_NO_ERROR;
@@ -10668,9 +10897,10 @@ move_edit_obstruction(const svn_test_opt
{0}
};
conflict_info_t conflicts[] = {
- { "A_mv/B/E/alpha", FALSE, FALSE, TRUE },
- { "A_mv/B/F", FALSE, FALSE, TRUE },
-
+ {"A_mv/B/E/alpha", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_obstructed}},
+ {"A_mv/B/F", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_obstructed}},
{0}
};
Modified: subversion/branches/pin-externals/subversion/tests/libsvn_wc/wc-test-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_wc/wc-test-queries.sql?rev=1659301&r1=1659300&r2=1659301&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/libsvn_wc/wc-test-queries.sql (original)
+++ subversion/branches/pin-externals/subversion/tests/libsvn_wc/wc-test-queries.sql Thu Feb 12 16:14:28 2015
@@ -22,28 +22,26 @@
*/
-- STMT_SELECT_NODES_INFO
-SELECT op_depth, nodes.presence, nodes.local_relpath, revision,
+SELECT op_depth, n.presence, n.local_relpath, revision,
repos_path, file_external, def_local_relpath, moved_to, moved_here,
properties
-FROM nodes
-LEFT OUTER JOIN externals
- ON nodes.wc_id = externals.wc_id
- AND nodes.local_relpath = externals.local_relpath
-WHERE nodes.local_relpath = ?1 OR nodes.local_relpath LIKE ?2
+FROM nodes n
+LEFT OUTER JOIN externals e
+ ON n.wc_id = e.wc_id
+ AND n.local_relpath = e.local_relpath
+WHERE n.wc_id = ?1
+ AND (n.local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2))
-- STMT_SELECT_ACTUAL_INFO
SELECT local_relpath
FROM actual_node
-WHERE conflict_data is NOT NULL AND local_relpath = ?1 OR local_relpath LIKE ?2
+WHERE wc_id = ?1
+ AND conflict_data is NOT NULL
+ AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
-- STMT_DELETE_NODES
DELETE FROM nodes;
--- STMT_INSERT_NODE_ROOT
-INSERT INTO nodes (local_relpath, op_depth, presence, repos_path,
- revision, wc_id, repos_id, kind, depth)
- VALUES (?1, ?2, ?3, ?4, ?5, 1, 1, 'dir', 'infinity');
-
-- STMT_INSERT_NODE
INSERT INTO nodes (local_relpath, op_depth, presence, repos_path,
revision, parent_relpath, wc_id, repos_id, kind, depth)
@@ -52,10 +50,6 @@ INSERT INTO nodes (local_relpath, op_dep
-- STMT_DELETE_ACTUAL
DELETE FROM actual_node;
--- STMT_INSERT_ACTUAL_ROOT
-INSERT INTO actual_node (local_relpath, changelist, wc_id)
- VALUES (?1, ?2, 1)
-
-- STMT_INSERT_ACTUAL
INSERT INTO actual_node (local_relpath, parent_relpath, changelist, wc_id)
VALUES (?1, ?2, ?3, 1)
Modified: subversion/branches/pin-externals/subversion/tests/svn_test.h
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/svn_test.h?rev=1659301&r1=1659300&r2=1659301&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/svn_test.h (original)
+++ subversion/branches/pin-externals/subversion/tests/svn_test.h Thu Feb 12 16:14:28 2015
@@ -27,6 +27,8 @@
#define SVN_DEPRECATED
#endif /* ! SVN_ENABLE_DEPRECATION_WARNINGS_IN_TESTS */
+#include <stdio.h>
+
#include <apr_pools.h>
#include "svn_delta.h"
@@ -54,6 +56,23 @@ extern "C" {
#expr, __FILE__, __LINE__); \
} while (0)
+/**
+ * Macro for testing assumptions when the context does not allow
+ * returning an svn_error_t*.
+ *
+ * Will write to stderr and cause a segfault if EXPR is false.
+ */
+#define SVN_TEST_ASSERT_NO_RETURN(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ unsigned int z_e_r_o_p_a_g_e__; \
+ fprintf(stderr, "TEST ASSERTION FAILED: %s\n", #expr); \
+ z_e_r_o_p_a_g_e__ = *(volatile unsigned int*)0; \
+ *(volatile unsigned int*)0 = z_e_r_o_p_a_g_e__; \
+ } \
+ } while (0)
+
/** Handy macro for testing an expected svn_error_t return value.
* EXPECTED must be a real error (neither SVN_NO_ERROR nor APR_SUCCESS).
* The error returned by EXPR will be cleared.
@@ -146,6 +165,11 @@ typedef svn_error_t* (*svn_test_driver2_
typedef svn_error_t* (*svn_test_driver_opts_t)(const svn_test_opts_t *opts,
apr_pool_t *pool);
+/* Prototype for test predicate functions. */
+typedef svn_boolean_t (*svn_test_predicate_func_t)(const svn_test_opts_t *opts,
+ const char *predicate_value,
+ apr_pool_t *pool);
+
/* Test modes. */
enum svn_test_mode_t
{
@@ -155,6 +179,23 @@ enum svn_test_mode_t
svn_test_all
};
+/* Structure for runtime test predicates. */
+struct svn_test_predicate_t
+{
+ /* The predicate function. */
+ svn_test_predicate_func_t func;
+
+ /* The value that the predicate function tests. */
+ const char *value;
+
+ /* The test mode that's used if the predicate matches. */
+ enum svn_test_mode_t alternate_mode;
+
+ /* Description for the test log */
+ const char *description;
+};
+
+
/* Each test gets a test descriptor, holding the function and other
* associated data.
*/
@@ -174,6 +215,9 @@ struct svn_test_descriptor_t
/* An optional description of a work-in-progress test. */
const char *wip;
+
+ /* An optional runtiume predicate. */
+ struct svn_test_predicate_t predicate;
};
/* All Subversion test programs include an array of svn_test_descriptor_t's
@@ -217,6 +261,8 @@ int svn_test_main(int argc, const char *
#define SVN_TEST_OPTS_XFAIL(func, msg) {svn_test_xfail, NULL, func, msg}
#define SVN_TEST_OPTS_XFAIL_COND(func, p, msg) \
{(p) ? svn_test_xfail : svn_test_pass, NULL, func, msg}
+#define SVN_TEST_OPTS_XFAIL_OTOH(func, msg, predicate) \
+ {svn_test_xfail, NULL, func, msg, NULL, predicate}
#define SVN_TEST_OPTS_SKIP(func, p, msg) \
{(p) ? svn_test_skip : svn_test_pass, NULL, func, msg}
@@ -283,6 +329,33 @@ svn_error_t *
svn_test__init_auth_baton(svn_auth_baton_t **baton,
apr_pool_t *result_pool);
+
+/*
+ * Test predicates
+ */
+
+#define SVN_TEST_PASS_IF_FS_TYPE_IS(fs_type) \
+ { svn_test__fs_type_is, fs_type, svn_test_pass, \
+ "PASS if fs-type = " fs_type }
+
+#define SVN_TEST_PASS_IF_FS_TYPE_IS_NOT(fs_type) \
+ { svn_test__fs_type_not, fs_type, svn_test_pass, \
+ "PASS if fs-type != " fs_type }
+
+/* Return TRUE if the fs-type in OPTS matches PREDICATE_VALUE. */
+svn_boolean_t
+svn_test__fs_type_is(const svn_test_opts_t *opts,
+ const char *predicate_value,
+ apr_pool_t *pool);
+
+
+/* Return TRUE if the fs-type in OPTS does not matches PREDICATE_VALUE. */
+svn_boolean_t
+svn_test__fs_type_not(const svn_test_opts_t *opts,
+ const char *predicate_value,
+ apr_pool_t *pool);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/pin-externals/subversion/tests/svn_test_main.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/svn_test_main.c?rev=1659301&r1=1659300&r2=1659301&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/svn_test_main.c (original)
+++ subversion/branches/pin-externals/subversion/tests/svn_test_main.c Thu Feb 12 16:14:28 2015
@@ -328,14 +328,18 @@ log_results(const char *progname,
if (msg_only)
{
+ const svn_boolean_t otoh = !!desc->predicate.description;
+
if (run_this_test)
- printf(" %3d %-5s %s%s%s%s\n",
+ printf(" %3d %-5s %s%s%s%s%s%s\n",
test_num,
(xfail ? "XFAIL" : (skip ? "SKIP" : "")),
msg ? msg : "(test did not provide name)",
(wimp && verbose_mode) ? " [[" : "",
(wimp && verbose_mode) ? desc->wip : "",
- (wimp && verbose_mode) ? "]]" : "");
+ (wimp && verbose_mode) ? "]]" : "",
+ (otoh ? " / " : ""),
+ (otoh ? desc->predicate.description : ""));
}
else if (run_this_test && ((! quiet_mode) || test_failed))
{
@@ -388,6 +392,7 @@ do_test_num(const char *progname,
const struct svn_test_descriptor_t *desc;
const int array_size = get_array_size(test_funcs);
svn_boolean_t run_this_test; /* This test's mode matches DESC->MODE. */
+ enum svn_test_mode_t test_mode;
/* Check our array bounds! */
if (test_num < 0)
@@ -402,11 +407,18 @@ do_test_num(const char *progname,
}
desc = &test_funcs[test_num];
- skip = desc->mode == svn_test_skip;
- xfail = desc->mode == svn_test_xfail;
+ /* Check the test predicate. */
+ if (desc->predicate.func
+ && desc->predicate.func(opts, desc->predicate.value, pool))
+ test_mode = desc->predicate.alternate_mode;
+ else
+ test_mode = desc->mode;
+
+ skip = test_mode == svn_test_skip;
+ xfail = test_mode == svn_test_xfail;
wimp = xfail && desc->wip;
msg = desc->msg;
- run_this_test = mode_filter == svn_test_all || mode_filter == desc->mode;
+ run_this_test = mode_filter == svn_test_all || mode_filter == test_mode;
if (run_this_test && header_msg && *header_msg)
{
@@ -488,6 +500,7 @@ test_thread(apr_thread_t *thread, void *
svn_error_t *err;
const struct svn_test_descriptor_t *desc;
svn_boolean_t run_this_test; /* This test's mode matches DESC->MODE. */
+ enum svn_test_mode_t test_mode;
test_params_t *params = data;
svn_atomic_t test_num;
apr_pool_t *pool;
@@ -510,11 +523,18 @@ test_thread(apr_thread_t *thread, void *
#endif
desc = ¶ms->test_funcs[test_num];
- skip = desc->mode == svn_test_skip;
- xfail = desc->mode == svn_test_xfail;
+ /* Check the test predicate. */
+ if (desc->predicate.func
+ && desc->predicate.func(params->opts, desc->predicate.value, pool))
+ test_mode = desc->predicate.alternate_mode;
+ else
+ test_mode = desc->mode;
+
+ skip = test_mode == svn_test_skip;
+ xfail = test_mode == svn_test_xfail;
wimp = xfail && desc->wip;
run_this_test = mode_filter == svn_test_all
- || mode_filter == desc->mode;
+ || mode_filter == test_mode;
/* Do test */
if (skip || !run_this_test)
@@ -1024,3 +1044,20 @@ svn_test_main(int argc, const char *argv
return got_error;
}
+
+
+svn_boolean_t
+svn_test__fs_type_is(const svn_test_opts_t *opts,
+ const char *predicate_value,
+ apr_pool_t *pool)
+{
+ return (0 == strcmp(predicate_value, opts->fs_type));
+}
+
+svn_boolean_t
+svn_test__fs_type_not(const svn_test_opts_t *opts,
+ const char *predicate_value,
+ apr_pool_t *pool)
+{
+ return (0 != strcmp(predicate_value, opts->fs_type));
+}