You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2018/11/07 12:30:11 UTC
svn commit: r1846002 [40/44] - in /subversion/branches/ra-git: ./ build/
build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/generator/util/ build/win32/
contrib/client-side/ contrib/client-side/svn_load_dirs/ contr...
Modified: subversion/branches/ra-git/subversion/tests/libsvn_client/mtcc-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_client/mtcc-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_client/mtcc-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_client/mtcc-test.c Wed Nov 7 12:30:06 2018
@@ -783,6 +783,35 @@ test_iprops_path_format(const svn_test_o
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_move_and_delete_ancestor(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_client__mtcc_t *mtcc;
+ svn_client_ctx_t *ctx;
+ const char *repos_url;
+
+ SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-move-and-delete",
+ opts, pool, pool));
+
+ SVN_ERR(make_greek_tree(repos_url, pool));
+
+ SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
+ SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool));
+
+ SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
+
+ SVN_ERR(svn_client__mtcc_add_move("A/B", "B", mtcc, pool));
+ SVN_ERR(svn_client__mtcc_add_move("A/mu", "mu", mtcc, pool));
+ SVN_ERR(svn_client__mtcc_add_delete("A", mtcc, pool));
+
+ SVN_ERR(verify_mtcc_commit(mtcc, 2, pool));
+
+ return SVN_NO_ERROR;
+
+}
+
+
/* ========================================================================== */
@@ -811,6 +840,8 @@ static struct svn_test_descriptor_t test
"test ra_get_file_revs2 both ways"),
SVN_TEST_OPTS_PASS(test_iprops_path_format,
"test iprops url format"),
+ SVN_TEST_OPTS_PASS(test_move_and_delete_ancestor,
+ "test move and delete ancestor (issue 4666)"),
SVN_TEST_NULL
};
Propchange: subversion/branches/ra-git/subversion/tests/libsvn_delta/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Nov 7 12:30:06 2018
@@ -8,6 +8,7 @@ vdelta-test
random-test
xml-output-test
svndiff-test
+svndiff-stream-test
window-test
editor-test
combined
Modified: subversion/branches/ra-git/subversion/tests/libsvn_delta/random-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_delta/random-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_delta/random-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_delta/random-test.c Wed Nov 7 12:30:06 2018
@@ -41,7 +41,7 @@
#include "delta-window-test.h"
-#define DEFAULT_ITERATIONS 30
+#define DEFAULT_ITERATIONS 60
#define DEFAULT_MAXLEN (100 * 1024)
#define DEFAULT_DUMP_FILES 0
#define DEFAULT_PRINT_WINDOWS 0
@@ -329,9 +329,9 @@ do_random_test(apr_pool_t *pool,
delta_pool);
/* Make stage 2: encode the text delta in svndiff format using
- varying compression levels. */
- svn_txdelta_to_svndiff3(&handler, &handler_baton, stream, 1, i % 10,
- delta_pool);
+ varying svndiff versions and compression levels. */
+ svn_txdelta_to_svndiff3(&handler, &handler_baton, stream, i % 3,
+ i % 10, delta_pool);
/* Make stage 1: create the text delta. */
svn_txdelta2(&txdelta_stream,
@@ -425,9 +425,9 @@ do_random_combine_test(apr_pool_t *pool,
delta_pool);
/* Make stage 2: encode the text delta in svndiff format using
- varying compression levels. */
- svn_txdelta_to_svndiff3(&handler, &handler_baton, stream, 1, i % 10,
- delta_pool);
+ varying svndiff versions and compression levels. */
+ svn_txdelta_to_svndiff3(&handler, &handler_baton, stream, i % 3,
+ i % 10, delta_pool);
/* Make stage 1: create the text deltas. */
@@ -515,6 +515,96 @@ random_combine_test(apr_pool_t *pool)
}
+/* (Note: *LAST_SEED is an output parameter.) */
+static svn_error_t *
+do_random_txdelta_to_svndiff_stream_test(apr_pool_t *pool,
+ apr_uint32_t *last_seed)
+{
+ apr_uint32_t seed;
+ apr_uint32_t maxlen;
+ apr_size_t bytes_range;
+ int i;
+ int iterations;
+ int dump_files;
+ int print_windows;
+ const char *random_bytes;
+ apr_pool_t *iterpool;
+
+ /* Initialize parameters and print out the seed in case we dump core
+ or something. */
+ init_params(&seed, &maxlen, &iterations, &dump_files, &print_windows,
+ &random_bytes, &bytes_range, pool);
+
+ iterpool = svn_pool_create(pool);
+ for (i = 0; i < iterations; i++)
+ {
+ apr_uint32_t subseed_base;
+ apr_file_t *source;
+ apr_file_t *target;
+ apr_file_t *source_copy;
+ apr_file_t *new_target;
+ svn_txdelta_stream_t *txstream;
+ svn_stream_t *delta_stream;
+ svn_txdelta_window_handler_t handler;
+ void *handler_baton;
+ svn_stream_t *push_stream;
+
+ svn_pool_clear(iterpool);
+
+ /* Generate source and target for the delta and its application. */
+ *last_seed = seed;
+ subseed_base = svn_test_rand(&seed);
+ source = generate_random_file(maxlen, subseed_base, &seed,
+ random_bytes, bytes_range,
+ dump_files, iterpool);
+ target = generate_random_file(maxlen, subseed_base, &seed,
+ random_bytes, bytes_range,
+ dump_files, iterpool);
+ source_copy = copy_tempfile(source, iterpool);
+ new_target = open_tempfile(NULL, iterpool);
+
+ /* Create a txdelta stream that turns the source into target;
+ turn it into a generic readable svn_stream_t. */
+ svn_txdelta2(&txstream,
+ svn_stream_from_aprfile2(source, TRUE, iterpool),
+ svn_stream_from_aprfile2(target, TRUE, iterpool),
+ FALSE, iterpool);
+ delta_stream = svn_txdelta_to_svndiff_stream(txstream, i % 3, i % 10,
+ iterpool);
+
+ /* Apply it to a copy of the source file to see if we get the
+ same target back. */
+ svn_txdelta_apply(svn_stream_from_aprfile2(source_copy, TRUE, iterpool),
+ svn_stream_from_aprfile2(new_target, TRUE, iterpool),
+ NULL, NULL, iterpool, &handler, &handler_baton);
+ push_stream = svn_txdelta_parse_svndiff(handler, handler_baton, TRUE,
+ iterpool);
+ SVN_ERR(svn_stream_copy3(delta_stream, push_stream, NULL, NULL,
+ iterpool));
+
+ SVN_ERR(compare_files(target, new_target, dump_files));
+
+ apr_file_close(source);
+ apr_file_close(target);
+ apr_file_close(source_copy);
+ apr_file_close(new_target);
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+/* Implements svn_test_driver_t. */
+static svn_error_t *
+random_txdelta_to_svndiff_stream_test(apr_pool_t *pool)
+{
+ apr_uint32_t seed;
+ svn_error_t *err = do_random_txdelta_to_svndiff_stream_test(pool, &seed);
+ if (err)
+ fprintf(stderr, "SEED: %lu\n", (unsigned long)seed);
+ return err;
+}
+
/* Change to 1 to enable the unit test for the delta combiner's range index: */
#if 0
#include "range-index-test.h"
@@ -533,6 +623,8 @@ static struct svn_test_descriptor_t test
"random delta test"),
SVN_TEST_PASS2(random_combine_test,
"random combine delta test"),
+ SVN_TEST_PASS2(random_txdelta_to_svndiff_stream_test,
+ "random txdelta to svndiff stream test"),
#ifdef SVN_RANGE_INDEX_TEST_H
SVN_TEST_PASS2(random_range_index_test,
"random range index test"),
Modified: subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c Wed Nov 7 12:30:06 2018
@@ -2407,8 +2407,6 @@ merge_with_part_already_present(apr_pool
/* Merge is more "aggressive" about resolving conflicts than traditional
* patch or diff3. Some people consider this behaviour to be a bug, see
* http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=35014
- *
- * The original behavior of this test (added in 2003) was tweaked in 2016.
*/
static svn_error_t *
merge_adjacent_changes(apr_pool_t *pool)
@@ -2430,13 +2428,8 @@ merge_adjacent_changes(apr_pool_t *pool)
"zig\n"
"foo\n"
- "<<<<<<< adj2\n"
"new_bar\n"
- "baz\n"
- "=======\n"
- "bar\n"
- "new_baz\n"
- ">>>>>>> adj3\n",
+ "new_baz\n",
NULL,
svn_diff_conflict_display_modified_latest,
@@ -3003,8 +2996,6 @@ three_way_double_add(apr_pool_t *pool)
"D\n" /* New line 1a */
"E\n" /* New line 2a */
"F\n" /* New line 3a*/
- "||||||| doubleadd1\n"
- "C\n"
"=======\n"
"O\n"
"P\n" /* New line 1b */
@@ -3018,7 +3009,7 @@ three_way_double_add(apr_pool_t *pool)
svn_diff_conflict_display_modified_original_latest,
pool));
- SVN_ERR(three_way_merge("doubleadd4", "doubleadd5", "doubleadd6",
+ SVN_ERR(three_way_merge("doubleadd1", "doubleadd2", "doubleadd3",
"A\n"
"B\n"
"C\n"
@@ -3053,21 +3044,18 @@ three_way_double_add(apr_pool_t *pool)
will be a PASS. */
"A\n"
"B\n"
- "<<<<<<< doubleadd5\n"
+ "<<<<<<< doubleadd2\n"
"C\n"
"D\n" /* New line 1a */
"E\n" /* New line 2a */
"F\n" /* New line 3a*/
- "||||||| doubleadd4\n"
- "C\n"
- "J\n"
"=======\n"
"O\n"
"P\n" /* New line 1b */
"Q\n" /* New line 2b */
"R\n" /* New line 3b */
"J\n"
- ">>>>>>> doubleadd6\n"
+ ">>>>>>> doubleadd3\n"
"K\n"
"L",
NULL,
@@ -3119,7 +3107,7 @@ static struct svn_test_descriptor_t test
"2-way issue #3362 test v1"),
SVN_TEST_PASS2(two_way_issue_3362_v2,
"2-way issue #3362 test v2"),
- SVN_TEST_PASS2(three_way_double_add,
+ SVN_TEST_XFAIL2(three_way_double_add,
"3-way merge, double add"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c Wed Nov 7 12:30:06 2018
@@ -40,6 +40,7 @@
#include "svn_version.h"
#include "svn_private_config.h"
+#include "private/svn_cache.h"
#include "private/svn_fs_util.h"
#include "private/svn_fs_private.h"
#include "private/svn_fspath.h"
@@ -7187,6 +7188,187 @@ commit_with_locked_rep_cache(const svn_t
return SVN_NO_ERROR;
}
+
+static svn_error_t *
+test_cache_clear_during_stream(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root, *rev_root;
+ svn_revnum_t new_rev;
+ const char *fs_path;
+ apr_pool_t *iterpool = svn_pool_create(pool);
+ apr_pool_t *subpool = svn_pool_create(pool);
+ svn_txdelta_window_handler_t consumer_func;
+ void *consumer_baton;
+ int i;
+ svn_stream_t *stream;
+ svn_stringbuf_t *buf;
+
+
+ fs_path = "test-repo-cache_clear_during_stream";
+ SVN_ERR(svn_test__create_fs(&fs, fs_path, opts, pool));
+
+ /* r1: Add a file. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "/foo", pool));
+
+ /* Make the file large enough to span multiple txdelta windows.
+ * Just to be sure, make it not too uniform to keep self-txdelta at bay. */
+ SVN_ERR(svn_fs_apply_textdelta(&consumer_func, &consumer_baton,
+ txn_root, "/foo", NULL, NULL, subpool));
+ stream = svn_txdelta_target_push(consumer_func, consumer_baton,
+ svn_stream_empty(subpool), subpool);
+ for (i = 0; i < 10000; ++ i)
+ {
+ svn_string_t *text;
+
+ svn_pool_clear(iterpool);
+ text = svn_string_createf(iterpool, "some dummy text - %d\n", i);
+ SVN_ERR(svn_stream_write(stream, text->data, &text->len));
+ }
+
+ SVN_ERR(svn_stream_close(stream));
+ svn_pool_destroy(subpool);
+
+ SVN_ERR(test_commit_txn(&new_rev, txn, NULL, pool));
+ SVN_TEST_INT_ASSERT(new_rev, 1);
+
+ /* Read the file once to populate the fulltext cache. */
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, 1, pool));
+ SVN_ERR(svn_fs_file_contents(&stream, rev_root, "/foo", pool));
+ SVN_ERR(svn_test__stream_to_string(&buf, stream, pool));
+
+ /* Start reading it again from cache, clear the cache and continue.
+ * Make sure we read more than one txdelta window before clearing
+ * the cache. That gives the FS backend a chance to skip windows
+ * when continuing the read from disk. */
+ SVN_ERR(svn_fs_file_contents(&stream, rev_root, "/foo", pool));
+ buf->len = 2 * SVN_STREAM_CHUNK_SIZE;
+ SVN_ERR(svn_stream_read_full(stream, buf->data, &buf->len));
+ SVN_ERR(svn_cache__membuffer_clear(svn_cache__get_global_membuffer_cache()));
+ SVN_ERR(svn_test__stream_to_string(&buf, stream, pool));
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_rep_sharing_strict_content_check(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_revnum_t new_rev;
+ const char *fs_path, *fs_path2;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ svn_error_t *err;
+
+ /* Bail (with success) on known-untestable scenarios */
+ if (strcmp(opts->fs_type, SVN_FS_TYPE_BDB) == 0)
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "BDB repositories don't support rep-sharing");
+
+ /* Create 2 repos with same structure & size but different contents */
+ fs_path = "test-rep-sharing-strict-content-check1";
+ fs_path2 = "test-rep-sharing-strict-content-check2";
+
+ SVN_ERR(svn_test__create_fs(&fs, fs_path, opts, subpool));
+
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, subpool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
+ SVN_ERR(svn_fs_make_file(txn_root, "/foo", subpool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "foo", "quite bad", subpool));
+ SVN_ERR(test_commit_txn(&new_rev, txn, NULL, subpool));
+ SVN_TEST_INT_ASSERT(new_rev, 1);
+
+ SVN_ERR(svn_test__create_fs(&fs, fs_path2, opts, subpool));
+
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, subpool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
+ SVN_ERR(svn_fs_make_file(txn_root, "foo", subpool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "foo", "very good", subpool));
+ SVN_ERR(test_commit_txn(&new_rev, txn, NULL, subpool));
+ SVN_TEST_INT_ASSERT(new_rev, 1);
+
+ /* Close both repositories. */
+ svn_pool_clear(subpool);
+
+ /* Doctor the first repo such that it uses the wrong rep-cache. */
+ SVN_ERR(svn_io_copy_file(svn_relpath_join(fs_path2, "rep-cache.db", pool),
+ svn_relpath_join(fs_path, "rep-cache.db", pool),
+ FALSE, pool));
+
+ /* Changing the file contents such that rep-sharing would kick in if
+ the file contents was not properly compared. */
+ SVN_ERR(svn_fs_open2(&fs, fs_path, NULL, subpool, subpool));
+
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 1, 0, subpool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
+ err = svn_test__set_file_contents(txn_root, "foo", "very good", subpool);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_AMBIGUOUS_CHECKSUM_REP);
+
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+closest_copy_test_svn_4677(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root, *rev_root, *croot;
+ svn_revnum_t after_rev;
+ const char *cpath;
+ apr_pool_t *spool = svn_pool_create(pool);
+
+ /* Prepare a filesystem. */
+ SVN_ERR(svn_test__create_fs(&fs, "test-repo-svn-4677",
+ opts, pool));
+
+ /* In first txn, create file A/foo. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, spool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, spool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "A", spool));
+ SVN_ERR(svn_fs_make_file(txn_root, "A/foo", spool));
+ SVN_ERR(test_commit_txn(&after_rev, txn, NULL, spool));
+ svn_pool_clear(spool);
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, spool));
+
+ /* Move A to B, and commit. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, spool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, spool));
+ SVN_ERR(svn_fs_copy(rev_root, "A", txn_root, "B", spool));
+ SVN_ERR(svn_fs_delete(txn_root, "A", spool));
+ SVN_ERR(test_commit_txn(&after_rev, txn, NULL, spool));
+ svn_pool_clear(spool);
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, spool));
+
+ /* Replace file B/foo with directory B/foo, add B/foo/bar, and commit. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, spool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, spool));
+ SVN_ERR(svn_fs_delete(txn_root, "B/foo", spool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "B/foo", spool));
+ SVN_ERR(svn_fs_make_file(txn_root, "B/foo/bar", spool));
+ SVN_ERR(test_commit_txn(&after_rev, txn, NULL, spool));
+ svn_pool_clear(spool);
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, spool));
+
+ /* B/foo/bar has been copied.
+ Issue 4677 was caused by returning an error in this situation. */
+ SVN_ERR(svn_fs_closest_copy(&croot, &cpath, rev_root, "B/foo/bar", spool));
+ SVN_TEST_ASSERT(cpath == NULL);
+ SVN_TEST_ASSERT(croot == NULL);
+
+ return SVN_NO_ERROR;
+}
+
/* ------------------------------------------------------------------------ */
/* The test table. */
@@ -7325,6 +7507,12 @@ static struct svn_test_descriptor_t test
"test reading a large changed paths list"),
SVN_TEST_OPTS_PASS(commit_with_locked_rep_cache,
"test commit with locked rep-cache"),
+ SVN_TEST_OPTS_PASS(test_cache_clear_during_stream,
+ "test clearing the cache while streaming a rep"),
+ SVN_TEST_OPTS_PASS(test_rep_sharing_strict_content_check,
+ "test rep-sharing on content rather than SHA1"),
+ SVN_TEST_OPTS_PASS(closest_copy_test_svn_4677,
+ "test issue SVN-4677 regression"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c Wed Nov 7 12:30:06 2018
@@ -1631,8 +1631,8 @@ delta_chain_with_plain(const svn_test_op
svn_hash_sets(props, "p", svn_string_create(prop_value->data, pool));
hash_rep = svn_stringbuf_create_empty(pool);
- svn_hash_write2(props, svn_stream_from_stringbuf(hash_rep, pool), "END",
- pool);
+ SVN_ERR(svn_hash_write2(props, svn_stream_from_stringbuf(hash_rep, pool),
+ "END", pool));
SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
SVN_ERR(svn_fs_txn_root(&root, txn, pool));
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c Wed Nov 7 12:30:06 2018
@@ -85,8 +85,10 @@ verify_representation_stats(const svn_fs
SVN_TEST_ASSERT(stats->total.count == expected_count);
SVN_TEST_ASSERT( stats->total.packed_size >= 10 * expected_count
&& stats->total.packed_size <= 1000 * expected_count);
- SVN_TEST_ASSERT( stats->total.packed_size >= stats->total.expanded_size
- && stats->total.packed_size <= 2 * stats->total.expanded_size);
+ /* Expect the packed size to be sane, keeping in mind that it might
+ * be less or more than the expanded size due differences in the
+ * compression algorithms or options such as directory deltification. */
+ SVN_TEST_ASSERT(stats->total.packed_size <= 2 * stats->total.expanded_size);
SVN_TEST_ASSERT( stats->total.overhead_size >= 5 * expected_count
&& stats->total.overhead_size <= 100 * expected_count);
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c Wed Nov 7 12:30:06 2018
@@ -870,7 +870,7 @@ test_batch_fsync(const svn_test_opts_t *
/* Initialize infrastructure with a pool that lives as long as this
* application. */
- SVN_ERR(svn_fs_x__batch_fsync_init());
+ SVN_ERR(svn_fs_x__batch_fsync_init(pool));
/* We use and re-use the same batch object throughout this test. */
SVN_ERR(svn_fs_x__batch_fsync_create(&batch, TRUE, pool));
Modified: subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c Wed Nov 7 12:30:06 2018
@@ -427,17 +427,7 @@ lock_cb(void *baton,
struct lock_result_t *result = apr_palloc(b->pool,
sizeof(struct lock_result_t));
- if (lock)
- {
- result->lock = apr_palloc(b->pool, sizeof(svn_lock_t));
- *result->lock = *lock;
- result->lock->path = apr_pstrdup(b->pool, lock->path);
- result->lock->token = apr_pstrdup(b->pool, lock->token);
- result->lock->owner = apr_pstrdup(b->pool, lock->owner);
- result->lock->comment = apr_pstrdup(b->pool, lock->comment);
- }
- else
- result->lock = NULL;
+ result->lock = svn_lock_dup(lock, b->pool);
result->err = ra_err;
svn_hash_sets(b->results, apr_pstrdup(b->pool, path), result);
@@ -1682,6 +1672,118 @@ commit_empty_last_change(const svn_test_
return SVN_NO_ERROR;
}
+static svn_error_t *
+commit_locked_file(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ const char *url;
+ svn_ra_callbacks2_t *cbtable;
+ svn_ra_session_t *session;
+ const svn_delta_editor_t *editor;
+ void *edit_baton;
+ void *root_baton;
+ void *file_baton;
+ struct lock_result_t *lock_result;
+ apr_hash_t *lock_tokens;
+ svn_txdelta_window_handler_t handler;
+ void *handler_baton;
+ svn_revnum_t fetched_rev;
+ apr_hash_t *fetched_props;
+ const svn_string_t *propval;
+
+ SVN_ERR(svn_test__create_repos2(NULL, &url, NULL,
+ "test-repo-commit-locked-file-test",
+ opts, pool, pool));
+
+ SVN_ERR(svn_ra_initialize(pool));
+ SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
+ SVN_ERR(svn_test__init_auth_baton(&cbtable->auth_baton, pool));
+
+ SVN_ERR(svn_ra_open4(&session, NULL, url, NULL, cbtable,
+ NULL, NULL, pool));
+ SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+ apr_hash_make(pool),
+ NULL, NULL, NULL, TRUE, pool));
+ /* Add a file. */
+ SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
+ pool, &root_baton));
+ SVN_ERR(editor->add_file("file", root_baton, NULL, SVN_INVALID_REVNUM,
+ pool, &file_baton));
+ SVN_ERR(editor->close_file(file_baton, NULL, pool));
+ SVN_ERR(editor->close_directory(root_baton, pool));
+ SVN_ERR(editor->close_edit(edit_baton, pool));
+
+ /* Acquire a lock on this file. */
+ {
+ struct lock_baton_t baton = {0};
+ svn_revnum_t rev = 1;
+ apr_hash_t *lock_targets;
+
+ baton.results = apr_hash_make(pool);
+ baton.pool = pool;
+
+ lock_targets = apr_hash_make(pool);
+ svn_hash_sets(lock_targets, "file", &rev);
+ SVN_ERR(svn_ra_lock(session, lock_targets, "comment", FALSE,
+ lock_cb, &baton, pool));
+
+ SVN_ERR(expect_lock("file", baton.results, session, pool));
+ lock_result = svn_hash_gets(baton.results, "file");
+ }
+
+ /* Open a new session using the file parent's URL. */
+ SVN_ERR(svn_ra_open4(&session, NULL, url, NULL, cbtable,
+ NULL, NULL, pool));
+
+ /* Create a new commit editor supplying our lock token. */
+ lock_tokens = apr_hash_make(pool);
+ svn_hash_sets(lock_tokens, "file", lock_result->lock->token);
+ SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+ apr_hash_make(pool), NULL, NULL,
+ lock_tokens, TRUE, pool));
+ /* Edit the locked file. */
+ SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
+ pool, &root_baton));
+ SVN_ERR(editor->open_file("file", root_baton, SVN_INVALID_REVNUM, pool,
+ &file_baton));
+ SVN_ERR(editor->apply_textdelta(file_baton, NULL, pool, &handler,
+ &handler_baton));
+ SVN_ERR(svn_txdelta_send_string(svn_string_create("A", pool),
+ handler, handler_baton, pool));
+ SVN_ERR(editor->close_file(file_baton, NULL, pool));
+ SVN_ERR(editor->close_directory(root_baton, pool));
+ SVN_ERR(editor->close_edit(edit_baton, pool));
+
+ /* Check the result. */
+ SVN_ERR(svn_ra_get_file(session, "file", SVN_INVALID_REVNUM, NULL,
+ &fetched_rev, NULL, pool));
+ SVN_TEST_INT_ASSERT((int) fetched_rev, 2);
+
+ /* Change property of the locked file. */
+ SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+ apr_hash_make(pool), NULL, NULL,
+ lock_tokens, TRUE, pool));
+ SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
+ pool, &root_baton));
+ SVN_ERR(editor->open_file("file", root_baton, SVN_INVALID_REVNUM, pool,
+ &file_baton));
+ SVN_ERR(editor->change_file_prop(file_baton, "propname",
+ svn_string_create("propval", pool),
+ pool));
+ SVN_ERR(editor->close_file(file_baton, NULL, pool));
+ SVN_ERR(editor->close_directory(root_baton, pool));
+ SVN_ERR(editor->close_edit(edit_baton, pool));
+
+ /* Check the result. */
+ SVN_ERR(svn_ra_get_file(session, "file", SVN_INVALID_REVNUM, NULL,
+ &fetched_rev, &fetched_props, pool));
+ SVN_TEST_INT_ASSERT((int) fetched_rev, 3);
+ propval = svn_hash_gets(fetched_props, "propname");
+ SVN_TEST_ASSERT(propval);
+ SVN_TEST_STRING_ASSERT(propval->data, "propval");
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
@@ -1716,6 +1818,8 @@ static struct svn_test_descriptor_t test
"verify checkout over a tunnel"),
SVN_TEST_OPTS_PASS(commit_empty_last_change,
"check how last change applies to empty commit"),
+ SVN_TEST_OPTS_PASS(commit_locked_file,
+ "check commit editor for a locked file"),
SVN_TEST_NULL
};
Propchange: subversion/branches/ra-git/subversion/tests/libsvn_repos/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Nov 7 12:30:06 2018
@@ -11,3 +11,4 @@ md5args
.*~
*.exe
dump-load-test
+authz-test
Modified: subversion/branches/ra-git/subversion/tests/libsvn_repos/dump-load-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_repos/dump-load-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_repos/dump-load-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_repos/dump-load-test.c Wed Nov 7 12:30:06 2018
@@ -79,9 +79,9 @@ test_dump_bad_props(svn_stringbuf_t **du
SVN_ERR(svn_repos_dump_fs4(repos, stream, start_rev, end_rev,
FALSE, FALSE, TRUE, TRUE,
notify_func, notify_baton,
- NULL, NULL,
+ NULL, NULL, NULL, NULL,
pool));
- svn_stream_close(stream);
+ SVN_ERR(svn_stream_close(stream));
/* Check that the property appears in the dump data */
expected_str = apr_psprintf(pool, "K %d\n%s\n"
@@ -120,17 +120,18 @@ test_load_bad_props(svn_stringbuf_t *dum
svn_revnum_t youngest_rev;
svn_string_t *loaded_prop_val;
- SVN_ERR(svn_repos_load_fs5(repos, stream,
+ SVN_ERR(svn_repos_load_fs6(repos, stream,
SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
svn_repos_load_uuid_default,
parent_fspath,
FALSE, FALSE, /*use_*_commit_hook*/
validate_props,
FALSE /*ignore_dates*/,
+ FALSE /*normalize_props*/,
notify_func, notify_baton,
NULL, NULL, /*cancellation*/
pool));
- svn_stream_close(stream);
+ SVN_ERR(svn_stream_close(stream));
/* Check the loaded property */
fs = svn_repos_fs(repos);
Modified: subversion/branches/ra-git/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_repos/repos-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_repos/repos-test.c Wed Nov 7 12:30:06 2018
@@ -22,7 +22,9 @@
#include <stdlib.h>
#include <string.h>
+
#include <apr_pools.h>
+#include <apr_time.h>
#include "../svn_test.h"
@@ -1282,7 +1284,7 @@ authz(apr_pool_t *pool)
contents =
"[greek:/A]" NL
"* = r" NL
- "plato = w" NL
+ "plato = rw" NL
"" NL
"[greek:/iota]" NL
"* =" NL
@@ -1381,11 +1383,536 @@ authz(apr_pool_t *pool)
SVN_TEST_ASSERT_ERROR(authz_get_handle(&authz_cfg, contents, FALSE, subpool),
SVN_ERR_AUTHZ_INVALID_CONFIG);
+ /* Verify that the rule on /dir2/secret doesn't affect this
+ request */
+ SVN_ERR(svn_repos_authz_check_access(authz_cfg, "greek",
+ "/dir", NULL,
+ (svn_authz_read
+ | svn_authz_recursive),
+ &access_granted, subpool));
+ if (!access_granted)
+ return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+ "Regression: incomplete ancestry test "
+ "for recursive access lookup.");
+
/* That's a wrap! */
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
+/* Test the supported authz wildcard variants. */
+static svn_error_t *
+test_authz_wildcards(apr_pool_t *pool)
+{
+ svn_authz_t *authz_cfg;
+
+ /* Some non-trivially overlapping wildcard rules, convering all types
+ * of wildcards: "any", "any-var", "prefix", "postfix" and "complex".
+ *
+ * Note that the rules are not in 1:1 correspondence to that enumeration.
+ */
+ const char *contents =
+ "[:glob:/**/G]" NL
+ "* = r" NL
+ "" NL
+ "[:glob:/A/*/G]" NL
+ "* =" NL
+ "" NL
+ "[:glob:/A/**/*a*]" NL
+ "* = r" NL
+ "" NL
+ "[:glob:/**/*a]" NL
+ "* = rw" NL
+ "" NL
+ "[:glob:/A/**/g*]" NL
+ "* =" NL
+ "" NL
+ "[:glob:/**/lambda]" NL
+ "* = rw" NL;
+
+ /* Definition of the paths to test and expected replies for each. */
+ struct check_access_tests test_set[] = {
+ /* Test that read rules are correctly used. */
+ { "/", NULL, NULL, svn_authz_read, FALSE }, /* default */
+ { "/iota", NULL, NULL, svn_authz_write, TRUE }, /* rule 4 */
+ { "/A", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/mu", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/B", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/B/lambda", NULL, NULL, svn_authz_write, TRUE }, /* rule 6 */
+ { "/A/B/E", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/B/E/alpha", NULL, NULL, svn_authz_write, TRUE }, /* rule 4 */
+ { "/A/B/E/beta", NULL, NULL, svn_authz_write, TRUE }, /* rule 4 */
+ { "/A/B/F", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/C", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/D", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/D/gamma", NULL, NULL, svn_authz_read, FALSE }, /* rule 5 */
+ { "/A/D/G", NULL, NULL, svn_authz_read, FALSE }, /* rule 2 */
+ { "/A/D/G/pi", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/D/G/rho", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/D/G/tau", NULL, NULL, svn_authz_read, TRUE }, /* rule 3 */
+ { "/A/D/G/tau", NULL, NULL, svn_authz_write, FALSE }, /* rule 3 */
+ { "/A/D/H", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/D/H/chi", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/D/H/psi", NULL, NULL, svn_authz_read, FALSE }, /* inherited */
+ { "/A/D/H/omega", NULL, NULL, svn_authz_write, TRUE }, /* rule 4 */
+ /* Non-greek tree paths: */
+ { "/A/G", NULL, NULL, svn_authz_read, TRUE }, /* rule 1 */
+ { "/A/G", NULL, NULL, svn_authz_write, FALSE }, /* rule 1 */
+ { "/A/G/G", NULL, NULL, svn_authz_read, FALSE }, /* rule 2 */
+ { "/G", NULL, NULL, svn_authz_read, TRUE }, /* rule 1 */
+ { "/G", NULL, NULL, svn_authz_write, FALSE }, /* rule 1 */
+ { "/Y/G", NULL, NULL, svn_authz_read, TRUE }, /* rule 1 */
+ { "/Y/G", NULL, NULL, svn_authz_write, FALSE }, /* rule 1 */
+ { "/X/Z/G", NULL, NULL, svn_authz_read, TRUE }, /* rule 1 */
+ { "/X/Z/G", NULL, NULL, svn_authz_write, FALSE }, /* rule 1 */
+ /* Rule 5 prevents recursive access anywhere below /A. */
+ { "/", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/iota", NULL, NULL, svn_authz_read | svn_authz_recursive, TRUE },
+ { "/iota", NULL, NULL, svn_authz_write | svn_authz_recursive, FALSE },
+ { "/A", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/mu", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/B", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/B/lambda", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/B/E", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/B/E/alpha", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/B/E/beta", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/B/F", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/C", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/gamma", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/G", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/G/pi", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/G/rho", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/G/tau", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/H", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/H/chi", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/H/psi", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D/H/omega", NULL, NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Load the test authz rules. */
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, FALSE, pool));
+
+ /* Loop over the test array and test each case. */
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Test the authz performance with wildcard rules. */
+static svn_error_t *
+test_authz_wildcard_performance(apr_pool_t *pool)
+{
+ svn_authz_t *authz_cfg;
+ svn_boolean_t access_granted;
+ int i, k;
+ apr_time_t start, end;
+
+ /* Some non-trivially overlapping wildcard rules, convering all types
+ * of wildcards: "any", "any-var", "prefix", "postfix" and "complex".
+ */
+ const char *contents =
+ "[:glob:greek:/A/*/G]" NL
+ "* =" NL
+ "" NL
+ "[:glob:greek:/A/**/*a*]" NL
+ "* = r" NL
+ "" NL
+ "[:glob:greek:/**/*a]" NL
+ "* = rw" NL
+ "" NL
+ "[:glob:greek:/A/**/g*]" NL
+ "* =" NL
+ "" NL
+ "[:glob:greek:/**/lambda]" NL
+ "* = rw" NL;
+
+ /* Load the test authz rules. */
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, FALSE, pool));
+
+ start = apr_time_now();
+ for (k = 0; k < 100000; ++k)
+ for (i = 1; i < 4; ++i)
+ {
+ const char **path;
+ const char *paths[] =
+ { "/iota",
+ "/A",
+ "/A/mu",
+ "/A/B",
+ "/A/B/lambda",
+ "/A/B/E",
+ "/A/B/E/alpha",
+ "/A/B/E/beta",
+ "/A/B/F",
+ "/A/C",
+ "/A/D",
+ "/A/D/gamma",
+ "/A/D/G",
+ "/A/D/G/pi",
+ "/A/D/G/rho",
+ "/A/D/G/tau",
+ "/A/D/H",
+ "/A/D/H/chi",
+ "/A/D/H/psi",
+ "/A/D/H/omega",
+ NULL
+ };
+
+ for (path = paths; *path; ++path)
+ SVN_ERR(svn_repos_authz_check_access(authz_cfg, "greek",
+ *path, NULL, i,
+ &access_granted, pool));
+ }
+
+ end = apr_time_now();
+ printf("%"APR_TIME_T_FMT" musecs\n", end - start);
+ printf("%"APR_TIME_T_FMT" checks / sec\n",
+ (k * (i - 1) * 20 * 1000000l) / (end - start));
+
+ return SVN_NO_ERROR;
+}
+
+/* Test that the latest definition wins, regardless of whether the ":glob:"
+ * prefix has been given. */
+static svn_error_t *
+test_authz_prefixes(apr_pool_t *pool)
+{
+ svn_authz_t *authz_cfg;
+ apr_pool_t *iterpool = svn_pool_create(pool);
+ int i, combi;
+
+ /* Set all rights at some folder and replace them again. Make sure to
+ * cover the "/" b/c that already has an implicit rule, so we* overwrite
+ * it twice. The first 2 string placeholders in the rules are for the
+ * repository name and the optional glob support marker. */
+ const char *contents_format =
+ "[%s%s%s]" NL
+ "* = r" NL
+ "plato = rw" NL
+ "" NL
+ "[%s%s%s]" NL
+ "* =" NL
+ "plato = r" NL;
+
+ /* The paths on which to apply this test. */
+ enum { PATH_COUNT = 2 };
+ const char *test_paths[PATH_COUNT] = { "/", "/A" };
+
+ /* Definition of the paths to test and expected replies for each. */
+ struct check_access_tests test_set1[] = {
+ /* Test that read rules are correctly used. */
+ { "", "greek", NULL, svn_authz_read, FALSE },
+ /* Test that write rules are correctly used. */
+ { "", "greek", "plato", svn_authz_read, TRUE },
+ { "", "greek", "plato", svn_authz_write, FALSE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* To be used when global rules are specified after per-repos rules.
+ * In that case, the global rules still win. */
+ struct check_access_tests test_set2[] = {
+ /* Test that read rules are correctly used. */
+ { "", "greek", NULL, svn_authz_read, TRUE },
+ { "", "greek", NULL, svn_authz_write, FALSE },
+ /* Test that write rules are correctly used. */
+ { "", "greek", "plato", svn_authz_read, TRUE },
+ { "", "greek", "plato", svn_authz_write, TRUE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* There is a total of 16 combinations of authz content. */
+ for (combi = 0; combi < 16; ++combi)
+ {
+ const char *contents;
+ const char *glob1 = (combi & 1) ? ":glob:" : "";
+ const char *glob2 = (combi & 2) ? ":glob:" : "";
+ const char *repo1 = (combi & 4) ? "greek:" : "";
+ const char *repo2 = (combi & 4) ? "" : "greek:";
+ const char *test_path = test_paths[combi / 8];
+ struct check_access_tests *test_set = (combi & 4) ? test_set2 : test_set1;
+
+ /* Create and parse the authz rules. */
+ svn_pool_clear(iterpool);
+ contents = apr_psprintf(iterpool, contents_format,
+ glob1, repo1, test_path,
+ glob2, repo2, test_path);
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, FALSE, iterpool));
+
+ /* iterate over all test paths */
+ for (i = combi / 8; i < PATH_COUNT; ++i)
+ {
+ /* Set the path for all test cases to the current test path. */
+ struct check_access_tests *test;
+ for (test = test_set; test->path != NULL; ++test)
+ test->path = test_paths[i];
+
+ /* Loop over the test array and test each case. */
+ SVN_ERR(authz_check_access(authz_cfg, test_set, iterpool));
+ }
+ }
+
+ /* That's a wrap! */
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_authz_recursive_override(apr_pool_t *pool)
+{
+ svn_authz_t *authz_cfg;
+
+ /* Set all rights at some folder and replace them again. Make sure to
+ * cover the "/" b/c that already has an implicit rule, so we* overwrite
+ * it twice. The first 2 string placeholders in the rules are for the
+ * repository name and the optional glob support marker. */
+ const char *contents =
+ "[:glob:/A/B]" NL
+ "plato = rw" NL
+ "" NL
+ "[:glob:/A/**]" NL
+ "plato = r" NL
+ "" NL
+ "[:glob:/B/C]" NL
+ "plato =" NL
+ "" NL
+ "[:glob:/B/**]" NL
+ "plato = rw" NL
+ "" NL
+ "[:glob:/C/D]" NL
+ "plato = rw" NL
+ "" NL
+ "[:glob:/C/**/E]" NL
+ "plato = r" NL
+ "" NL
+ "[:glob:/D/E]" NL
+ "plato = r" NL
+ "" NL
+ "[:glob:/D/**/F]" NL
+ "plato = rw" NL;
+
+ /* Definition of the paths to test and expected replies for each. */
+ struct check_access_tests test_set[] = {
+ /* The root shall not be affected -> defaults to "no access". */
+ { "/", NULL, "plato", svn_authz_read, FALSE },
+ /* Recursive restriction of rights shall work. */
+ { "/A", NULL, "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/A", NULL, "plato", svn_authz_write | svn_authz_recursive, FALSE },
+ /* Recursive extension of rights shall work. */
+ { "/B", NULL, "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/B", NULL, "plato", svn_authz_write | svn_authz_recursive, TRUE },
+ /* Partial replacements shall not result in recursive rights. */
+ { "/C", NULL, "plato", svn_authz_read | svn_authz_recursive, FALSE },
+ { "/C/D", NULL, "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/C/D", NULL, "plato", svn_authz_write | svn_authz_recursive, FALSE },
+ { "/D", NULL, "plato", svn_authz_read | svn_authz_recursive, FALSE },
+ { "/D/E", NULL, "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/D/E", NULL, "plato", svn_authz_write | svn_authz_recursive, FALSE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, FALSE, pool));
+
+ /* Loop over the test array and test each case. */
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* That's a wrap! */
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_authz_pattern_tests(apr_pool_t *pool)
+{
+ svn_authz_t *authz_cfg;
+
+ /* Rules will be considered for recursive access checks irrespective of
+ * whether the respective paths actually do exist. */
+ const char *contents =
+ "[:glob:/**/Yeti]" NL
+ "plato = r" NL
+ "" NL
+ "[/]" NL
+ "plato = r" NL
+ "" NL
+ "[/trunk]" NL
+ "plato = rw" NL;
+
+ /* Definition of the paths to test and expected replies for each. */
+ struct check_access_tests test_set[] = {
+ /* We have no recursive write access anywhere. */
+ { "/", NULL, "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/", NULL, "plato", svn_authz_write | svn_authz_recursive, FALSE },
+ { "/trunk", NULL, "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/trunk", NULL, "plato", svn_authz_write | svn_authz_recursive, FALSE },
+
+ /* We do have ordinary write access to anything under /trunk that is
+ * not a Yeti. */
+ { "/trunk", NULL, "plato", svn_authz_write, TRUE },
+ { "/trunk/A/B/C", NULL, "plato", svn_authz_write, TRUE },
+
+ /* We don't have write access to Yetis. */
+ { "/trunk/A/B/C/Yeti", NULL, "plato", svn_authz_write, FALSE },
+ { "/trunk/Yeti", NULL, "plato", svn_authz_write, FALSE },
+ { "/Yeti", NULL, "plato", svn_authz_write, FALSE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Global override via "**" and selective override for a specific path. */
+ const char *contents2 =
+ "[:glob:/X]" NL
+ "user1 =" NL
+ "" NL
+ "[:glob:/X/**]" NL
+ "user1 = rw" NL
+ "user2 = rw" NL
+ "" NL
+ "[:glob:/X/Y/Z]" NL
+ "user2 =" NL;
+
+ /* Definition of the paths to test and expected replies for each. */
+ struct check_access_tests test_set2[] = {
+ /* No access at the root*/
+ { "/", NULL, "user1", svn_authz_read, FALSE },
+ { "/", NULL, "user2", svn_authz_read, FALSE },
+
+ /* User 1 has recursive write access anywhere. */
+ { "/X", NULL, "user1", svn_authz_write | svn_authz_recursive, TRUE },
+ { "/X/Y", NULL, "user1", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/X/Y/Z", NULL, "user1", svn_authz_read | svn_authz_recursive, TRUE },
+
+ /* User 2 only has recursive read access to X/Y/Z. */
+ { "/X", NULL, "user1", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/X", NULL, "user2", svn_authz_write | svn_authz_recursive, FALSE },
+ { "/X/Y", NULL, "user2", svn_authz_write | svn_authz_recursive, FALSE },
+ { "/X/Y/Z", NULL, "user2", svn_authz_write | svn_authz_recursive, FALSE },
+
+ /* However, user2 has ordinary write access X and recursive write access
+ * to anything not in X/Y/Z. */
+ { "/X", NULL, "user2", svn_authz_write, TRUE },
+ { "/X/A", NULL, "user2", svn_authz_write | svn_authz_recursive, TRUE },
+ { "/X/Y/A", NULL, "user2", svn_authz_write | svn_authz_recursive, TRUE },
+
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Global patterns vs. global path rules. */
+ const char *contents3 =
+ "[groups]" NL
+ "Team1 = user1" NL
+ "Team2 = user1, user2" NL
+ "" NL
+ "[/]" NL
+ "* =" NL
+ "" NL
+ "[:glob:Repo1:/**/folder*]" NL
+ "@Team1 = rw" NL
+ "" NL
+ "[Repo2:/]" NL
+ "@Team2 = r" NL;
+
+ /* Definition of the paths to test and expected replies for each. */
+ struct check_access_tests test_set3[] = {
+ /* No access at the root of Repo1 (inherited from global settings) */
+ { "/", "Repo1", "user1", svn_authz_read, FALSE },
+ { "/", "Repo1", "user2", svn_authz_read, FALSE },
+
+ /* r/o access for both users at the root of Repo2 */
+ { "/", "Repo2", "user1", svn_authz_read, TRUE },
+ { "/", "Repo2", "user2", svn_authz_read, TRUE },
+ { "/", "Repo2", "user1", svn_authz_write, FALSE },
+ { "/", "Repo2", "user2", svn_authz_write, FALSE },
+
+ /* user1 has recursive write access (b/c there are no further rules
+ * restricting the access once granted at the parent) wherever there is
+ * a "folder..." in the path, while user2 has no access at all. */
+ { "/folder_1", "Repo1", "user1",
+ svn_authz_write | svn_authz_recursive, TRUE },
+ { "/folder_1", "Repo1", "user2", svn_authz_read, FALSE },
+ { "/1_folder", "Repo1", "user1", svn_authz_read, FALSE },
+ { "/foo/bar/folder_2/random", "Repo1", "user1",
+ svn_authz_write | svn_authz_recursive, TRUE },
+ { "/foo/bar/folder_2/random", "Repo1", "user2", svn_authz_read, FALSE },
+ { "/foo/bar/2_folder/random", "Repo1", "user1", svn_authz_read, FALSE },
+ { "/foo/bar/folder", "Repo1", "user1",
+ svn_authz_write | svn_authz_recursive, TRUE },
+ { "/foo/bar/folder", "Repo1", "user2", svn_authz_read, FALSE },
+
+ /* Doesn't quite match the pattern: */
+ { "/foo/bar/folde", "Repo1", "user1", svn_authz_read, FALSE },
+ { "/foo/bar/folde", "Repo1", "user2", svn_authz_read, FALSE },
+
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Illustrate the difference between "matching" rule and "applying" rule.
+ * "*" only _matches_ a single level and will _apply_ to sub-paths only
+ * if no other rule _applies_. The "**" rule applies to all paths in
+ * trunk and will only be eclipsed for members of team1 and then only for
+ * the first sub-level. */
+ const char *contents4 =
+ "[groups]" NL
+ "team1 = user1, user3" NL
+ "team2 = user2, user3" NL
+ "" NL
+ "[:glob:Repo1:/trunk/**]" NL
+ "@team2 = rw" NL
+ "" NL
+ "[:glob:Repo1:/trunk/*]" NL
+ "@team1 = r" NL;
+
+ /* Definition of the paths to test and expected replies for each. */
+ struct check_access_tests test_set4[] = {
+ /* Team2 has r/w access to /trunk */
+ { "/trunk", "Repo1", "user1", svn_authz_read, FALSE },
+ { "/trunk", "Repo1", "user2", svn_authz_write, TRUE },
+ { "/trunk", "Repo1", "user3", svn_authz_write, TRUE },
+
+ /* At the first sub-level, team1 has only read access;
+ * the remainder of team2 has write access. */
+ { "/trunk/A", "Repo1", "user1", svn_authz_read, TRUE },
+ { "/trunk/A", "Repo1", "user3", svn_authz_read, TRUE },
+ { "/trunk/A", "Repo1", "user1", svn_authz_write, FALSE },
+ { "/trunk/A", "Repo1", "user2", svn_authz_write, TRUE },
+ { "/trunk/A", "Repo1", "user3", svn_authz_write, FALSE },
+
+ /* At the second sub-level, team2 has full write access;
+ * the remainder of team1 has still r/o access. */
+ { "/trunk/A/B", "Repo1", "user2",
+ svn_authz_write | svn_authz_recursive, TRUE },
+ { "/trunk/A/B", "Repo1", "user3",
+ svn_authz_write | svn_authz_recursive, TRUE },
+ { "/trunk/A/B", "Repo1", "user1", svn_authz_read, TRUE },
+ { "/trunk/A/B", "Repo1", "user1", svn_authz_write, FALSE },
+
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Verify that the rules are applies as expected. */
+ SVN_ERR(authz_get_handle(&authz_cfg, contents, FALSE, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ SVN_ERR(authz_get_handle(&authz_cfg, contents2, FALSE, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set2, pool));
+
+ SVN_ERR(authz_get_handle(&authz_cfg, contents3, FALSE, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set3, pool));
+
+ SVN_ERR(authz_get_handle(&authz_cfg, contents4, FALSE, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set4, pool));
+
+ /* That's a wrap! */
+ return SVN_NO_ERROR;
+}
+
/* Test in-repo authz paths */
static svn_error_t *
@@ -1798,7 +2325,7 @@ groups_authz(const svn_test_opts_t *opts
SVN_ERR(authz_check_access(authz_cfg, test_set1, pool));
- /* Access rights in the global groups file are discarded. */
+ /* Access rights in the global groups file are forbidden. */
groups_contents =
"[groups]" NL
"philosophers = socrates" NL
@@ -1812,6 +2339,19 @@ groups_authz(const svn_test_opts_t *opts
"@philosophers = rw" NL
"" NL;
+ SVN_TEST_ASSERT_ERROR(
+ authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, TRUE, pool),
+ SVN_ERR_AUTHZ_INVALID_CONFIG);
+ SVN_TEST_ASSERT_ERROR(
+ authz_groups_get_handle(&authz_cfg, authz_contents,
+ groups_contents, FALSE, pool),
+ SVN_ERR_AUTHZ_INVALID_CONFIG);
+
+ groups_contents =
+ "[groups]" NL
+ "philosophers = socrates" NL
+ "" NL;
SVN_ERR(authz_groups_get_handle(&authz_cfg, authz_contents,
groups_contents, TRUE, pool));
@@ -3350,18 +3890,14 @@ test_config_pool(const svn_test_opts_t *
svn_error_t *err;
svn_repos__config_pool_t *config_pool;
- apr_pool_t *config_pool_pool;
apr_pool_t *subpool = svn_pool_create(pool);
const char *wrk_dir = svn_test_data_path("config_pool", pool);
SVN_ERR(svn_io_make_dir_recursively(wrk_dir, pool));
- /* read all config info through a single config pool and we want to be
- able to control its lifetime. The latter requires a separate pool. */
- config_pool_pool = svn_pool_create(pool);
- SVN_ERR(svn_repos__config_pool_create(&config_pool, TRUE,
- config_pool_pool));
+ /* read all config info through a single config pool. */
+ SVN_ERR(svn_repos__config_pool_create(&config_pool, TRUE, pool));
/* have two different configurations */
SVN_ERR(svn_test_get_srcdir(&srcdir, opts, pool));
@@ -3402,11 +3938,11 @@ test_config_pool(const svn_test_opts_t *
for (i = 0; i < 4; ++i)
{
SVN_ERR(svn_repos__config_pool_get(
- &cfg, NULL, config_pool,
+ &cfg, config_pool,
svn_dirent_join(wrk_dir,
"config-pool-test1.cfg",
pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
if (sections1 == NULL)
sections1 = cfg->sections;
@@ -3421,11 +3957,11 @@ test_config_pool(const svn_test_opts_t *
for (i = 0; i < 4; ++i)
{
SVN_ERR(svn_repos__config_pool_get(
- &cfg, NULL, config_pool,
+ &cfg, config_pool,
svn_dirent_join(wrk_dir,
"config-pool-test2.cfg",
pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
SVN_TEST_ASSERT(cfg->sections == sections1);
@@ -3437,11 +3973,11 @@ test_config_pool(const svn_test_opts_t *
for (i = 0; i < 2; ++i)
{
SVN_ERR(svn_repos__config_pool_get(
- &cfg, NULL, config_pool,
+ &cfg, config_pool,
svn_dirent_join(wrk_dir,
"config-pool-test3.cfg",
pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
if (sections2 == NULL)
sections2 = cfg->sections;
@@ -3467,11 +4003,11 @@ test_config_pool(const svn_test_opts_t *
SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
/* reading the config from the repo should still give cfg1 */
- SVN_ERR(svn_repos__config_pool_get(&cfg, NULL, config_pool,
+ SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(
repo_root_url,
"dir/config", pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
@@ -3485,48 +4021,48 @@ test_config_pool(const svn_test_opts_t *
SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
/* reading the config from the repo should give cfg2 now */
- SVN_ERR(svn_repos__config_pool_get(&cfg, NULL, config_pool,
+ SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(
repo_root_url,
"dir/config", pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
SVN_TEST_ASSERT(cfg->sections == sections2);
svn_pool_clear(subpool);
/* reading the copied config should still give cfg1 */
- SVN_ERR(svn_repos__config_pool_get(&cfg, NULL, config_pool,
+ SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(
repo_root_url,
"another-dir/config",
pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
/* once again: repeated reads. This triggers a different code path. */
- SVN_ERR(svn_repos__config_pool_get(&cfg, NULL, config_pool,
+ SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(
repo_root_url,
"dir/config", pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
SVN_TEST_ASSERT(cfg->sections == sections2);
- SVN_ERR(svn_repos__config_pool_get(&cfg, NULL, config_pool,
+ SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(
repo_root_url,
"another-dir/config",
pool),
- TRUE, TRUE, NULL, subpool));
+ TRUE, NULL, subpool));
SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
/* access paths that don't exist */
- SVN_TEST_ASSERT_ERROR(svn_repos__config_pool_get(&cfg, NULL, config_pool,
+ SVN_TEST_ASSERT_ERROR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(repo_root_url, "X",
pool),
- TRUE, TRUE, NULL, subpool),
+ TRUE, NULL, subpool),
SVN_ERR_ILLEGAL_TARGET);
- err = svn_repos__config_pool_get(&cfg, NULL, config_pool, "X.cfg",
- TRUE, TRUE, NULL, subpool);
+ err = svn_repos__config_pool_get(&cfg, config_pool, "X.cfg", TRUE, NULL,
+ subpool);
SVN_TEST_ASSERT(err && APR_STATUS_IS_ENOENT(err->apr_err));
svn_error_clear(err);
svn_pool_clear(subpool);
@@ -3925,7 +4461,7 @@ test_list(const svn_test_opts_t *opts,
SVN_ERR(svn_repos_list(rev_root, "/A", patterns, svn_depth_infinity, FALSE,
NULL, NULL, list_callback, &counter, NULL, NULL,
pool));
- SVN_TEST_ASSERT(counter == 6);
+ SVN_TEST_ASSERT(counter == 7);
return SVN_NO_ERROR;
}
@@ -3989,6 +4525,16 @@ static struct svn_test_descriptor_t test
"authz for svn_repos_trace_node_locations"),
SVN_TEST_OPTS_PASS(commit_aborted_txn,
"test committing a previously aborted txn"),
+ SVN_TEST_PASS2(test_authz_prefixes,
+ "test authz prefixes"),
+ SVN_TEST_PASS2(test_authz_recursive_override,
+ "test recursively authz rule override"),
+ SVN_TEST_PASS2(test_authz_pattern_tests,
+ "test various basic authz pattern combinations"),
+ SVN_TEST_PASS2(test_authz_wildcards,
+ "test the different types of authz wildcards"),
+ SVN_TEST_SKIP2(test_authz_wildcard_performance, TRUE,
+ "optional authz wildcard performance test"),
SVN_TEST_OPTS_PASS(test_list,
"test svn_repos_list"),
SVN_TEST_NULL
Propchange: subversion/branches/ra-git/subversion/tests/libsvn_subr/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Nov 7 12:30:06 2018
@@ -10,6 +10,7 @@ Debug
Release
checksum-test
compat-test
+compress-test
config-test
crypto-test
error-test
@@ -54,3 +55,4 @@ io-test-*
sqlite-test-*
x509-test
xml-test
+test_apr_trunc_workaround
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/auth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/auth-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/auth-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/auth-test.c Wed Nov 7 12:30:06 2018
@@ -50,7 +50,7 @@ test_platform_specific_auth_providers(ap
SVN_ERR(svn_auth_get_platform_specific_client_providers(&providers, NULL,
pool));
-#ifdef SVN_HAVE_GNOME_KEYRING
+#if defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_LIBSECRET)
number_of_providers += 2;
#endif
#ifdef SVN_HAVE_KWALLET
@@ -145,7 +145,7 @@ test_platform_specific_auth_providers(ap
#endif
/* Test GNOME Keyring auth providers */
-#ifdef SVN_HAVE_GNOME_KEYRING
+#if defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_LIBSECRET)
SVN_ERR(svn_auth_get_platform_specific_provider(&provider, "gnome_keyring",
"simple", pool));
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/checksum-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/checksum-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/checksum-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/checksum-test.c Wed Nov 7 12:30:06 2018
@@ -296,6 +296,74 @@ test_checksum_parse_all_zero(apr_pool_t
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_checksummed_stream_read(apr_pool_t *pool)
+{
+ const svn_string_t *str = svn_string_create("abcde", pool);
+ svn_checksum_kind_t kind;
+
+ for (kind = svn_checksum_md5; kind <= svn_checksum_fnv1a_32x4; ++kind)
+ {
+ svn_stream_t *stream;
+ svn_checksum_t *expected_checksum;
+ svn_checksum_t *actual_checksum;
+ char buf[64];
+ apr_size_t len;
+
+ stream = svn_stream_from_string(str, pool);
+ stream = svn_stream_checksummed2(stream, &actual_checksum, NULL,
+ kind, TRUE, pool);
+ len = str->len;
+ SVN_ERR(svn_stream_read_full(stream, buf, &len));
+ SVN_TEST_INT_ASSERT((int) len, str->len);
+
+ SVN_ERR(svn_stream_close(stream));
+
+ SVN_ERR(svn_checksum(&expected_checksum, kind,
+ str->data, str->len, pool));
+ SVN_TEST_ASSERT(svn_checksum_match(expected_checksum, actual_checksum));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_checksummed_stream_reset(apr_pool_t *pool)
+{
+ const svn_string_t *str = svn_string_create("abcde", pool);
+ svn_checksum_kind_t kind;
+
+ for (kind = svn_checksum_md5; kind <= svn_checksum_fnv1a_32x4; ++kind)
+ {
+ svn_stream_t *stream;
+ svn_checksum_t *expected_checksum;
+ svn_checksum_t *actual_checksum;
+ char buf[64];
+ apr_size_t len;
+
+ stream = svn_stream_from_string(str, pool);
+ stream = svn_stream_checksummed2(stream, &actual_checksum, NULL,
+ kind, TRUE, pool);
+ len = str->len;
+ SVN_ERR(svn_stream_read_full(stream, buf, &len));
+ SVN_TEST_INT_ASSERT((int) len, str->len);
+
+ SVN_ERR(svn_stream_reset(stream));
+
+ len = str->len;
+ SVN_ERR(svn_stream_read_full(stream, buf, &len));
+ SVN_TEST_INT_ASSERT((int) len, str->len);
+
+ SVN_ERR(svn_stream_close(stream));
+
+ SVN_ERR(svn_checksum(&expected_checksum, kind,
+ str->data, str->len, pool));
+ SVN_TEST_ASSERT(svn_checksum_match(expected_checksum, actual_checksum));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* An array of all test functions */
static int max_threads = 1;
@@ -317,6 +385,10 @@ static struct svn_test_descriptor_t test
"checksum (de-)serialization"),
SVN_TEST_PASS2(test_checksum_parse_all_zero,
"checksum parse all zero"),
+ SVN_TEST_PASS2(test_checksummed_stream_read,
+ "read from checksummed stream"),
+ SVN_TEST_PASS2(test_checksummed_stream_reset,
+ "reset checksummed stream"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.c Wed Nov 7 12:30:06 2018
@@ -37,6 +37,7 @@
#include "svn_error.h"
#include "svn_config.h"
#include "private/svn_subr_private.h"
+#include "private/svn_config_private.h"
#include "../svn_test.h"
@@ -69,12 +70,12 @@ get_config_file_path(const char **cfg_fi
}
static const char *config_keys[] = { "foo", "a", "b", "c", "d", "e", "f", "g",
- "h", "i", NULL };
+ "h", "i", "m", NULL };
static const char *config_values[] = { "bar", "Aa", "100", "bar",
"a %(bogus)s oyster bar",
"%(bogus)s shmoo %(",
"%Aa", "lyrical bard", "%(unterminated",
- "Aa 100", NULL };
+ "Aa 100", "foo bar baz", NULL };
static svn_error_t *
test_text_retrieval(const svn_test_opts_t *opts,
@@ -403,6 +404,60 @@ test_invalid_bom(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_serialization(apr_pool_t *pool)
+{
+ svn_stringbuf_t *original_content;
+ svn_stringbuf_t *written_content;
+ svn_config_t *cfg;
+
+ const struct
+ {
+ const char *section;
+ const char *option;
+ const char *value;
+ } test_data[] =
+ {
+ { "my section", "value1", "some" },
+ { "my section", "value2", "something" },
+ { "another Section", "value1", "one" },
+ { "another Section", "value2", "two" },
+ { "another Section", "value 3", "more" },
+ };
+ int i;
+
+ /* Format the original with the same formatting that the writer will use. */
+ original_content = svn_stringbuf_create("\n[my section]\n"
+ "value1=some\n"
+ "value2=%(value1)sthing\n"
+ "\n[another Section]\n"
+ "value1=one\n"
+ "value2=two\n"
+ "value 3=more\n",
+ pool);
+ written_content = svn_stringbuf_create_empty(pool);
+
+ SVN_ERR(svn_config_parse(&cfg,
+ svn_stream_from_stringbuf(original_content, pool),
+ TRUE, TRUE, pool));
+ SVN_ERR(svn_config__write(svn_stream_from_stringbuf(written_content, pool),
+ cfg, pool));
+ SVN_ERR(svn_config_parse(&cfg,
+ svn_stream_from_stringbuf(written_content, pool),
+ TRUE, TRUE, pool));
+
+ /* The serialized and re-parsed config must have the expected contents. */
+ for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
+ {
+ const char *val;
+ svn_config_get(cfg, &val, test_data[i].section, test_data[i].option,
+ NULL);
+ SVN_TEST_STRING_ASSERT(val, test_data[i].value);
+ }
+
+ return SVN_NO_ERROR;
+}
+
/*
====================================================================
If you add a new test to this file, update this array.
@@ -437,6 +492,8 @@ static struct svn_test_descriptor_t test
"test variable expansion"),
SVN_TEST_PASS2(test_invalid_bom,
"test parsing config file with invalid BOM"),
+ SVN_TEST_PASS2(test_serialization,
+ "test writing a config"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.cfg
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.cfg?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.cfg (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/config-test.cfg Wed Nov 7 12:30:06 2018
@@ -45,6 +45,10 @@ j=some %(k)scle
k=c%(j)sy
# Depends on a cyclic definition
l=depends on a %(j)scycle!
+# line continuation
+m = foo
+ bar
+ baz
[UpperCaseSection]
a=Aa
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/dirent_uri-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/dirent_uri-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/dirent_uri-test.c Wed Nov 7 12:30:06 2018
@@ -938,6 +938,13 @@ static const testcase_canonicalize_t uri
/* Hostnames that look like non-canonical paths */
{ "file://./foo", "file://./foo" },
{ "http://./foo", "http://./foo" },
+ /* Some invalid URLs, these still have a canonical form */
+ { "http://server:81:81/", "http://server:81:81" },
+ { "http://server:81foo/", "http://server:81foo" },
+ { "http://server::/", "http://server::" },
+ { "http://server:-/", "http://server:-" },
+ { "http://hst:1.2.3.4.5/", "http://hst:1.2.3.4.5"},
+ { "http://hst:1.2.999.4/", "http://hst:1.2.999.4"},
/* svn_uri_is_canonical() was a private function in the 1.6 API, and
has since taken a MAJOR change of direction, namely that only
absolute URLs are considered canonical uris now. */
@@ -1238,6 +1245,12 @@ test_uri_is_canonical(apr_pool_t *pool)
t->path,
canonical ? "TRUE" : "FALSE",
t->result);
+
+ if (t->result && !svn_uri_is_canonical(t->result, pool))
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "svn_uri_is_canonical(\"%s\") returned "
+ "FALSE on canonical form",
+ t->result);
}
return SVN_NO_ERROR;
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/mergeinfo-test.c Wed Nov 7 12:30:06 2018
@@ -1670,10 +1670,123 @@ test_remove_prefix_from_catalog(apr_pool
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_rangelist_merge_overlap(apr_pool_t *pool)
+{
+ const char *rangelist_str = "19473-19612*,19615-19630*,19631-19634";
+ const char *changes_str = "15014-20515*";
+ const char *expected_str = "15014-19630*,19631-19634,19635-20515*";
+ /* wrong result: "15014-19630*,19634-19631*,19631-19634,19635-20515*" */
+ svn_rangelist_t *rangelist, *changes;
+ svn_string_t *result_string;
+
+ /* prepare the inputs */
+ SVN_ERR(svn_rangelist__parse(&rangelist, rangelist_str, pool));
+ SVN_ERR(svn_rangelist__parse(&changes, changes_str, pool));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(rangelist));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(changes));
+
+ /* perform the merge */
+ SVN_ERR(svn_rangelist_merge2(rangelist, changes, pool, pool));
+
+ /* check the output */
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(rangelist));
+ SVN_ERR(svn_rangelist_to_string(&result_string, rangelist, pool));
+ SVN_TEST_STRING_ASSERT(result_string->data, expected_str);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_rangelist_loop(apr_pool_t *pool)
+{
+ apr_pool_t *iterpool = svn_pool_create(pool);
+ int x, y;
+
+ for (x = 0; x < 62; x++)
+ for (y = x + 1; y < 63; y++)
+ {
+ svn_rangelist_t *base_list;
+ svn_rangelist_t *change_list;
+ svn_merge_range_t *mrange;
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_rangelist__parse(&base_list,
+ "2,4,7-9,12-15,18-20,"
+ "22*,25*,28-30*,33-35*,"
+ "38-40,43-45*,48-50,52-54,56-59*",
+ iterpool));
+
+ change_list = apr_array_make(iterpool, 1, sizeof(mrange));
+
+ mrange = apr_pcalloc(pool, sizeof(*mrange));
+ mrange->start = x;
+ mrange->end = y;
+ APR_ARRAY_PUSH(change_list, svn_merge_range_t *) = mrange;
+
+ {
+ svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool);
+ svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool);
+
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl));
+
+ SVN_ERR(svn_rangelist_merge2(bl, cl, iterpool, iterpool));
+
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl));
+
+ /* TODO: Verify result */
+ }
+
+ {
+ svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool);
+ svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool);
+
+ SVN_ERR(svn_rangelist_merge2(cl, bl, iterpool, iterpool));
+
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl));
+
+ /* TODO: Verify result */
+ }
+
+ mrange->inheritable = TRUE;
+
+ {
+ svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool);
+ svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool);
+
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl));
+
+ SVN_ERR(svn_rangelist_merge2(bl, cl, iterpool, iterpool));
+
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl));
+
+ /* TODO: Verify result */
+ }
+
+ {
+ svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool);
+ svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool);
+
+ SVN_ERR(svn_rangelist_merge2(cl, bl, iterpool, iterpool));
+
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl));
+ SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl));
+
+ /* TODO: Verify result */
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
/* The test table. */
-static int max_threads = 1;
+static int max_threads = 4;
static struct svn_test_descriptor_t test_funcs[] =
{
@@ -1714,6 +1827,10 @@ static struct svn_test_descriptor_t test
"diff of rangelists"),
SVN_TEST_PASS2(test_remove_prefix_from_catalog,
"removal of prefix paths from catalog keys"),
+ SVN_TEST_PASS2(test_rangelist_merge_overlap,
+ "merge of rangelists with overlaps (issue 4686)"),
+ SVN_TEST_PASS2(test_rangelist_loop,
+ "test rangelist edgecases via loop"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/priority-queue-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/priority-queue-test.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/priority-queue-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/priority-queue-test.c Wed Nov 7 12:30:06 2018
@@ -125,7 +125,7 @@ verify_queue_order(svn_priority_queue__t
}
/* the queue should now be empty */
- verify_empty_queue(queue);
+ SVN_ERR(verify_empty_queue(queue));
return SVN_NO_ERROR;
}
@@ -154,7 +154,7 @@ test_empty_queue(apr_pool_t *pool)
svn_priority_queue__t *queue
= svn_priority_queue__create(elements, compare_func);
- verify_empty_queue(queue);
+ SVN_ERR(verify_empty_queue(queue));
return SVN_NO_ERROR;
}
@@ -214,7 +214,7 @@ test_update(apr_pool_t *pool)
}
/* the queue should now be empty */
- verify_empty_queue(queue);
+ SVN_ERR(verify_empty_queue(queue));
return SVN_NO_ERROR;
}