You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/04/29 20:38:56 UTC
svn commit: r1741682 [21/26] - in /subversion/branches/authzperf: ./ build/
build/ac-macros/ build/generator/ contrib/server-side/svncutter/ notes/
notes/api-errata/1.9/ notes/move-tracking/ subversion/
subversion/bindings/ctypes-python/ subversion/bin...
Modified: subversion/branches/authzperf/subversion/svnserve/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svnserve/cyrus_auth.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svnserve/cyrus_auth.c (original)
+++ subversion/branches/authzperf/subversion/svnserve/cyrus_auth.c Fri Apr 29 18:38:53 2016
@@ -74,6 +74,8 @@ static int canonicalize_username(sasl_co
{
/* The only valid realm is user_realm (i.e. the repository's realm).
If the user gave us another realm, complain. */
+ if (realm_len != inlen-(pos-in+1))
+ return SASL_BADPROT;
if (strncmp(pos+1, user_realm, inlen-(pos-in+1)) != 0)
return SASL_BADPROT;
}
@@ -110,11 +112,12 @@ static svn_error_t *initialize(void *bat
/* The second parameter tells SASL to look for a configuration file
named subversion.conf. */
- result = sasl_server_init(callbacks, SVN_RA_SVN_SASL_NAME);
+ result = svn_sasl__server_init(callbacks, SVN_RA_SVN_SASL_NAME);
if (result != SASL_OK)
{
- svn_error_t *err = svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
- sasl_errstring(result, NULL, NULL));
+ svn_error_t *err = svn_error_create(
+ SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ svn_sasl__errstring(result, NULL, NULL));
return svn_error_quick_wrap(err,
_("Could not initialize the SASL library"));
}
@@ -133,7 +136,7 @@ svn_error_t *cyrus_init(apr_pool_t *pool
static svn_error_t *
fail_auth(svn_ra_svn_conn_t *conn, apr_pool_t *pool, sasl_conn_t *sasl_ctx)
{
- const char *msg = sasl_errdetail(sasl_ctx);
+ const char *msg = svn_sasl__errdetail(sasl_ctx);
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(c)", "failure", msg));
return svn_ra_svn__flush(conn, pool);
}
@@ -154,7 +157,7 @@ static svn_error_t *
fail_cmd(svn_ra_svn_conn_t *conn, apr_pool_t *pool, sasl_conn_t *sasl_ctx)
{
svn_error_t *err = svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
- sasl_errdetail(sasl_ctx));
+ svn_sasl__errdetail(sasl_ctx));
SVN_ERR(write_failure(conn, pool, &err));
return svn_ra_svn__flush(conn, pool);
}
@@ -190,9 +193,10 @@ static svn_error_t *try_auth(svn_ra_svn_
return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("Initial token is too long"));
- result = sasl_server_start(sasl_ctx, mech,
- in ? in->data : NULL,
- in ? (unsigned int) in->len : 0, &out, &outlen);
+ result = svn_sasl__server_start(sasl_ctx, mech,
+ in ? in->data : NULL,
+ in ? (unsigned int) in->len : 0,
+ &out, &outlen);
if (result != SASL_OK && result != SASL_CONTINUE)
return fail_auth(conn, pool, sasl_ctx);
@@ -221,8 +225,9 @@ static svn_error_t *try_auth(svn_ra_svn_
return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("Step response is too long"));
- result = sasl_server_step(sasl_ctx, in->data, (unsigned int) in->len,
- &out, &outlen);
+ result = svn_sasl__server_step(sasl_ctx, in->data,
+ (unsigned int) in->len,
+ &out, &outlen);
}
if (result != SASL_OK)
@@ -244,7 +249,7 @@ static svn_error_t *try_auth(svn_ra_svn_
static apr_status_t sasl_dispose_cb(void *data)
{
sasl_conn_t *sasl_ctx = (sasl_conn_t*) data;
- sasl_dispose(&sasl_ctx);
+ svn_sasl__dispose(&sasl_ctx);
return APR_SUCCESS;
}
@@ -276,15 +281,16 @@ svn_error_t *cyrus_auth_request(svn_ra_s
/* Create a SASL context. SASL_SUCCESS_DATA tells SASL that the protocol
supports sending data along with the final "success" message. */
- result = sasl_server_new(SVN_RA_SVN_SASL_NAME,
- hostname, b->repository->realm,
- localaddrport, remoteaddrport,
- NULL, SASL_SUCCESS_DATA,
- &sasl_ctx);
+ result = svn_sasl__server_new(SVN_RA_SVN_SASL_NAME,
+ hostname, b->repository->realm,
+ localaddrport, remoteaddrport,
+ NULL, SASL_SUCCESS_DATA,
+ &sasl_ctx);
if (result != SASL_OK)
{
- svn_error_t *err = svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
- sasl_errstring(result, NULL, NULL));
+ svn_error_t *err = svn_error_create(
+ SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ svn_sasl__errstring(result, NULL, NULL));
SVN_ERR(write_failure(conn, pool, &err));
return svn_ra_svn__flush(conn, pool);
}
@@ -305,20 +311,20 @@ svn_error_t *cyrus_auth_request(svn_ra_s
secprops.max_ssf = b->repository->max_ssf;
/* Set security properties. */
- result = sasl_setprop(sasl_ctx, SASL_SEC_PROPS, &secprops);
+ result = svn_sasl__setprop(sasl_ctx, SASL_SEC_PROPS, &secprops);
if (result != SASL_OK)
return fail_cmd(conn, pool, sasl_ctx);
/* SASL needs to know if we are externally authenticated. */
if (b->client_info->tunnel_user)
- result = sasl_setprop(sasl_ctx, SASL_AUTH_EXTERNAL,
- b->client_info->tunnel_user);
+ result = svn_sasl__setprop(sasl_ctx, SASL_AUTH_EXTERNAL,
+ b->client_info->tunnel_user);
if (result != SASL_OK)
return fail_cmd(conn, pool, sasl_ctx);
/* Get the list of mechanisms. */
- result = sasl_listmech(sasl_ctx, NULL, NULL, " ", NULL,
- &mechlist, NULL, &mech_count);
+ result = svn_sasl__listmech(sasl_ctx, NULL, NULL, " ", NULL,
+ &mechlist, NULL, &mech_count);
if (result != SASL_OK)
return fail_cmd(conn, pool, sasl_ctx);
@@ -354,7 +360,7 @@ svn_error_t *cyrus_auth_request(svn_ra_s
const void *user;
/* Get the authenticated username. */
- result = sasl_getprop(sasl_ctx, SASL_USERNAME, &user);
+ result = svn_sasl__getprop(sasl_ctx, SASL_USERNAME, &user);
if (result != SASL_OK)
return fail_cmd(conn, pool, sasl_ctx);
Modified: subversion/branches/authzperf/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svnserve/serve.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svnserve/serve.c (original)
+++ subversion/branches/authzperf/subversion/svnserve/serve.c Fri Apr 29 18:38:53 2016
@@ -87,6 +87,9 @@ typedef struct log_baton_t {
const char *fs_path;
svn_ra_svn_conn_t *conn;
int stack_depth;
+
+ /* Set to TRUE when at least one changed path has been sent. */
+ svn_boolean_t started;
} log_baton_t;
typedef struct file_revs_baton_t {
@@ -627,11 +630,12 @@ create_fs_access(server_baton_t *b, apr_
* On authentication failure, report failure to the client and set
* *success to FALSE. On communications failure, return an error.
* If NEEDS_USERNAME is TRUE, don't allow anonymous authentication. */
-static svn_error_t *auth(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+static svn_error_t *auth(svn_boolean_t *success,
+ svn_ra_svn_conn_t *conn,
const char *mech, const char *mecharg,
server_baton_t *b, enum access_type required,
svn_boolean_t needs_username,
- svn_boolean_t *success)
+ apr_pool_t *scratch_pool)
{
const char *user;
*success = FALSE;
@@ -640,10 +644,10 @@ static svn_error_t *auth(svn_ra_svn_conn
&& b->client_info->tunnel_user && strcmp(mech, "EXTERNAL") == 0)
{
if (*mecharg && strcmp(mecharg, b->client_info->tunnel_user) != 0)
- return svn_ra_svn__write_tuple(conn, pool, "w(c)", "failure",
+ return svn_ra_svn__write_tuple(conn, scratch_pool, "w(c)", "failure",
"Requested username does not match");
b->client_info->user = b->client_info->tunnel_user;
- SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w()", "success"));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "w()", "success"));
*success = TRUE;
return SVN_NO_ERROR;
}
@@ -651,7 +655,7 @@ static svn_error_t *auth(svn_ra_svn_conn
if (b->repository->anon_access >= required
&& strcmp(mech, "ANONYMOUS") == 0 && ! needs_username)
{
- SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w()", "success"));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "w()", "success"));
*success = TRUE;
return SVN_NO_ERROR;
}
@@ -659,13 +663,13 @@ static svn_error_t *auth(svn_ra_svn_conn
if (b->repository->auth_access >= required
&& b->repository->pwdb && strcmp(mech, "CRAM-MD5") == 0)
{
- SVN_ERR(svn_ra_svn_cram_server(conn, pool, b->repository->pwdb,
+ SVN_ERR(svn_ra_svn_cram_server(conn, scratch_pool, b->repository->pwdb,
&user, success));
b->client_info->user = apr_pstrdup(b->pool, user);
return SVN_NO_ERROR;
}
- return svn_ra_svn__write_tuple(conn, pool, "w(c)", "failure",
+ return svn_ra_svn__write_tuple(conn, scratch_pool, "w(c)", "failure",
"Must authenticate with listed mechanism");
}
@@ -677,19 +681,26 @@ internal_auth_request(svn_ra_svn_conn_t
{
svn_boolean_t success;
const char *mech, *mecharg;
+ apr_pool_t *iterpool;
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "success"));
SVN_ERR(send_mechs(conn, pool, b, required, needs_username));
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)c)", b->repository->realm));
+
+ iterpool = svn_pool_create(pool);
do
{
+ svn_pool_clear(iterpool);
+
SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "w(?c)", &mech, &mecharg));
if (!*mech)
break;
- SVN_ERR(auth(conn, pool, mech, mecharg, b, required, needs_username,
- &success));
+ SVN_ERR(auth(&success, conn, mech, mecharg, b, required,
+ needs_username, iterpool));
}
while (!success);
+ svn_pool_destroy(iterpool);
+
return SVN_NO_ERROR;
}
@@ -839,7 +850,7 @@ static svn_error_t *set_path(svn_ra_svn_
svn_depth_t depth = svn_depth_infinity;
svn_boolean_t start_empty;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "crb?(?c)?w",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "crb?(?c)?w",
&path, &rev, &start_empty, &lock_token,
&depth_word));
if (depth_word)
@@ -862,7 +873,7 @@ static svn_error_t *delete_path(svn_ra_s
report_driver_baton_t *b = baton;
const char *path;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &path));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &path));
path = svn_relpath_canonicalize(path, pool);
if (!b->err)
b->err = svn_repos_delete_path(b->report_baton, path, pool);
@@ -879,7 +890,7 @@ static svn_error_t *link_path(svn_ra_svn
/* Default to infinity, for old clients that don't send depth. */
svn_depth_t depth = svn_depth_infinity;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccrb?(?c)?w",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "ccrb?(?c)?w",
&path, &url, &rev, &start_empty,
&lock_token, &depth_word));
@@ -1105,7 +1116,7 @@ reparent(svn_ra_svn_conn_t *conn,
const char *url;
const char *fs_path;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &url));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &url));
url = svn_uri_canonicalize(url, pool);
SVN_ERR(trivial_auth_request(conn, pool, b));
SVN_CMD_ERR(get_fs_path(svn_path_uri_decode(b->repository->repos_url, pool),
@@ -1145,7 +1156,7 @@ get_dated_rev(svn_ra_svn_conn_t *conn,
apr_time_t tm;
const char *timestr;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", ×tr));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c", ×tr));
SVN_ERR(log_command(b, conn, pool, "get-dated-rev %s", timestr));
SVN_ERR(trivial_auth_request(conn, pool, b));
@@ -1197,7 +1208,7 @@ change_rev_prop2(svn_ra_svn_conn_t *conn
svn_string_t *old_value;
svn_boolean_t dont_care;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "rc(?s)(b?s)",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "rc(?s)(b?s)",
&rev, &name, &value,
&dont_care, &old_value));
@@ -1236,7 +1247,7 @@ change_rev_prop(svn_ra_svn_conn_t *conn,
/* Because the revprop value was at one time mandatory, the usual
optional element pattern "(?s)" isn't used. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "rc?s", &rev, &name, &value));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "rc?s", &rev, &name, &value));
SVN_ERR(do_change_rev_prop(conn, b, rev, name, NULL, value, pool));
@@ -1257,7 +1268,7 @@ rev_proplist(svn_ra_svn_conn_t *conn,
ab.server = b;
ab.conn = conn;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "r", &rev));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "r", &rev));
SVN_ERR(log_command(b, conn, pool, "%s", svn_log__rev_proplist(rev, pool)));
SVN_ERR(trivial_auth_request(conn, pool, b));
@@ -1286,7 +1297,7 @@ rev_prop(svn_ra_svn_conn_t *conn,
ab.server = b;
ab.conn = conn;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "rc", &rev, &name));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "rc", &rev, &name));
SVN_ERR(log_command(b, conn, pool, "%s",
svn_log__rev_prop(rev, name, pool)));
@@ -1455,7 +1466,7 @@ commit(svn_ra_svn_conn_t *conn,
{
/* Clients before 1.2 don't send lock-tokens, keep-locks,
and rev-props fields. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &log_msg));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &log_msg));
lock_tokens = NULL;
keep_locks = TRUE;
revprop_list = NULL;
@@ -1463,7 +1474,7 @@ commit(svn_ra_svn_conn_t *conn,
else
{
/* Clients before 1.5 don't send the rev-props field. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "clb?l", &log_msg,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "clb?l", &log_msg,
&lock_tokens, &keep_locks,
&revprop_list));
}
@@ -1568,7 +1579,7 @@ get_file(svn_ra_svn_conn_t *conn,
ab.conn = conn;
/* Parse arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)bb?B", &path, &rev,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)bb?B", &path, &rev,
&want_props, &want_contents,
&wants_inherited_props));
@@ -1674,6 +1685,19 @@ get_dir(svn_ra_svn_conn_t *conn,
svn_ra_svn__list_t *params,
void *baton)
{
+ static const svn_string_t str_kind
+ = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_KIND);
+ static const svn_string_t str_size
+ = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_SIZE);
+ static const svn_string_t str_has_props
+ = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_HAS_PROPS);
+ static const svn_string_t str_created_rev
+ = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_CREATED_REV);
+ static const svn_string_t str_time
+ = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_TIME);
+ static const svn_string_t str_last_author
+ = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_LAST_AUTHOR);
+
server_baton_t *b = baton;
const char *path, *full_path;
svn_revnum_t rev;
@@ -1693,7 +1717,7 @@ get_dir(svn_ra_svn_conn_t *conn,
ab.server = b;
ab.conn = conn;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)bb?l?B", &path, &rev,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)bb?l?B", &path, &rev,
&want_props, &want_contents,
&dirent_fields_list,
&wants_inherited_props));
@@ -1717,17 +1741,17 @@ get_dir(svn_ra_svn_conn_t *conn,
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
"Dirent field not a string");
- if (strcmp(SVN_RA_SVN_DIRENT_KIND, elt->u.word) == 0)
+ if (svn_string_compare(&str_kind, &elt->u.word))
dirent_fields |= SVN_DIRENT_KIND;
- else if (strcmp(SVN_RA_SVN_DIRENT_SIZE, elt->u.word) == 0)
+ else if (svn_string_compare(&str_size, &elt->u.word))
dirent_fields |= SVN_DIRENT_SIZE;
- else if (strcmp(SVN_RA_SVN_DIRENT_HAS_PROPS, elt->u.word) == 0)
+ else if (svn_string_compare(&str_has_props, &elt->u.word))
dirent_fields |= SVN_DIRENT_HAS_PROPS;
- else if (strcmp(SVN_RA_SVN_DIRENT_CREATED_REV, elt->u.word) == 0)
+ else if (svn_string_compare(&str_created_rev, &elt->u.word))
dirent_fields |= SVN_DIRENT_CREATED_REV;
- else if (strcmp(SVN_RA_SVN_DIRENT_TIME, elt->u.word) == 0)
+ else if (svn_string_compare(&str_time, &elt->u.word))
dirent_fields |= SVN_DIRENT_TIME;
- else if (strcmp(SVN_RA_SVN_DIRENT_LAST_AUTHOR, elt->u.word) == 0)
+ else if (svn_string_compare(&str_last_author, &elt->u.word))
dirent_fields |= SVN_DIRENT_LAST_AUTHOR;
}
}
@@ -1807,7 +1831,7 @@ get_dir(svn_ra_svn_conn_t *conn,
entry_kind = fsent->kind;
if (dirent_fields & SVN_DIRENT_SIZE)
- if (entry_kind != svn_node_dir)
+ if (fsent->kind != svn_node_dir)
SVN_CMD_ERR(svn_fs_file_length(&entry_size, root, file_path,
subpool));
@@ -1890,7 +1914,7 @@ update(svn_ra_svn_conn_t *conn,
svn_boolean_t is_checkout;
/* Parse the arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)cb?w3?3", &rev, &target,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cb?w3?3", &rev, &target,
&recurse, &depth_word,
&send_copyfrom_args, &ignore_ancestry));
target = svn_relpath_canonicalize(target, pool);
@@ -1948,7 +1972,7 @@ switch_cmd(svn_ra_svn_conn_t *conn,
svn_tristate_t ignore_ancestry; /* Optional; default TRUE */
/* Parse the arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)cbc?w?33", &rev, &target,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cbc?w?33", &rev, &target,
&recurse, &switch_url, &depth_word,
&send_copyfrom_args, &ignore_ancestry));
target = svn_relpath_canonicalize(target, pool);
@@ -1998,7 +2022,7 @@ status(svn_ra_svn_conn_t *conn,
svn_depth_t depth = svn_depth_unknown;
/* Parse the arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cb?(?r)?w",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "cb?(?r)?w",
&target, &recurse, &rev, &depth_word));
target = svn_relpath_canonicalize(target, pool);
@@ -2041,14 +2065,14 @@ diff(svn_ra_svn_conn_t *conn,
if (params->nelts == 5)
{
/* Clients before 1.4 don't send the text_deltas boolean or depth. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)cbbc", &rev, &target,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cbbc", &rev, &target,
&recurse, &ignore_ancestry, &versus_url));
text_deltas = TRUE;
depth_word = NULL;
}
else
{
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)cbbcb?w",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cbbcb?w",
&rev, &target, &recurse,
&ignore_ancestry, &versus_url,
&text_deltas, &depth_word));
@@ -2113,7 +2137,7 @@ get_mergeinfo(svn_ra_svn_conn_t *conn,
ab.server = b;
ab.conn = conn;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "l(?r)wb", &paths, &rev,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "l(?r)wb", &paths, &rev,
&inherit_word, &include_descendants));
inherit = svn_inheritance_from_word(inherit_word);
@@ -2166,14 +2190,58 @@ get_mergeinfo(svn_ra_svn_conn_t *conn,
return SVN_NO_ERROR;
}
-/* Send a log entry to the client. */
-static svn_error_t *log_receiver(void *baton,
- svn_log_entry_t *log_entry,
- apr_pool_t *pool)
+/* Send a changed paths list entry to the client.
+ This implements svn_repos_path_change_receiver_t. */
+static svn_error_t *
+path_change_receiver(void *baton,
+ svn_repos_path_change_t *change,
+ apr_pool_t *scratch_pool)
+{
+ const char symbol[] = "MADR";
+
+ log_baton_t *b = baton;
+ svn_ra_svn_conn_t *conn = b->conn;
+
+ /* Sanitize and convert change kind to ra-svn level action.
+
+ Pushing that conversion down into libsvn_ra_svn would add yet another
+ API dependency there. */
+ char action = ( change->change_kind < svn_fs_path_change_modify
+ || change->change_kind > svn_fs_path_change_replace)
+ ? 0
+ : symbol[change->change_kind];
+
+ /* Open lists once: LOG_ENTRY and LOG_ENTRY->CHANGED_PATHS. */
+ if (!b->started)
+ {
+ SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
+ SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
+ b->started = TRUE;
+ }
+
+ /* Serialize CHANGE. */
+ SVN_ERR(svn_ra_svn__write_data_log_changed_path(
+ conn, scratch_pool,
+ &change->path,
+ action,
+ change->copyfrom_path,
+ change->copyfrom_rev,
+ change->node_kind,
+ change->text_mod,
+ change->prop_mod));
+
+ return SVN_NO_ERROR;
+}
+
+/* Send a the meta data and the revpros for LOG_ENTRY to the client.
+ This implements svn_log_entry_receiver_t. */
+static svn_error_t *
+revision_receiver(void *baton,
+ svn_repos_log_entry_t *log_entry,
+ apr_pool_t *scratch_pool)
{
log_baton_t *b = baton;
svn_ra_svn_conn_t *conn = b->conn;
- apr_hash_index_t *h;
svn_boolean_t invalid_revnum = FALSE;
const svn_string_t *author, *date, *message;
unsigned revprop_count;
@@ -2194,55 +2262,52 @@ static svn_error_t *log_receiver(void *b
svn_compat_log_revprops_out_string(&author, &date, &message,
log_entry->revprops);
- svn_compat_log_revprops_clear(log_entry->revprops);
- if (log_entry->revprops)
- revprop_count = apr_hash_count(log_entry->revprops);
- else
- revprop_count = 0;
- /* send LOG_ENTRY */
- SVN_ERR(svn_ra_svn__start_list(conn, pool));
-
- /* send LOG_ENTRY->CHANGED_PATHS2 */
- SVN_ERR(svn_ra_svn__start_list(conn, pool));
- if (log_entry->changed_paths2)
+ /* Revprops list filtering is somewhat expensive.
+ Avoid doing that for the 90% case where only the standard revprops
+ have been requested and delivered. */
+ if (author && date && message && apr_hash_count(log_entry->revprops) == 3)
{
- for (h = apr_hash_first(pool, log_entry->changed_paths2); h;
- h = apr_hash_next(h))
- {
- const char *path = apr_hash_this_key(h);
- svn_log_changed_path2_t *change = apr_hash_this_val(h);
+ revprop_count = 0;
+ }
+ else
+ {
+ svn_compat_log_revprops_clear(log_entry->revprops);
+ if (log_entry->revprops)
+ revprop_count = apr_hash_count(log_entry->revprops);
+ else
+ revprop_count = 0;
+ }
- SVN_ERR(svn_ra_svn__write_data_log_changed_path(
- conn, pool,
- path,
- change->action,
- change->copyfrom_path,
- change->copyfrom_rev,
- change->node_kind,
- /* text_modified and props_modified are never unknown */
- change->text_modified == svn_tristate_true,
- change->props_modified == svn_tristate_true));
- }
+ /* Open lists once: LOG_ENTRY and LOG_ENTRY->CHANGED_PATHS. */
+ if (!b->started)
+ {
+ SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
+ SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
}
- SVN_ERR(svn_ra_svn__end_list(conn, pool));
+
+ /* Close LOG_ENTRY->CHANGED_PATHS. */
+ SVN_ERR(svn_ra_svn__end_list(conn, scratch_pool));
+ b->started = FALSE;
/* send LOG_ENTRY main members */
- SVN_ERR(svn_ra_svn__write_data_log_entry(conn, pool,
+ SVN_ERR(svn_ra_svn__write_data_log_entry(conn, scratch_pool,
log_entry->revision,
author, date, message,
log_entry->has_children,
invalid_revnum, revprop_count));
/* send LOG_ENTRY->REVPROPS */
- SVN_ERR(svn_ra_svn__start_list(conn, pool));
+ SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
if (revprop_count)
- SVN_ERR(svn_ra_svn__write_proplist(conn, pool, log_entry->revprops));
- SVN_ERR(svn_ra_svn__end_list(conn, pool));
+ SVN_ERR(svn_ra_svn__write_proplist(conn, scratch_pool,
+ log_entry->revprops));
+ SVN_ERR(svn_ra_svn__end_list(conn, scratch_pool));
/* send LOG_ENTRY members that were added in later SVN releases */
- SVN_ERR(svn_ra_svn__write_boolean(conn, pool, log_entry->subtractive_merge));
- SVN_ERR(svn_ra_svn__end_list(conn, pool));
+ SVN_ERR(svn_ra_svn__write_boolean(conn, scratch_pool,
+ log_entry->subtractive_merge));
+ SVN_ERR(svn_ra_svn__end_list(conn, scratch_pool));
if (log_entry->has_children)
b->stack_depth++;
@@ -2273,7 +2338,7 @@ log_cmd(svn_ra_svn_conn_t *conn,
ab.server = b;
ab.conn = conn;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "l(?r)(?r)bb?n?Bwl", &paths,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "l(?r)(?r)bb?n?Bwl", &paths,
&start_rev, &end_rev, &send_changed_paths,
&strict_node, &limit,
&include_merged_revs_param,
@@ -2340,11 +2405,14 @@ log_cmd(svn_ra_svn_conn_t *conn,
lb.fs_path = b->repository->fs_path->data;
lb.conn = conn;
lb.stack_depth = 0;
- err = svn_repos_get_logs4(b->repository->repos, full_paths, start_rev,
- end_rev, (int) limit, send_changed_paths,
+ lb.started = FALSE;
+ err = svn_repos_get_logs5(b->repository->repos, full_paths, start_rev,
+ end_rev, (int) limit,
strict_node, include_merged_revisions,
revprops, authz_check_access_cb_func(b), &ab,
- log_receiver, &lb, pool);
+ send_changed_paths ? path_change_receiver : NULL,
+ send_changed_paths ? &lb : NULL,
+ revision_receiver, &lb, pool);
write_err = svn_ra_svn__write_word(conn, pool, "done");
if (write_err)
@@ -2369,7 +2437,7 @@ check_path(svn_ra_svn_conn_t *conn,
svn_fs_root_t *root;
svn_node_kind_t kind;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)", &path, &rev));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)", &path, &rev));
full_path = svn_fspath__join(b->repository->fs_path->data,
svn_relpath_canonicalize(path, pool), pool);
@@ -2402,7 +2470,7 @@ stat_cmd(svn_ra_svn_conn_t *conn,
svn_fs_root_t *root;
svn_dirent_t *dirent;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)", &path, &rev));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)", &path, &rev));
full_path = svn_fspath__join(b->repository->fs_path->data,
svn_relpath_canonicalize(path, pool), pool);
@@ -2463,7 +2531,7 @@ get_locations(svn_ra_svn_conn_t *conn,
ab.conn = conn;
/* Parse the arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "crl", &relative_path,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "crl", &relative_path,
&peg_revision,
&loc_revs_proto));
relative_path = svn_relpath_canonicalize(relative_path, pool);
@@ -2560,7 +2628,7 @@ get_location_segments(svn_ra_svn_conn_t
ab.conn = conn;
/* Parse the arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)(?r)(?r)",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)(?r)(?r)",
&relative_path, &peg_revision,
&start_rev, &end_rev));
relative_path = svn_relpath_canonicalize(relative_path, pool);
@@ -2729,7 +2797,7 @@ get_file_revs(svn_ra_svn_conn_t *conn,
ab.conn = conn;
/* Parse arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)(?r)?B",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)(?r)?B",
&path, &start_rev, &end_rev,
&include_merged_revs_param));
path = svn_relpath_canonicalize(path, pool);
@@ -2779,7 +2847,7 @@ lock(svn_ra_svn_conn_t *conn,
svn_revnum_t current_rev;
svn_lock_t *l;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?c)b(?r)", &path, &comment,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?c)b(?r)", &path, &comment,
&steal_lock, ¤t_rev));
full_path = svn_fspath__join(b->repository->fs_path->data,
svn_relpath_canonicalize(path, pool), pool);
@@ -2860,7 +2928,7 @@ lock_many(svn_ra_svn_conn_t *conn,
apr_hash_index_t *hi;
struct lock_many_baton_t lmb;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?c)bl", &comment, &steal_lock,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "(?c)bl", &comment, &steal_lock,
&path_revs));
subpool = svn_pool_create(pool);
@@ -2885,7 +2953,7 @@ lock_many(svn_ra_svn_conn_t *conn,
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
"Lock requests should be list of lists");
- SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, subpool, "c(?r)", &path,
+ SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, "c(?r)", &path,
¤t_rev));
full_path = svn_fspath__join(b->repository->fs_path->data,
@@ -2944,7 +3012,7 @@ lock_many(svn_ra_svn_conn_t *conn,
svn_pool_clear(subpool);
- write_err = svn_ra_svn__parse_tuple(&item->u.list, subpool, "c(?r)",
+ write_err = svn_ra_svn__parse_tuple(&item->u.list, "c(?r)",
&path, ¤t_rev);
if (write_err)
break;
@@ -3009,7 +3077,7 @@ unlock(svn_ra_svn_conn_t *conn,
const char *path, *token, *full_path;
svn_boolean_t break_lock;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?c)b", &path, &token,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?c)b", &path, &token,
&break_lock));
full_path = svn_fspath__join(b->repository->fs_path->data,
@@ -3046,8 +3114,7 @@ unlock_many(svn_ra_svn_conn_t *conn,
apr_hash_index_t *hi;
struct lock_many_baton_t lmb;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "bl", &break_lock,
- &unlock_tokens));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "bl", &break_lock, &unlock_tokens));
/* Username required unless break_lock was specified. */
SVN_ERR(must_have_access(conn, pool, b, svn_authz_write, NULL, ! break_lock));
@@ -3066,7 +3133,7 @@ unlock_many(svn_ra_svn_conn_t *conn,
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
"Unlock request should be a list of lists");
- SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, subpool, "c(?c)", &path,
+ SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, "c(?c)", &path,
&token));
if (!token)
token = "";
@@ -3124,7 +3191,7 @@ unlock_many(svn_ra_svn_conn_t *conn,
svn_pool_clear(subpool);
- write_err = svn_ra_svn__parse_tuple(&item->u.list, subpool, "c(?c)",
+ write_err = svn_ra_svn__parse_tuple(&item->u.list, "c(?c)",
&path, &token);
if (write_err)
break;
@@ -3183,7 +3250,7 @@ get_lock(svn_ra_svn_conn_t *conn,
const char *full_path;
svn_lock_t *l;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &path));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &path));
full_path = svn_fspath__join(b->repository->fs_path->data,
svn_relpath_canonicalize(path, pool), pool);
@@ -3222,7 +3289,7 @@ get_locks(svn_ra_svn_conn_t *conn,
ab.server = b;
ab.conn = conn;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c?(?w)", &path, &depth_word));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c?(?w)", &path, &depth_word));
depth = depth_word ? svn_depth_from_word(depth_word) : svn_depth_infinity;
if ((depth != svn_depth_empty) &&
@@ -3305,7 +3372,7 @@ replay(svn_ra_svn_conn_t *conn,
svn_boolean_t send_deltas;
server_baton_t *b = baton;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "rrb", &rev, &low_water_mark,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "rrb", &rev, &low_water_mark,
&send_deltas));
SVN_ERR(trivial_auth_request(conn, pool, b));
@@ -3333,7 +3400,7 @@ replay_range(svn_ra_svn_conn_t *conn,
ab.server = b;
ab.conn = conn;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "rrrb", &start_rev,
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "rrrb", &start_rev,
&end_rev, &low_water_mark,
&send_deltas));
@@ -3378,7 +3445,7 @@ get_deleted_rev(svn_ra_svn_conn_t *conn,
svn_revnum_t end_revision;
svn_revnum_t revision_deleted;
- SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "crr",
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "crr",
&path, &peg_revision, &end_revision));
full_path = svn_fspath__join(b->repository->fs_path->data,
svn_relpath_canonicalize(path, pool), pool);
@@ -3410,7 +3477,7 @@ get_inherited_props(svn_ra_svn_conn_t *c
ab.conn = conn;
/* Parse arguments. */
- SVN_ERR(svn_ra_svn__parse_tuple(params, iterpool, "c(?r)", &path, &rev));
+ SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)", &path, &rev));
full_path = svn_fspath__join(b->repository->fs_path->data,
svn_relpath_canonicalize(path, iterpool),
@@ -3952,9 +4019,12 @@ construct_server_baton(server_baton_t **
sizeof(const char *));
for (i = 0; i < caplist->nelts; i++)
{
+ static const svn_string_t str_cap_mergeinfo
+ = SVN__STATIC_STRING(SVN_RA_SVN_CAP_MERGEINFO);
+
item = &SVN_RA_SVN__LIST_ITEM(caplist, i);
/* ra_svn_set_capabilities() already type-checked for us */
- if (strcmp(item->u.word, SVN_RA_SVN_CAP_MERGEINFO) == 0)
+ if (svn_string_compare(&item->u.word, &str_cap_mergeinfo))
{
APR_ARRAY_PUSH(b->repository->capabilities, const char *)
= SVN_RA_CAPABILITY_MERGEINFO;
@@ -3962,7 +4032,7 @@ construct_server_baton(server_baton_t **
/* Save for operational log. */
if (cap_log->len > 0)
svn_stringbuf_appendcstr(cap_log, " ");
- svn_stringbuf_appendcstr(cap_log, item->u.word);
+ svn_stringbuf_appendcstr(cap_log, item->u.word.data);
}
}
@@ -4100,10 +4170,12 @@ serve_interruptable(svn_boolean_t *termi
/* create the connection, configure ports etc. */
connection->conn
- = svn_ra_svn_create_conn4(connection->usock, NULL, NULL,
+ = svn_ra_svn_create_conn5(connection->usock, NULL, NULL,
connection->params->compression_level,
connection->params->zero_copy_limit,
connection->params->error_check_interval,
+ connection->params->max_request_size,
+ connection->params->max_response_size,
connection->pool);
/* Construct server baton and open the repository for the first time. */
Modified: subversion/branches/authzperf/subversion/svnserve/server.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svnserve/server.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svnserve/server.h (original)
+++ subversion/branches/authzperf/subversion/svnserve/server.h Fri Apr 29 18:38:53 2016
@@ -65,8 +65,10 @@ typedef struct repository_t {
enum username_case_type username_case; /* Case-normalize the username? */
svn_boolean_t use_sasl; /* Use Cyrus SASL for authentication;
always false if SVN_HAVE_SASL not defined */
+#ifdef SVN_HAVE_SASL
unsigned min_ssf; /* min-encryption SASL parameter */
unsigned max_ssf; /* max-encryption SASL parameter */
+#endif
enum access_type auth_access; /* access granted to authenticated users */
enum access_type anon_access; /* access granted to annonymous users */
@@ -152,6 +154,12 @@ typedef struct serve_params_t {
coming in from the client. */
apr_size_t error_check_interval;
+ /* If not 0, error out on requests exceeding this value. */
+ apr_uint64_t max_request_size;
+
+ /* If not 0, stop sending a response once it exceeds this value. */
+ apr_uint64_t max_response_size;
+
/* Use virtual-host-based path to repo. */
svn_boolean_t vhost;
} serve_params_t;
Modified: subversion/branches/authzperf/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svnserve/svnserve.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/authzperf/subversion/svnserve/svnserve.c Fri Apr 29 18:38:53 2016
@@ -155,6 +155,15 @@ enum run_mode {
*/
#define ACCEPT_BACKLOG 128
+/* Default limit to the client request size in MBytes. This effectively
+ * limits the size of a paths and individual property values to about
+ * this value.
+ *
+ * Note that (MAX_REQUEST_SIZE + 4M) * THREADPOOL_MAX_SIZE is roughly
+ * the peak memory usage of the RA layer.
+ */
+#define MAX_REQUEST_SIZE 16
+
#ifdef WIN32
static apr_os_sock_t winservice_svnserve_accept_socket = INVALID_SOCKET;
@@ -210,6 +219,9 @@ void winservice_notify_stop(void)
#define SVNSERVE_OPT_MIN_THREADS 271
#define SVNSERVE_OPT_MAX_THREADS 272
#define SVNSERVE_OPT_BLOCK_READ 273
+#define SVNSERVE_OPT_MAX_REQUEST 274
+#define SVNSERVE_OPT_MAX_RESPONSE 275
+#define SVNSERVE_OPT_CACHE_NODEPROPS 276
/* Text macro because we can't use #ifdef sections inside a N_("...")
macro expansion. */
@@ -307,6 +319,12 @@ static const apr_getopt_option_t svnserv
"Default is no.\n"
" "
"[used for FSFS and FSX repositories only]")},
+ {"cache-nodeprops", SVNSERVE_OPT_CACHE_NODEPROPS, 1,
+ N_("enable or disable caching of node properties\n"
+ " "
+ "Default is yes.\n"
+ " "
+ "[used for FSFS repositories only]")},
{"client-speed", SVNSERVE_OPT_CLIENT_SPEED, 1,
N_("Optimize network handling based on the assumption\n"
" "
@@ -345,6 +363,29 @@ static const apr_getopt_option_t svnserv
"Default is " APR_STRINGIFY(THREADPOOL_MAX_SIZE) "."
ONLY_AVAILABLE_WITH_THEADS)},
#endif
+ {"max-request-size", SVNSERVE_OPT_MAX_REQUEST, 1,
+ N_("Maximum acceptable size of a client request in MB.\n"
+ " "
+ "This implicitly limits the length of paths and\n"
+ " "
+ "property values that can be sent to the server.\n"
+ " "
+ "Also the peak memory usage for protocol handling\n"
+ " "
+ "per server thread or sub-process.\n"
+ " "
+ "0 disables the size check; default is "
+ APR_STRINGIFY(MAX_REQUEST_SIZE) ".")},
+ {"max-response-size", SVNSERVE_OPT_MAX_RESPONSE, 1,
+ N_("Maximum acceptable server response size in MB.\n"
+ " "
+ "Longer responses get truncated and return an\n"
+ " "
+ "error. This limits the server load e.g. when\n"
+ " "
+ "checking out at the wrong path level.\n"
+ " "
+ "Default is 0 (disabled).")},
{"foreground", SVNSERVE_OPT_FOREGROUND, 0,
N_("run in foreground (useful for debugging)\n"
" "
@@ -680,6 +721,7 @@ sub_main(int *exit_code, int argc, const
svn_boolean_t is_multi_threaded;
enum connection_handling_mode handling_mode = CONNECTION_DEFAULT;
svn_boolean_t cache_fulltexts = TRUE;
+ svn_boolean_t cache_nodeprops = TRUE;
svn_boolean_t cache_txdeltas = TRUE;
svn_boolean_t cache_revprops = FALSE;
svn_boolean_t use_block_read = FALSE;
@@ -728,6 +770,8 @@ sub_main(int *exit_code, int argc, const
params.memory_cache_size = (apr_uint64_t)-1;
params.zero_copy_limit = 0;
params.error_check_interval = 4096;
+ params.max_request_size = MAX_REQUEST_SIZE * 0x100000;
+ params.max_response_size = 0;
while (1)
{
@@ -870,6 +914,10 @@ sub_main(int *exit_code, int argc, const
cache_revprops = svn_tristate__from_word(arg) == svn_tristate_true;
break;
+ case SVNSERVE_OPT_CACHE_NODEPROPS:
+ cache_nodeprops = svn_tristate__from_word(arg) == svn_tristate_true;
+ break;
+
case SVNSERVE_OPT_BLOCK_READ:
use_block_read = svn_tristate__from_word(arg) == svn_tristate_true;
break;
@@ -891,6 +939,14 @@ sub_main(int *exit_code, int argc, const
}
break;
+ case SVNSERVE_OPT_MAX_REQUEST:
+ params.max_request_size = 0x100000 * apr_strtoi64(arg, NULL, 0);
+ break;
+
+ case SVNSERVE_OPT_MAX_RESPONSE:
+ params.max_response_size = 0x100000 * apr_strtoi64(arg, NULL, 0);
+ break;
+
case SVNSERVE_OPT_MIN_THREADS:
min_thread_count = (apr_size_t)apr_strtoi64(arg, NULL, 0);
break;
@@ -980,6 +1036,8 @@ sub_main(int *exit_code, int argc, const
cache_txdeltas ? "1" :"0");
svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
cache_fulltexts ? "1" :"0");
+ svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+ cache_nodeprops ? "1" :"0");
svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
cache_revprops ? "2" :"0");
svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ,
@@ -1039,10 +1097,12 @@ sub_main(int *exit_code, int argc, const
* the pool cleanup handlers that call sasl_dispose() (connection_pool)
* and sasl_done() (pool) are run in the right order. See issue #3664. */
connection_pool = svn_pool_create(pool);
- conn = svn_ra_svn_create_conn4(NULL, stdin_stream, stdout_stream,
+ conn = svn_ra_svn_create_conn5(NULL, stdin_stream, stdout_stream,
params.compression_level,
params.zero_copy_limit,
params.error_check_interval,
+ params.max_request_size,
+ params.max_response_size,
connection_pool);
err = serve(conn, ¶ms, connection_pool);
svn_pool_destroy(connection_pool);
Modified: subversion/branches/authzperf/subversion/svnsync/svnsync.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svnsync/svnsync.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svnsync/svnsync.c (original)
+++ subversion/branches/authzperf/subversion/svnsync/svnsync.c Fri Apr 29 18:38:53 2016
@@ -43,7 +43,6 @@
#include "svn_private_config.h"
-#include <apr_signal.h>
#include <apr_uuid.h>
static svn_opt_subcommand_t initialize_cmd,
@@ -324,29 +323,8 @@ typedef struct opt_baton_t {
/*** Helper functions ***/
-/* Global record of whether the user has requested cancellation. */
-static volatile sig_atomic_t cancelled = FALSE;
-
-
-/* Callback function for apr_signal(). */
-static void
-signal_handler(int signum)
-{
- apr_signal(signum, SIG_IGN);
- cancelled = TRUE;
-}
-
-
/* Cancellation callback function. */
-static svn_error_t *
-check_cancel(void *baton)
-{
- if (cancelled)
- return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Caught signal"));
- else
- return SVN_NO_ERROR;
-}
-
+static svn_cancel_func_t check_cancel = 0;
/* Check that the version of libraries in use match what we expect. */
static svn_error_t *
@@ -1549,7 +1527,7 @@ do_synchronize(svn_ra_session_t *to_sess
/* Now check to see if there are any revisions to copy. */
SVN_ERR(svn_ra_get_latest_revnum(from_session, &from_latest, pool));
- if (from_latest < last_merged)
+ if (from_latest <= last_merged)
return SVN_NO_ERROR;
/* Ok, so there are new revisions, iterate over them copying them
@@ -2363,33 +2341,7 @@ sub_main(int *exit_code, int argc, const
opt_baton.source_prop_encoding = source_prop_encoding;
- apr_signal(SIGINT, signal_handler);
-
-#ifdef SIGBREAK
- /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
- apr_signal(SIGBREAK, signal_handler);
-#endif
-
-#ifdef SIGHUP
- apr_signal(SIGHUP, signal_handler);
-#endif
-
-#ifdef SIGTERM
- apr_signal(SIGTERM, signal_handler);
-#endif
-
-#ifdef SIGPIPE
- /* Disable SIGPIPE generation for the platforms that have it. */
- apr_signal(SIGPIPE, SIG_IGN);
-#endif
-
-#ifdef SIGXFSZ
- /* Disable SIGXFSZ generation for the platforms that have it,
- otherwise working with large files when compiled against an APR
- that doesn't have large file support will crash the program,
- which is uncool. */
- apr_signal(SIGXFSZ, SIG_IGN);
-#endif
+ check_cancel = svn_cmdline__setup_cancellation_handler();
err = svn_cmdline_create_auth_baton2(
&opt_baton.source_auth_baton,
@@ -2470,5 +2422,8 @@ main(int argc, const char *argv[])
}
svn_pool_destroy(pool);
+
+ svn_cmdline__cancellation_exit();
+
return exit_code;
}
Modified: subversion/branches/authzperf/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/authz_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/authz_tests.py Fri Apr 29 18:38:53 2016
@@ -359,7 +359,7 @@ def authz_write_access(sbox):
def authz_checkout_test(sbox):
"test authz for checkout"
- sbox.build(create_wc = False, read_only = True)
+ sbox.build(create_wc = False)
local_dir = sbox.wc_dir
write_restrictive_svnserve_conf(sbox.repo_dir)
@@ -398,7 +398,7 @@ def authz_checkout_test(sbox):
def authz_checkout_and_update_test(sbox):
"test authz for checkout and update"
- sbox.build(create_wc = False, read_only = True)
+ sbox.build(create_wc = False)
local_dir = sbox.wc_dir
write_restrictive_svnserve_conf(sbox.repo_dir)
@@ -460,7 +460,7 @@ def authz_checkout_and_update_test(sbox)
def authz_partial_export_test(sbox):
"test authz for export with unreadable subfolder"
- sbox.build(create_wc = False, read_only = True)
+ sbox.build(create_wc = False)
local_dir = sbox.wc_dir
# cleanup remains of a previous test run.
@@ -656,7 +656,7 @@ def authz_aliases(sbox):
def authz_validate(sbox):
"test the authz validation rules"
- sbox.build(create_wc = False, read_only = True)
+ sbox.build(create_wc = False)
write_restrictive_svnserve_conf(sbox.repo_dir)
@@ -782,7 +782,7 @@ def authz_locking(sbox):
sbox.ospath('A/mu'))
if sbox.repo_url.startswith('http'):
- expected_err = ".*svn: warning: W160039: Unlock.*[Ff]orbidden.*"
+ expected_err = ".*svn: warning: W160039: .*([Aa]uth.*perf|[Ff]orbidden).*"
else:
expected_err = ".*svn: warning: W170001: Authorization failed.*"
@@ -874,7 +874,7 @@ def authz_svnserve_anon_access_read(sbox
def authz_switch_to_directory(sbox):
"switched to directory, no read access on parents"
- sbox.build(read_only = True)
+ sbox.build()
write_authz_file(sbox, {"/": "*=rw", "/A/B": "*=", "/A/B/E": "jrandom = rw"})
@@ -1610,6 +1610,57 @@ def authz_log_censor_revprops(sbox):
args=['--with-revprop', 'svn:author', '--with-revprop', 's',
'-r1', sbox.repo_url])
+@Skip(svntest.main.is_ra_type_file)
+def remove_access_after_commit(sbox):
+ "remove a subdir with authz file"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ svntest.main.write_restrictive_svnserve_conf(sbox.repo_dir)
+ svntest.main.write_authz_file(sbox, { "/" : "*=rw"})
+
+ # Modification in subtree
+ sbox.simple_append('A/B/E/alpha', 'appended\n')
+ sbox.simple_append('A/D/G/rho', 'appended\n')
+ sbox.simple_commit()
+
+ svntest.main.write_authz_file(sbox, { "/" : "*=rw",
+ "/A/B" : "*=",
+ "/A/D" : "*="})
+
+ # Local modification
+ sbox.simple_append('A/D/G/pi', 'appended\n')
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/B' : Item(status='D '),
+ 'A/D' : Item(status=' ', treeconflict='C'),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/D/G/rho',
+ contents="This is the file 'rho'.\nappended\n")
+ expected_disk.tweak('A/D/G/pi',
+ contents="This is the file 'pi'.\nappended\n")
+ expected_disk.remove('A/B', 'A/B/E', 'A/B/E/alpha', 'A/B/E/beta',
+ 'A/B/F', 'A/B/lambda')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+
+ expected_status.tweak('A/D', status='R ',treeconflict='C', )
+ expected_status.tweak('A/D', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
+ 'A/D/H', 'A/D/H/omega', 'A/D/H/chi', 'A/D/H/psi',
+ 'A/D/gamma', copied='+', wc_rev='-')
+ expected_status.tweak('A/D/G/pi', status='M ')
+ expected_status.remove('A/B', 'A/B/E', 'A/B/E/alpha', 'A/B/E/beta', 'A/B/F',
+ 'A/B/lambda')
+
+ # And expect a mixed rev copy
+ expected_status.tweak('A/D/G/rho', status='A ', entry_status=' ')
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ [], True)
+
########################################################################
# Run the tests
@@ -1646,6 +1697,7 @@ test_list = [ None,
log_diff_dontdothat,
authz_file_external_to_authz,
authz_log_censor_revprops,
+ remove_access_after_commit,
]
serial_only = True
Modified: subversion/branches/authzperf/subversion/tests/cmdline/davautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/davautocheck.sh?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/davautocheck.sh (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/davautocheck.sh Fri Apr 29 18:38:53 2016
@@ -163,7 +163,8 @@ get_prog_name() {
}
# Don't assume sbin is in the PATH.
-# ### Presumably this is used to locate /usr/sbin/apxs or /usr/sbin/apache2
+# This is used to locate apxs when the script is invoked manually; when
+# invoked by 'make davautocheck' the APXS environment variable is set.
PATH="$PATH:/usr/sbin:/usr/local/sbin"
# Find the source and build directories. The build dir can be found if it is
Modified: subversion/branches/authzperf/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/diff_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/diff_tests.py Fri Apr 29 18:38:53 2016
@@ -5077,6 +5077,7 @@ def diff_symlinks(sbox):
'Index: %s\n' % sbox.path('to-iota'),
'===================================================================\n',
'diff --git a/to-iota b/to-iota\n',
+ 'index 3ef26e44..9930f9a0 120644\n',
'--- a/to-iota\t(revision 2)\n',
'+++ b/to-iota\t(working copy)\n',
'@@ -1 +1 @@\n',
@@ -5087,6 +5088,59 @@ def diff_symlinks(sbox):
], [], 'diff', wc_dir, '--git')
+@Issue(4597)
+def diff_peg_resolve(sbox):
+ "peg resolving during diff"
+
+ sbox.build()
+ repo_url = sbox.repo_url
+ wc_dir = sbox.wc_dir
+
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', repo_url, '-m', 'Q',
+ 'mkdir', 'branches',
+ 'cp', 1, 'A', 'branches/A1',
+ 'cp', 1, 'A', 'branches/A2',
+ 'rm', 'A')
+
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', repo_url, '-m', 'Q2',
+ 'rm', 'branches/A1')
+
+ svntest.actions.run_and_verify_svn(None, [],
+ 'diff', repo_url + '/branches/A1@2',
+ sbox.wc_dir,
+ '--notice-ancestry')
+
+ svntest.actions.run_and_verify_svn(None, [],
+ 'diff',
+ '--old=' + repo_url + '/branches/A1@2',
+ '--new=' + sbox.wc_dir,
+ '--git')
+
+ svntest.actions.run_and_verify_svn(None, [],
+ 'diff',
+ '--old=' + repo_url + '/branches/A1@2',
+ '--new=' + repo_url + '/A@1',
+ '--git')
+
+ svntest.actions.run_and_verify_svn(None, '.*E160005: Target path.*A1',
+ 'diff',
+ repo_url + '/branches/A1',
+ wc_dir,
+ '--summarize')
+
+ svntest.actions.run_and_verify_svn(None, [],
+ 'diff',
+ repo_url + '/branches/A2',
+ wc_dir)
+
+ svntest.actions.run_and_verify_svn(None, '.*E200009: .*mix.*',
+ 'diff',
+ repo_url + '/branches/A2',
+ wc_dir, '-r1:2')
+
+
########################################################################
#Run the tests
@@ -5181,6 +5235,7 @@ test_list = [ None,
diff_incomplete,
diff_incomplete_props,
diff_symlinks,
+ diff_peg_resolve,
]
if __name__ == '__main__':
Modified: subversion/branches/authzperf/subversion/tests/cmdline/export_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/export_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/export_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/export_tests.py Fri Apr 29 18:38:53 2016
@@ -1102,7 +1102,7 @@ test_list = [ None,
export_file_overwrite_with_force,
export_custom_keywords,
export_file_external,
- export_file_externals2
+ export_file_externals2,
]
if __name__ == '__main__':
Modified: subversion/branches/authzperf/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/externals_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/externals_tests.py Fri Apr 29 18:38:53 2016
@@ -3076,6 +3076,7 @@ def list_include_externals(sbox):
expected_stdout, [], 0, 'ls', '--include-externals', C_url)
@Issue(4293)
+@XFail()
def move_with_file_externals(sbox):
"move with file externals"
@@ -3252,18 +3253,28 @@ def file_external_unversioned_obstructio
# Update reports a tree-conflict but status doesn't show any such
# conflict. I'm no sure whether this is correct.
- expected_output = svntest.wc.State(wc_dir, {
- 'A' : Item(status=' U'),
- 'A/mu-ext' : Item(status=' ', treeconflict='A'),
- })
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
'A/mu-ext' : Item('unversioned obstruction'),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ svntest.actions.run_and_verify_svn(
+ None,
+ ".*svn: warning: W155014: The file external '.*mu-ext'"
+ " can not be created because the node exists.*",
+ 'up', wc_dir)
+ svntest.actions.verify_disk(wc_dir, expected_disk)
+ svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+ os.remove(sbox.ospath('A/mu-ext'))
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/mu-ext' : Item(status='A '),
+ })
expected_status.add({
- 'A/mu-ext' : Item(status='M ', wc_rev='2', switched='X'),
+ 'A/mu-ext' : Item(status=' ', wc_rev='2', switched='X'),
})
+ expected_disk.tweak('A/mu-ext', contents="This is the file 'mu'.\n")
svntest.actions.run_and_verify_update(wc_dir,
expected_output, expected_disk,
expected_status)
Modified: subversion/branches/authzperf/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/lock_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/lock_tests.py Fri Apr 29 18:38:53 2016
@@ -1360,11 +1360,8 @@ def unlocked_lock_of_other_user(sbox):
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# now try to unlock with user jconstant, should fail but exit 0.
- if sbox.repo_url.startswith("http"):
- expected_err = "svn: warning: W160039: .*[Uu]nlock of .*403 Forbidden.*"
- else:
- expected_err = "svn: warning: W160039: User '%s' is trying to use a lock owned by "\
- "'%s'.*" % (svntest.main.wc_author2, svntest.main.wc_author)
+ expected_err = "svn: warning: W160039: User '%s' is trying to use a lock owned by "\
+ "'%s'.*" % (svntest.main.wc_author2, svntest.main.wc_author)
svntest.actions.run_and_verify_svn([], expected_err,
'unlock',
'--username', svntest.main.wc_author2,
@@ -2077,25 +2074,6 @@ def dav_lock_timeout(sbox):
expected_status.tweak('iota', writelocked='K')
svntest.actions.run_and_verify_status(wc_dir, expected_status)
-def http_connection(repo_url):
-
- import httplib
- from urlparse import urlparse
-
- loc = urlparse(repo_url)
- if loc.scheme == 'http':
- h = httplib.HTTPConnection(loc.hostname, loc.port)
- else:
- try:
- import ssl # new in python 2.6
- c = ssl.create_default_context()
- c.check_hostname = False
- c.verify_mode = ssl.CERT_NONE
- h = httplib.HTTPSConnection(loc.hostname, loc.port, context=c)
- except:
- h = httplib.HTTPSConnection(loc.hostname, loc.port)
- return h
-
@SkipUnless(svntest.main.is_ra_type_dav)
def create_dav_lock_timeout(sbox):
"create generic DAV lock with timeout"
@@ -2106,7 +2084,7 @@ def create_dav_lock_timeout(sbox):
sbox.build()
wc_dir = sbox.wc_dir
- h = http_connection(sbox.repo_url)
+ h = svntest.main.create_http_connection(sbox.repo_url)
lock_body = '<?xml version="1.0" encoding="utf-8" ?>' \
'<D:lockinfo xmlns:D="DAV:">' \
@@ -2122,9 +2100,6 @@ def create_dav_lock_timeout(sbox):
'Timeout': 'Second-86400'
}
- # Enabling the following line makes this test easier to debug
- h.set_debuglevel(9)
-
h.request('LOCK', sbox.repo_url + '/iota', lock_body, lock_headers)
r = h.getresponse()
@@ -2251,7 +2226,7 @@ def dav_lock_refresh(sbox):
sbox.repo_url + '/iota')
# Try to refresh lock using 'If' header
- h = http_connection(sbox.repo_url)
+ h = svntest.main.create_http_connection(sbox.repo_url)
lock_token = svntest.actions.run_and_parse_info(sbox.repo_url + '/iota')[0]['Lock Token']
@@ -2261,9 +2236,6 @@ def dav_lock_refresh(sbox):
'Timeout': 'Second-7200'
}
- # Enabling the following line makes this test easier to debug
- h.set_debuglevel(9)
-
h.request('LOCK', sbox.repo_url + '/iota', '', lock_headers)
# XFAIL Refreshing of DAV lock fails with error '412 Precondition Failed'
@@ -2365,7 +2337,6 @@ def copy_dir_with_locked_file(sbox):
'-m', '')
@Issue(4557)
-@XFail(svntest.main.is_ra_type_dav)
def delete_dir_with_lots_of_locked_files(sbox):
"delete a directory containing lots of locked files"
@@ -2394,12 +2365,6 @@ def delete_dir_with_lots_of_locked_files
# always used a special non-standard request)
sbox.simple_rm("A")
- # But a further replacement never worked
- sbox.simple_mkdir("A")
- # And an additional propset didn't work either
- # (but doesn't require all lock tokens recursively)
- sbox.simple_propset("k", "v", "A")
-
# Commit the deletion
# XFAIL: As of 1.8.10, this commit fails with:
# svn: E175002: Unexpected HTTP status 400 'Bad Request' on '<path>'
@@ -2462,7 +2427,49 @@ def delete_locks_on_depth_commit(sbox):
expected_status.tweak('', 'iota', wc_rev=2)
svntest.actions.run_and_verify_status(wc_dir, expected_status)
+@Issue(4557)
+@XFail(svntest.main.is_ra_type_dav)
+def replace_dir_with_lots_of_locked_files(sbox):
+ "replace directory containing lots of locked files"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # A lot of paths.
+ nfiles = 75 # NOTE: test XPASSES with 50 files!!!
+ locked_paths = []
+ for i in range(nfiles):
+ locked_paths.append(sbox.ospath("A/locked_files/file-%i" % i))
+ # Create files at these paths
+ os.mkdir(sbox.ospath("A/locked_files"))
+ for file_path in locked_paths:
+ svntest.main.file_write(file_path, "This is '%s'.\n" % (file_path,))
+ sbox.simple_add("A/locked_files")
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ # lock all the files
+ svntest.actions.run_and_verify_svn(None, [], 'lock',
+ '-m', 'All locks',
+ *locked_paths)
+ # Locally delete A (regression against earlier versions, which
+ # always used a special non-standard request)
+ sbox.simple_rm("A")
+
+ # But a further replacement never worked
+ sbox.simple_mkdir("A")
+ # And an additional propset didn't work either
+ # (but doesn't require all lock tokens recursively)
+ sbox.simple_propset("k", "v", "A")
+
+ # Commit the deletion
+ # XFAIL: As of 1.8.10, this commit fails with:
+ # svn: E175002: Unexpected HTTP status 400 'Bad Request' on '<path>'
+ # and the following error in the httpd error log:
+ # request failed: error reading the headers
+ # This problem was introduced on the 1.8.x branch in r1606976.
+ sbox.simple_commit()
########################################################################
# Run the tests
@@ -2531,6 +2538,7 @@ test_list = [ None,
copy_dir_with_locked_file,
delete_dir_with_lots_of_locked_files,
delete_locks_on_depth_commit,
+ replace_dir_with_lots_of_locked_files,
]
if __name__ == '__main__':
Modified: subversion/branches/authzperf/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/log_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/log_tests.py Fri Apr 29 18:38:53 2016
@@ -2288,13 +2288,13 @@ def log_search(sbox):
log_chain = parse_log_output(output)
check_log_chain(log_chain, [7, 6, 3])
- # search is case-sensitive
+ # search is case-insensitive
exit_code, output, err = svntest.actions.run_and_verify_svn(
None, [], 'log', '--search',
'FOR REVISION [367]')
log_chain = parse_log_output(output)
- check_log_chain(log_chain, [])
+ check_log_chain(log_chain, [7, 6, 3])
# multi-pattern search
exit_code, output, err = svntest.actions.run_and_verify_svn(
Modified: subversion/branches/authzperf/subversion/tests/cmdline/merge_automatic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/merge_automatic_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/merge_automatic_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/merge_automatic_tests.py Fri Apr 29 18:38:53 2016
@@ -1429,7 +1429,7 @@ test_list = [ None,
effective_sync_results_in_reintegrate,
reintegrate_subtree_not_updated,
merge_to_copy_and_add,
- merge_delete_crlf_file
+ merge_delete_crlf_file,
]
if __name__ == '__main__':
Modified: subversion/branches/authzperf/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/merge_reintegrate_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/merge_reintegrate_tests.py Fri Apr 29 18:38:53 2016
@@ -2456,65 +2456,98 @@ def no_source_subtree_mergeinfo(sbox):
svntest.main.file_write(sbox.ospath('A/B/E/alpha'),
'AAA\n' +
+ 'X\n' +
'BBB\n' +
+ 'Y\n' +
'CCC\n')
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
- svntest.main.run_svn(None, 'update', wc_dir)
+ sbox.simple_commit()
+ sbox.simple_update()
# Create branch-1
svntest.main.run_svn(None, 'copy',
sbox.ospath('A/B'),
sbox.ospath('A/B1'))
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+ sbox.simple_commit()
# Create branch-1
svntest.main.run_svn(None, 'copy',
sbox.ospath('A/B'),
sbox.ospath('A/B2'))
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+ sbox.simple_commit()
# Change on trunk
svntest.main.file_write(sbox.ospath('A/B/E/alpha'),
'AAAxx\n' +
+ 'X\n' +
'BBB\n' +
+ 'Y\n' +
'CCC\n')
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+ sbox.simple_commit()
# Change on branch-1
svntest.main.file_write(sbox.ospath('A/B1/E/alpha'),
'AAA\n' +
+ 'X\n' +
'BBBxx\n' +
+ 'Y\n' +
'CCC\n')
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+ sbox.simple_commit()
# Change on branch-2
svntest.main.file_write(sbox.ospath('A/B2/E/alpha'),
'AAA\n' +
+ 'X\n' +
'BBB\n' +
+ 'Y\n' +
'CCCxx\n')
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
- svntest.main.run_svn(None, 'update', wc_dir)
+ sbox.simple_commit()
+ sbox.simple_update()
# Merge trunk to branch-1
- svntest.main.run_svn(None, 'merge', '^/A/B', sbox.ospath('A/B1'))
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
- svntest.main.run_svn(None, 'update', wc_dir)
+ # svntest.main.run_svn(None, 'merge', '^/A/B', sbox.ospath('A/B1'))
+ A_B1 = sbox.ospath('A/B1')
+ expected_output = wc.State(A_B1, {
+ 'E/alpha' : Item(status='U '),
+ })
+ expected_skip = wc.State(A_B1, { })
+ svntest.actions.run_and_verify_merge(A_B1, None, None, '^/A/B', None,
+ expected_output, None, None, None, None,
+ expected_skip, [])
+ sbox.simple_commit()
+ sbox.simple_update()
# Reintegrate branch-1 subtree to trunk subtree
run_reintegrate('^/A/B1/E', sbox.ospath('A/B/E'))
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
- svntest.main.run_svn(None, 'update', wc_dir)
+ sbox.simple_commit()
+ sbox.simple_update()
# Merge trunk to branch-2
- svntest.main.run_svn(None, 'merge', '^/A/B', sbox.ospath('A/B2'))
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+ #svntest.main.run_svn(None, 'merge', '^/A/B', sbox.ospath('A/B2'))
+ A_B2 = sbox.ospath('A/B2')
+ expected_output = wc.State(A_B2, {
+ 'E' : Item(status=' U'),
+ 'E/alpha' : Item(status='U '),
+ })
+ expected_skip = wc.State(A_B1, { })
+ svntest.actions.run_and_verify_merge(A_B2, None, None, '^/A/B', None,
+ expected_output, None, None, None, None,
+ expected_skip, [])
+ sbox.simple_commit()
svntest.main.run_svn(None, 'update', wc_dir)
# Reverse merge branch-1 subtree to branch-2 subtree, this removes
# the subtree mergeinfo from branch 2
- svntest.main.run_svn(None, 'merge', '-r8:2',
- '^/A/B1/E', sbox.ospath('A/B2/E'))
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+ #svntest.main.run_svn(None, 'merge', '-r8:2',
+ # '^/A/B1/E', sbox.ospath('A/B2/E'))
+ A_B2_E = sbox.ospath('A/B2/E')
+ expected_output = wc.State(A_B2_E, {
+ 'alpha' : Item(status='U '),
+ })
+ expected_skip = wc.State(A_B2_E, { })
+ svntest.actions.run_and_verify_merge(A_B2_E, 8, 2, '^/A/B1/E', None,
+ expected_output, None, None, None, None,
+ expected_skip, [])
+ sbox.simple_commit()
svntest.main.run_svn(None, 'update', wc_dir)
# Verify that merge results in no subtree mergeinfo
@@ -2525,8 +2558,8 @@ def no_source_subtree_mergeinfo(sbox):
# Merge trunk to branch-2
svntest.main.run_svn(None, 'merge', '^/A/B', sbox.ospath('A/B2'))
- svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
- svntest.main.run_svn(None, 'update', wc_dir)
+ sbox.simple_commit()
+ sbox.simple_update()
# Verify that there is still no subtree mergeinfo
svntest.actions.run_and_verify_svn([], expected_stderr,
@@ -2550,7 +2583,9 @@ def no_source_subtree_mergeinfo(sbox):
'' : Item(props={SVN_PROP_MERGEINFO : '/A/B2:4-12'}),
'E' : Item(),
'E/alpha' : Item("AAA\n" +
+ "X\n" +
"BBB\n" +
+ "Y\n" +
"CCCxx\n"),
'E/beta' : Item("This is the file 'beta'.\n"),
'F' : Item(),
Modified: subversion/branches/authzperf/subversion/tests/cmdline/merge_tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/merge_tree_conflict_tests.py (original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/merge_tree_conflict_tests.py Fri Apr 29 18:38:53 2016
@@ -2192,6 +2192,112 @@ def merge_obstruction_recording(sbox):
# A resolver action could be smarter though...
+def added_revision_recording_in_tree_conflict(sbox):
+ "tree conflict stores added revision for victim"
+
+ sbox.build(empty=True)
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_mkdir('trunk')
+ sbox.simple_commit() #r1
+
+ # Create a branch
+ svntest.actions.run_and_verify_svn(None, [],
+ 'copy', sbox.repo_url + '/trunk',
+ sbox.repo_url + '/branch',
+ '-mcopy') # r2
+
+ sbox.simple_add_text('The file on trunk\n', 'trunk/foo')
+ sbox.simple_commit() #r3
+
+ sbox.simple_update()
+
+ # Merge ^/trunk into ^/branch
+ expected_output = svntest.wc.State(sbox.ospath('branch'), {
+ 'foo' : Item(status='A '),
+ })
+ expected_mergeinfo_output = wc.State(sbox.ospath('branch'), {
+ '' : Item(status=' U')
+ })
+ expected_elision_output = wc.State(wc_dir, {
+ })
+ expected_disk = wc.State('', {
+ 'foo' : Item(contents="The file on trunk\n"),
+ '.' : Item(props={u'svn:mergeinfo': u'/trunk:2-3'}),
+ })
+ expected_status = wc.State(sbox.ospath('branch'), {
+ '' : Item(status=' M', wc_rev='3'),
+ 'foo' : Item(status='A ', copied='+', wc_rev='-'),
+ })
+ expected_skip = wc.State('', {
+ })
+ svntest.actions.run_and_verify_merge(sbox.ospath('branch'), None, None,
+ sbox.repo_url + '/trunk',
+ None,
+ expected_output,
+ expected_mergeinfo_output,
+ expected_elision_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ check_props=True)
+
+ sbox.simple_commit() #r4
+
+ # Edit the file on the branch
+ sbox.simple_append('branch/foo', 'The file on the branch\n')
+ sbox.simple_commit() #r5
+
+ # Replace file with a directory on trunk
+ sbox.simple_rm('trunk/foo')
+ sbox.simple_mkdir('trunk/foo')
+ sbox.simple_commit() #r6
+
+ sbox.simple_update()
+
+ # Merge ^/trunk into ^/branch
+ expected_output = svntest.wc.State(sbox.ospath('branch'), {
+ 'foo' : Item(status=' ', treeconflict='C')
+ })
+ expected_mergeinfo_output = wc.State(sbox.ospath('branch'), {
+ '' : Item(status=' U'),
+ })
+ expected_elision_output = wc.State(wc_dir, {
+ })
+ expected_disk = wc.State('', {
+ 'foo' : Item(contents="The file on trunk\nThe file on the branch\n"),
+ '.' : Item(props={u'svn:mergeinfo': u'/trunk:2-6'}),
+ })
+ expected_status = wc.State(sbox.ospath('branch'), {
+ '' : Item(status=' M', wc_rev='6'),
+ 'foo' : Item(status=' ', treeconflict='C', wc_rev='6'),
+ })
+ expected_skip = wc.State('', {
+ })
+ svntest.actions.run_and_verify_merge(sbox.ospath('branch'), None, None,
+ sbox.repo_url + '/trunk',
+ None,
+ expected_output,
+ expected_mergeinfo_output,
+ expected_elision_output,
+ expected_disk,
+ expected_status,
+ expected_skip,
+ check_props=True)
+
+ # Ensure that revisions in tree conflict info match what we expect.
+ # We used to record source left as ^/trunk/foo@1 instead of ^/trunk/foo@3.
+ # Note that foo was first added in r3.
+ expected_info = [
+ {
+ "Path" : re.escape(sbox.ospath('branch/foo')),
+ "Tree conflict": re.escape(
+ 'local file edit, incoming replace with dir upon merge' +
+ ' Source left: (file) ^/trunk/foo@3' +
+ ' Source right: (dir) ^/trunk/foo@6'),
+ },
+ ]
+ svntest.actions.run_and_verify_info(expected_info, sbox.ospath('branch/foo'))
########################################################################
# Run the tests
@@ -2225,6 +2331,7 @@ test_list = [ None,
merge_replace_on_del_fails,
merge_conflict_details,
merge_obstruction_recording,
+ added_revision_recording_in_tree_conflict,
]
if __name__ == '__main__':