Modified: subversion/branches/ev2-export/subversion/tests/libsvn_repos/repos-test.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_repos/repos-test.c?rev=1449262&r1=1449261&r2=1449262&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/tests/libsvn_repos/repos-test.c (original) +++ subversion/branches/ev2-export/subversion/tests/libsvn_repos/repos-test.c Sat Feb 23 01:25:38 2013 @@ -1157,7 +1157,7 @@ authz_get_handle(svn_authz_t **authz_p, SVN_ERR_W(svn_stream_puts(stream, authz_contents), "Writing authz contents to stream"); - SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, pool), + SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, NULL, pool), "Parsing the authz contents"); SVN_ERR_W(svn_stream_close(stream), @@ -1451,34 +1451,35 @@ in_repo_authz(const svn_test_opts_t *opt /* repos relative URL */ repos_root = svn_repos_path(repos, pool); - SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", TRUE, repos_root, - pool)); + SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", NULL, TRUE, + repos_root, pool)); SVN_ERR(authz_check_access(authz_cfg, test_set, pool)); /* absolute file URL, repos_root is NULL to validate the contract that it * is not needed except when a repos relative URL is passed. */ SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_root, pool)); authz_url = apr_pstrcat(pool, repos_url, "/authz", (char *)NULL); - SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, TRUE, NULL, pool)); + SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, NULL, TRUE, + NULL, pool)); SVN_ERR(authz_check_access(authz_cfg, test_set, pool)); /* Non-existant path in the repo with must_exist set to FALSE */ - SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz", FALSE, repos_root, - pool)); + SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz", NULL, FALSE, + repos_root, pool)); /* Non-existant path in the repo with must_exist set to TRUE */ - err = svn_repos_authz_read2(&authz_cfg, "^/A/authz", TRUE, repos_root, - pool); - if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG) + err = svn_repos_authz_read2(&authz_cfg, "^/A/authz", NULL, TRUE, + repos_root, pool); + if (!err || err->apr_err != SVN_ERR_ILLEGAL_TARGET) return svn_error_createf(SVN_ERR_TEST_FAILED, err, "Got %s error instead of expected " - "SVN_ERR_AUTHZ_INVALID_CONFIG", + "SVN_ERR_ILLEGAL_TARGET", err ? "unexpected" : "no"); svn_error_clear(err); /* http:// URL which is unsupported */ err = svn_repos_authz_read2(&authz_cfg, "http://example.com/repo/authz", - TRUE, repos_root, pool); + NULL, TRUE, repos_root, pool); if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL) return svn_error_createf(SVN_ERR_TEST_FAILED, err, "Got %s error instead of expected " @@ -1488,6 +1489,160 @@ in_repo_authz(const svn_test_opts_t *opt /* svn:// URL which is unsupported */ err = svn_repos_authz_read2(&authz_cfg, "svn://example.com/repo/authz", + NULL, TRUE, repos_root, pool); + if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL) + return svn_error_createf(SVN_ERR_TEST_FAILED, err, + "Got %s error instead of expected " + "SVN_ERR_RA_ILLEGAL_URL", + err ? "unexpected" : "no"); + svn_error_clear(err); + + + return SVN_NO_ERROR; +} + + +/* Test in-repo authz with global groups. */ +static svn_error_t * +in_repo_groups_authz(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_repos_t *repos; + svn_fs_t *fs; + svn_fs_txn_t *txn; + svn_fs_root_t *txn_root; + svn_revnum_t youngest_rev; + svn_authz_t *authz_cfg; + const char *groups_contents; + const char *authz_contents; + const char *repos_root; + const char *repos_url; + const char *groups_url; + const char *authz_url; + svn_error_t *err; + struct check_access_tests test_set[] = { + /* reads */ + { "/A", NULL, NULL, svn_authz_read, FALSE }, + { "/A", NULL, "plato", svn_authz_read, TRUE }, + { "/A", NULL, "socrates", svn_authz_read, TRUE }, + { "/A", NULL, "solon", svn_authz_read, TRUE }, + { "/A", NULL, "ephialtes", svn_authz_read, TRUE }, + /* writes */ + { "/A", NULL, NULL, svn_authz_write, FALSE }, + { "/A", NULL, "plato", svn_authz_write, FALSE }, + { "/A", NULL, "socrates", svn_authz_write, FALSE }, + { "/A", NULL, "solon", svn_authz_write, TRUE }, + { "/A", NULL, "ephialtes", svn_authz_write, TRUE }, + /* Sentinel */ + { NULL, NULL, NULL, svn_authz_none, FALSE } + }; + + /* Test plan: + * 1. Create an authz file, a global groups file and an empty authz file, + * put all these files in the repository. The empty authz file is + * required to perform the non-existent path checks (4-7) -- + * otherwise we would get the authz validation error due to undefined + * groups. + * 2. Verify that the groups file can be read with an relative URL. + * 3. Verify that the groups file can be read with an absolute URL. + * 4. Verify that non-existent groups file path does not error out when + * must_exist is FALSE. + * 5. Same as (4), but when both authz and groups file paths do + * not exist. + * 6. Verify that non-existent path for the groups file does error out when + * must_exist is TRUE. + * 7. Verify that an http:// URL produces an error. + * 8. Verify that an svn:// URL produces an error. + */ + + /* What we'll put in the authz and groups files, it's simple since + * we're not testing the parsing, just that we got what we expected. */ + + groups_contents = + "[groups]" NL + "philosophers = plato, socrates" NL + "senate = solon, ephialtes" NL + "" NL; + + authz_contents = + "[/]" NL + "@senate = rw" NL + "@philosophers = r" NL + "" NL; + + /* Create a filesystem and repository. */ + SVN_ERR(svn_test__create_repos(&repos, + "test-repo-in-repo-global-groups-authz", + opts, pool)); + fs = svn_repos_fs(repos); + + /* Commit the authz, empty authz and groups files to the repo. */ + SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); + SVN_ERR(svn_fs_make_file(txn_root, "groups", pool)); + SVN_ERR(svn_fs_make_file(txn_root, "authz", pool)); + SVN_ERR(svn_fs_make_file(txn_root, "empty-authz", pool)); + SVN_ERR(svn_test__set_file_contents(txn_root, "groups", + groups_contents, pool)); + SVN_ERR(svn_test__set_file_contents(txn_root, "authz", + authz_contents, pool)); + SVN_ERR(svn_test__set_file_contents(txn_root, "empty-authz", "", pool)); + SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); + SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev)); + + /* repos relative URLs */ + repos_root = svn_repos_path(repos, pool); + SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", "^/groups", + TRUE, repos_root, pool)); + SVN_ERR(authz_check_access(authz_cfg, test_set, pool)); + + /* absolute file URLs, repos_root is NULL to validate the contract that it + * is not needed except when a repos relative URLs are passed. */ + SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_root, pool)); + authz_url = apr_pstrcat(pool, repos_url, "/authz", (char *)NULL); + groups_url = apr_pstrcat(pool, repos_url, "/groups", (char *)NULL); + SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, groups_url, + TRUE, NULL, pool)); + SVN_ERR(authz_check_access(authz_cfg, test_set, pool)); + + /* Non-existent path for the groups file with must_exist + * set to TRUE */ + SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/empty-authz", + "^/A/groups", FALSE, + repos_root, pool)); + + /* Non-existent paths for both the authz and the groups files + * with must_exist set to TRUE */ + SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz", + "^/A/groups", FALSE, + repos_root, pool)); + + /* Non-existent path for the groups file with must_exist + * set to TRUE */ + err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz", + "^/A/groups", TRUE, + repos_root, pool); + if (!err || err->apr_err != SVN_ERR_ILLEGAL_TARGET) + return svn_error_createf(SVN_ERR_TEST_FAILED, err, + "Got %s error instead of expected " + "SVN_ERR_ILLEGAL_TARGET", + err ? "unexpected" : "no"); + svn_error_clear(err); + + /* http:// URL which is unsupported */ + err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz", + "http://example.com/repo/groups", + TRUE, repos_root, pool); + if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL) + return svn_error_createf(SVN_ERR_TEST_FAILED, err, + "Got %s error instead of expected " + "SVN_ERR_RA_ILLEGAL_URL", + err ? "unexpected" : "no"); + svn_error_clear(err); + + /* svn:// URL which is unsupported */ + err = svn_repos_authz_read2(&authz_cfg, "^/empty-authz", + "http://example.com/repo/groups", TRUE, repos_root, pool); if (!err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL) return svn_error_createf(SVN_ERR_TEST_FAILED, err, @@ -1500,6 +1655,249 @@ in_repo_authz(const svn_test_opts_t *opt return SVN_NO_ERROR; } + +/* Helper for the groups_authz test. Set *AUTHZ_P to a representation of + AUTHZ_CONTENTS in conjuction with GROUPS_CONTENTS, using POOL for + temporary allocation. If DISK is TRUE then write the contents to + temporary files and use svn_repos_authz_read2() to get the data if FALSE + write the data to a buffered stream and use svn_repos_authz_parse(). */ +static svn_error_t * +authz_groups_get_handle(svn_authz_t **authz_p, + const char *authz_contents, + const char *groups_contents, + svn_boolean_t disk, + apr_pool_t *pool) +{ + if (disk) + { + const char *authz_file_path; + const char *groups_file_path; + + /* Create temporary files. */ + SVN_ERR_W(svn_io_write_unique(&authz_file_path, NULL, + authz_contents, + strlen(authz_contents), + svn_io_file_del_on_pool_cleanup, pool), + "Writing temporary authz file"); + SVN_ERR_W(svn_io_write_unique(&groups_file_path, NULL, + groups_contents, + strlen(groups_contents), + svn_io_file_del_on_pool_cleanup, pool), + "Writing temporary groups file"); + + /* Read the authz configuration back and start testing. */ + SVN_ERR_W(svn_repos_authz_read2(authz_p, authz_file_path, + groups_file_path, TRUE, NULL, pool), + "Opening test authz and groups files"); + + /* Done with the files. */ + SVN_ERR_W(svn_io_remove_file(authz_file_path, pool), + "Removing test authz file"); + SVN_ERR_W(svn_io_remove_file(groups_file_path, pool), + "Removing test groups file"); + } + else + { + svn_stream_t *stream; + svn_stream_t *groups_stream; + + /* Create the streams. */ + stream = svn_stream_buffered(pool); + groups_stream = svn_stream_buffered(pool); + + SVN_ERR_W(svn_stream_puts(stream, authz_contents), + "Writing authz contents to stream"); + SVN_ERR_W(svn_stream_puts(groups_stream, groups_contents), + "Writing groups contents to stream"); + + /* Read the authz configuration from the streams and start testing. */ + SVN_ERR_W(svn_repos_authz_parse(authz_p, stream, groups_stream, pool), + "Parsing the authz and groups contents"); + + /* Done with the streams. */ + SVN_ERR_W(svn_stream_close(stream), + "Closing the authz stream"); + SVN_ERR_W(svn_stream_close(groups_stream), + "Closing the groups stream"); + } + + return SVN_NO_ERROR; +} + +/* Test authz with global groups. */ +static svn_error_t * +groups_authz(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_authz_t *authz_cfg; + const char *authz_contents; + const char *groups_contents; + svn_error_t *err; + + struct check_access_tests test_set1[] = { + /* reads */ + { "/A", "greek", NULL, svn_authz_read, FALSE }, + { "/A", "greek", "plato", svn_authz_read, TRUE }, + { "/A", "greek", "demetrius", svn_authz_read, TRUE }, + { "/A", "greek", "galenos", svn_authz_read, TRUE }, + { "/A", "greek", "pamphilos", svn_authz_read, FALSE }, + /* writes */ + { "/A", "greek", NULL, svn_authz_write, FALSE }, + { "/A", "greek", "plato", svn_authz_write, TRUE }, + { "/A", "greek", "demetrius", svn_authz_write, FALSE }, + { "/A", "greek", "galenos", svn_authz_write, FALSE }, + { "/A", "greek", "pamphilos", svn_authz_write, FALSE }, + /* Sentinel */ + { NULL, NULL, NULL, svn_authz_none, FALSE } + }; + + struct check_access_tests test_set2[] = { + /* reads */ + { "/A", "greek", NULL, svn_authz_read, FALSE }, + { "/A", "greek", "socrates", svn_authz_read, FALSE }, + { "/B", "greek", NULL, svn_authz_read, FALSE}, + { "/B", "greek", "socrates", svn_authz_read, TRUE }, + /* writes */ + { "/A", "greek", NULL, svn_authz_write, FALSE }, + { "/A", "greek", "socrates", svn_authz_write, FALSE }, + { "/B", "greek", NULL, svn_authz_write, FALSE}, + { "/B", "greek", "socrates", svn_authz_write, TRUE }, + /* Sentinel */ + { NULL, NULL, NULL, svn_authz_none, FALSE } + }; + + /* Test plan: + * 1. Ensure that a simple setup with global groups and access rights in + * two separate files works as expected. + * 2. Verify that access rights written in the global groups file are + * discarded and affect nothing in authorization terms. + * 3. Verify that local groups in the authz file are prohibited in + * conjuction with global groups (and that a configuration error is + * reported in this scenario). + * 4. Ensure that group cycles in the global groups file are reported. + * + * All checks are performed twice -- for the configurations stored on disk + * and in memory. See authz_groups_get_handle. + */ + + groups_contents = + "[groups]" NL + "slaves = pamphilos,@gladiators" NL + "gladiators = demetrius,galenos" NL + "philosophers = plato" NL + "" NL; + + authz_contents = + "[greek:/A]" NL + "@slaves = " NL + "@gladiators = r" NL + "@philosophers = rw" NL + "" NL; + + SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, TRUE, pool)); + + SVN_ERR(authz_check_access(authz_cfg, test_set1, pool)); + + SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, FALSE, pool)); + + SVN_ERR(authz_check_access(authz_cfg, test_set1, pool)); + + /* Access rights in the global groups file are discarded. */ + groups_contents = + "[groups]" NL + "philosophers = socrates" NL + "" NL + "[greek:/A]" NL + "@philosophers = rw" NL + "" NL; + + authz_contents = + "[greek:/B]" NL + "@philosophers = rw" NL + "" NL; + + SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, TRUE, pool)); + + SVN_ERR(authz_check_access(authz_cfg, test_set2, pool)); + + SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, FALSE, pool)); + + SVN_ERR(authz_check_access(authz_cfg, test_set2, pool)); + + /* Local groups cannot be used in conjuction with global groups. */ + groups_contents = + "[groups]" NL + "slaves = maximus" NL + "" NL; + + authz_contents = + "[greek:/A]" NL + "@slaves = " NL + "@kings = rw" NL + "" NL + "[groups]" NL + /* That's an epic story of the slave who tried to become a king. */ + "kings = maximus" NL + "" NL; + + err = authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, TRUE, pool); + + if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG) + return svn_error_createf(SVN_ERR_TEST_FAILED, err, + "Got %s error instead of expected " + "SVN_ERR_AUTHZ_INVALID_CONFIG", + err ? "unexpected" : "no"); + svn_error_clear(err); + + err = authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, FALSE, pool); + + if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG) + return svn_error_createf(SVN_ERR_TEST_FAILED, err, + "Got %s error instead of expected " + "SVN_ERR_AUTHZ_INVALID_CONFIG", + err ? "unexpected" : "no"); + svn_error_clear(err); + + /* Ensure that group cycles are reported. */ + groups_contents = + "[groups]" NL + "slaves = cooks,scribes,@gladiators" NL + "gladiators = equites,thraces,@slaves" NL + "" NL; + + authz_contents = + "[greek:/A]" NL + "@slaves = r" NL + "" NL; + + err = authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, TRUE, pool); + + if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG) + return svn_error_createf(SVN_ERR_TEST_FAILED, err, + "Got %s error instead of expected " + "SVN_ERR_AUTHZ_INVALID_CONFIG", + err ? "unexpected" : "no"); + svn_error_clear(err); + + err = authz_groups_get_handle(&authz_cfg, authz_contents, + groups_contents, FALSE, pool); + + if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG) + return svn_error_createf(SVN_ERR_TEST_FAILED, err, + "Got %s error instead of expected " + "SVN_ERR_AUTHZ_INVALID_CONFIG", + err ? "unexpected" : "no"); + svn_error_clear(err); + + return SVN_NO_ERROR; +} /* Callback for the commit editor tests that relays requests to authz. */ @@ -2423,7 +2821,7 @@ prop_validation(const svn_test_opts_t *o { svn_error_t *err; svn_repos_t *repos; - const char non_utf8_string[5] = { 'a', (char)0xff, 'b', '\n', 0 }; + const char non_utf8_string[5] = { 'a', '\xff', 'b', '\n', 0 }; const char *non_lf_string = "a\r\nb\n\rc\rd\n"; apr_pool_t *subpool = svn_pool_create(pool); @@ -2644,6 +3042,7 @@ test_get_file_revs(const svn_test_opts_t }; apr_hash_t *ht_trunk_results = apr_hash_make(subpool); apr_hash_t *ht_branch_results = apr_hash_make(subpool); + apr_hash_t *ht_reverse_results = apr_hash_make(subpool); for (i = 0; i < sizeof(trunk_results) / sizeof(trunk_results[0]); i++) apr_hash_set(ht_trunk_results, &trunk_results[i].rev, @@ -2653,6 +3052,11 @@ test_get_file_revs(const svn_test_opts_t apr_hash_set(ht_branch_results, &branch_results[i].rev, sizeof(svn_revnum_t), &branch_results[i]); + for (i = 0; i < sizeof(trunk_results) / sizeof(trunk_results[0]); i++) + if (!trunk_results[i].result_of_merge) + apr_hash_set(ht_reverse_results, &trunk_results[i].rev, + sizeof(svn_revnum_t), &trunk_results[i]); + /* Create the repository and verify blame results. */ SVN_ERR(svn_test__create_blame_repository(&repos, "test-repo-get-filerevs", opts, subpool)); @@ -2662,7 +3066,7 @@ test_get_file_revs(const svn_test_opts_t /* Verify blame of /trunk/A/mu */ SVN_ERR(svn_repos_get_file_revs2(repos, "/trunk/A/mu", 0, youngest_rev, - 1, NULL, NULL, + TRUE, NULL, NULL, file_rev_handler, ht_trunk_results, subpool)); @@ -2671,7 +3075,7 @@ test_get_file_revs(const svn_test_opts_t /* Verify blame of /branches/1.0.x/A/mu */ SVN_ERR(svn_repos_get_file_revs2(repos, "/branches/1.0.x/A/mu", 0, youngest_rev, - 1, NULL, NULL, + TRUE, NULL, NULL, file_rev_handler, ht_branch_results, subpool)); @@ -2679,6 +3083,13 @@ test_get_file_revs(const svn_test_opts_t /* ### TODO: Verify blame of /branches/1.0.x/A/mu in range 6-7 */ + SVN_ERR(svn_repos_get_file_revs2(repos, "/trunk/A/mu", youngest_rev, 0, + FALSE, NULL, NULL, + file_rev_handler, + ht_reverse_results, + subpool)); + SVN_TEST_ASSERT(apr_hash_count(ht_reverse_results) == 0); + svn_pool_destroy(subpool); return SVN_NO_ERROR; @@ -2723,6 +3134,36 @@ issue_4060(const svn_test_opts_t *opts, return SVN_NO_ERROR; } +/* Test svn_repos_delete(). */ +static svn_error_t * +test_delete_repos(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + const char *path; + svn_node_kind_t kind; + + /* We have to use a subpool to close the svn_repos_t before calling + svn_repos_delete. */ + { + svn_repos_t *repos; + apr_pool_t *subpool = svn_pool_create(pool); + SVN_ERR(svn_test__create_repos(&repos, "test-repo-delete-repos", opts, + subpool)); + path = svn_repos_path(repos, pool); + svn_pool_destroy(subpool); + } + + SVN_ERR(svn_io_check_path(path, &kind, pool)); + SVN_TEST_ASSERT(kind != svn_node_none); + SVN_ERR(svn_repos_delete(path, pool)); + SVN_ERR(svn_io_check_path(path, &kind, pool)); + SVN_TEST_ASSERT(kind == svn_node_none); + + /* Recreate dir so that test cleanup doesn't fail. */ + SVN_ERR(svn_io_dir_make(path, APR_OS_DEFAULT, pool)); + + return SVN_NO_ERROR; +} /* The test table. */ @@ -2745,6 +3186,10 @@ struct svn_test_descriptor_t test_funcs[ "test authz access control"), SVN_TEST_OPTS_PASS(in_repo_authz, "test authz stored in the repo"), + SVN_TEST_OPTS_PASS(in_repo_groups_authz, + "test authz and global groups stored in the repo"), + SVN_TEST_OPTS_PASS(groups_authz, + "test authz with global groups"), SVN_TEST_OPTS_PASS(commit_editor_authz, "test authz in the commit editor"), SVN_TEST_OPTS_PASS(commit_continue_txn, @@ -2761,5 +3206,7 @@ struct svn_test_descriptor_t test_funcs[ "test svn_repos_get_file_revsN"), SVN_TEST_OPTS_PASS(issue_4060, "test issue 4060"), + SVN_TEST_OPTS_PASS(test_delete_repos, + "test svn_repos_delete"), SVN_TEST_NULL };
Modified: subversion/branches/ev2-export/subversion/tests/libsvn_subr/auth-test.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_subr/auth-test.c?rev=1449262&r1=1449261&r2=1449262&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/tests/libsvn_subr/auth-test.c (original) +++ subversion/branches/ev2-export/subversion/tests/libsvn_subr/auth-test.c Sat Feb 23 01:25:38 2013 @@ -22,9 +22,11 @@ */ #include "svn_auth.h" +#include "svn_dirent_uri.h" #include "svn_private_config.h" #include "../svn_test.h" +#include "private/svn_auth_private.h" static svn_error_t * test_platform_specific_auth_providers(apr_pool_t *pool) @@ -206,6 +208,108 @@ test_platform_specific_auth_providers(ap return SVN_NO_ERROR; } +/* Helper for test_auth_clear(). Implements svn_auth_cleanup_callback */ +static svn_error_t * +cleanup_callback(svn_boolean_t *delete_cred, + void *cleanup_baton, + const char *cred_kind, + const char *realmstring, + const char *provider, + apr_pool_t *scratch_pool) +{ + if (!strcmp(provider, SVN_AUTH__SIMPLE_PASSWORD_TYPE)) + return SVN_NO_ERROR; + + SVN_TEST_ASSERT(! strcmp(cred_kind, SVN_AUTH_CRED_SIMPLE)); + SVN_TEST_ASSERT(! strcmp(realmstring, "<http://my.host> My realm")); + + *delete_cred = TRUE; + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_auth_clear(apr_pool_t *pool) +{ + const char *auth_dir; + svn_auth_provider_object_t *provider; + svn_auth_baton_t *baton; + apr_array_header_t *providers; + void *credentials; + svn_auth_cred_simple_t *creds; + svn_auth_iterstate_t *state; + + SVN_ERR(svn_dirent_get_absolute(&auth_dir, "", pool)); + auth_dir = svn_dirent_join(auth_dir, "auth-clear", pool); + + svn_test_add_dir_cleanup(auth_dir); + + 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_auth_get_simple_provider2(&provider, NULL, NULL, 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)); + + /* Obtain the default credentials just passed */ + SVN_ERR(svn_auth_first_credentials(&credentials, + &state, + SVN_AUTH_CRED_SIMPLE, + "<http://my.host> My realm", + baton, + pool)); + + creds = credentials; + SVN_TEST_ASSERT(! strcmp(creds->username, "jrandom")); + SVN_TEST_ASSERT(creds->may_save); + + /* And tell that they are ok and can be saved */ + SVN_ERR(svn_auth_save_credentials(state, pool)); + + /* Ok, and now we try to remove the credentials */ + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_DEFAULT_USERNAME, NULL); + svn_auth_set_parameter(baton, SVN_AUTH_PARAM_DEFAULT_PASSWORD, NULL); + + /* Are they still in the baton? */ + SVN_ERR(svn_auth_first_credentials(&credentials, + &state, + SVN_AUTH_CRED_SIMPLE, + "<http://my.host> My realm", + baton, + pool)); + + SVN_TEST_ASSERT(credentials); + creds = credentials; + SVN_TEST_ASSERT(! strcmp(creds->username, "jrandom")); + SVN_TEST_ASSERT(creds->may_save); + + + SVN_ERR(svn_auth_cleanup_walk(baton, + cleanup_callback, NULL, + pool)); + + SVN_ERR(svn_auth_first_credentials(&credentials, + &state, + SVN_AUTH_CRED_SIMPLE, + "<http://my.host> My realm", + baton, + pool)); + + SVN_TEST_ASSERT(! credentials); + + return SVN_NO_ERROR; +} + /* The test table. */ @@ -214,5 +318,13 @@ struct svn_test_descriptor_t test_funcs[ SVN_TEST_NULL, SVN_TEST_PASS2(test_platform_specific_auth_providers, "test retrieving platform-specific auth providers"), +#ifndef SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE + SVN_TEST_PASS2(test_auth_clear, + "test svn_auth_clear()"), +#else + SVN_TEST_WIMP(test_auth_clear, + "test svn_auth_clear()", + "Needs testing with SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE"), +#endif SVN_TEST_NULL }; Modified: subversion/branches/ev2-export/subversion/tests/libsvn_subr/dirent_uri-test.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1449262&r1=1449261&r2=1449262&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/tests/libsvn_subr/dirent_uri-test.c (original) +++ subversion/branches/ev2-export/subversion/tests/libsvn_subr/dirent_uri-test.c Sat Feb 23 01:25:38 2013 @@ -618,6 +618,11 @@ test_uri_dirname(apr_pool_t *pool) { "http://server", "http://server" }, { "file:///a/b", "file:///a" }, { "file:///a", "file://" }, + { "file://", "file://" }, +#ifdef WIN32 + { "file:///A:/dir", "file:///A:" }, + { "file:///A:", "file://" }, +#endif }; for (i = 0; i < COUNT_OF(tests); i++) Modified: subversion/branches/ev2-export/subversion/tests/libsvn_subr/subst_translate-test.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_subr/subst_translate-test.c?rev=1449262&r1=1449261&r2=1449262&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/tests/libsvn_subr/subst_translate-test.c (original) +++ subversion/branches/ev2-export/subversion/tests/libsvn_subr/subst_translate-test.c Sat Feb 23 01:25:38 2013 @@ -96,9 +96,7 @@ test_svn_subst_translate_string2(apr_poo source_string, "ISO-8859-1", FALSE, pool, pool); - SVN_TEST_ASSERT(err != SVN_NO_ERROR); - SVN_TEST_ASSERT(err->apr_err == SVN_ERR_IO_INCONSISTENT_EOL); - svn_error_clear(err); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_IO_INCONSISTENT_EOL); } return SVN_NO_ERROR; Modified: subversion/branches/ev2-export/subversion/tests/libsvn_wc/conflict-data-test.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_wc/conflict-data-test.c?rev=1449262&r1=1449261&r2=1449262&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/tests/libsvn_wc/conflict-data-test.c (original) +++ subversion/branches/ev2-export/subversion/tests/libsvn_wc/conflict-data-test.c Sat Feb 23 01:25:38 2013 @@ -501,9 +501,10 @@ test_serialize_tree_conflict(const svn_t SVN_ERR(svn_wc__conflict_skel_add_tree_conflict( conflict_skel, - sbox.wc_ctx->db, sbox.wc_abspath, + sbox.wc_ctx->db, sbox_wc_path(&sbox, "A/B"), svn_wc_conflict_reason_moved_away, svn_wc_conflict_action_delete, + sbox_wc_path(&sbox, "A/B"), pool, pool)); SVN_ERR(svn_wc__conflict_skel_set_op_switch( @@ -520,9 +521,11 @@ test_serialize_tree_conflict(const svn_t { svn_wc_conflict_reason_t local_change; svn_wc_conflict_action_t incoming_change; + const char *moved_away_op_root_abspath; SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change, &incoming_change, + &moved_away_op_root_abspath, sbox.wc_ctx->db, sbox.wc_abspath, conflict_skel, @@ -530,6 +533,8 @@ test_serialize_tree_conflict(const svn_t SVN_TEST_ASSERT(local_change == svn_wc_conflict_reason_moved_away); SVN_TEST_ASSERT(incoming_change == svn_wc_conflict_action_delete); + SVN_TEST_ASSERT(!strcmp(moved_away_op_root_abspath, + sbox_wc_path(&sbox, "A/B"))); } return SVN_NO_ERROR; Modified: subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c?rev=1449262&r1=1449261&r2=1449262&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c (original) +++ subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c Sat Feb 23 01:25:38 2013 @@ -546,8 +546,7 @@ test_getting_info(apr_pool_t *pool) NULL, NULL, NULL, NULL, db, svn_dirent_join(local_abspath, "missing-file", pool), pool, pool); - SVN_TEST_ASSERT(err != NULL && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND); - svn_error_clear(err); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_PATH_NOT_FOUND); return SVN_NO_ERROR; } Modified: subversion/branches/ev2-export/subversion/tests/libsvn_wc/entries-compat.c URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_wc/entries-compat.c?rev=1449262&r1=1449261&r2=1449262&view=diff ============================================================================== --- subversion/branches/ev2-export/subversion/tests/libsvn_wc/entries-compat.c (original) +++ subversion/branches/ev2-export/subversion/tests/libsvn_wc/entries-compat.c Sat Feb 23 01:25:38 2013 @@ -332,7 +332,7 @@ create_open(svn_wc__db_t **db, pool)); SVN_ERR(svn_wc__db_open(db, NULL /* config */, - FALSE /* auto_upgrade */, + FALSE /* not_upgraded_ok */, TRUE /* enforce_empty_wq */, pool, pool)); @@ -601,12 +601,14 @@ test_access_baton_like_locking(apr_pool_ { const char *url, *repos_root_url, *repos_uuid; const char *subdir = svn_dirent_join(local_abspath, "sub-wc", pool); + const char *repos_relpath; svn_boolean_t is_root; - SVN_ERR(svn_wc__node_get_url(&url, wc_ctx, local_abspath, pool, pool)); - SVN_ERR(svn_wc__node_get_repos_info(&repos_root_url, &repos_uuid, + SVN_ERR(svn_wc__node_get_repos_info(NULL, &repos_relpath, + &repos_root_url, &repos_uuid, wc_ctx, local_abspath, pool, pool)); + url = svn_path_url_add_component2(repos_root_url, repos_relpath, pool); SVN_ERR(svn_io_make_dir_recursively(subdir, pool)); SVN_ERR(svn_wc_ensure_adm3(subdir, repos_uuid,
