Modified: subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c (original) +++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c Sun Jun 14 20:58:10 2015 @@ -128,6 +128,7 @@ typedef struct conflict_info_t { #define NO_COPY_FROM SVN_INVALID_REVNUM, NULL, FALSE #define MOVED_HERE FALSE, NULL, TRUE #define NOT_MOVED FALSE, NULL, FALSE +#define FILE_EXTERNAL TRUE /* Return a comma-separated list of the prop names in PROPS, in lexically * ascending order, or NULL if PROPS is empty or NULL. (Here, we don't @@ -176,13 +177,17 @@ print_row(const nodes_row_t *row, else moved_to_str = ""; - if (row->moved_here) + if (row->moved_here && !row->file_external && !row->moved_to) moved_here_str = ", MOVED_HERE"; + else if (row->moved_to) + moved_here_str = ", TRUE"; else moved_here_str = ""; if (row->file_external) - file_external_str = ", file-external"; + file_external_str = ", FILE_EXTERNAL"; + else if (row->moved_to || row->props) + file_external_str = ", FALSE"; else file_external_str = ""; @@ -194,14 +199,14 @@ print_row(const nodes_row_t *row, if (row->repo_revnum == SVN_INVALID_REVNUM) return apr_psprintf(result_pool, "%d, %-20s%-15s NO_COPY_FROM%s%s%s%s", row->op_depth, relpath_str, presence_str, - moved_here_str, moved_to_str, - file_external_str, props); + file_external_str, moved_here_str, moved_to_str, + props); else return apr_psprintf(result_pool, "%d, %-20s%-15s %d, \"%s\"%s%s%s%s", row->op_depth, relpath_str, presence_str, (int)row->repo_revnum, row->repo_relpath, - moved_here_str, moved_to_str, - file_external_str, props); + file_external_str, moved_here_str, moved_to_str, + props); } /* A baton to pass through svn_hash_diff() to compare_nodes_rows(). */ typedef struct comparison_baton_t { @@ -305,16 +310,17 @@ check_db_rows(svn_test__sandbox_t *b, row->repo_revnum = svn_sqlite__column_revnum(stmt, 3); row->repo_relpath = svn_sqlite__column_text(stmt, 4, b->pool); row->file_external = !svn_sqlite__column_is_null(stmt, 5); - if (row->file_external && svn_sqlite__column_is_null(stmt, 6)) - comparison_baton.errors - = svn_error_createf(SVN_ERR_TEST_FAILED, comparison_baton.errors, - "incomplete {%s}", print_row(row, b->pool)); row->moved_to = svn_sqlite__column_text(stmt, 7, b->pool); row->moved_here = svn_sqlite__column_boolean(stmt, 8); SVN_ERR(svn_sqlite__column_properties(&props_hash, stmt, 9, b->pool, b->pool)); row->props = props_hash_to_text(props_hash, b->pool); + if (row->file_external && svn_sqlite__column_is_null(stmt, 6)) + comparison_baton.errors + = svn_error_createf(SVN_ERR_TEST_FAILED, comparison_baton.errors, + "incomplete {%s}", print_row(row, b->pool)); + key = apr_psprintf(b->pool, "%d %s", row->op_depth, row->local_relpath); apr_hash_set(found_hash, key, APR_HASH_KEY_STRING, row); @@ -509,7 +515,8 @@ check_db_conflicts(svn_test__sandbox_t * 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, + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL, + b->wc_ctx->db, local_abspath, iterpool, iterpool)); SVN_TEST_ASSERT(conflict != NULL); @@ -561,6 +568,34 @@ check_db_conflicts(svn_test__sandbox_t * return comparison_baton.errors; } +static svn_error_t * +verify_db_callback(void *baton, + const char *wc_abspath, + const char *local_relpath, + int op_depth, + int id, + const char *msg, + apr_pool_t *scratch_pool) +{ + if (op_depth >= 0) + return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL, + "Verify: %s: %s (%d): SV%04d %s", + wc_abspath, local_relpath, op_depth, id, msg); + else + return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL, + "DB-VRFY: %s: %s: SV%04d %s", + wc_abspath, local_relpath, id, msg); +} + +static svn_error_t * +verify_db(svn_test__sandbox_t *b) +{ + SVN_ERR(svn_wc__db_verify_db_full(b->wc_ctx->db, b->wc_abspath, + verify_db_callback, NULL, b->pool)); + + return SVN_NO_ERROR; +} + /* ---------------------------------------------------------------------- */ /* The test functions */ @@ -1266,6 +1301,34 @@ insert_dirs(svn_test__sandbox_t *b, ? svn_relpath_dirname(nodes->local_relpath, b->pool) : NULL)); + + if (nodes->moved_to) + SVN_ERR(svn_sqlite__bind_text(stmt, 7, nodes->moved_to)); + if (nodes->moved_here) + SVN_ERR(svn_sqlite__bind_int(stmt, 8, 1)); + if (nodes->props) + { + int i; + apr_hash_t *props = apr_hash_make(b->pool); + apr_array_header_t *names = svn_cstring_split(nodes->props, ",", + TRUE, b->pool); + + for (i = 0; i < names->nelts; i++) + { + const char *name = APR_ARRAY_IDX(names, i, const char *); + svn_hash_sets(props, name, svn_string_create(name, b->pool)); + } + + SVN_ERR(svn_sqlite__bind_properties(stmt, 9, props, b->pool)); + } + else if (nodes->repo_relpath + && strcmp(nodes->presence, "normal") == 0) + { + SVN_ERR(svn_sqlite__bind_text(stmt, 9, "()")); + } + + /* File externals? */ + SVN_ERR(svn_sqlite__step_done(stmt)); ++nodes; } @@ -1316,9 +1379,7 @@ base_dir_insert_remove(svn_test__sandbox SVN_ERR(check_db_rows(b, "", after)); SVN_ERR(svn_wc__db_base_remove(b->wc_ctx->db, dir_abspath, - FALSE /* keep_as_Working */, - FALSE /* queue_deletes */, - FALSE /* remove_locks */, + FALSE, FALSE, FALSE, SVN_INVALID_REVNUM, NULL, NULL, b->pool)); SVN_ERR(svn_wc__wq_run(b->wc_ctx->db, dir_abspath, @@ -1628,29 +1689,11 @@ test_base_dir_insert_remove(const svn_te } static svn_error_t * -temp_op_make_copy(svn_test__sandbox_t *b, - const char *local_relpath, - nodes_row_t *before, - nodes_row_t *after) -{ - const char *dir_abspath = svn_path_join(b->wc_abspath, local_relpath, - b->pool); - - SVN_ERR(insert_dirs(b, before)); - - SVN_ERR(svn_wc__db_op_make_copy(b->wc_ctx->db, dir_abspath, NULL, NULL, b->pool)); - - SVN_ERR(check_db_rows(b, "", after)); - - return SVN_NO_ERROR; -} - -static svn_error_t * -test_temp_op_make_copy(const svn_test_opts_t *opts, apr_pool_t *pool) +test_db_make_copy(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_test__sandbox_t b; - SVN_ERR(svn_test__sandbox_create(&b, "temp_op_make_copy", opts, pool)); + SVN_ERR(svn_test__sandbox_create(&b, "make_copy", opts, pool)); { /* / norm - @@ -1681,7 +1724,7 @@ test_temp_op_make_copy(const svn_test_op { 2, "A/F", "normal", 1, "S2" }, { 2, "A/F/G", "normal", 1, "S2/G" }, { 2, "A/F/H", "not-present", 1, "S2/H" }, - { 2, "A/F/E", "base-deleted", 2, "A/F/E" }, + { 2, "A/F/E", "base-deleted", NO_COPY_FROM }, { 0 } }; /* / norm - @@ -1719,14 +1762,18 @@ test_temp_op_make_copy(const svn_test_op { 2, "A/B", "normal", NO_COPY_FROM }, { 2, "A/B/C", "base-deleted", NO_COPY_FROM }, { 2, "A/F", "normal", 1, "S2" }, - { 2, "A/F/E", "base-deleted", 2, "A/F/E" }, + { 2, "A/F/E", "base-deleted", NO_COPY_FROM }, { 2, "A/F/G", "normal", 1, "S2/G" }, { 2, "A/F/H", "not-present", 1, "S2/H" }, { 3, "A/B/C", "normal", NO_COPY_FROM }, { 0 } }; - SVN_ERR(temp_op_make_copy(&b, "A", before, after)); + SVN_ERR(insert_dirs(&b, before)); + SVN_ERR(svn_wc__db_op_make_copy(b.wc_ctx->db, sbox_wc_path(&b, "A"), + NULL, NULL, pool)); + + SVN_ERR(check_db_rows(&b, "", after)); } return SVN_NO_ERROR; @@ -2044,6 +2091,9 @@ insert_actual(svn_test__sandbox_t *b, SVN_ERR(svn_sqlite__step_done(stmt)); if (actual->changelist) { + SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, + STMT_ENSURE_EMPTY_PRISTINE)); + SVN_ERR(svn_sqlite__step_done(stmt)); SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_NODES_SET_FILE)); SVN_ERR(svn_sqlite__bindf(stmt, "s", actual->local_relpath)); SVN_ERR(svn_sqlite__step_done(stmt)); @@ -2793,8 +2843,8 @@ test_children_of_replaced_dir(const svn_ &children_array, b.wc_ctx->db, A_abspath, pool, pool)); SVN_ERR(CHECK_ARRAY(children_array, working_children_inc_hidden, pool)); - SVN_ERR(svn_wc__node_get_children(&children_array, b.wc_ctx, A_abspath, - TRUE /* show_hidden */, pool, pool)); + SVN_ERR(svn_wc__db_read_children(&children_array, b.wc_ctx->db, A_abspath, + pool, pool)); SVN_ERR(CHECK_ARRAY(children_array, all_children_inc_hidden, pool)); /* I am not testing svn_wc__node_get_children(show_hidden=FALSE) because @@ -2803,12 +2853,7 @@ test_children_of_replaced_dir(const svn_ * a 'hidden' child of the working dir (so should be excluded). */ SVN_ERR(svn_wc__node_get_children_of_working_node( - &children_array, b.wc_ctx, A_abspath, TRUE /* show_hidden */, - pool, pool)); - SVN_ERR(CHECK_ARRAY(children_array, working_children_inc_hidden, pool)); - - SVN_ERR(svn_wc__node_get_children_of_working_node( - &children_array, b.wc_ctx, A_abspath, FALSE /* show_hidden */, + &children_array, b.wc_ctx, A_abspath, pool, pool)); SVN_ERR(CHECK_ARRAY(children_array, working_children_exc_hidden, pool)); @@ -3538,11 +3583,13 @@ revert_file_externals(const svn_test_opt SVN_ERR(sbox_wc_update(&b, "", 1)); { nodes_row_t rows[] = { - { 0, "", "normal", 1, "" }, - { 0, "f", "normal", 1, "f" }, - { 1, "A", "normal", NO_COPY_FROM }, - { 0, "h", "normal", 1, "f", TRUE }, - { 0, "A/g", "normal", 1, "f", TRUE }, + { 0, "", "normal", 1, "" }, + { 0, "f", "normal", 1, "f" }, + { 1, "A", "normal", NO_COPY_FROM }, + { 0, "h", "normal", 1, "f", TRUE }, + { 0, "A/g", "normal", 1, "f", TRUE }, + + { 0, "g", "not-present", 0, "g"}, { 0 } }; SVN_ERR(check_db_rows(&b, "", rows)); @@ -3551,10 +3598,12 @@ revert_file_externals(const svn_test_opt SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity)); { nodes_row_t rows[] = { - { 0, "", "normal", 1, "" }, - { 0, "f", "normal", 1, "f" }, - { 0, "h", "normal", 1, "f", TRUE }, - { 0, "A/g", "normal", 1, "f", TRUE }, + { 0, "", "normal", 1, "" }, + { 0, "f", "normal", 1, "f" }, + { 0, "h", "normal", 1, "f", TRUE }, + { 0, "A/g", "normal", 1, "f", TRUE }, + + { 0, "g", "not-present", 0, "g"}, { 0 } }; SVN_ERR(check_db_rows(&b, "", rows)); @@ -3563,9 +3612,22 @@ revert_file_externals(const svn_test_opt SVN_ERR(sbox_wc_update(&b, "", 1)); { nodes_row_t rows[] = { - { 0, "", "normal", 1, "" }, - { 0, "f", "normal", 1, "f" }, - { 0, "g", "normal", 1, "f", TRUE }, + { 0, "", "normal", 1, "" }, + { 0, "f", "normal", 1, "f" }, + { 0, "g", "normal", 1, "f", TRUE }, + + { 0, "h", "not-present", 0, "h"}, + { 0 } + }; + SVN_ERR(check_db_rows(&b, "", rows)); + } + + SVN_ERR(sbox_wc_update(&b, "", 1)); + { + nodes_row_t rows[] = { + { 0, "", "normal", 1, "" }, + { 0, "f", "normal", 1, "f" }, + { 0, "g", "normal", 1, "f", TRUE }, { 0 } }; SVN_ERR(check_db_rows(&b, "", rows)); @@ -3742,6 +3804,8 @@ incomplete_switch(const svn_test_opts_t }; SVN_ERR(insert_dirs(&b, before)); + SVN_ERR(svn_io_remove_dir2(sbox_wc_path(&b, "A/B/C/D"), FALSE, + NULL, NULL, pool)); SVN_ERR(check_db_rows(&b, "", before)); SVN_ERR(sbox_wc_update(&b, "", 4)); SVN_ERR(check_db_rows(&b, "", after_update)); @@ -5928,8 +5992,8 @@ check_tree_conflict_repos_path(svn_test_ const apr_array_header_t *locations; svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted; - SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db, - sbox_wc_path(b, wc_path), + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL, + b->wc_ctx->db, sbox_wc_path(b, wc_path), b->pool, b->pool)); SVN_TEST_ASSERT(conflict != NULL); @@ -6110,7 +6174,16 @@ move_update_delete_mods(const svn_test_o {2, "B2/C/f", "normal", 1, "A/B/C/f"}, {0} }; + conflict_info_t conflicts[] = { + {"B2/C", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_edited}}, + {"B2/D", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_deleted}}, + { 0 } + }; + SVN_ERR(check_db_rows(&b, "", nodes)); + SVN_ERR(check_db_conflicts(&b, "", conflicts)); } SVN_ERR(check_tree_conflict_repos_path(&b, "B2/C", "A/B/C", "A/B/C")); @@ -6918,6 +6991,31 @@ commit_moved_descendant(const svn_test_o shadowed, like in this case. The commit processing doesn't support this yet though*/ + { + nodes_row_t nodes[] = { + {0, "", "normal", 0, ""}, + {0, "A", "normal", 1, "A"}, + {0, "A/A", "normal", 2, "A/A"}, + {0, "A/A/A", "normal", 2, "A/A/A"}, + {0, "A/A/A/A", "normal", 2, "A/A/A/A"}, + {0, "A/A/A/A/A", "normal", 2, "A/A/A/A/A"}, + {0, "A/A/A/A/A/A", "normal", 2, "A/A/A/A/A/A"}, + {0, "A_copied", "normal", 2, "A_copied"}, + {0, "A_copied/A", "normal", 2, "A_copied/A"}, + {0, "A_copied/A/A", "normal", 2, "A_copied/A/A"}, + {0, "A_copied/A/A/A", "normal", 2, "A_copied/A/A/A"}, + {0, "A_copied/A/A/A/A", "normal", 2, "A_copied/A/A/A/A"}, + {0, "A_copied/A/A/A/A/A","normal", 2, "A_copied/A/A/A/A/A"}, + {0, "AAA_moved", "normal", 2, "AAA_moved"}, + {0, "AAA_moved/A", "normal", 2, "AAA_moved/A"}, + {0, "AAA_moved/A/A", "normal", 2, "AAA_moved/A/A"}, + {0, "AAA_moved/A/A/A", "normal", 2, "AAA_moved/A/A/A"}, + + {0} + }; + SVN_ERR(check_db_rows(&b, "", nodes)); + } + return SVN_NO_ERROR; } @@ -6940,10 +7038,63 @@ commit_moved_away_descendant(const svn_t SVN_ERR(sbox_wc_delete(&b, "A/A")); SVN_ERR(sbox_wc_copy(&b, "A_copied/A", "A/A")); + { + nodes_row_t nodes[] = { + {0, "", "normal", 0, ""}, + {0, "A", "normal", 1, "A"}, + {0, "A/A", "normal", 1, "A/A"}, + {0, "A/A/A", "normal", 1, "A/A/A"}, + {0, "A/A/A/A", "normal", 1, "A/A/A/A"}, + {0, "A/A/A/A/A", "normal", 1, "A/A/A/A/A"}, + {0, "A/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"}, + {1, "A_copied", "normal", 1, "A"}, + {1, "A_copied/A", "normal", 1, "A/A"}, + {1, "A_copied/A/A", "normal", 1, "A/A/A"}, + {1, "A_copied/A/A/A", "normal", 1, "A/A/A/A"}, + {1, "A_copied/A/A/A/A", "normal", 1, "A/A/A/A/A"}, + {1, "A_copied/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"}, + {1, "AAA_moved", "normal", 1, "A/A/A", MOVED_HERE}, + {1, "AAA_moved/A", "normal", 1, "A/A/A/A", MOVED_HERE}, + {1, "AAA_moved/A/A", "normal", 1, "A/A/A/A/A", MOVED_HERE}, + {1, "AAA_moved/A/A/A", "normal", 1, "A/A/A/A/A/A", MOVED_HERE}, + {2, "A/A", "normal", 1, "A/A"}, + {2, "A/A/A", "normal", 1, "A/A/A", FALSE, "AAA_moved"}, + {2, "A/A/A/A", "normal", 1, "A/A/A/A"}, + {2, "A/A/A/A/A", "normal", 1, "A/A/A/A/A"}, + {2, "A/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"}, + {0} + }; + SVN_ERR(check_db_rows(&b, "", nodes)); + } + /* And now I want to make sure that I can't commit A, without also committing AAA_moved, as that would break the move*/ SVN_ERR(sbox_wc_commit(&b, "A")); + { + nodes_row_t nodes[] = { + {0, "", "normal", 0, ""}, + {0, "A", "normal", 1, "A"}, + {0, "A/A", "normal", 2, "A/A"}, + {0, "A/A/A", "normal", 2, "A/A/A"}, + {0, "A/A/A/A", "normal", 2, "A/A/A/A"}, + {0, "A/A/A/A/A", "normal", 2, "A/A/A/A/A"}, + {0, "A/A/A/A/A/A", "normal", 2, "A/A/A/A/A/A"}, + {1, "A_copied", "normal", 1, "A"}, + {1, "A_copied/A", "normal", 1, "A/A"}, + {1, "A_copied/A/A", "normal", 1, "A/A/A"}, + {1, "A_copied/A/A/A", "normal", 1, "A/A/A/A"}, + {1, "A_copied/A/A/A/A", "normal", 1, "A/A/A/A/A"}, + {1, "A_copied/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"}, + {1, "AAA_moved", "normal", 1, "A/A/A"}, + {1, "AAA_moved/A", "normal", 1, "A/A/A/A"}, + {1, "AAA_moved/A/A", "normal", 1, "A/A/A/A/A"}, + {1, "AAA_moved/A/A/A", "normal", 1, "A/A/A/A/A/A"}, + {0} + }; + SVN_ERR(check_db_rows(&b, "", nodes)); + } + return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "The commit should have failed"); @@ -7166,11 +7317,23 @@ move_away_delete_update(const svn_test_o {0, "", "normal", 2, ""}, {0, "A", "normal", 2, "A"}, {0, "P", "normal", 2, "P"}, - {1, "C2", "normal", 1, "A/B/C"}, + {1, "C2", "normal", 1, "A/B/C", MOVED_HERE}, {1, "Q2", "normal", 1, "P/Q"}, + + {2, "A/B", "normal", 1, "A/B"}, + {2, "A/B/C", "normal", 1, "A/B/C"}, + {3, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"}, + {0} + }; + conflict_info_t conflicts[] = { + {"A/B", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_edited}}, + {"P/Q", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_moved_away, "P/Q"}}, {0} }; SVN_ERR(check_db_rows(&b, "", nodes)); + SVN_ERR(check_db_conflicts(&b, "", conflicts)); } return SVN_NO_ERROR; @@ -8311,7 +8474,15 @@ move_retract(const svn_test_opts_t *opts {0} }; + conflict_info_t conflicts[] = { + {"A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "A/A"}}, + {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_replaced}}, + { 0 }, + }; SVN_ERR(check_db_rows(&b, "", nodes)); + SVN_ERR(check_db_conflicts(&b, "", conflicts)); } @@ -8342,9 +8513,21 @@ move_retract(const svn_test_opts_t *opts /* Still conflicted */ {1, "D", "normal", 1, "A/B/A/D", MOVED_HERE }, + {4, "A/B/A/C", "normal", 1, "A/A/A/C"}, + + {0} }; + conflict_info_t conflicts[] = { + {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_replaced}}, + {"A/B/A/C", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_edited}}, + {0} + }; + SVN_ERR(check_db_rows(&b, "", nodes)); + SVN_ERR(check_db_conflicts(&b, "", conflicts)); } /* ### TODO: Resolve via which specific target? */ @@ -8354,7 +8537,7 @@ move_retract(const svn_test_opts_t *opts { nodes_row_t nodes[] = { - {1, "D", "normal", 2, "A/B/A/D", MOVED_HERE }, + {1, "D", "normal", 1, "A/B/A/D", MOVED_HERE }, {0} }; @@ -8612,36 +8795,46 @@ move_update_parent_replace(const svn_tes SVN_ERR(sbox_wc_update(&b, "", 2)); { nodes_row_t nodes[] = { - {0, "", "normal", 2, ""}, - {0, "A", "normal", 2, "A"}, - {0, "A/B", "normal", 2, "A/B"}, - {2, "A/C", "normal", 1, "A/B/C"}, + {0, "", "normal", 2, ""}, + {0, "A", "normal", 2, "A"}, + {0, "A/B", "normal", 2, "A/B"}, + + {2, "A/C", "normal", 1, "A/B/C", MOVED_HERE}, + + {2, "A/B", "normal", 1, "A/B"}, + {2, "A/B/C", "normal", 1, "A/B/C", FALSE}, + + {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/C"}, + {0} }; - actual_row_t actual[] = { - {"A/B", NULL}, + conflict_info_t conflicts[] = { + {"A/B", FALSE, FALSE, {svn_wc_conflict_action_replace, + svn_wc_conflict_reason_edited}}, {0} }; SVN_ERR(check_db_rows(&b, "", nodes)); - SVN_ERR(check_db_actual(&b, actual)); + SVN_ERR(check_db_conflicts(&b, "", conflicts)); } SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_infinity, - svn_wc_conflict_choose_mine_conflict)); + svn_wc_conflict_choose_merged)); { nodes_row_t nodes[] = { - {0, "", "normal", 2, ""}, - {0, "A", "normal", 2, "A"}, - {0, "A/B", "normal", 2, "A/B"}, - {2, "A/C", "normal", 1, "A/B/C"}, - {0} - }; - actual_row_t actual[] = { + {0, "", "normal", 2, ""}, + {0, "A", "normal", 2, "A"}, + {0, "A/B", "normal", 2, "A/B"}, + {2, "A/C", "normal", 1, "A/B/C", MOVED_HERE}, + {2, "A/B", "normal", 1, "A/B"}, + {2, "A/B/C", "normal", 1, "A/B/C", FALSE}, + {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/C"}, + {0} }; + SVN_ERR(check_db_rows(&b, "", nodes)); - SVN_ERR(check_db_actual(&b, actual)); + SVN_ERR(check_db_conflicts(&b, "", NULL)); } return SVN_NO_ERROR; @@ -9140,15 +9333,15 @@ move_twice_within_delete(const svn_test_ nodes_row_t nodes[] = { { 0, "", "normal", 1, "" }, - + { 0, "A", "normal", 1, "A" }, { 0, "A/A", "normal", 1, "A/A" }, { 0, "A/A/A", "normal", 1, "A/A/A" }, - + { 1, "A", "base-deleted", NO_COPY_FROM, "B/A" }, { 1, "A/A", "base-deleted", NO_COPY_FROM }, { 1, "A/A/A", "base-deleted", NO_COPY_FROM }, - + { 1, "AA", "normal", 1, "A/A/A", MOVED_HERE }, { 1, "B", "normal", NO_COPY_FROM }, @@ -9475,8 +9668,14 @@ del4_update_edit_AAA(const svn_test_opts SVN_ERR(check_db_conflicts(&b, "", conflicts)); } + /* This breaks the move A/A/A -> AAA_1 */ + SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty, svn_wc_conflict_choose_merged)); + /* This breaks the move B -> A */ + SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty, svn_wc_conflict_choose_merged)); + /* This breaks the move C/A/A -> A/A */ + SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty, svn_wc_conflict_choose_merged)); /* This breaks the move from D/A/A -> A/A/A */ - SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged)); + SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty, svn_wc_conflict_choose_merged)); { nodes_row_t nodes[] = { @@ -9499,12 +9698,12 @@ del4_update_edit_AAA(const svn_test_opts {0, "D/A/A/A", "normal", 2, "D/A/A/A", NOT_MOVED, "key"}, {1, "A", "normal", 1, "B"}, {1, "A/A", "normal", 1, "B/A"}, - {1, "A/A/A", "normal", 1, "B/A/A", FALSE, "AAA_1"}, + {1, "A/A/A", "normal", 1, "B/A/A", FALSE}, {1, "A/A/A/A", "normal", 1, "B/A/A/A"}, - {1, "AAA_1", "normal", 1, "A/A/A", MOVED_HERE}, - {1, "AAA_1/A", "normal", 1, "A/A/A/A", MOVED_HERE}, - {1, "AAA_2", "normal", 1, "B/A/A"}, - {1, "AAA_2/A", "normal", 1, "B/A/A/A"}, + {1, "AAA_1", "normal", 1, "A/A/A"}, + {1, "AAA_1/A", "normal", 1, "A/A/A/A"}, + {1, "AAA_2", "normal", 1, "B/A/A", MOVED_HERE}, + {1, "AAA_2/A", "normal", 1, "B/A/A/A", MOVED_HERE}, {1, "AAA_3", "normal", 1, "C/A/A", MOVED_HERE}, {1, "AAA_3/A", "normal", 1, "C/A/A/A", MOVED_HERE}, {1, "B", "base-deleted", NO_COPY_FROM}, @@ -9512,7 +9711,7 @@ del4_update_edit_AAA(const svn_test_opts {1, "B/A/A", "base-deleted", NO_COPY_FROM}, {1, "B/A/A/A", "base-deleted", NO_COPY_FROM}, {2, "A/A", "normal", 1, "C/A"}, - {2, "A/A/A", "normal", 1, "C/A/A"}, + {2, "A/A/A", "normal", 1, "C/A/A", FALSE, "AAA_2"}, {2, "A/A/A/A", "normal", 1, "C/A/A/A"}, {2, "C/A", "base-deleted", NO_COPY_FROM}, {2, "C/A/A", "base-deleted", NO_COPY_FROM}, @@ -9541,12 +9740,53 @@ del4_update_delete_AAA(const svn_test_op /* Update and resolve via mine strategy */ SVN_ERR(sbox_wc_update(&b, "", 2)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + SVN_ERR(check_db_conflicts(&b, "", conflicts)); + } 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)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + 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)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + SVN_ERR(check_db_conflicts(&b, "", conflicts)); + } SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged)); return SVN_NO_ERROR; @@ -9561,12 +9801,53 @@ del4_update_add_AAA(const svn_test_opts_ /* Update and resolve via mine strategy */ SVN_ERR(sbox_wc_update(&b, "", 2)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + SVN_ERR(check_db_conflicts(&b, "", conflicts)); + } 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)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + 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)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + SVN_ERR(check_db_conflicts(&b, "", conflicts)); + } SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged)); return SVN_NO_ERROR; @@ -9581,27 +9862,6 @@ del4_update_replace_AAA(const svn_test_o /* Update and resolve via mine strategy */ SVN_ERR(sbox_wc_update(&b, "", 2)); - 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)); - /* 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 * -del4_update_delself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool) -{ - svn_test__sandbox_t b; - - SVN_ERR(init_move4(&b, "del4_update_delself_AAA", opts, FALSE, pool)); - - /* Update and resolve via mine strategy */ - SVN_ERR(sbox_wc_update(&b, "", 2)); - { conflict_info_t conflicts[] = { {"A", FALSE, FALSE, {svn_wc_conflict_action_edit, @@ -9610,23 +9870,89 @@ del4_update_delself_AAA(const svn_test_o 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, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "D/A/A"}}, {0} }; SVN_ERR(check_db_conflicts(&b, "", conflicts)); } - - - /* Resolve a few conflicts manually */ - 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)); - + 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)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + 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)); + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + SVN_ERR(check_db_conflicts(&b, "", conflicts)); + } + SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged)); + + return SVN_NO_ERROR; +} + +static svn_error_t * +del4_update_delself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool) +{ + svn_test__sandbox_t b; + + SVN_ERR(init_move4(&b, "del4_update_delself_AAA", opts, FALSE, pool)); + + /* Update and resolve via mine strategy */ + SVN_ERR(sbox_wc_update(&b, "", 2)); + + { + 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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + {0} + }; + + SVN_ERR(check_db_conflicts(&b, "", conflicts)); + } + + + /* Resolve a few conflicts manually */ + 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)); + { nodes_row_t nodes[] = { {0, "", "normal", 2, ""}, @@ -9686,7 +10012,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)); @@ -9921,7 +10280,21 @@ move4_update_delself_AAA(const svn_test_ { 0 }, }; - SVN_ERR(check_db_rows(&b, "", nodes)); + conflict_info_t conflicts[] = { + {"A_moved/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_moved_away, "A_moved/A/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"}}, + {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete, + svn_wc_conflict_reason_moved_away, "D/A/A"}}, + + { 0 }, + }; + + SVN_ERR(check_db_rows(&b, "", nodes)); + SVN_ERR(check_db_conflicts(&b, "", conflicts)); } SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty, @@ -9989,14 +10362,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_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_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 * @@ -10191,8 +10596,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, @@ -10203,8 +10635,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[] = { @@ -10259,6 +10693,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; @@ -10815,10 +11251,640 @@ move_edit_obstruction(const svn_test_opt return SVN_NO_ERROR; } +static svn_error_t * +move_deep_bump(const svn_test_opts_t *opts, apr_pool_t *pool) +{ + svn_test__sandbox_t b; + + SVN_ERR(svn_test__sandbox_create(&b, "move_deep_bump", opts, pool)); + + SVN_ERR(sbox_wc_mkdir(&b, "B")); + SVN_ERR(sbox_wc_mkdir(&b, "B/B")); + SVN_ERR(sbox_wc_mkdir(&b, "B/B/A")); + SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A")); + SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A/A")); + SVN_ERR(sbox_wc_mkdir(&b, "C")); + SVN_ERR(sbox_wc_mkdir(&b, "C/C")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_mkdir(&b, "Z")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A/A/A")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_update(&b, "", 1)); + + SVN_ERR(sbox_wc_move(&b, "B/B/A", "B/B/B")); + SVN_ERR(sbox_wc_move(&b, "B/B/B/A", "C/C/A")); + + /* This can't bump C/C/A as that is outside the lock range + so we expect a tree conflict. + + This used to cause a node not found during bumping + because B/B/B/A doesn't have a BASE node */ + SVN_ERR(sbox_wc_update(&b, "B/B", 2)); + + { + nodes_row_t nodes[] = { + {0, "", "normal", 1, ""}, + {0, "B", "normal", 1, "B"}, + {0, "B/B", "normal", 2, "B/B"}, + {0, "B/B/A", "normal", 2, "B/B/A"}, + {0, "B/B/A/A", "normal", 2, "B/B/A/A"}, + {0, "B/B/A/A/A", "normal", 2, "B/B/A/A/A"}, + {0, "C", "normal", 1, "C"}, + {0, "C/C", "normal", 1, "C/C"}, + {3, "B/B/A", "base-deleted", NO_COPY_FROM, "B/B/B"}, + {3, "B/B/A/A", "base-deleted", NO_COPY_FROM}, + {3, "B/B/A/A/A", "base-deleted", NO_COPY_FROM}, + {3, "B/B/B", "normal", 2, "B/B/A", MOVED_HERE}, + {3, "B/B/B/A", "normal", 2, "B/B/A/A", MOVED_HERE}, + {3, "B/B/B/A/A", "normal", 2, "B/B/A/A/A", MOVED_HERE}, + {3, "C/C/A", "normal", 1, "B/B/A/A", MOVED_HERE}, + {3, "C/C/A/A", "normal", 1, "B/B/A/A/A", MOVED_HERE}, + {4, "B/B/B/A", "base-deleted", NO_COPY_FROM, "C/C/A"}, + {4, "B/B/B/A/A", "base-deleted", NO_COPY_FROM}, + {0} + }; + conflict_info_t conflicts[] = { + {"B/B/B/A", FALSE, FALSE, {svn_wc_conflict_action_edit, + svn_wc_conflict_reason_moved_away, "B/B/B/A"}}, + {0} + }; + + SVN_ERR(check_db_rows(&b, "", nodes)); + SVN_ERR(check_db_conflicts(&b, "", conflicts)); + } + + SVN_ERR(sbox_wc_resolve(&b, "B/B/B/A", svn_depth_empty, + svn_wc_conflict_choose_mine_conflict)); + SVN_ERR(check_db_conflicts(&b, "", NULL)); + + return SVN_NO_ERROR; +} + +static svn_error_t * +make_copy_mixed(const svn_test_opts_t *opts, apr_pool_t *pool) +{ + svn_test__sandbox_t b; + + SVN_ERR(svn_test__sandbox_create(&b, "make_copy_mixed", opts, pool)); + + SVN_ERR(sbox_wc_mkdir(&b, "A")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/E")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/F")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/H")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/I")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/K")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/L")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/M")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/O")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/P")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/Q")); + SVN_ERR(sbox_wc_mkdir(&b, "A/R")); + SVN_ERR(sbox_wc_mkdir(&b, "A/R/S")); + SVN_ERR(sbox_wc_mkdir(&b, "A/R/S/T")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_update(&b, "", 1)); + SVN_ERR(sbox_wc_propset(&b, "k", "r2", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_propset(&b, "k", "r3", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_propset(&b, "k", "r4", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_propset(&b, "k", "r5", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + + SVN_ERR(sbox_wc_update(&b, "", 5)); + SVN_ERR(sbox_wc_update(&b, "A", 4)); + SVN_ERR(sbox_wc_update(&b, "A/B", 3)); + SVN_ERR(sbox_wc_update(&b, "A/B/C", 2)); + SVN_ERR(sbox_wc_update(&b, "A/B/K", 1)); + SVN_ERR(sbox_wc_update(&b, "A/N/O", 3)); + + SVN_ERR(sbox_wc_delete(&b, "A/B/C/F")); + SVN_ERR(sbox_wc_delete(&b, "A/B/G/J")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J")); + + SVN_ERR(sbox_wc_update(&b, "A/N/P", 1)); + SVN_ERR(sbox_wc_update(&b, "A/N/Q", 1)); + SVN_ERR(sbox_wc_delete(&b, "A/N/P")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/P")); + SVN_ERR(sbox_wc_move(&b, "A/N/Q", "Q")); + SVN_ERR(sbox_wc_move(&b, "A/B/G/H", "H")); + + /* And something that can't be represented */ + SVN_ERR(sbox_wc_update(&b, "A/B/C/E", 1)); + SVN_ERR(sbox_wc_move(&b, "A/B/C/E", "E")); + + { + nodes_row_t nodes[] = { + {0, "", "normal", 5, "", NOT_MOVED, "k"}, + {0, "A", "normal", 4, "A"}, + {0, "A/B", "normal", 3, "A/B"}, + {0, "A/B/C", "normal", 2, "A/B/C"}, + {0, "A/B/C/D", "normal", 2, "A/B/C/D"}, + {0, "A/B/C/E", "normal", 1, "A/B/C/E"}, + {0, "A/B/C/F", "normal", 2, "A/B/C/F"}, + {0, "A/B/G", "normal", 3, "A/B/G"}, + {0, "A/B/G/H", "normal", 3, "A/B/G/H"}, + {0, "A/B/G/I", "normal", 3, "A/B/G/I"}, + {0, "A/B/G/J", "normal", 3, "A/B/G/J"}, + {0, "A/B/K", "normal", 1, "A/B/K"}, + {0, "A/B/K/L", "normal", 1, "A/B/K/L"}, + {0, "A/B/K/M", "normal", 1, "A/B/K/M"}, + {0, "A/N", "normal", 4, "A/N"}, + {0, "A/N/O", "normal", 3, "A/N/O"}, + {0, "A/N/P", "normal", 1, "A/N/P"}, + {0, "A/N/Q", "normal", 1, "A/N/Q"}, + {0, "A/R", "normal", 4, "A/R"}, + {0, "A/R/S", "normal", 4, "A/R/S"}, + {0, "A/R/S/T", "normal", 4, "A/R/S/T"}, + {1, "E", "normal", 1, "A/B/C/E", MOVED_HERE}, + {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE}, + {1, "Q", "normal", 1, "A/N/Q", MOVED_HERE}, + {3, "A/N/P", "normal", NO_COPY_FROM}, + {3, "A/N/Q", "base-deleted", NO_COPY_FROM, "Q"}, + {4, "A/B/C/E", "base-deleted", NO_COPY_FROM, "E"}, + {4, "A/B/C/F", "base-deleted", NO_COPY_FROM}, + {4, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"}, + {4, "A/B/G/J", "normal", NO_COPY_FROM}, + + {0} + }; + + SVN_ERR(check_db_rows(&b, "", nodes)); + } + + SVN_ERR(svn_wc__db_op_make_copy(b.wc_ctx->db, sbox_wc_path(&b, "A"), + NULL, NULL, pool)); + + { + nodes_row_t nodes[] = { + {0, "", "normal", 5, "", NOT_MOVED, "k"}, + {0, "A", "normal", 4, "A"}, + {0, "A/B", "normal", 3, "A/B"}, + {0, "A/B/C", "normal", 2, "A/B/C"}, + {0, "A/B/C/D", "normal", 2, "A/B/C/D"}, + {0, "A/B/C/E", "normal", 1, "A/B/C/E"}, + {0, "A/B/C/F", "normal", 2, "A/B/C/F"}, + {0, "A/B/G", "normal", 3, "A/B/G"}, + {0, "A/B/G/H", "normal", 3, "A/B/G/H"}, + {0, "A/B/G/I", "normal", 3, "A/B/G/I"}, + {0, "A/B/G/J", "normal", 3, "A/B/G/J"}, + {0, "A/B/K", "normal", 1, "A/B/K"}, + {0, "A/B/K/L", "normal", 1, "A/B/K/L"}, + {0, "A/B/K/M", "normal", 1, "A/B/K/M"}, + {0, "A/N", "normal", 4, "A/N"}, + {0, "A/N/O", "normal", 3, "A/N/O"}, + {0, "A/N/P", "normal", 1, "A/N/P"}, + {0, "A/N/Q", "normal", 1, "A/N/Q"}, + {0, "A/R", "normal", 4, "A/R"}, + {0, "A/R/S", "normal", 4, "A/R/S"}, + {0, "A/R/S/T", "normal", 4, "A/R/S/T"}, + {1, "A", "normal", 4, "A"}, + {1, "A/B", "not-present", 3, "A/B"}, + {1, "A/B/C", "base-deleted", NO_COPY_FROM}, + {1, "A/B/C/D", "base-deleted", NO_COPY_FROM}, + {1, "A/B/C/E", "base-deleted", NO_COPY_FROM, "E"}, + {1, "A/B/C/F", "base-deleted", NO_COPY_FROM}, + {1, "A/B/G", "base-deleted", NO_COPY_FROM}, + {1, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"}, + {1, "A/B/G/I", "base-deleted", NO_COPY_FROM}, + {1, "A/B/G/J", "base-deleted", NO_COPY_FROM}, + {1, "A/B/K", "base-deleted", NO_COPY_FROM}, + {1, "A/B/K/L", "base-deleted", NO_COPY_FROM}, + {1, "A/B/K/M", "base-deleted", NO_COPY_FROM}, + {1, "A/N", "normal", 4, "A/N"}, + {1, "A/N/O", "not-present", 3, "A/N/O"}, + {1, "A/N/P", "not-present", 1, "A/N/P"}, + {1, "A/N/Q", "not-present", 1, "A/N/Q", FALSE, "Q"}, + {1, "A/R", "normal", 4, "A/R"}, + {1, "A/R/S", "normal", 4, "A/R/S"}, + {1, "A/R/S/T", "normal", 4, "A/R/S/T"}, + {1, "E", "normal", 1, "A/B/C/E", MOVED_HERE}, + {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE}, + {1, "Q", "normal", 1, "A/N/Q", MOVED_HERE}, + {2, "A/B", "normal", 3, "A/B"}, + {2, "A/B/C", "not-present", 2, "A/B/C"}, + {2, "A/B/G", "normal", 3, "A/B/G"}, + {2, "A/B/G/H", "normal", 3, "A/B/G/H"}, + {2, "A/B/G/I", "normal", 3, "A/B/G/I"}, + {2, "A/B/G/J", "normal", 3, "A/B/G/J"}, + {2, "A/B/K", "not-present", 1, "A/B/K"}, + {3, "A/B/C", "normal", 2, "A/B/C"}, + {3, "A/B/C/D", "normal", 2, "A/B/C/D"}, + {3, "A/B/C/E", "not-present", 1, "A/B/C/E"}, + {3, "A/B/C/F", "normal", 2, "A/B/C/F"}, + {3, "A/B/K", "normal", 1, "A/B/K"}, + {3, "A/B/K/L", "normal", 1, "A/B/K/L"}, + {3, "A/B/K/M", "normal", 1, "A/B/K/M"}, + {3, "A/N/O", "normal", 3, "A/N/O"}, + {3, "A/N/P", "normal", NO_COPY_FROM}, + {4, "A/B/C/F", "base-deleted", NO_COPY_FROM}, + {4, "A/B/G/H", "base-deleted", NO_COPY_FROM}, + {4, "A/B/G/J", "normal", NO_COPY_FROM}, + + {0} + }; + + SVN_ERR(check_db_rows(&b, "", nodes)); + } + + SVN_ERR(verify_db(&b)); + + return SVN_NO_ERROR; +} + +static svn_error_t * +make_copy_and_delete_mixed(const svn_test_opts_t *opts, apr_pool_t *pool) +{ + svn_test__sandbox_t b; + + SVN_ERR(svn_test__sandbox_create(&b, "make_copy_and_del_mixed", opts, pool)); + + SVN_ERR(sbox_wc_mkdir(&b, "A")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/E")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/F")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/H")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/I")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/K")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/L")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/M")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/O")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/P")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/Q")); + SVN_ERR(sbox_wc_mkdir(&b, "A/R")); + SVN_ERR(sbox_wc_mkdir(&b, "A/R/S")); + SVN_ERR(sbox_wc_mkdir(&b, "A/R/S/T")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_update(&b, "", 1)); + SVN_ERR(sbox_wc_propset(&b, "k", "r2", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_propset(&b, "k", "r3", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_propset(&b, "k", "r4", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_propset(&b, "k", "r5", "")); + SVN_ERR(sbox_wc_commit(&b, "")); + + SVN_ERR(sbox_wc_update(&b, "", 5)); + SVN_ERR(sbox_wc_update(&b, "A", 4)); + SVN_ERR(sbox_wc_update(&b, "A/B", 3)); + SVN_ERR(sbox_wc_update(&b, "A/B/C", 2)); + SVN_ERR(sbox_wc_update(&b, "A/B/K", 1)); + SVN_ERR(sbox_wc_update(&b, "A/N/O", 3)); + + SVN_ERR(sbox_wc_delete(&b, "A/B/C/F")); + SVN_ERR(sbox_wc_delete(&b, "A/B/G/J")); + SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J")); + + SVN_ERR(sbox_wc_update(&b, "A/N/P", 1)); + SVN_ERR(sbox_wc_update(&b, "A/N/Q", 1)); + SVN_ERR(sbox_wc_delete(&b, "A/N/P")); + SVN_ERR(sbox_wc_mkdir(&b, "A/N/P")); + SVN_ERR(sbox_wc_move(&b, "A/N/Q", "Q")); + SVN_ERR(sbox_wc_move(&b, "A/B/G/H", "H")); + + /* And something that can't be represented */ + SVN_ERR(sbox_wc_update(&b, "A/B/C/E", 1)); + SVN_ERR(sbox_wc_move(&b, "A/B/C/E", "E")); + + { + nodes_row_t nodes[] = { + {0, "", "normal", 5, "", NOT_MOVED, "k"}, + {0, "A", "normal", 4, "A"}, + {0, "A/B", "normal", 3, "A/B"}, + {0, "A/B/C", "normal", 2, "A/B/C"}, + {0, "A/B/C/D", "normal", 2, "A/B/C/D"}, + {0, "A/B/C/E", "normal", 1, "A/B/C/E"}, + {0, "A/B/C/F", "normal", 2, "A/B/C/F"}, + {0, "A/B/G", "normal", 3, "A/B/G"}, + {0, "A/B/G/H", "normal", 3, "A/B/G/H"}, + {0, "A/B/G/I", "normal", 3, "A/B/G/I"}, + {0, "A/B/G/J", "normal", 3, "A/B/G/J"}, + {0, "A/B/K", "normal", 1, "A/B/K"}, + {0, "A/B/K/L", "normal", 1, "A/B/K/L"}, + {0, "A/B/K/M", "normal", 1, "A/B/K/M"}, + {0, "A/N", "normal", 4, "A/N"}, + {0, "A/N/O", "normal", 3, "A/N/O"}, + {0, "A/N/P", "normal", 1, "A/N/P"}, + {0, "A/N/Q", "normal", 1, "A/N/Q"}, + {0, "A/R", "normal", 4, "A/R"}, + {0, "A/R/S", "normal", 4, "A/R/S"}, + {0, "A/R/S/T", "normal", 4, "A/R/S/T"}, + {1, "E", "normal", 1, "A/B/C/E", MOVED_HERE}, + {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE}, + {1, "Q", "normal", 1, "A/N/Q", MOVED_HERE}, + {3, "A/N/P", "normal", NO_COPY_FROM}, + {3, "A/N/Q", "base-deleted", NO_COPY_FROM, "Q"}, + {4, "A/B/C/E", "base-deleted", NO_COPY_FROM, "E"}, + {4, "A/B/C/F", "base-deleted", NO_COPY_FROM}, + {4, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"}, + {4, "A/B/G/J", "normal", NO_COPY_FROM}, + + {0} + }; + + SVN_ERR(check_db_rows(&b, "", nodes)); + } + + SVN_ERR(svn_wc__db_base_remove(b.wc_ctx->db, sbox_wc_path(&b, "A"), + TRUE, TRUE, FALSE, 99, + NULL, NULL, pool)); + + { + nodes_row_t nodes[] = { + {0, "", "normal", 5, "", NOT_MOVED, "k"}, + {0, "A", "not-present", 99, "A"}, + {1, "A", "normal", 4, "A"}, + {1, "A/B", "not-present", 3, "A/B"}, + {1, "A/N", "normal", 4, "A/N"}, + {1, "A/N/O", "not-present", 3, "A/N/O"}, + {1, "A/N/P", "not-present", 1, "A/N/P"}, + {1, "A/N/Q", "not-present", 1, "A/N/Q", FALSE}, + {1, "A/R", "normal", 4, "A/R"}, + {1, "A/R/S", "normal", 4, "A/R/S"}, + {1, "A/R/S/T", "normal", 4, "A/R/S/T"}, + {1, "E", "normal", 1, "A/B/C/E"}, + {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE}, + {1, "Q", "normal", 1, "A/N/Q"}, + {2, "A/B", "normal", 3, "A/B"}, + {2, "A/B/C", "not-present", 2, "A/B/C"}, + {2, "A/B/G", "normal", 3, "A/B/G"}, + {2, "A/B/G/H", "normal", 3, "A/B/G/H"}, + {2, "A/B/G/I", "normal", 3, "A/B/G/I"}, + {2, "A/B/G/J", "normal", 3, "A/B/G/J"}, + {3, "A/B/C", "normal", 2, "A/B/C"}, + {3, "A/B/C/D", "normal", 2, "A/B/C/D"}, + {3, "A/B/C/E", "not-present", 1, "A/B/C/E"}, + {3, "A/B/C/F", "normal", 2, "A/B/C/F"}, + {2, "A/B/K", "not-present", 1, "A/B/K"}, + {3, "A/B/K", "normal", 1, "A/B/K"}, + {3, "A/B/K/L", "normal", 1, "A/B/K/L"}, + {3, "A/B/K/M", "normal", 1, "A/B/K/M"}, + {3, "A/N/O", "normal", 3, "A/N/O"}, + {3, "A/N/P", "normal", NO_COPY_FROM}, + {4, "A/B/C/F", "base-deleted", NO_COPY_FROM}, + {4, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"}, + {4, "A/B/G/J", "normal", NO_COPY_FROM}, + + {0} + }; + + /* This currently fails because Q and E are still marked as moved, + while there is nothing to be moved. */ + SVN_ERR(check_db_rows(&b, "", nodes)); + } + + SVN_ERR(verify_db(&b)); + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_global_commit(const svn_test_opts_t *opts, apr_pool_t *pool) +{ + svn_test__sandbox_t b; + + SVN_ERR(svn_test__sandbox_create(&b, "global_commit", opts, pool)); + + { + nodes_row_t before[] = { + { 0, "", "normal", 2, "" }, + { 0, "A", "normal", 2, "A" }, + { 0, "A/B", "normal", 2, "A/B" }, + { 0, "A/B/C", "normal", 2, "A/B/C" }, + { 0, "A/B/D", "normal", 2, "A/B/D" }, + { 0, "A/B/D/E", "normal", 2, "A/B/D/E" }, + { 0, "A/F", "normal", 2, "A/F" }, + { 0, "A/F/G", "normal", 2, "A/F/G" }, + { 0, "A/F/H", "normal", 2, "A/F/H" }, + { 0, "A/F/E", "normal", 2, "A/F/E" }, + { 0, "A/X", "normal", 2, "A/X" }, + { 0, "A/X/Y", "incomplete", 2, "A/X/Y" }, + { 1, "C", "normal", 2, "A/B/C", MOVED_HERE}, + { 1, "E", "normal", 2, "A/B/D/E", MOVED_HERE}, + { 2, "A/B", "normal", 3, "some", MOVED_HERE }, + { 2, "A/B/C", "base-deleted", NO_COPY_FROM, "C" }, + { 2, "A/B/D", "normal", 3, "some/D", MOVED_HERE}, + { 2, "A/B/D/E", "not-present", 3, "some/D/E", FALSE, "E", TRUE}, + { 3, "A/B/C", "normal", NO_COPY_FROM}, + { 2, "A/F", "normal", 1, "S2" }, + { 2, "A/F/G", "normal", 1, "S2/G" }, + { 2, "A/F/H", "not-present", 1, "S2/H" }, + { 2, "A/F/E", "base-deleted", NO_COPY_FROM }, + { 1, "some", "normal", 3, "some", FALSE, "A/B"}, + { 0 } + }; + SVN_ERR(insert_dirs(&b, before)); + SVN_ERR(check_db_rows(&b, "", before)); /* Check move insertion logic */ + SVN_ERR(verify_db(&b)); + } + + /* This should break the moves */ + SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db, + sbox_wc_path(&b, "A/B"), + 5, 5, 700, "me", NULL, NULL, + FALSE, FALSE, NULL, pool)); + { + nodes_row_t after[] = { + { 0, "", "normal", 2, "" }, + { 0, "A", "normal", 2, "A" }, + { 0, "A/B", "normal", 5, "A/B" }, + { 0, "A/B/D", "normal", 5, "A/B/D"}, + { 0, "A/B/D/E", "not-present", 5, "A/B/D/E"}, + { 0, "A/F", "normal", 2, "A/F" }, + { 0, "A/F/G", "normal", 2, "A/F/G" }, + { 0, "A/F/H", "normal", 2, "A/F/H" }, + { 0, "A/F/E", "normal", 2, "A/F/E" }, + { 0, "A/X", "normal", 2, "A/X" }, + { 0, "A/X/Y", "incomplete", 2, "A/X/Y" }, + { 1, "C", "normal", 2, "A/B/C"}, + { 1, "E", "normal", 2, "A/B/D/E"}, + { 1, "some", "normal", 3, "some"}, + { 3, "A/B/C", "normal", NO_COPY_FROM}, + { 2, "A/F", "normal", 1, "S2" }, + { 2, "A/F/G", "normal", 1, "S2/G" }, + { 2, "A/F/H", "not-present", 1, "S2/H" }, + { 2, "A/F/E", "base-deleted", NO_COPY_FROM }, + { 0 } + }; + + SVN_ERR(check_db_rows(&b, "", after)); + SVN_ERR(verify_db(&b)); + } + + SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db, + sbox_wc_path(&b, "A/F"), + 6, 6, 800, "me", NULL, NULL, + FALSE, FALSE, NULL, pool)); + + { + nodes_row_t after[] = { + { 0, "", "normal", 2, "" }, + { 0, "A", "normal", 2, "A" }, + { 0, "A/B", "normal", 5, "A/B" }, + { 0, "A/B/D", "normal", 5, "A/B/D"}, + { 0, "A/B/D/E", "not-present", 5, "A/B/D/E"}, + { 0, "A/F", "normal", 6, "A/F" }, + { 0, "A/F/G", "normal", 6, "A/F/G" }, + { 0, "A/F/H", "not-present", 6, "A/F/H" }, + { 0, "A/X", "normal", 2, "A/X" }, + { 0, "A/X/Y", "incomplete", 2, "A/X/Y" }, + { 1, "C", "normal", 2, "A/B/C"}, + { 1, "E", "normal", 2, "A/B/D/E"}, + { 1, "some", "normal", 3, "some"}, + { 3, "A/B/C", "normal", NO_COPY_FROM }, + { 0 } + }; + + SVN_ERR(check_db_rows(&b, "", after)); + SVN_ERR(verify_db(&b)); + } + + SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db, + sbox_wc_path(&b, "A/B/C"), + 7, 7, 900, "me", NULL, NULL, + FALSE, FALSE, NULL, pool)); + + { + nodes_row_t after[] = { + { 0, "", "normal", 2, "" }, + { 0, "A", "normal", 2, "A" }, + { 0, "A/B", "normal", 5, "A/B" }, + { 0, "A/B/C", "normal", 7, "A/B/C"}, + { 0, "A/B/D", "normal", 5, "A/B/D"}, + { 0, "A/B/D/E", "not-present", 5, "A/B/D/E"}, + { 0, "A/F", "normal", 6, "A/F" }, + { 0, "A/F/G", "normal", 6, "A/F/G" }, + { 0, "A/F/H", "not-present", 6, "A/F/H" }, + { 0, "A/X", "normal", 2, "A/X" }, + { 0, "A/X/Y", "incomplete", 2, "A/X/Y" }, + { 1, "some", "normal", 3, "some"}, + { 1, "E", "normal", 2, "A/B/D/E"}, + { 1, "C", "normal", 2, "A/B/C"}, + { 0 } + }; + + SVN_ERR(check_db_rows(&b, "", after)); + SVN_ERR(verify_db(&b)); + } + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_global_commit_switched(const svn_test_opts_t *opts, apr_pool_t *pool) +{ + svn_test__sandbox_t b; + + SVN_ERR(svn_test__sandbox_create(&b, "global_commit_switched", opts, pool)); + { + nodes_row_t before[] = { + { 0, "", "normal", 2, "" }, + { 0, "A", "normal", 2, "A" }, + /* A/B is switched... The libsvn_client layer tries to prevent this, + because it has such an unexpected behavior. */ + { 0, "A/B", "normal", 2, "N/B" }, + { 0, "A/B/C", "normal", 2, "N/B/C" }, + { 0, "A/B/C/D", "normal", 2, "N/B/C/D" }, + { 0, "A/B/C/E", "normal", 2, "N/B/C/E" }, + { 2, "A/B", "normal", 3, "Z/B" }, + { 2, "A/B/C", "normal", 3, "Z/B/C" }, + { 2, "A/B/C/D", "normal", 3, "Z/B/C/D" }, + { 2, "A/B/C/E", "base-deleted", NO_COPY_FROM }, + /* not-present nodes have an 'uninteresting path', + which doesn't have to be as implied by ancestor at same depth */ + { 2, "A/B/C/F", "not-present", 3, "ZZ-Z-Z_ZZ_Z_Z" }, + { 2, "A/B/C/G", "normal", 3, "Z/B/C/G" }, + { 2, "A/B/C/G/H", "normal", 3, "Z/B/C/G/H" }, + + { 3, "A/B/C", "normal", 4, "Q/C" }, + { 3, "A/B/C/D", "base-deleted", NO_COPY_FROM }, + { 3, "A/B/C/G", "normal", 4, "Q/C/G" }, + { 3, "A/B/C/G/H", "base-deleted", NO_COPY_FROM }, + + { 4, "A/B/C/F", "normal", NO_COPY_FROM }, + { 5, "A/B/C/G/H", "normal", NO_COPY_FROM }, + { 0 } + }; + SVN_ERR(insert_dirs(&b, before)); + SVN_ERR(verify_db(&b)); + } + + SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db, + sbox_wc_path(&b, "A/B"), + 7, 7, 12, "me", NULL, NULL, + FALSE, FALSE, NULL, pool)); + + { + nodes_row_t after[] = { + { 0, "", "normal", 2, "" }, + { 0, "A", "normal", 2, "A" }, + /* The commit is applied as A/B, because the path is calculated from A, + and not the shadowed node at A/B. (Fixed in r1663991) */ + { 0, "A/B", "normal", 7, "A/B" }, + { 0, "A/B/C", "normal", 7, "A/B/C" }, + { 0, "A/B/C/D", "normal", 7, "A/B/C/D" }, + /* Even calculated path of not-present is fixed */ + { 0, "A/B/C/F", "not-present", 7, "A/B/C/F" }, + { 0, "A/B/C/G", "normal", 7, "A/B/C/G" }, + { 0, "A/B/C/G/H", "normal", 7, "A/B/C/G/H" }, + + /* The higher layers are unaffected */ + { 3, "A/B/C", "normal", 4, "Q/C" }, + { 3, "A/B/C/D", "base-deleted", NO_COPY_FROM }, + { 3, "A/B/C/G", "normal", 4, "Q/C/G" }, + { 3, "A/B/C/G/H", "base-deleted", NO_COPY_FROM }, + + { 4, "A/B/C/F", "normal", NO_COPY_FROM }, + { 5, "A/B/C/G/H", "normal", NO_COPY_FROM }, + { 0 } + }; + SVN_ERR(verify_db(&b)); + SVN_ERR(check_db_rows(&b, "", after)); + } + + SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db, + sbox_wc_path(&b, "A/B/C"), + 8, 8, 12, "me", NULL, NULL, + FALSE, FALSE, NULL, pool)); + + { + nodes_row_t after[] = { + { 0, "", "normal", 2, "" }, + { 0, "A", "normal", 2, "A" }, + { 0, "A/B", "normal", 7, "A/B" }, + /* Base deleted and not-present are now gone */ + { 0, "A/B/C", "normal", 8, "A/B/C" }, + { 0, "A/B/C/G", "normal", 8, "A/B/C/G" }, + + { 4, "A/B/C/F", "normal", NO_COPY_FROM }, + { 5, "A/B/C/G/H", "normal", NO_COPY_FROM }, + { 0 } + }; + SVN_ERR(verify_db(&b)); + SVN_ERR(check_db_rows(&b, "", after)); + } + + return SVN_NO_ERROR; +} + /* ---------------------------------------------------------------------- */ /* The list of test functions */ -static int max_threads = 2; +static int max_threads = 4; static struct svn_test_descriptor_t test_funcs[] = { @@ -10843,8 +11909,8 @@ static struct svn_test_descriptor_t test "test_adds_change_kind"), SVN_TEST_OPTS_PASS(test_base_dir_insert_remove, "test_base_dir_insert_remove"), - SVN_TEST_OPTS_PASS(test_temp_op_make_copy, - "test_temp_op_make_copy"), + SVN_TEST_OPTS_PASS(test_db_make_copy, + "test_db_make_copy"), SVN_TEST_OPTS_PASS(test_wc_move, "test_wc_move"), SVN_TEST_OPTS_PASS(test_mixed_rev_copy, @@ -10964,7 +12030,7 @@ static struct svn_test_descriptor_t test "move_parent_into_child (issue 4333)"), SVN_TEST_OPTS_PASS(move_depth_expand, "move depth expansion"), - SVN_TEST_OPTS_PASS(move_retract, + SVN_TEST_OPTS_XFAIL(move_retract, "move retract (issue 4336)"), SVN_TEST_OPTS_PASS(move_delete_file_externals, "move/delete file externals (issue 4293)"), @@ -10986,11 +12052,11 @@ static struct svn_test_descriptor_t test "move twice and then delete"), SVN_TEST_OPTS_PASS(del4_update_edit_AAA, "del4: edit AAA"), - SVN_TEST_OPTS_PASS(del4_update_delete_AAA, + SVN_TEST_OPTS_XFAIL(del4_update_delete_AAA, "del4: delete AAA"), - SVN_TEST_OPTS_PASS(del4_update_add_AAA, + SVN_TEST_OPTS_XFAIL(del4_update_add_AAA, "del4: add AAA"), - SVN_TEST_OPTS_PASS(del4_update_replace_AAA, + SVN_TEST_OPTS_XFAIL(del4_update_replace_AAA, "del4: replace AAA"), SVN_TEST_OPTS_PASS(del4_update_delself_AAA, "del4: delete self AAA"), @@ -10998,11 +12064,11 @@ static struct svn_test_descriptor_t test "del4: replace self AAA"), SVN_TEST_OPTS_PASS(move4_update_edit_AAA, "move4: edit AAA"), - SVN_TEST_OPTS_PASS(move4_update_delete_AAA, + SVN_TEST_OPTS_XFAIL(move4_update_delete_AAA, "move4: delete AAA"), - SVN_TEST_OPTS_PASS(move4_update_add_AAA, + SVN_TEST_OPTS_XFAIL(move4_update_add_AAA, "move4: add AAA"), - SVN_TEST_OPTS_PASS(move4_update_replace_AAA, + SVN_TEST_OPTS_XFAIL(move4_update_replace_AAA, "move4: replace AAA"), SVN_TEST_OPTS_PASS(move4_update_delself_AAA, "move4: delete self AAA"), @@ -11022,6 +12088,16 @@ static struct svn_test_descriptor_t test "move within mixed move"), SVN_TEST_OPTS_PASS(move_edit_obstruction, "move edit obstruction"), + SVN_TEST_OPTS_PASS(move_deep_bump, + "move deep bump"), + SVN_TEST_OPTS_PASS(make_copy_mixed, + "make a copy of a mixed revision tree"), + SVN_TEST_OPTS_PASS(make_copy_and_delete_mixed, + "make a copy of a mixed revision tree and del"), + SVN_TEST_OPTS_PASS(test_global_commit, + "test global commit"), + SVN_TEST_OPTS_PASS(test_global_commit_switched, + "test global commit switched"), SVN_TEST_NULL };
Modified: subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c (original) +++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c Sun Jun 14 20:58:10 2015 @@ -33,7 +33,7 @@ #include "../../libsvn_wc/wc-queries.h" #define SVN_WC__I_AM_WC_DB #include "../../libsvn_wc/wc_db_private.h" - +#include "../../libsvn_wc/token-map.h" svn_error_t * svn_test__create_client_ctx(svn_client_ctx_t **ctx, svn_test__sandbox_t *sbox, @@ -122,6 +122,9 @@ WC_QUERIES_SQL_DECLARE_STATEMENTS(statem svn_error_t * svn_test__create_fake_wc(const char *wc_abspath, const char *extra_statements, + const svn_test__nodes_data_t nodes[], + const svn_test__actual_data_t actuals[], + apr_pool_t *scratch_pool) { const char *dotsvn_abspath = svn_dirent_join(wc_abspath, ".svn", @@ -129,6 +132,8 @@ svn_test__create_fake_wc(const char *wc_ svn_sqlite__db_t *sdb; const char **my_statements; int i; + svn_sqlite__stmt_t *stmt; + const apr_int64_t wc_id = 1; /* Allocate MY_STATEMENTS in RESULT_POOL because the SDB will continue to * refer to it over its lifetime. */ @@ -153,6 +158,110 @@ svn_test__create_fake_wc(const char *wc_ SVN_ERR(svn_sqlite__close(sdb)); + if (!nodes && !actuals) + return SVN_NO_ERROR; + + /* Re-open with normal set of statements */ + SVN_ERR(svn_wc__db_util_open_db(&sdb, wc_abspath, "wc.db", + svn_sqlite__mode_readwrite, + FALSE /* exclusive */, 0 /* timeout */, + statements, + scratch_pool, scratch_pool)); + + if (nodes) + { + SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, + STMT_INSERT_NODE)); + + for (i = 0; nodes[i].local_relpath; i++) + { + SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnns", + wc_id, + nodes[i].local_relpath, + nodes[i].op_depth, + nodes[i].local_relpath[0] + ? svn_relpath_dirname(nodes[i].local_relpath, + scratch_pool) + : NULL, + nodes[i].presence)); + + if (nodes[i].repos_relpath) + { + SVN_ERR(svn_sqlite__bind_int64(stmt, 5, nodes[i].repos_id)); + SVN_ERR(svn_sqlite__bind_text(stmt, 6, nodes[i].repos_relpath)); + SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, nodes[i].revision)); + } + + if (nodes[i].depth) + SVN_ERR(svn_sqlite__bind_text(stmt, 9, nodes[i].depth)); + + if (nodes[i].kind != 0) + SVN_ERR(svn_sqlite__bind_token(stmt, 10, kind_map, nodes[i].kind)); + + if (nodes[i].last_author || nodes[i].last_date) + { + SVN_ERR(svn_sqlite__bind_revnum(stmt, 11, nodes[i].last_revision)); + SVN_ERR(svn_sqlite__bind_int64(stmt, 12, nodes[i].last_date)); + SVN_ERR(svn_sqlite__bind_text(stmt, 13, nodes[i].last_author)); + } + + if (nodes[i].checksum) + SVN_ERR(svn_sqlite__bind_text(stmt, 14, nodes[i].checksum)); + + if (nodes[i].properties) + SVN_ERR(svn_sqlite__bind_text(stmt, 15, nodes[i].properties)); + + if (nodes[i].recorded_size || nodes[i].recorded_time) + { + SVN_ERR(svn_sqlite__bind_int64(stmt, 16, nodes[i].recorded_size)); + SVN_ERR(svn_sqlite__bind_int64(stmt, 17, nodes[i].recorded_time)); + } + + /* 18 is DAV cache */ + + if (nodes[i].symlink_target) + SVN_ERR(svn_sqlite__bind_text(stmt, 19, nodes[i].symlink_target)); + + if (nodes[i].file_external) + SVN_ERR(svn_sqlite__bind_int(stmt, 20, 1)); + + if (nodes[i].moved_to) + SVN_ERR(svn_sqlite__bind_text(stmt, 21, nodes[i].moved_to)); + + if (nodes[i].moved_here) + SVN_ERR(svn_sqlite__bind_int(stmt, 22, 1)); + + if (nodes[i].inherited_props) + SVN_ERR(svn_sqlite__bind_text(stmt, 23, nodes[i].inherited_props)); + + SVN_ERR(svn_sqlite__step_done(stmt)); + } + } + + if (actuals) + { + SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, + STMT_INSERT_ACTUAL_NODE)); + + for (i = 0; actuals[i].local_relpath; i++) + { + SVN_ERR(svn_sqlite__bindf(stmt, "isssss", + wc_id, + actuals[i].local_relpath, + actuals[i].local_relpath[0] + ? svn_relpath_dirname(actuals[i].local_relpath, + scratch_pool) + : NULL, + actuals[i].properties, + actuals[i].changelist, + actuals[i].conflict_data)); + + SVN_ERR(svn_sqlite__step_done(stmt)); + } + } + + SVN_ERR(svn_sqlite__close(sdb)); + return SVN_NO_ERROR; } @@ -280,8 +389,14 @@ sbox_wc_copy_url(svn_test__sandbox_t *b, APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = src; - SVN_ERR(svn_client_copy6(sources, sbox_wc_path(b, to_path), - FALSE, FALSE, FALSE, NULL, NULL, NULL, + SVN_ERR(svn_client_copy7(sources, sbox_wc_path(b, to_path), + FALSE /* copy_as_child */, + FALSE /* make_parents */, + FALSE /* ignore_externals */, + FALSE /* metadata_only */, + FALSE, NULL /* pin_external */, + NULL /* revprops */, + NULL, NULL, /* commit_callback */ ctx, scratch_pool)); ctx->wc_ctx = NULL; @@ -484,6 +599,35 @@ sbox_wc_resolve(svn_test__sandbox_t *b, } svn_error_t * +sbox_wc_resolve_prop(svn_test__sandbox_t *b, const char *path, + const char *propname, + svn_wc_conflict_choice_t conflict_choice) +{ + const char *lock_abspath; + svn_error_t *err; + + SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, b->wc_ctx, + sbox_wc_path(b, path), + b->pool, b->pool)); + err = svn_wc__resolve_conflicts(b->wc_ctx, sbox_wc_path(b, path), + svn_depth_empty, + FALSE, + propname, + FALSE, + conflict_choice, + NULL, NULL, /* conflict func */ + NULL, NULL, /* cancellation */ + NULL, NULL, /* notification */ + b->pool); + + err = svn_error_compose_create(err, svn_wc__release_write_lock(b->wc_ctx, + lock_abspath, + b->pool)); + return err; +} + + +svn_error_t * sbox_wc_move(svn_test__sandbox_t *b, const char *src, const char *dst) { svn_client_ctx_t *ctx; Modified: subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h (original) +++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h Sun Jun 14 20:58:10 2015 @@ -166,6 +166,12 @@ sbox_wc_resolve(svn_test__sandbox_t *b, /* */ svn_error_t * +sbox_wc_resolve_prop(svn_test__sandbox_t *b, const char *path, + const char *propname, + svn_wc_conflict_choice_t conflict_choice); + +/* */ +svn_error_t * sbox_wc_move(svn_test__sandbox_t *b, const char *src, const char *dst); /* Set property NAME to VALUE on PATH. If VALUE=NULL, delete the property. */ @@ -179,6 +185,39 @@ sbox_wc_propset(svn_test__sandbox_t *b, svn_error_t * sbox_add_and_commit_greek_tree(svn_test__sandbox_t *b); +/* Initial data to store in NODES */ +typedef struct svn_test__nodes_data_t +{ + int op_depth; + const char *local_relpath; + const char *presence; + int repos_id; + const char *repos_relpath; + svn_revnum_t revision; + svn_boolean_t moved_here; + const char *moved_to; + svn_node_kind_t kind; + const char *properties; + const char *depth; + const char *checksum; + const char *symlink_target; + svn_revnum_t last_revision; + apr_time_t last_date; + const char *last_author; + svn_boolean_t file_external; + const char *inherited_props; + svn_filesize_t recorded_size; + apr_time_t recorded_time; +} svn_test__nodes_data_t; + +/* Initial data to store in ACTUAL */ +typedef struct svn_test__actual_data_t +{ + const char *local_relpath; + const char *properties; + const char *changelist; + const char *conflict_data; +} svn_test__actual_data_t; /* Create a WC directory at WC_ABSPATH containing a fake WC DB, generated by * executing the SQL statements EXTRA_STATEMENTS in addition to the standard @@ -186,6 +225,8 @@ sbox_add_and_commit_greek_tree(svn_test_ svn_error_t * svn_test__create_fake_wc(const char *wc_abspath, const char *extra_statements, + const svn_test__nodes_data_t nodes[], + const svn_test__actual_data_t actuals[], apr_pool_t *scratch_pool); Modified: subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c (original) +++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c Sun Jun 14 20:58:10 2015 @@ -97,6 +97,7 @@ static const int slow_statements[] = /* Full temporary table read */ STMT_INSERT_ACTUAL_EMPTIES, + STMT_INSERT_ACTUAL_EMPTIES_FILES, STMT_SELECT_REVERT_LIST_RECURSIVE, STMT_SELECT_DELETE_LIST, STMT_SELECT_UPDATE_MOVE_LIST, @@ -107,6 +108,7 @@ static const int slow_statements[] = /* Slow, but just if foreign keys are enabled: * STMT_DELETE_PRISTINE_IF_UNREFERENCED, */ + STMT_HAVE_STAT1_TABLE, /* Queries sqlite_master which has no index */ -1 /* final marker */ }; @@ -302,14 +304,21 @@ parse_explanation_item(struct explanatio item->search = TRUE; /* Search or scan */ token = apr_strtok(NULL, " ", &last); - if (!MATCH_TOKEN(token, "TABLE")) + if (MATCH_TOKEN(token, "TABLE")) + { + item->table = apr_strtok(NULL, " ", &last); + } + else if (MATCH_TOKEN(token, "SUBQUERY")) + { + item->table = apr_psprintf(result_pool, "SUBQUERY-%s", + apr_strtok(NULL, " ", &last)); + } + else { printf("DBG: Expected 'TABLE', got '%s' in '%s'\n", token, text); return SVN_NO_ERROR; /* Nothing to parse */ } - item->table = apr_strtok(NULL, " ", &last); - token = apr_strtok(NULL, " ", &last); /* Skip alias */ @@ -918,6 +927,15 @@ test_schema_statistics(apr_pool_t *scrat "VALUES (1, '', '')", NULL, NULL, NULL)); + SQLITE_ERR( + sqlite3_exec(sdb, + "INSERT INTO EXTERNALS (wc_id, local_relpath," + " parent_relpath, repos_id," + " presence, kind, def_local_relpath," + " def_repos_relpath) " + "VALUES (1, 'subdir', '', 1, 'normal', 'dir', '', '')", + NULL, NULL, NULL)); + /* These are currently not necessary for query optimization, but it's better to tell Sqlite how we intend to use this table anyway */ SQLITE_ERR( @@ -976,6 +994,59 @@ test_schema_statistics(apr_pool_t *scrat return SVN_NO_ERROR; } +/* An SQLite application defined function that allows SQL queries to + use "relpath_depth(local_relpath)". */ +static void relpath_depth_sqlite(sqlite3_context* context, + int argc, + sqlite3_value* values[]) +{ + SVN_ERR_MALFUNCTION_NO_RETURN(); /* STUB! */ +} + +/* Parse all verify/check queries */ +static svn_error_t * +test_verify_parsable(apr_pool_t *scratch_pool) +{ + sqlite3 *sdb; + int i; + + SVN_ERR(create_memory_db(&sdb, scratch_pool)); + + SQLITE_ERR(sqlite3_create_function(sdb, "relpath_depth", 1, SQLITE_ANY, NULL, + relpath_depth_sqlite, NULL, NULL)); + + for (i=STMT_VERIFICATION_TRIGGERS; wc_queries[i]; i++) + { + sqlite3_stmt *stmt; + const char *text = wc_queries[i]; + + /* Some of our statement texts contain multiple queries. We prepare + them all. */ + while (*text != '\0') + { + const char *tail; + int r = sqlite3_prepare_v2(sdb, text, -1, &stmt, &tail); + + if (r != SQLITE_OK) + return svn_error_createf(SVN_ERR_SQLITE_ERROR, NULL, + "Preparing %s failed: %s\n%s", + wc_query_info[i][0], + sqlite3_errmsg(sdb), + text); + + SQLITE_ERR(sqlite3_finalize(stmt)); + + /* Continue after the current statement */ + text = tail; + } + } + + SQLITE_ERR(sqlite3_close(sdb)); /* Close the DB if ok; otherwise leaked */ + + return SVN_NO_ERROR; +} + + static int max_threads = 1; static struct svn_test_descriptor_t test_funcs[] = @@ -991,6 +1062,8 @@ static struct svn_test_descriptor_t test "test query duplicates"), SVN_TEST_PASS2(test_schema_statistics, "test schema statistics"), + SVN_TEST_PASS2(test_verify_parsable, + "verify queries are parsable"), SVN_TEST_NULL };
