Author: kotkov Date: Fri Jun 26 12:44:26 2015 New Revision: 1687769 URL: http://svn.apache.org/r1687769 Log: Reimplement svn_repos_verify_fs3() to support an arbitrary callback that receives the information about an encountered problem and lets the caller decide on what happens next. This supersedes the keep_going argument for this API. A callback is optional; the behavior of this API if the callback is not provided is equivalent to how svn_repos_verify_fs2() deals with encountered errors. This allows seamless migration to the new API, if the callback is not necessary. The idea is partly taken from how our existing svn_fs_lock_many() API works with a svn_fs_lock_callback_t and passes error information to the caller.
Immediately use the new API to provide an alternative solution for the encountered problem with 'svnadmin verify --keep-going -q' (see r1684940) being useless in terms that it was only giving an indication of whether a particular repository passes the verification or not, without providing a root cause (details) of what's wrong. Discussion can be found in http://svn.haxx.se/dev/archive-2015-05/0141.shtml (Subject: "Possible incompatibility of svn_repos_verify_fs2() in 1.9.0-rc1") * subversion/include/svn_error_codes.h (SVN_ERR_REPOS_VERIFY_FAILED): Remove this error code, as we no longer need to send a specific error from within svn_repos_verify_fs3(). (SVN_ERR_CL_REPOS_VERIFY_FAILED): New. * subversion/include/svn_repos.h (svn_repos_notify_action_t): Remove svn_repos_notify_failure. (svn_repos_notify_t): Remove 'err' field, as it is no longer needed. (svn_repos_verify_callback_t): New optional callback type to be used with svn_repos_verify_fs3(). (svn_repos_verify_fs3): Drop 'keep_going' argument in favor of accepting a svn_repos_verify_callback_t. Update the docstring accordingly. (svn_repos_verify_fs2): Update the docstring for this deprecated function. * subversion/libsvn_repos/deprecated.c (svn_repos_verify_fs2): Update the call to svn_repos_verify_fs3() in this compatibility wrapper. Don't pass the verify callback. * subversion/libsvn_repos/dump.c (notify_verification_error): Remove; this function is no longer required. (report_error): New helper function. (svn_repos_verify_fs3): In case we've got a svn_repos_verify_callback_t, call it upon receiving an FS-specific structure failure or a revision verification failure. Delegate this action to the new report_error() helper function. Doing so makes the caller responsible for what's going to happen with the error. The caller can choose to store the error, ignore it or use it in any other necessary way. If a callback returns an error, stop the verification process and immediately return that error. If no callback is provided, mimic the behavior of svn_repos_verify_fs2() and return the first encountered error. Drop the logic related to error formatting, as we no longer need it at this layer. We are going to make a simpler replacement for it is the UI code (svnadmin.c), where it is supposed to live. * subversion/svnadmin/svnadmin.c (struct repos_verify_callback_baton): New. Contains the fields that are required to track the --keep-going errors taken from ... (struct repos_notify_handler_baton): ...this baton. After the previous step, this baton only contains the 'feedback_stream' field, so inline it into every calling site. (repos_notify_handler): Baton is now simply an svn_stream_t. Remove the boolean-based filtering logic from this handler and drop the handling of svn_repos_notify_failure. The latter is moved, with a bit of tweaking, into ... (repos_verify_callback): ...this new function, that implements a callback for svn_repos_verify_fs3(). Depending on whether we are in --keep-going mode or not, either dump the failure details to stderr and track them to produce a summary, or immediately return it through the callback, thus ending the verification process. Remember all errors in the --keep-going mode, not only those that are associated with a particular revision. Prior to handling the error itself, tell that we failed to verify the revision or metadata by writing corresponding messages to stderr. (subcommand_dump, subcommand_load, subcommand_recover, subcommand_upgrade, subcommand_hotcopy, subcommand_pack): Inline repos_notify_handler_baton here, as it now contains a single svn_stream_t field. (subcommand_verify): Inline repos_notify_handler_baton here, as it now contains a single svn_stream_t field. Avoid manipulations with boolean fields like b->silent_errors and b->silent_running, because we no longer need them, and the fields themselves are gone. Create a feedback stream only in non-quiet mode, as we do in other subcommand implementations. Create a baton for repos_verify_callback() and adjust the calling site of svn_repos_verify_fs3(), that now needs a callback. Adjust --keep-going summary printing to the new approach with the verification callback. Finally, provide a simple error if we encountered at least one failure in the --keep-going mode. * subversion/tests/cmdline/svnadmin_tests.py (verify_keep_going, verify_keep_going_quiet, verify_invalid_path_changes): Adjust the expectations, because now errors go straight to stderr in both --keep-going and ordinary modes. Where possible, make the expectations a bit stricter by extending the lines that we check with RegexListOutput(). * subversion/tests/libsvn_fs_fs/fs-fs-private-test.c (load_index, load_index_keep_going): Squash two tests into one; basically, undo the corresponding hunk from r1683311. As we no longer have separate keep_going mode in svn_repos_verify_fs3(), and the caller decides if the verification continues or not, we don't have to check two different scenarios. (test_funcs): Track the test changes. * subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c (fuzzing_1_byte_1_rev): Adjust the call to svn_repos_verify_fs3(). [in subversion/bindings] * javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java (ReposNotifyInformation.Action): Remove value that used to correspond to svn_repos_notify_failure. * javahl/src/org/apache/subversion/javahl/ISVNRepos.java (ISVNRepos.verify): Remove 'keepGoing' argument from the newest overload of this method and update the docstring. This patch does not expose the ability to have control over verification failures through a custom callback in JavaHL bindings, but we're going to address this separately. * javahl/src/org/apache/subversion/javahl/SVNRepos.java (SVNRepos.verify): Adjust two overloads of this method in the ISVNRepos interface implementation. * javahl/native/SVNRepos.h (SVNRepos::verify): Remove 'keepGoing' argument from declaration. * javahl/native/SVNRepos.cpp (SVNRepos::verify): Remove 'keepGoing' argument. Do not pass a verify callback when calling svn_repos_verify_fs3(). * javahl/native/org_apache_subversion_javahl_SVNRepos.cpp (Java_org_apache_subversion_javahl_SVNRepos_verify): Remove 'jkeepGoing' argument from this JNI wrapper. Modified: subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java subversion/trunk/subversion/include/svn_error_codes.h subversion/trunk/subversion/include/svn_repos.h subversion/trunk/subversion/libsvn_repos/deprecated.c subversion/trunk/subversion/libsvn_repos/dump.c subversion/trunk/subversion/svnadmin/svnadmin.c subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c Modified: subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp Fri Jun 26 12:44:26 2015 @@ -594,7 +594,7 @@ SVNRepos::getRevnum(svn_revnum_t *revnum void SVNRepos::verify(File &path, Revision &revisionStart, Revision &revisionEnd, - bool keepGoing, bool checkNormalization, bool metadataOnly, + bool checkNormalization, bool metadataOnly, ReposNotifyCallback *notifyCallback) { SVN::Pool requestPool; @@ -639,13 +639,13 @@ SVNRepos::verify(File &path, Revision &r _("Start revision cannot be higher than end revision")), ); SVN_JNI_ERR(svn_repos_verify_fs3(repos, lower, upper, - keepGoing, checkNormalization, metadataOnly, notifyCallback != NULL ? ReposNotifyCallback::notify : NULL, notifyCallback, + NULL, NULL, /* verify callback/baton */ checkCancel, this /* cancel callback/baton */, requestPool.getPool()), ); } Modified: subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h (original) +++ subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h Fri Jun 26 12:44:26 2015 @@ -45,7 +45,7 @@ class SVNRepos : public SVNBase void rmlocks(File &path, StringArray &locks); jobject lslocks(File &path, svn_depth_t depth); void verify(File &path, Revision &revisionStart, Revision &revisionEnd, - bool keepGoing, bool checkNormalization, bool metadataOnly, + bool checkNormalization, bool metadataOnly, ReposNotifyCallback *notifyCallback); void setRevProp(File &path, Revision &revision, const char *propName, const char *propValue, Modified: subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp Fri Jun 26 12:44:26 2015 @@ -419,7 +419,7 @@ JNIEXPORT void JNICALL Java_org_apache_subversion_javahl_SVNRepos_verify( JNIEnv *env, jobject jthis, jobject jpath, jobject jrevisionStart, jobject jrevisionEnd, - jboolean jkeepGoing, jboolean jcheckNormalization, jboolean jmetadataOnly, + jboolean jcheckNormalization, jboolean jmetadataOnly, jobject jcallback) { JNIEntry(SVNRepos, verify); @@ -447,7 +447,7 @@ Java_org_apache_subversion_javahl_SVNRep return; cl->verify(path, revisionStart, revisionEnd, - jkeepGoing, jcheckNormalization, jmetadataOnly, + jcheckNormalization, jmetadataOnly, jcallback != NULL ? &callback : NULL); } Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java Fri Jun 26 12:44:26 2015 @@ -299,7 +299,6 @@ public interface ISVNRepos { * @param path the path to the repository * @param start the first revision * @param end the last revision - * @param keepGoing continue verification even if a revision is bad * @param checkNormalization report directory entry and mergeinfo name collisions * caused by denormalized Unicode representations * @param metadataOnly check only metadata, not file contents @@ -308,8 +307,7 @@ public interface ISVNRepos { * @since 1.9 */ public abstract void verify(File path, Revision start, Revision end, - boolean keepGoing, boolean checkNormalization, - boolean metadataOnly, + boolean checkNormalization, boolean metadataOnly, ReposNotifyCallback callback) throws ClientException; Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java Fri Jun 26 12:44:26 2015 @@ -199,12 +199,6 @@ public class ReposNotifyInformation exte verify_rev_structure, /** - * A revision is found with corruption/errors. - * @since 1.9 - */ - failure, - - /** * A revprop shard got packed. @ * @since 1.9 */ Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java Fri Jun 26 12:44:26 2015 @@ -238,12 +238,11 @@ public class SVNRepos implements ISVNRep ReposNotifyCallback callback) throws ClientException { - verify(path, start, end, false, false, false, callback); + verify(path, start, end, false, false, callback); } public native void verify(File path, Revision start, Revision end, - boolean keepGoing, boolean checkNormalization, - boolean metadataOnly, + boolean checkNormalization, boolean metadataOnly, ReposNotifyCallback callback) throws ClientException; Modified: subversion/trunk/subversion/include/svn_error_codes.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_error_codes.h?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/include/svn_error_codes.h (original) +++ subversion/trunk/subversion/include/svn_error_codes.h Fri Jun 26 12:44:26 2015 @@ -922,11 +922,6 @@ SVN_ERROR_START SVN_ERR_REPOS_CATEGORY_START + 10, "Repository upgrade is not supported") - /** @since New in 1.9. */ - SVN_ERRDEF(SVN_ERR_REPOS_VERIFY_FAILED, - SVN_ERR_REPOS_CATEGORY_START + 11, - "Repository verification failed") - /* generic RA errors */ SVN_ERRDEF(SVN_ERR_RA_ILLEGAL_URL, @@ -1497,6 +1492,11 @@ SVN_ERROR_START SVN_ERR_CL_CATEGORY_START + 11, "Failed processing one or more externals definitions") + /** @since New in 1.9. */ + SVN_ERRDEF(SVN_ERR_CL_REPOS_VERIFY_FAILED, + SVN_ERR_CL_CATEGORY_START + 12, + "Repository verification failed") + /* ra_svn errors */ SVN_ERRDEF(SVN_ERR_RA_SVN_CMD_ERR, Modified: subversion/trunk/subversion/include/svn_repos.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/include/svn_repos.h (original) +++ subversion/trunk/subversion/include/svn_repos.h Fri Jun 26 12:44:26 2015 @@ -234,9 +234,6 @@ typedef enum svn_repos_notify_action_t /** The structure of a revision is being verified. @since New in 1.8. */ svn_repos_notify_verify_rev_structure, - /** A revision is found with corruption/errors. @since New in 1.9. */ - svn_repos_notify_failure, - /** A revprop shard got packed. @since New in 1.9. */ svn_repos_notify_pack_revprops, @@ -348,11 +345,6 @@ typedef struct svn_repos_notify_t /** For #svn_repos_notify_load_node_start, the path of the node. */ const char *path; - /** For #svn_repos_notify_failure, this error chain indicates what - went wrong during verification. - @since New in 1.9. */ - svn_error_t *err; - /** For #svn_repos_notify_hotcopy_rev_range, the start of the copied revision range. @since New in 1.9. */ @@ -2825,6 +2817,22 @@ enum svn_repos_load_uuid svn_repos_load_uuid_force }; +/** Callback type for use with svn_repos_verify_fs3(). @a revision + * and @a verify_err are the details of a single verification failure + * that occurred during the svn_repos_verify_fs3() call. @a baton is + * the same baton given to svn_repos_verify_fs3(). @a scratch_pool is + * provided for the convenience of the implementor, who should not + * expect it to live longer than a single callback call. + * + * @see svn_repos_verify_fs3 + * + * @since New in 1.9. + */ +typedef svn_error_t *(*svn_repos_verify_callback_t)(void *baton, + svn_revnum_t revision, + svn_error_t *verify_err, + apr_pool_t *scratch_pool); + /** * Verify the contents of the file system in @a repos. * @@ -2835,9 +2843,6 @@ enum svn_repos_load_uuid * range, then also verify "global invariants" of the repository, as * described in svn_fs_verify(). * - * When a failure is found, if @a keep_going is @c TRUE then continue - * verification from the next revision, otherwise stop. - * * If @a check_normalization is @c TRUE, report any name collisions * within the same directory or svn:mergeinfo property where the names * differ only in character representation, but are otherwise @@ -2848,25 +2853,31 @@ enum svn_repos_load_uuid * file context reconstruction and verification. For FSFS format 7+ and * FSX, this allows for a very fast check against external corruption. * + * If @a verify_callback is not @c NULL, call it with @a verify_baton upon + * receiving an FS-specific structure failure or a revision verification + * failure. Set @c revision callback argument to #SVN_INVALID_REVNUM or + * to the revision number respectively. Set @c verify_err to svn_error_t + * describing the reason of the failure. @c verify_err will be cleared + * after the callback returns, use svn_error_dup() to preserve the error. + * If @a verify_callback returns an error different from #SVN_NO_ERROR, + * stop verifying the repository and immediately return the error from + * @a verify_callback. + * + * If @a verify_callback is @c NULL, this function returns the first + * encountered verification error or #SVN_NO_ERROR if there were no failures + * during the verification. Errors that prevent the verification process + * from continuing, such as #SVN_ERR_CANCELLED, are returned immediately + * and do not trigger an invocation of @a verify_callback. + * * If @a notify_func is not null, then call it with @a notify_baton and * with a notification structure in which the fields are set as follows. - * (For a warning or error notification that does not apply to a specific - * revision, the revision number is #SVN_INVALID_REVNUM.) + * (For a warning that does not apply to a specific revision, the revision + * number is #SVN_INVALID_REVNUM.) * * For each FS-specific structure warning: * @c action = svn_repos_notify_verify_rev_structure * @c revision = the revision or #SVN_INVALID_REVNUM * - * For a FS-specific structure failure: - * @c action = #svn_repos_notify_failure - * @c revision = #SVN_INVALID_REVNUM - * @c err = the corresponding error chain - * - * For each revision verification failure: - * @c action = #svn_repos_notify_failure - * @c revision = the revision - * @c err = the corresponding error chain - * * For each revision verification warning: * @c action = #svn_repos_notify_warning * @c warning and @c warning_str fields set accordingly @@ -2888,29 +2899,26 @@ enum svn_repos_load_uuid * * Use @a scratch_pool for temporary allocation. * - * Return an error if there were any failures during verification, or - * #SVN_NO_ERROR if there were no failures. A failure means an event that, - * if a notification callback were provided, would send a notification - * with @c action = #svn_repos_notify_failure. - * * @since New in 1.9. */ svn_error_t * svn_repos_verify_fs3(svn_repos_t *repos, svn_revnum_t start_rev, svn_revnum_t end_rev, - svn_boolean_t keep_going, svn_boolean_t check_normalization, svn_boolean_t metadata_only, svn_repos_notify_func_t notify_func, void *notify_baton, + svn_repos_verify_callback_t verify_callback, + void *verify_baton, svn_cancel_func_t cancel, void *cancel_baton, apr_pool_t *scratch_pool); /** - * Like svn_repos_verify_fs3(), but with @a keep_going, - * @a check_normalization and @a metadata_only set to @c FALSE. + * Like svn_repos_verify_fs3(), but with @a verify_callback and + * @a verify_baton set to @c NULL and with @a check_normalization + * and @a metadata_only set to @c FALSE. * * @since New in 1.7. * @deprecated Provided for backward compatibility with the 1.8 API. Modified: subversion/trunk/subversion/libsvn_repos/deprecated.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/deprecated.c?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_repos/deprecated.c (original) +++ subversion/trunk/subversion/libsvn_repos/deprecated.c Fri Jun 26 12:44:26 2015 @@ -774,9 +774,9 @@ svn_repos_verify_fs2(svn_repos_t *repos, end_rev, FALSE, FALSE, - FALSE, notify_func, notify_baton, + NULL, NULL, cancel_func, cancel_baton, pool)); Modified: subversion/trunk/subversion/libsvn_repos/dump.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/dump.c?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_repos/dump.c (original) +++ subversion/trunk/subversion/libsvn_repos/dump.c Fri Jun 26 12:44:26 2015 @@ -2265,24 +2265,6 @@ verify_close_directory(void *dir_baton, return close_directory(dir_baton, pool); } -static void -notify_verification_error(svn_revnum_t rev, - svn_error_t *err, - svn_repos_notify_func_t notify_func, - void *notify_baton, - apr_pool_t *pool) -{ - svn_repos_notify_t *notify_failure; - - if (notify_func == NULL) - return; - - notify_failure = svn_repos_notify_create(svn_repos_notify_failure, pool); - notify_failure->err = err; - notify_failure->revision = rev; - notify_func(notify_baton, notify_failure, pool); -} - /* Verify revision REV in file system FS. */ static svn_error_t * verify_one_revision(svn_fs_t *fs, @@ -2359,15 +2341,42 @@ verify_fs_notify_func(svn_revnum_t revis notify_baton->notify, pool); } +static svn_error_t * +report_error(svn_revnum_t revision, + svn_error_t *verify_err, + svn_repos_verify_callback_t verify_callback, + void *verify_baton, + apr_pool_t *pool) +{ + if (verify_callback) + { + svn_error_t *cb_err; + + /* The caller provided us with a callback, so make him responsible + for what's going to happen with the error. */ + cb_err = verify_callback(verify_baton, revision, verify_err, pool); + svn_error_clear(verify_err); + SVN_ERR(cb_err); + + return SVN_NO_ERROR; + } + else + { + /* No callback -- no second guessing. Just return the error. */ + return svn_error_trace(verify_err); + } +} + svn_error_t * svn_repos_verify_fs3(svn_repos_t *repos, svn_revnum_t start_rev, svn_revnum_t end_rev, - svn_boolean_t keep_going, svn_boolean_t check_normalization, svn_boolean_t metadata_only, svn_repos_notify_func_t notify_func, void *notify_baton, + svn_repos_verify_callback_t verify_callback, + void *verify_baton, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *pool) @@ -2380,8 +2389,6 @@ svn_repos_verify_fs3(svn_repos_t *repos, svn_fs_progress_notify_func_t verify_notify = NULL; struct verify_fs_notify_func_baton_t *verify_notify_baton = NULL; svn_error_t *err; - svn_boolean_t failed_metadata = FALSE; - svn_revnum_t failed_revisions = 0; /* Determine the current youngest revision of the filesystem. */ SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool)); @@ -2430,20 +2437,8 @@ svn_repos_verify_fs3(svn_repos_t *repos, } else if (err) { - notify_verification_error(SVN_INVALID_REVNUM, err, notify_func, - notify_baton, iterpool); - - if (!keep_going) - { - /* Return the error, the caller doesn't want us to continue. */ - return svn_error_trace(err); - } - else - { - /* Clear the error and keep going. */ - failed_metadata = TRUE; - svn_error_clear(err); - } + SVN_ERR(report_error(SVN_INVALID_REVNUM, err, verify_callback, + verify_baton, iterpool)); } if (!metadata_only) @@ -2463,20 +2458,8 @@ svn_repos_verify_fs3(svn_repos_t *repos, } else if (err) { - notify_verification_error(rev, err, notify_func, notify_baton, - iterpool); - - if (!keep_going) - { - /* Return the error, the caller doesn't want us to continue. */ - return svn_error_trace(err); - } - else - { - /* Clear the error and keep going. */ - ++failed_revisions; - svn_error_clear(err); - } + SVN_ERR(report_error(rev, err, verify_callback, verify_baton, + iterpool)); } else if (notify_func) { @@ -2495,40 +2478,5 @@ svn_repos_verify_fs3(svn_repos_t *repos, svn_pool_destroy(iterpool); - /* Summarize the results. */ - if (failed_metadata || 0 != failed_revisions) - { - const char *const repos_path = - svn_dirent_local_style(svn_repos_path(repos, pool), pool); - - if (0 == failed_revisions) - { - return svn_error_createf( - SVN_ERR_REPOS_VERIFY_FAILED, NULL, - _("Metadata verification failed on repository '%s'"), - repos_path); - } - else - { - const char* format_string; - - if (failed_metadata) - format_string = apr_psprintf( - pool, _("Verification of metadata and" - " %%%s out of %%%s revisions" - " failed on repository '%%s'"), - SVN_REVNUM_T_FMT, SVN_REVNUM_T_FMT); - else - format_string = apr_psprintf( - pool, _("Verification of %%%s out of %%%s revisions" - " failed on repository '%%s'"), - SVN_REVNUM_T_FMT, SVN_REVNUM_T_FMT); - - return svn_error_createf( - SVN_ERR_REPOS_VERIFY_FAILED, NULL, format_string, - failed_revisions, end_rev - start_rev + 1, repos_path); - } - } - return SVN_NO_ERROR; } Modified: subversion/trunk/subversion/svnadmin/svnadmin.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/svnadmin.c?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/svnadmin/svnadmin.c (original) +++ subversion/trunk/subversion/svnadmin/svnadmin.c Fri Jun 26 12:44:26 2015 @@ -864,25 +864,60 @@ err_cleanup(void *data) return APR_SUCCESS; } -struct repos_notify_handler_baton { - /* Stream to write progress and other non-error output to. */ - svn_stream_t *feedback_stream; - - /* Suppress notifications that are neither errors nor warnings. */ - svn_boolean_t silent_running; - - /* Whether errors contained in notifications should be printed along - with the notification. If FALSE, any errors will only be - summarized. */ - svn_boolean_t silent_errors; +struct repos_verify_callback_baton +{ + /* Should we continue after receiving a first verification error? */ + svn_boolean_t keep_going; /* List of errors encountered during 'svnadmin verify --keep-going'. */ apr_array_header_t *error_summary; - /* Pool for data collected during notifications. */ + /* Pool for data collected during callback invocations. */ apr_pool_t *result_pool; }; +/* Implementation of svn_repos_verify_callback_t to handle errors coming + from svn_repos_verify_fs3(). */ +static svn_error_t * +repos_verify_callback(void *baton, + svn_revnum_t revision, + svn_error_t *verify_err, + apr_pool_t *scratch_pool) +{ + struct repos_verify_callback_baton *b = baton; + + if (revision == SVN_INVALID_REVNUM) + { + SVN_ERR(svn_cmdline_fputs(_("* Error verifying repository metadata.\n"), + stderr, scratch_pool)); + } + else + { + SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, + _("* Error verifying revision %ld.\n"), + revision)); + } + + if (b->keep_going) + { + struct verification_error *verr; + + svn_handle_error2(verify_err, stderr, FALSE, "svnadmin: "); + + /* Remember the error in B->ERROR_SUMMARY. */ + verr = apr_palloc(b->result_pool, sizeof(*verr)); + verr->rev = revision; + verr->err = svn_error_dup(verify_err); + apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup, + apr_pool_cleanup_null); + APR_ARRAY_PUSH(b->error_summary, struct verification_error *) = verr; + + return SVN_NO_ERROR; + } + else + return svn_error_trace(svn_error_dup(verify_err)); +} + /* Implementation of svn_repos_notify_func_t to wrap the output to a response stream for svn_repos_dump_fs2(), svn_repos_verify_fs(), svn_repos_hotcopy3() and others. */ @@ -891,16 +926,7 @@ repos_notify_handler(void *baton, const svn_repos_notify_t *notify, apr_pool_t *scratch_pool) { - struct repos_notify_handler_baton *b = baton; - svn_stream_t *feedback_stream = b->feedback_stream; - - /* Don't print anything if the feedback stream isn't provided. - Only print errors and warnings in silent mode. */ - if (!feedback_stream - || (b->silent_running - && notify->action != svn_repos_notify_warning - && notify->action != svn_repos_notify_failure)) - return; + svn_stream_t *feedback_stream = baton; switch (notify->action) { @@ -910,32 +936,6 @@ repos_notify_handler(void *baton, notify->warning_str)); return; - case svn_repos_notify_failure: - if (notify->revision != SVN_INVALID_REVNUM) - svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool, - _("* Error verifying revision %ld.\n"), - notify->revision)); - if (notify->err) - { - if (!b->silent_errors) - svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */, - "svnadmin: "); - - if (b->error_summary && notify->revision != SVN_INVALID_REVNUM) - { - struct verification_error *verr; - - verr = apr_palloc(b->result_pool, sizeof(*verr)); - verr->rev = notify->revision; - verr->err = svn_error_dup(notify->err); - apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup, - apr_pool_cleanup_null); - APR_ARRAY_PUSH(b->error_summary, - struct verification_error *) = verr; - } - } - return; - case svn_repos_notify_dump_rev_end: svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool, _("* Dumped revision %ld.\n"), @@ -1183,7 +1183,7 @@ subcommand_dump(apr_getopt_t *os, void * svn_stream_t *stdout_stream; svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM; svn_revnum_t youngest; - struct repos_notify_handler_baton notify_baton = { 0 }; + svn_stream_t *feedback_stream = NULL; /* Expect no more arguments. */ SVN_ERR(parse_args(NULL, os, 0, 0, pool)); @@ -1217,12 +1217,12 @@ subcommand_dump(apr_getopt_t *os, void * /* Progress feedback goes to STDERR, unless they asked to suppress it. */ if (! opt_state->quiet) - notify_baton.feedback_stream = recode_stream_create(stderr, pool); + feedback_stream = recode_stream_create(stderr, pool); SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper, opt_state->incremental, opt_state->use_deltas, !opt_state->quiet ? repos_notify_handler : NULL, - ¬ify_baton, check_cancel, NULL, pool)); + feedback_stream, check_cancel, NULL, pool)); return SVN_NO_ERROR; } @@ -1372,7 +1372,7 @@ subcommand_load(apr_getopt_t *os, void * svn_repos_t *repos; svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM; svn_stream_t *stdin_stream; - struct repos_notify_handler_baton notify_baton = { 0 }; + svn_stream_t *feedback_stream = NULL; /* Expect no more arguments. */ SVN_ERR(parse_args(NULL, os, 0, 0, pool)); @@ -1406,7 +1406,7 @@ subcommand_load(apr_getopt_t *os, void * /* Progress feedback goes to STDOUT, unless they asked to suppress it. */ if (! opt_state->quiet) - notify_baton.feedback_stream = recode_stream_create(stdout, pool); + feedback_stream = recode_stream_create(stdout, pool); err = svn_repos_load_fs5(repos, stdin_stream, lower, upper, opt_state->uuid_action, opt_state->parent_dir, @@ -1415,7 +1415,7 @@ subcommand_load(apr_getopt_t *os, void * !opt_state->bypass_prop_validation, opt_state->ignore_dates, opt_state->quiet ? NULL : repos_notify_handler, - ¬ify_baton, check_cancel, NULL, pool); + feedback_stream, check_cancel, NULL, pool); if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE) return svn_error_quick_wrap(err, _("Invalid property value found in " @@ -1462,12 +1462,12 @@ subcommand_recover(apr_getopt_t *os, voi svn_repos_t *repos; svn_error_t *err; struct svnadmin_opt_state *opt_state = baton; - struct repos_notify_handler_baton notify_baton = { 0 }; + svn_stream_t *feedback_stream = NULL; /* Expect no more arguments. */ SVN_ERR(parse_args(NULL, os, 0, 0, pool)); - SVN_ERR(svn_stream_for_stdout(¬ify_baton.feedback_stream, pool)); + SVN_ERR(svn_stream_for_stdout(&feedback_stream, pool)); /* Restore default signal handlers until after we have acquired the * exclusive lock so that the user interrupt before we actually @@ -1475,7 +1475,7 @@ subcommand_recover(apr_getopt_t *os, voi setup_cancellation_signals(SIG_DFL); err = svn_repos_recover4(opt_state->repository_path, TRUE, - repos_notify_handler, ¬ify_baton, + repos_notify_handler, feedback_stream, check_cancel, NULL, pool); if (err) { @@ -1493,7 +1493,7 @@ subcommand_recover(apr_getopt_t *os, voi " another process has it open?\n"))); SVN_ERR(svn_cmdline_fflush(stdout)); SVN_ERR(svn_repos_recover4(opt_state->repository_path, FALSE, - repos_notify_handler, ¬ify_baton, + repos_notify_handler, feedback_stream, check_cancel, NULL, pool)); } @@ -1779,7 +1779,7 @@ subcommand_pack(apr_getopt_t *os, void * { struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; - struct repos_notify_handler_baton notify_baton = { 0 }; + svn_stream_t *feedback_stream = NULL; /* Expect no more arguments. */ SVN_ERR(parse_args(NULL, os, 0, 0, pool)); @@ -1788,11 +1788,11 @@ subcommand_pack(apr_getopt_t *os, void * /* Progress feedback goes to STDOUT, unless they asked to suppress it. */ if (! opt_state->quiet) - notify_baton.feedback_stream = recode_stream_create(stdout, pool); + feedback_stream = recode_stream_create(stdout, pool); return svn_error_trace( svn_repos_fs_pack2(repos, !opt_state->quiet ? repos_notify_handler : NULL, - ¬ify_baton, check_cancel, NULL, pool)); + feedback_stream, check_cancel, NULL, pool)); } @@ -1804,10 +1804,8 @@ subcommand_verify(apr_getopt_t *os, void svn_repos_t *repos; svn_fs_t *fs; svn_revnum_t youngest, lower, upper; - struct repos_notify_handler_baton notify_baton = { 0 }; - struct repos_notify_handler_baton *notify_baton_p = ¬ify_baton; - svn_repos_notify_func_t notify_func = repos_notify_handler; - svn_error_t *verify_err; + svn_stream_t *feedback_stream = NULL; + struct repos_verify_callback_baton verify_baton = { 0 }; /* Expect no more arguments. */ SVN_ERR(parse_args(NULL, os, 0, 0, pool)); @@ -1851,42 +1849,27 @@ subcommand_verify(apr_getopt_t *os, void upper = lower; } - /* Set up the notification handler. */ - if (!opt_state->quiet || opt_state->keep_going) - { - if (opt_state->quiet) - { - notify_baton.silent_running = TRUE; - notify_baton.feedback_stream = recode_stream_create(stderr, pool); - } - else - notify_baton.feedback_stream = recode_stream_create(stdout, pool); + if (!opt_state->quiet) + feedback_stream = recode_stream_create(stdout, pool); - if (opt_state->keep_going) - notify_baton.error_summary = - apr_array_make(pool, 0, sizeof(struct verification_error *)); - else - notify_baton.silent_errors = TRUE; - - notify_baton.result_pool = pool; - } - else - { - notify_func = NULL; - notify_baton_p = NULL; - } - - verify_err = svn_repos_verify_fs3(repos, lower, upper, - opt_state->keep_going, - opt_state->check_normalization, - opt_state->metadata_only, - notify_func, notify_baton_p, - check_cancel, NULL, pool); + verify_baton.keep_going = opt_state->keep_going; + verify_baton.error_summary = + apr_array_make(pool, 0, sizeof(struct verification_error *)); + verify_baton.result_pool = pool; + + SVN_ERR(svn_repos_verify_fs3(repos, lower, upper, + opt_state->check_normalization, + opt_state->metadata_only, + !opt_state->quiet + ? repos_notify_handler : NULL, + feedback_stream, + repos_verify_callback, &verify_baton, + check_cancel, NULL, pool)); /* Show the --keep-going error summary. */ if (!opt_state->quiet && opt_state->keep_going - && notify_baton.error_summary->nelts > 0) + && verify_baton.error_summary->nelts > 0) { int rev_maxlength; svn_revnum_t end_revnum; @@ -1894,15 +1877,15 @@ subcommand_verify(apr_getopt_t *os, void int i; svn_error_clear( - svn_stream_puts(notify_baton.feedback_stream, + svn_stream_puts(feedback_stream, _("\n-----Summary of corrupt revisions-----\n"))); /* The standard column width for the revision number is 6 characters. If the revision number can potentially be larger (i.e. if end_revnum is larger than 1000000), we increase the column width as needed. */ rev_maxlength = 6; - end_revnum = APR_ARRAY_IDX(notify_baton.error_summary, - notify_baton.error_summary->nelts - 1, + end_revnum = APR_ARRAY_IDX(verify_baton.error_summary, + verify_baton.error_summary->nelts - 1, struct verification_error *)->rev; while (end_revnum >= 1000000) { @@ -1911,7 +1894,7 @@ subcommand_verify(apr_getopt_t *os, void } iterpool = svn_pool_create(pool); - for (i = 0; i < notify_baton.error_summary->nelts; i++) + for (i = 0; i < verify_baton.error_summary->nelts; i++) { struct verification_error *verr; svn_error_t *err; @@ -1919,29 +1902,40 @@ subcommand_verify(apr_getopt_t *os, void svn_pool_clear(iterpool); - verr = APR_ARRAY_IDX(notify_baton.error_summary, i, + verr = APR_ARRAY_IDX(verify_baton.error_summary, i, struct verification_error *); - rev_str = apr_psprintf(iterpool, "r%ld", verr->rev); - rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str); - for (err = svn_error_purge_tracing(verr->err); - err != SVN_NO_ERROR; err = err->child) - { - char buf[512]; - const char *message; - message = svn_err_best_message(err, buf, sizeof(buf)); - svn_error_clear(svn_stream_printf(notify_baton.feedback_stream, - iterpool, - "%s: E%06d: %s\n", - rev_str, err->apr_err, - message)); + if (verr->rev != SVN_INVALID_REVNUM) + { + rev_str = apr_psprintf(iterpool, "r%ld", verr->rev); + rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str); + for (err = svn_error_purge_tracing(verr->err); + err != SVN_NO_ERROR; err = err->child) + { + char buf[512]; + const char *message; + + message = svn_err_best_message(err, buf, sizeof(buf)); + svn_error_clear(svn_stream_printf(feedback_stream, iterpool, + "%s: E%06d: %s\n", + rev_str, err->apr_err, + message)); + } } } svn_pool_destroy(iterpool); } - return svn_error_trace(verify_err); + if (verify_baton.error_summary->nelts > 0) + { + return svn_error_createf(SVN_ERR_CL_REPOS_VERIFY_FAILED, NULL, + _("Failed to verify repository '%s'"), + svn_dirent_local_style( + opt_state->repository_path, pool)); + } + + return SVN_NO_ERROR; } /* This implements `svn_opt_subcommand_t'. */ @@ -1949,7 +1943,7 @@ svn_error_t * subcommand_hotcopy(apr_getopt_t *os, void *baton, apr_pool_t *pool) { struct svnadmin_opt_state *opt_state = baton; - struct repos_notify_handler_baton notify_baton = { 0 }; + svn_stream_t *feedback_stream = NULL; apr_array_header_t *targets; const char *new_repos_path; @@ -1960,12 +1954,12 @@ subcommand_hotcopy(apr_getopt_t *os, voi /* Progress feedback goes to STDOUT, unless they asked to suppress it. */ if (! opt_state->quiet) - notify_baton.feedback_stream = recode_stream_create(stdout, pool); + feedback_stream = recode_stream_create(stdout, pool); return svn_repos_hotcopy3(opt_state->repository_path, new_repos_path, opt_state->clean_logs, opt_state->incremental, !opt_state->quiet ? repos_notify_handler : NULL, - ¬ify_baton, check_cancel, NULL, pool); + feedback_stream, check_cancel, NULL, pool); } svn_error_t * @@ -2349,18 +2343,18 @@ subcommand_upgrade(apr_getopt_t *os, voi { svn_error_t *err; struct svnadmin_opt_state *opt_state = baton; - struct repos_notify_handler_baton notify_baton = { 0 }; + svn_stream_t *feedback_stream = NULL; /* Expect no more arguments. */ SVN_ERR(parse_args(NULL, os, 0, 0, pool)); - SVN_ERR(svn_stream_for_stdout(¬ify_baton.feedback_stream, pool)); + SVN_ERR(svn_stream_for_stdout(&feedback_stream, pool)); /* Restore default signal handlers. */ setup_cancellation_signals(SIG_DFL); err = svn_repos_upgrade2(opt_state->repository_path, TRUE, - repos_notify_handler, ¬ify_baton, pool); + repos_notify_handler, feedback_stream, pool); if (err) { if (APR_STATUS_IS_EAGAIN(err->apr_err)) @@ -2378,7 +2372,7 @@ subcommand_upgrade(apr_getopt_t *os, voi " another process has it open?\n"))); SVN_ERR(svn_cmdline_fflush(stdout)); SVN_ERR(svn_repos_upgrade2(opt_state->repository_path, FALSE, - repos_notify_handler, ¬ify_baton, + repos_notify_handler, feedback_stream, pool)); } else if (err->apr_err == SVN_ERR_FS_UNSUPPORTED_UPGRADE) Modified: subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py Fri Jun 26 12:44:26 2015 @@ -2070,8 +2070,6 @@ def verify_keep_going(sbox): exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.", ".*Verified revision 1.", - ".*Error verifying revision 2.", - ".*Error verifying revision 3.", ".*", ".*Summary.*", ".*r2: E160004:.*", @@ -2082,8 +2080,18 @@ def verify_keep_going(sbox): if (svntest.main.fs_has_rep_sharing()): exp_out.insert(0, ".*Verifying.*metadata.*") - exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*", - "svnadmin: E165011:.*"], False) + exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.", + "svnadmin: E160004:.*", + "svnadmin: E160004:.*", + ".*Error verifying revision 3.", + "svnadmin: E160004:.*", + "svnadmin: E160004:.*", + "svnadmin: E205012:.*"], False) + + if (svntest.main.is_fs_log_addressing()): + exp_err.insert(0, ".*Error verifying repository metadata.") + exp_err.insert(1, "svnadmin: E160004:.*") + if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.", output, errput, exp_out, exp_err): raise svntest.Failure @@ -2095,12 +2103,19 @@ def verify_keep_going(sbox): exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision 0"]) else: exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.", - ".*Verified revision 1.", - ".*Error verifying revision 2."]) + ".*Verified revision 1."]) if (svntest.main.fs_has_rep_sharing()): exp_out.insert(0, ".*Verifying repository metadata.*") - exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*"], False) + if (svntest.main.is_fs_log_addressing()): + exp_err = svntest.verify.RegexListOutput([ + ".*Error verifying repository metadata.", + "svnadmin: E160004:.*"], False) + else: + exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.", + "svnadmin: E160004:.*", + "svnadmin: E160004:.*"], False) + if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.", output, errput, exp_out, exp_err): raise svntest.Failure @@ -2110,8 +2125,17 @@ def verify_keep_going(sbox): "--quiet", sbox.repo_dir) + if (svntest.main.is_fs_log_addressing()): + exp_err = svntest.verify.RegexListOutput([ + ".*Error verifying repository metadata.", + "svnadmin: E160004:.*"], False) + else: + exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.", + "svnadmin: E160004:.*", + "svnadmin: E160004:.*"], False) + if svntest.verify.verify_outputs("Output of 'svnadmin verify' is unexpected.", - None, errput, None, "svnadmin: E160004:.*"): + None, errput, None, exp_err): raise svntest.Failure # Don't leave a corrupt repository @@ -2152,11 +2176,12 @@ def verify_keep_going_quiet(sbox): ".*Error verifying revision 3.", "svnadmin: E160004:.*", "svnadmin: E160004:.*", - "svnadmin: E165011:.*"], False) + "svnadmin: E205012:.*"], False) # Insert another expected error from checksum verification if (svntest.main.is_fs_log_addressing()): - exp_err.insert(0, "svnadmin: E160004:.*") + exp_err.insert(0, ".*Error verifying repository metadata.") + exp_err.insert(1, "svnadmin: E160004:.*") if svntest.verify.verify_outputs( "Unexpected error while running 'svnadmin verify'.", @@ -2231,23 +2256,15 @@ def verify_invalid_path_changes(sbox): exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.", ".*Verified revision 1.", - ".*Error verifying revision 2.", ".*Verified revision 3.", - ".*Error verifying revision 4.", ".*Verified revision 5.", - ".*Error verifying revision 6.", ".*Verified revision 7.", ".*Verified revision 8.", ".*Verified revision 9.", - ".*Error verifying revision 10.", ".*Verified revision 11.", - ".*Error verifying revision 12.", ".*Verified revision 13.", - ".*Error verifying revision 14.", ".*Verified revision 15.", - ".*Error verifying revision 16.", ".*Verified revision 17.", - ".*Error verifying revision 18.", ".*Verified revision 19.", ".*", ".*Summary.*", @@ -2271,9 +2288,30 @@ def verify_invalid_path_changes(sbox): if svntest.main.is_fs_log_addressing(): exp_out.insert(1, ".*Verifying.*metadata.*") - exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*", + exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.", + "svnadmin: E160020:.*", + "svnadmin: E160020:.*", + ".*Error verifying revision 4.", + "svnadmin: E160013:.*", + ".*Error verifying revision 6.", + "svnadmin: E160013:.*", + "svnadmin: E160013:.*", + ".*Error verifying revision 10.", + "svnadmin: E160013:.*", + "svnadmin: E160013:.*", + ".*Error verifying revision 12.", + "svnadmin: E145001:.*", + "svnadmin: E145001:.*", + ".*Error verifying revision 14.", + "svnadmin: E160013:.*", + "svnadmin: E160013:.*", + ".*Error verifying revision 16.", "svnadmin: E145001:.*", - "svnadmin: E160013:.*"], False) + "svnadmin: E145001:.*", + ".*Error verifying revision 18.", + "svnadmin: E160013:.*", + "svnadmin: E160013:.*", + "svnadmin: E205012:.*"], False) if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.", @@ -2284,9 +2322,10 @@ def verify_invalid_path_changes(sbox): sbox.repo_dir) exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.", - ".*Verified revision 1.", - ".*Error verifying revision 2."]) - exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*"], False) + ".*Verified revision 1."]) + exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.", + "svnadmin: E160020:.*", + "svnadmin: E160020:.*"], False) if (svntest.main.fs_has_rep_sharing()): exp_out.insert(0, ".*Verifying.*metadata.*") @@ -2301,8 +2340,13 @@ def verify_invalid_path_changes(sbox): "--quiet", sbox.repo_dir) + exp_out = [] + exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.", + "svnadmin: E160020:.*", + "svnadmin: E160020:.*"], False) + if svntest.verify.verify_outputs("Output of 'svnadmin verify' is unexpected.", - None, errput, None, "svnadmin: E160020:.*"): + output, errput, exp_out, exp_err): raise svntest.Failure # Don't leave a corrupt repository Modified: subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c (original) +++ subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c Fri Jun 26 12:44:26 2015 @@ -117,8 +117,9 @@ fuzzing_1_byte_1_rev(const char *repo_na svn_fs_set_warning_func(svn_repos_fs(repos), dont_filter_warnings, NULL); /* This shall detect the corruption and return an error. */ - err = svn_repos_verify_fs3(repos, revision, revision, TRUE, FALSE, FALSE, - NULL, NULL, NULL, NULL, iterpool); + err = svn_repos_verify_fs3(repos, revision, revision, FALSE, FALSE, + NULL, NULL, NULL, NULL, NULL, NULL, + iterpool); /* Case-only changes in checksum digests are not an error. * We allow upper case chars to be used in MD5 checksums in all other Modified: subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c?rev=1687769&r1=1687768&r2=1687769&view=diff ============================================================================== --- subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c (original) +++ subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c Fri Jun 26 12:44:26 2015 @@ -361,9 +361,10 @@ receive_index(const svn_fs_fs__p2l_entry return SVN_NO_ERROR; } +#define REPO_NAME "test-repo-load-index-test" + static svn_error_t * -load_index_test(const svn_test_opts_t *opts, apr_pool_t *pool, - const char *repo_name, svn_boolean_t keep_going) +load_index(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_repos_t *repos; svn_revnum_t rev; @@ -381,7 +382,7 @@ load_index_test(const svn_test_opts_t *o "pre-1.9 SVN doesn't have FSFS indexes"); /* Create a filesystem */ - SVN_ERR(create_greek_repo(&repos, &rev, opts, repo_name, pool, pool)); + SVN_ERR(create_greek_repo(&repos, &rev, opts, REPO_NAME, pool, pool)); /* Read the original index contents for REV in ENTRIES. */ SVN_ERR(svn_fs_fs__dump_index(svn_repos_fs(repos), rev, receive_index, @@ -397,34 +398,21 @@ load_index_test(const svn_test_opts_t *o APR_ARRAY_PUSH(alt_entries, svn_fs_fs__p2l_entry_t *) = &entry; SVN_ERR(svn_fs_fs__load_index(svn_repos_fs(repos), rev, alt_entries, pool)); - SVN_TEST_ASSERT_ERROR(svn_repos_verify_fs3(repos, rev, rev, - keep_going, FALSE, FALSE, - NULL, NULL, NULL, NULL, pool), - (keep_going - ? SVN_ERR_REPOS_VERIFY_FAILED - : SVN_ERR_FS_INDEX_CORRUPTION)); + SVN_TEST_ASSERT_ERROR(svn_repos_verify_fs3(repos, rev, rev, FALSE, FALSE, + NULL, NULL, NULL, NULL, NULL, + NULL, pool), + SVN_ERR_FS_INDEX_CORRUPTION); /* Restore the original index. */ SVN_ERR(svn_fs_fs__load_index(svn_repos_fs(repos), rev, entries, pool)); - SVN_ERR(svn_repos_verify_fs3(repos, rev, rev, keep_going, FALSE, FALSE, + SVN_ERR(svn_repos_verify_fs3(repos, rev, rev, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL, NULL, pool)); return SVN_NO_ERROR; } -static svn_error_t * -load_index(const svn_test_opts_t *opts, - apr_pool_t *pool) -{ - return load_index_test(opts, pool, "test-repo-load-index-test", FALSE); -} +#undef REPO_NAME -static svn_error_t * -load_index_keep_going(const svn_test_opts_t *opts, - apr_pool_t *pool) -{ - return load_index_test(opts, pool, "test-repo-load-index-full-test", TRUE); -} /* The test table. */ @@ -440,8 +428,6 @@ static struct svn_test_descriptor_t test "dump the P2L index"), SVN_TEST_OPTS_PASS(load_index, "load the P2L index"), - SVN_TEST_OPTS_PASS(load_index_keep_going, - "load the P2L index (full verification)"), SVN_TEST_NULL };
