Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c?rev=1666947&r1=1666946&r2=1666947&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c Mon Mar 16 10:10:20 2015 @@ -27,7 +27,6 @@ #include <apr_pools.h> #include <apr_file_io.h> #include <assert.h> -#define SVN_DEPRECATED #include "svn_error.h" #include "svn_delta.h" @@ -82,13 +81,15 @@ commit_changes(svn_ra_session_t *session SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton, revprop_table, NULL, NULL, NULL, TRUE, pool)); - SVN_ERR(svn_ra_get_repos_root(session, &repos_root_url, pool)); + SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, pool)); SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM, pool, &root_baton)); /* copy root-dir@0 to A@1 */ SVN_ERR(editor->add_directory("A", root_baton, repos_root_url, 0, pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->close_directory(root_baton, pool)); SVN_ERR(editor->close_edit(edit_baton, pool)); return SVN_NO_ERROR; } @@ -106,7 +107,7 @@ commit_tree(svn_ra_session_t *session, SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton, revprop_table, NULL, NULL, NULL, TRUE, pool)); - SVN_ERR(svn_ra_get_repos_root(session, &repos_root_url, pool)); + SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, pool)); SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM, pool, &root_baton)); @@ -131,6 +132,7 @@ commit_tree(svn_ra_session_t *session, SVN_ERR(editor->close_file(file_baton, NULL, pool)); SVN_ERR(editor->close_directory(B_baton, pool)); SVN_ERR(editor->close_directory(A_baton, pool)); + SVN_ERR(editor->close_directory(root_baton, pool)); SVN_ERR(editor->close_edit(edit_baton, pool)); return SVN_NO_ERROR; } @@ -339,13 +341,14 @@ check_tunnel_callback_test(const svn_tes cbtable->check_tunnel_func = check_tunnel; cbtable->open_tunnel_func = open_tunnel; cbtable->tunnel_baton = &b; - SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton, - TRUE /* non_interactive */, - "jrandom", "rayjandom", - NULL, - TRUE /* no_auth_cache */, - FALSE /* trust_server_cert */, - NULL, NULL, NULL, pool)); + SVN_ERR(svn_cmdline_create_auth_baton2(&cbtable->auth_baton, + TRUE /* non_interactive */, + "jrandom", "rayjandom", + NULL, + TRUE /* no_auth_cache */, + FALSE /* trust_server_cert */, + FALSE, FALSE, FALSE, FALSE, + NULL, NULL, NULL, pool)); b.last_check = TRUE; err = svn_ra_open4(&session, NULL, "svn+foo://localhost/no-repo", @@ -380,13 +383,14 @@ tunnel_callback_test(const svn_test_opts cbtable->check_tunnel_func = check_tunnel; cbtable->open_tunnel_func = open_tunnel; cbtable->tunnel_baton = &b; - SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton, - TRUE /* non_interactive */, - "jrandom", "rayjandom", - NULL, - TRUE /* no_auth_cache */, - FALSE /* trust_server_cert */, - NULL, NULL, NULL, pool)); + SVN_ERR(svn_cmdline_create_auth_baton2(&cbtable->auth_baton, + TRUE /* non_interactive */, + "jrandom", "rayjandom", + NULL, + TRUE /* no_auth_cache */, + FALSE /* trust_server_cert */, + FALSE, FALSE, FALSE, FALSE, + NULL, NULL, NULL, pool)); b.last_check = FALSE; err = svn_ra_open4(&session, NULL, url, NULL, cbtable, NULL, NULL, @@ -732,6 +736,7 @@ delete_revision_above_youngest(const svn SVN_ERR(editor->add_directory("A", root_baton, NULL, SVN_INVALID_REVNUM, pool, &dir_baton)); SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->close_directory(root_baton, pool)); SVN_ERR(editor->close_edit(edit_baton, pool)); } @@ -757,10 +762,688 @@ delete_revision_above_youngest(const svn return SVN_NO_ERROR; } +/* Stub svn_log_entry_receiver_t */ +static svn_error_t * +stub_log_receiver(void *baton, + svn_log_entry_t *entry, + apr_pool_t *scratch_pool) +{ + return SVN_NO_ERROR; +} + +/* Stub svn_location_segment_receiver_t */ +static svn_error_t * +stub_segment_receiver(svn_location_segment_t *segment, + void *baton, + apr_pool_t *scratch_pool) +{ + return SVN_NO_ERROR; +} +/* Stub svn_file_rev_handler_t */ +static svn_error_t * +stub_file_rev_handler(void *baton, + const char *path, + svn_revnum_t rev, + apr_hash_t *rev_props, + svn_boolean_t result_of_merge, + svn_txdelta_window_handler_t *delta_handler, + void **delta_baton, + apr_array_header_t *prop_diffs, + apr_pool_t *pool) +{ + if (delta_handler) + *delta_handler = svn_delta_noop_window_handler; + + return SVN_NO_ERROR; +} + +struct lock_stub_baton_t +{ + apr_status_t result_code; +}; + +static svn_error_t * +store_lock_result(void *baton, + const char *path, + svn_boolean_t do_lock, + const svn_lock_t *lock, + svn_error_t *ra_err, + apr_pool_t *pool) +{ + struct lock_stub_baton_t *b = baton; + + b->result_code = ra_err ? ra_err->apr_err : APR_SUCCESS; + return SVN_NO_ERROR; +} + +static svn_error_t * +replay_range_rev_start(svn_revnum_t revision, + void *replay_baton, + const svn_delta_editor_t **editor, + void **edit_baton, + apr_hash_t *rev_props, + apr_pool_t *pool) +{ + *editor = svn_delta_default_editor(pool); + *edit_baton = NULL; + return SVN_NO_ERROR; +} + +static svn_error_t * +replay_range_rev_end(svn_revnum_t revision, + void *replay_baton, + const svn_delta_editor_t *editor, + void *edit_baton, + apr_hash_t *rev_props, + apr_pool_t *pool) +{ + return SVN_NO_ERROR; +} + +static svn_error_t * +ra_revision_errors(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_ra_session_t *ra_session; + const svn_delta_editor_t *editor; + svn_error_t *err; + void *edit_baton; + + /* This function DOESN'T use a scratch/iter pool between requests... + + That has a reason: some ra layers (e.g. Serf) are sensitive to + reusing the same pool. In that case they may produce bad results + that they wouldn't do (as often) when the pool wasn't reused. + + It the amount of memory used gets too big we should probably split + this test... as the reuse already discovered a few issues that + are now resolved in ra_serf. + */ + SVN_ERR(make_and_open_repos(&ra_session, "ra_revision_errors", + opts, pool)); + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, pool)); + + { + void *root_baton; + void *dir_baton; + void *file_baton; + + SVN_ERR(editor->open_root(edit_baton, 0, pool, &root_baton)); + SVN_ERR(editor->add_directory("A", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->add_file("A/iota", dir_baton, NULL, SVN_INVALID_REVNUM, + pool, &file_baton)); + SVN_ERR(editor->close_file(file_baton, NULL, pool)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->add_directory("B", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->add_directory("C", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->add_directory("D", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->close_directory(root_baton, pool)); + SVN_ERR(editor->close_edit(edit_baton, pool)); + } + + { + const svn_ra_reporter3_t *reporter; + void *report_baton; + + err = svn_ra_do_update3(ra_session, &reporter, &report_baton, + 2, "", svn_depth_infinity, FALSE, FALSE, + svn_delta_default_editor(pool), NULL, + pool, pool); + + if (!err) + err = reporter->set_path(report_baton, "", 0, svn_depth_infinity, FALSE, + NULL, pool); + + if (!err) + err = reporter->finish_report(report_baton, pool); + + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_NO_SUCH_REVISION); + } + + { + const svn_ra_reporter3_t *reporter; + void *report_baton; + + err = svn_ra_do_update3(ra_session, &reporter, &report_baton, + 1, "", svn_depth_infinity, FALSE, FALSE, + svn_delta_default_editor(pool), NULL, + pool, pool); + + if (!err) + err = reporter->set_path(report_baton, "", 2, svn_depth_infinity, FALSE, + NULL, pool); + + if (!err) + err = reporter->finish_report(report_baton, pool); + + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_NO_SUCH_REVISION); + } + + { + const svn_ra_reporter3_t *reporter; + void *report_baton; + + err = svn_ra_do_update3(ra_session, &reporter, &report_baton, + 1, "", svn_depth_infinity, FALSE, FALSE, + svn_delta_default_editor(pool), NULL, + pool, pool); + + if (!err) + err = reporter->set_path(report_baton, "", 0, svn_depth_infinity, FALSE, + NULL, pool); + + if (!err) + err = reporter->finish_report(report_baton, pool); + + SVN_ERR(err); + } + + { + svn_revnum_t revision; + + SVN_ERR(svn_ra_get_dated_revision(ra_session, &revision, + apr_time_now() - apr_time_from_sec(3600), + pool)); + + SVN_TEST_ASSERT(revision == 0); + + SVN_ERR(svn_ra_get_dated_revision(ra_session, &revision, + apr_time_now() + apr_time_from_sec(3600), + pool)); + + SVN_TEST_ASSERT(revision == 1); + } + + { + /* SVN_INVALID_REVNUM is protected by assert in ra loader */ + + SVN_TEST_ASSERT_ERROR(svn_ra_change_rev_prop2(ra_session, + 2, + "bad", NULL, + svn_string_create("value", + pool), + pool), + SVN_ERR_FS_NO_SUCH_REVISION); + } + + { + apr_hash_t *props; + svn_string_t *value; + + /* SVN_INVALID_REVNUM is protected by assert in ra loader */ + + SVN_TEST_ASSERT_ERROR(svn_ra_rev_proplist(ra_session, 2, &props, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_rev_prop(ra_session, 2, "bad", &value, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + } + + { + apr_hash_t *props; + svn_string_t *value; + + /* SVN_INVALID_REVNUM is protected by assert in ra loader */ + + SVN_TEST_ASSERT_ERROR(svn_ra_rev_proplist(ra_session, 2, &props, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_rev_prop(ra_session, 2, "bad", &value, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + } + + { + svn_revnum_t fetched; + apr_hash_t *props; + + SVN_TEST_ASSERT_ERROR(svn_ra_get_file(ra_session, "A", 1, + svn_stream_empty(pool), &fetched, + &props, pool), + SVN_ERR_FS_NOT_FILE); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_file(ra_session, "A/iota", 2, + svn_stream_empty(pool), &fetched, + &props, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_file(ra_session, "Z", 1, + svn_stream_empty(pool), &fetched, + &props, pool), + SVN_ERR_FS_NOT_FOUND); + + SVN_ERR(svn_ra_get_file(ra_session, "A/iota", SVN_INVALID_REVNUM, + svn_stream_empty(pool), &fetched, + &props, pool)); + SVN_TEST_ASSERT(fetched == 1); + } + + { + svn_revnum_t fetched; + apr_hash_t *dirents; + apr_hash_t *props; + + SVN_TEST_ASSERT_ERROR(svn_ra_get_dir2(ra_session, &dirents, &fetched, + &props, "A/iota", 1, + SVN_DIRENT_ALL, pool), + SVN_ERR_FS_NOT_DIRECTORY); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_dir2(ra_session, &dirents, &fetched, + &props, "A", 2, + SVN_DIRENT_ALL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_dir2(ra_session, &dirents, &fetched, + &props, "Z", 1, + SVN_DIRENT_ALL, pool), + SVN_ERR_FS_NOT_FOUND); + + SVN_ERR(svn_ra_get_dir2(ra_session, &dirents, &fetched, + &props, "A", SVN_INVALID_REVNUM, + SVN_DIRENT_ALL, pool)); + SVN_TEST_ASSERT(fetched == 1); + SVN_TEST_ASSERT(apr_hash_count(dirents) == 1); + } + + { + svn_mergeinfo_catalog_t catalog; + apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char*)); + APR_ARRAY_PUSH(paths, const char *) = "A"; + + SVN_TEST_ASSERT_ERROR(svn_ra_get_mergeinfo(ra_session, &catalog, paths, + 2, svn_mergeinfo_inherited, + FALSE, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_mergeinfo(ra_session, &catalog, paths, + 0, svn_mergeinfo_inherited, + FALSE, pool), + SVN_ERR_FS_NOT_FOUND); + + SVN_ERR(svn_ra_get_mergeinfo(ra_session, &catalog, paths, + SVN_INVALID_REVNUM, svn_mergeinfo_inherited, + FALSE, pool)); + } + + { + apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char*)); + APR_ARRAY_PUSH(paths, const char *) = "A"; + + SVN_TEST_ASSERT_ERROR(svn_ra_get_log2(ra_session, paths, 0, 2, -1, + FALSE, FALSE, FALSE, NULL, + stub_log_receiver, NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_log2(ra_session, paths, 2, 0, -1, + FALSE, FALSE, FALSE, NULL, + stub_log_receiver, NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_log2(ra_session, paths, + SVN_INVALID_REVNUM, 2, -1, + FALSE, FALSE, FALSE, NULL, + stub_log_receiver, NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_log2(ra_session, paths, + 2, SVN_INVALID_REVNUM, -1, + FALSE, FALSE, FALSE, NULL, + stub_log_receiver, NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + } + + { + svn_node_kind_t kind; + SVN_TEST_ASSERT_ERROR(svn_ra_check_path(ra_session, "A", 2, &kind, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_ERR(svn_ra_check_path(ra_session, "A", SVN_INVALID_REVNUM, &kind, + pool)); + + SVN_TEST_ASSERT(kind == svn_node_dir); + } + + { + svn_dirent_t *dirent; + apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char*)); + APR_ARRAY_PUSH(paths, const char *) = "A"; + + SVN_TEST_ASSERT_ERROR(svn_ra_stat(ra_session, "A", 2, &dirent, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_ERR(svn_ra_stat(ra_session, "A", SVN_INVALID_REVNUM, &dirent, + pool)); + + SVN_TEST_ASSERT(dirent->kind == svn_node_dir); + } + + { + apr_hash_t *locations; + apr_array_header_t *revisions = apr_array_make(pool, 2, sizeof(svn_revnum_t)); + APR_ARRAY_PUSH(revisions, svn_revnum_t) = 1; + + /* SVN_INVALID_REVNUM as passed revision doesn't work */ + + SVN_TEST_ASSERT_ERROR(svn_ra_get_locations(ra_session, &locations, "A", 2, + revisions, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + APR_ARRAY_PUSH(revisions, svn_revnum_t) = 7; + SVN_TEST_ASSERT_ERROR(svn_ra_get_locations(ra_session, &locations, "A", 1, + revisions, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + /* Putting SVN_INVALID_REVNUM in the array doesn't marshal properly in svn:// + */ + } + + { + /* peg_rev -> SVN_INVALID_REVNUM -> youngest + start_rev -> SVN_INVALID_REVNUM -> peg_rev + end_rev -> SVN_INVALID_REVNUM -> 0 */ + SVN_TEST_ASSERT_ERROR(svn_ra_get_location_segments(ra_session, "A", + 2, 1, 0, + stub_segment_receiver, + NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_location_segments(ra_session, "A", + SVN_INVALID_REVNUM, + 2, 0, + stub_segment_receiver, + NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + + SVN_TEST_ASSERT_ERROR(svn_ra_get_location_segments(ra_session, "A", + SVN_INVALID_REVNUM, + SVN_INVALID_REVNUM, + 2, + stub_segment_receiver, + NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_ERR(svn_ra_get_location_segments(ra_session, "A", + SVN_INVALID_REVNUM, + SVN_INVALID_REVNUM, + SVN_INVALID_REVNUM, + stub_segment_receiver, + NULL, pool)); + } + + { + SVN_TEST_ASSERT_ERROR(svn_ra_get_file_revs2(ra_session, "A/iota", 2, 0, + FALSE, stub_file_rev_handler, + NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_file_revs2(ra_session, "A/iota", 0, 2, + FALSE, stub_file_rev_handler, + NULL, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_file_revs2(ra_session, "A", 1, 1, + FALSE, stub_file_rev_handler, + NULL, pool), + SVN_ERR_FS_NOT_FILE); + } + + { + apr_hash_t *locks = apr_hash_make(pool); + svn_revnum_t rev = 2; + struct lock_stub_baton_t lr = {0}; + + svn_hash_sets(locks, "A/iota", &rev); + + SVN_ERR(svn_ra_lock(ra_session, locks, "comment", FALSE, + store_lock_result, &lr, pool)); + SVN_TEST_ASSERT(lr.result_code == SVN_ERR_FS_NO_SUCH_REVISION); + + rev = 0; + SVN_ERR(svn_ra_lock(ra_session, locks, "comment", FALSE, + store_lock_result, &lr, pool)); + SVN_TEST_ASSERT(lr.result_code == SVN_ERR_FS_OUT_OF_DATE); + + svn_hash_sets(locks, "A/iota", NULL); + svn_hash_sets(locks, "A", &rev); + rev = SVN_INVALID_REVNUM; + SVN_ERR(svn_ra_lock(ra_session, locks, "comment", FALSE, + store_lock_result, &lr, pool)); + SVN_TEST_ASSERT(lr.result_code == SVN_ERR_FS_NOT_FILE); + } + + { + apr_hash_t *locks = apr_hash_make(pool); + struct lock_stub_baton_t lr = {0}; + + svn_hash_sets(locks, "A/iota", "no-token"); + + SVN_ERR(svn_ra_unlock(ra_session, locks, FALSE, + store_lock_result, &lr, pool)); + SVN_TEST_ASSERT(lr.result_code == SVN_ERR_FS_NO_SUCH_LOCK); + + + svn_hash_sets(locks, "A/iota", NULL); + svn_hash_sets(locks, "A", "no-token"); + SVN_ERR(svn_ra_unlock(ra_session, locks, FALSE, + store_lock_result, &lr, pool)); + SVN_TEST_ASSERT(lr.result_code == SVN_ERR_FS_NO_SUCH_LOCK); + } + + { + svn_lock_t *lock; + SVN_ERR(svn_ra_get_lock(ra_session, &lock, "A", pool)); + SVN_TEST_ASSERT(lock == NULL); + } + + { + SVN_TEST_ASSERT_ERROR(svn_ra_replay(ra_session, 2, 0, TRUE, + svn_delta_default_editor(pool), NULL, + pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + /* Simply assumes everything is there*/ + SVN_ERR(svn_ra_replay(ra_session, 1, 2, TRUE, + svn_delta_default_editor(pool), NULL, + pool)); + } + + { + SVN_TEST_ASSERT_ERROR(svn_ra_replay_range(ra_session, 1, 2, 0, + TRUE, + replay_range_rev_start, + replay_range_rev_end, NULL, + pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + /* Simply assumes everything is there*/ + SVN_TEST_ASSERT_ERROR(svn_ra_replay_range(ra_session, 2, 2, 0, + TRUE, + replay_range_rev_start, + replay_range_rev_end, NULL, + pool), + SVN_ERR_FS_NO_SUCH_REVISION); + } + + { + svn_revnum_t del_rev; + + /* ### Explicitly documented to not return an FS or RA error???? */ + + SVN_TEST_ASSERT_ERROR(svn_ra_get_deleted_rev(ra_session, "Z", 2, 1, + &del_rev, pool), + SVN_ERR_CLIENT_BAD_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_deleted_rev(ra_session, "Z", + SVN_INVALID_REVNUM, 2, + &del_rev, pool), + SVN_ERR_CLIENT_BAD_REVISION); + + } + + { + apr_array_header_t *iprops; + + SVN_TEST_ASSERT_ERROR(svn_ra_get_inherited_props(ra_session, &iprops, + "A", 2, pool, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + SVN_TEST_ASSERT_ERROR(svn_ra_get_inherited_props(ra_session, &iprops, + "A", SVN_INVALID_REVNUM, + pool, pool), + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_TEST_ASSERT_ERROR(svn_ra_get_inherited_props(ra_session, &iprops, + "Z", 1, + pool, pool), + SVN_ERR_FS_NOT_FOUND); + } + + return SVN_NO_ERROR; +} +/* svn_log_entry_receiver_t returning cease invocation */ +static svn_error_t * +error_log_receiver(void *baton, + svn_log_entry_t *entry, + apr_pool_t *scratch_pool) +{ + return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL); +} + +/* Stub svn_location_segment_receiver_t */ +static svn_error_t * +error_segment_receiver(svn_location_segment_t *segment, + void *baton, + apr_pool_t *scratch_pool) +{ + return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL); +} + + +static svn_error_t * +errors_from_callbacks(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_ra_session_t *ra_session; + const svn_delta_editor_t *editor; + void *edit_baton; + + /* This function DOESN'T use a scratch/iter pool between requests... + + That has a reason: some ra layers (e.g. Serf) are sensitive to + reusing the same pool. In that case they may produce bad results + that they wouldn't do (as often) when the pool wasn't reused. + + It the amount of memory used gets too big we should probably split + this test... as the reuse already discovered a few issues that + are now resolved in ra_serf. + */ + SVN_ERR(make_and_open_repos(&ra_session, "errors_from_callbacks", + opts, pool)); + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, pool)); + + { + void *root_baton; + void *dir_baton; + void *file_baton; + + SVN_ERR(editor->open_root(edit_baton, 0, pool, &root_baton)); + SVN_ERR(editor->add_directory("A", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->add_file("A/iota", dir_baton, NULL, SVN_INVALID_REVNUM, + pool, &file_baton)); + SVN_ERR(editor->close_file(file_baton, NULL, pool)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->add_directory("B", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->add_directory("C", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->add_directory("D", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->close_directory(root_baton, pool)); + SVN_ERR(editor->close_edit(edit_baton, pool)); + } + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, pool)); + + { + void *root_baton; + void *dir_baton; + void *file_baton; + + SVN_ERR(editor->open_root(edit_baton, 1, pool, &root_baton)); + SVN_ERR(editor->open_directory("A", root_baton, 1, pool, &dir_baton)); + SVN_ERR(editor->open_file("A/iota", dir_baton, 1, pool, &file_baton)); + + SVN_ERR(editor->change_file_prop(file_baton, "A", svn_string_create("B", + pool), + pool)); + + SVN_ERR(editor->close_file(file_baton, NULL, pool)); + + SVN_ERR(editor->change_dir_prop(dir_baton, "A", svn_string_create("B", + pool), + pool)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->close_directory(root_baton, pool)); + SVN_ERR(editor->close_edit(edit_baton, pool)); + } + + { + apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char*)); + APR_ARRAY_PUSH(paths, const char *) = "A/iota"; + + /* Note that ra_svn performs OK for SVN_ERR_CEASE_INVOCATION, but any + other error will make it break the ra session for further operations */ + + SVN_TEST_ASSERT_ERROR(svn_ra_get_log2(ra_session, paths, 2, 0, -1, + FALSE, FALSE, FALSE, NULL, + error_log_receiver, NULL, pool), + SVN_ERR_CEASE_INVOCATION); + } + + { + /* Note that ra_svn performs OK for SVN_ERR_CEASE_INVOCATION, but any + other error will make it break the ra session for further operations */ + + SVN_TEST_ASSERT_ERROR(svn_ra_get_location_segments(ra_session, "A/iota", + 2, 2, 0, + error_segment_receiver, + NULL, pool), + SVN_ERR_CEASE_INVOCATION); + } + + /* And a final check to see if the ra session is still ok */ + { + svn_node_kind_t kind; + + SVN_ERR(svn_ra_check_path(ra_session, "A", 2, &kind, pool)); + + SVN_TEST_ASSERT(kind == svn_node_dir); + } + return SVN_NO_ERROR; +} + /* The test table. */ -static int max_threads = 2; +static int max_threads = 4; static struct svn_test_descriptor_t test_funcs[] = { @@ -781,6 +1464,10 @@ static struct svn_test_descriptor_t test "base revision newer than youngest"), SVN_TEST_OPTS_PASS(delete_revision_above_youngest, "delete revision newer than youngest"), + SVN_TEST_OPTS_PASS(ra_revision_errors, + "check how ra functions handle bad revisions"), + SVN_TEST_OPTS_PASS(errors_from_callbacks, + "check how ra layers handle errors from callbacks"), SVN_TEST_NULL };
Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/auth-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/auth-test.c?rev=1666947&r1=1666946&r2=1666947&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/auth-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/auth-test.c Mon Mar 16 10:10:20 2015 @@ -312,6 +312,153 @@ test_auth_clear(apr_pool_t *pool) return SVN_NO_ERROR; } +struct plaintext_baton_t +{ + int nr_calls; + svn_boolean_t may_save; +}; +static svn_error_t * +plaintext_prompt_cb(svn_boolean_t *may_save_plaintext, + const char *realmstring, + void *baton, + apr_pool_t *pool) +{ + struct plaintext_baton_t *b = baton; + b->nr_calls++; + *may_save_plaintext = b->may_save; + return SVN_NO_ERROR; +} + +static svn_error_t * +test_save_cleartext(apr_pool_t *pool) +{ +#ifndef SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE +# define EXPECT_NO_CALLS 0 +# define EXPECT_ONE_CALL 1 +# define EXPECT_TWO_CALLS 2 +#else +# define EXPECT_NO_CALLS 0 +# define EXPECT_ONE_CALL 0 +# define EXPECT_TWO_CALLS 0 +#endif + + const char *auth_dir; + svn_auth_baton_t *baton, *slave; + svn_auth_provider_object_t *provider; + apr_array_header_t *providers; + void *credentials; + svn_auth_iterstate_t *state; + struct plaintext_baton_t pb = {0, FALSE}; + + SVN_ERR(svn_dirent_get_absolute(&auth_dir, "save-cleartext", pool)); + + SVN_ERR(svn_io_remove_dir2(auth_dir, TRUE, NULL, NULL, pool)); + SVN_ERR(svn_io_dir_make(auth_dir, APR_OS_DEFAULT, pool)); + svn_test_add_dir_cleanup(auth_dir); + + svn_auth_get_simple_provider2(&provider, plaintext_prompt_cb, &pb, pool); + + providers = apr_array_make(pool, 1, sizeof(svn_auth_provider_object_t *)); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + + svn_auth_open(&baton, providers, pool); + + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_DEFAULT_USERNAME, "jrandom"); + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_DEFAULT_PASSWORD, "rayjandom"); + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_CONFIG_DIR, auth_dir); + + /* Create the auth subdirs. Without these we can't store passwords */ + SVN_ERR(svn_config_ensure(auth_dir, pool)); + pb.nr_calls = 0; + + /* Legacy behavior: Don't ask: Save */ + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-1", baton, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_NO_CALLS); + + /* Set to ask */ + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS, + SVN_CONFIG_ASK); + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-2", baton, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_ONE_CALL); + + /* Set to true */ + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS, + SVN_CONFIG_TRUE); + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-3", baton, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_ONE_CALL); + + /* Set to false */ + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS, + SVN_CONFIG_FALSE); + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-4", baton, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_ONE_CALL); + + /* Reset baton...*/ + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS, + NULL); + pb.nr_calls = 0; + + SVN_ERR(svn_auth__make_session_auth(&slave, baton, NULL, "dummy", + pool, pool)); + + + /* Standard behavior after make session auth: */ + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-1a", slave, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_ONE_CALL); + + /* Set to ask */ + svn_auth_set_parameter(slave, SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS, + SVN_CONFIG_ASK); + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-2a", slave, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_TWO_CALLS); + + /* Set to true */ + svn_auth_set_parameter(slave, SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS, + SVN_CONFIG_TRUE); + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-3a", slave, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_TWO_CALLS); + + /* Set to false */ + svn_auth_set_parameter(slave, SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS, + SVN_CONFIG_FALSE); + SVN_ERR(svn_auth_first_credentials(&credentials, &state, + SVN_AUTH_CRED_SIMPLE, + "realm-4a", slave, pool)); + SVN_TEST_ASSERT(credentials != NULL); + SVN_ERR(svn_auth_save_credentials(state, pool)); + SVN_TEST_ASSERT(pb.nr_calls == EXPECT_TWO_CALLS); + + + return SVN_NO_ERROR; +} /* The test table. */ @@ -324,6 +471,8 @@ static struct svn_test_descriptor_t test "test retrieving platform-specific auth providers"), SVN_TEST_PASS2(test_auth_clear, "test svn_auth_clear()"), + SVN_TEST_PASS2(test_save_cleartext, + "test save cleartext info"), SVN_TEST_NULL }; Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c?rev=1666947&r1=1666946&r2=1666947&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c Mon Mar 16 10:10:20 2015 @@ -11773,6 +11773,103 @@ test_global_commit(const svn_test_opts_t 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 */ @@ -11988,6 +12085,8 @@ static struct svn_test_descriptor_t test "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"), SVN_TEST_NULL }; Modified: subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c?rev=1666947&r1=1666946&r2=1666947&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c Mon Mar 16 10:10:20 2015 @@ -746,13 +746,14 @@ svn_test__init_auth_baton(svn_auth_baton SVN_CONFIG_OPTION_PASSWORD_STORES, "windows-cryptoapi"); - SVN_ERR(svn_cmdline_create_auth_baton(ab, - TRUE /* non_interactive */, - "jrandom", "rayjandom", - NULL, - TRUE /* no_auth_cache */, - FALSE /* trust_server_cert */, - cfg_config, NULL, NULL, result_pool)); + SVN_ERR(svn_cmdline_create_auth_baton2(ab, + TRUE /* non_interactive */, + "jrandom", "rayjandom", + NULL, + TRUE /* no_auth_cache */, + FALSE /* trust_server_cert */, + FALSE, FALSE, FALSE, FALSE, + cfg_config, NULL, NULL, result_pool)); return SVN_NO_ERROR; } Propchange: subversion/branches/move-tracking-2/tools/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon Mar 16 10:10:20 2015 @@ -82,4 +82,4 @@ /subversion/branches/verify-at-commit/tools:1462039-1462408 /subversion/branches/verify-keep-going/tools:1439280-1546110 /subversion/branches/wc-collate-path/tools:1402685-1480384 -/subversion/trunk/tools:1606692-1665165 +/subversion/trunk/tools:1606692-1666945 Modified: subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd?rev=1666947&r1=1666946&r2=1666947&view=diff ============================================================================== --- subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd (original) +++ subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd Mon Mar 16 10:10:20 2015 @@ -80,29 +80,6 @@ if "%SVN_BRANCH%" GTR "1.9." ( echo Done. ) -) ELSE IF "%SVN_BRANCH%" GTR "1.8." ( - - mkdir "%TESTDIR%\swig\pl-debug\SVN" - mkdir "%TESTDIR%\swig\pl-debug\auto\SVN" - xcopy subversion\bindings\swig\perl\native\*.pm "%TESTDIR%\swig\pl-debug\SVN" > nul: - pushd debug\subversion\bindings\swig\perl\native - for %%i in (*.dll) do ( - set name=%%i - mkdir "%TESTDIR%\swig\pl-debug\auto\SVN\!name:~0,-4!" - xcopy "!name:~0,-4!.*" "%TESTDIR%\swig\pl-debug\auto\SVN\!name:~0,-4!" > nul: - xcopy /y "_Core.dll" "%TESTDIR%\swig\pl-debug\auto\SVN\!name:~0,-4!" > nul: - ) - popd - - - SET PERL5LIB=%PERL5LIB%;%TESTDIR%\swig\pl-debug; - pushd subversion\bindings\swig\perl\native - perl -MExtUtils::Command::MM -e "test_harness()" t\*.t - IF ERRORLEVEL 1 ( - echo [Test runner reported error !ERRORLEVEL!] - REM SET result=1 - ) - popd ) if "%SVN_BRANCH%" GTR "1.9." ( Modified: subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd?rev=1666947&r1=1666946&r2=1666947&view=diff ============================================================================== --- subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd (original) +++ subversion/branches/move-tracking-2/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd Mon Mar 16 10:10:20 2015 @@ -31,7 +31,7 @@ IF "%SVN_BRANCH%" LEQ "1.6.x" ( SET DEBUG_TARGETS=/t:__ALL_TESTS__ SET RELEASE_TARGETS=/t:__SWIG_PYTHON__ -if "%SVN_BRANCH%" GTR "1.8." ( +if "%SVN_BRANCH%" GTR "1.9." ( SET DEBUG_TARGETS=%DEBUG_TARGETS% /t:__SWIG_PERL__ ) Propchange: subversion/branches/move-tracking-2/tools/dev/wc-ng/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Mar 16 10:10:20 2015 @@ -0,0 +1 @@ +svn-wc-db-tester
