Modified: subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_client/conflicts-test.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_client/conflicts-test.c?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_client/conflicts-test.c (original) +++ subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_client/conflicts-test.c Thu Aug 24 08:42:40 2017 @@ -4578,6 +4578,89 @@ test_update_incoming_added_dir_merge2(co return SVN_NO_ERROR; } +static svn_error_t * +test_cherry_pick_post_move_edit(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b)); + const char *trunk_url; + svn_opt_revision_t peg_rev; + apr_array_header_t *ranges_to_merge; + svn_opt_revision_range_t merge_range; + svn_client_ctx_t *ctx; + svn_client_conflict_t *conflict; + svn_boolean_t tree_conflicted; + + SVN_ERR(svn_test__sandbox_create(b, + "test_cherry_pick_post_move_edit", + opts, pool)); + + SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */ + /* Create a copy of node "A". */ + SVN_ERR(sbox_wc_copy(b, "A", "A1")); + SVN_ERR(sbox_wc_commit(b, "")); /* r2 */ + /* On "trunk", move the file mu. */ + SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved")); + SVN_ERR(sbox_wc_commit(b, "")); /* r3 */ + /* On "trunk", edit mu-moved. This will be r4, which we'll cherry-pick. */ + SVN_ERR(sbox_file_write(b, "A/mu-moved", "Modified content.\n")); + SVN_ERR(sbox_wc_commit(b, "")); /* r4 */ + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + + /* Perform a cherry-pick merge of r4 from A to A1. */ + SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); + trunk_url = apr_pstrcat(b->pool, b->repos_url, "/A", SVN_VA_NULL); + peg_rev.kind = svn_opt_revision_number; + peg_rev.value.number = 4; + merge_range.start.kind = svn_opt_revision_number; + merge_range.start.value.number = 3; + merge_range.end.kind = svn_opt_revision_number; + merge_range.end.value.number = 4; + ranges_to_merge = apr_array_make(b->pool, 1, + sizeof(svn_opt_revision_range_t *)); + APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = &merge_range; + /* This should raise a "local delete or move vs incoming edit" conflict. */ + SVN_ERR(svn_client_merge_peg5(trunk_url, ranges_to_merge, &peg_rev, + sbox_wc_path(b, "A1"), svn_depth_infinity, + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + NULL, ctx, b->pool)); + + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"), + ctx, b->pool, b->pool)); + SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted, + conflict, b->pool, b->pool)); + SVN_TEST_ASSERT(tree_conflicted); + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, + b->pool)); + } + + SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool)); + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_local_move_file_text_merge, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, + b->pool)); + } + + /* Try to resolve the conflict. */ + SVN_ERR(svn_client_conflict_tree_resolve_by_id( + conflict, + svn_client_conflict_option_local_move_file_text_merge, + ctx, b->pool)); + + return SVN_NO_ERROR; +} + /* Regression test for chrash fixed in r1780259. */ static svn_error_t * test_cherry_pick_moved_file_with_propdel(const svn_test_opts_t *opts, @@ -4682,6 +4765,217 @@ test_cherry_pick_moved_file_with_propdel return SVN_NO_ERROR; } +static svn_error_t * +test_merge_incoming_move_file_text_merge_crlf(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b)); + svn_client_ctx_t *ctx; + svn_opt_revision_t opt_rev; + svn_client_conflict_t *conflict; + svn_boolean_t text_conflicted; + apr_array_header_t *props_conflicted; + svn_boolean_t tree_conflicted; + svn_stringbuf_t *buf; + + SVN_ERR(svn_test__sandbox_create( + b, "merge_incoming_move_file_text_merge_crlf", opts, pool)); + + SVN_ERR(sbox_add_and_commit_greek_tree(b)); + /* Edit the file to have CRLF line endings. */ + SVN_ERR(sbox_file_write(b, "A/mu", "Original content.\r\n")); + SVN_ERR(sbox_wc_commit(b, "")); + /* Create a copy of node "A". */ + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + SVN_ERR(sbox_wc_copy(b, "A", "A1")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "trunk", move the file. */ + SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "branch", edit the file. */ + SVN_ERR(sbox_file_write(b, "A1/mu", "Modified content.\r\n")); + SVN_ERR(sbox_wc_commit(b, "")); + + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + opt_rev.kind = svn_opt_revision_head; + opt_rev.value.number = SVN_INVALID_REVNUM; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, pool)); + + /* Merge "A" to "A1". */ + SVN_ERR(svn_client_merge_peg5(svn_path_url_add_component2(b->repos_url, "A", + pool), + NULL, &opt_rev, sbox_wc_path(b, "A1"), + svn_depth_infinity, + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + NULL, ctx, pool)); + + /* We should have a tree conflict in the file "mu". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu"), ctx, + pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(tree_conflicted); + + /* Check available tree conflict resolution options. */ + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_delete_ignore, + svn_client_conflict_option_incoming_delete_accept, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, pool)); + + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_move_file_text_merge, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + /* Resolve the tree conflict by moving "mu" to "mu-moved". */ + SVN_ERR(svn_client_conflict_tree_resolve_by_id( + conflict, svn_client_conflict_option_incoming_move_file_text_merge, + ctx, pool)); + + /* The file should no longer be in conflict, and should not have a + * text conflict, because the contents are identical in "trunk" and + * in the "branch". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"), + ctx, pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(!tree_conflicted); + + /* And it should have expected contents. */ + SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A1/mu-moved"), + pool)); + SVN_TEST_STRING_ASSERT(buf->data, "Modified content.\r\n"); + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_merge_incoming_move_file_text_merge_native_eol(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b)); + svn_client_ctx_t *ctx; + svn_opt_revision_t opt_rev; + svn_client_conflict_t *conflict; + svn_boolean_t text_conflicted; + apr_array_header_t *props_conflicted; + svn_boolean_t tree_conflicted; + svn_stringbuf_t *buf; + + SVN_ERR(svn_test__sandbox_create( + b, "merge_incoming_move_file_text_merge_native_eol", opts, pool)); + + SVN_ERR(sbox_add_and_commit_greek_tree(b)); + /* Set svn:eol-style on a file and edit it. */ + SVN_ERR(sbox_wc_propset(b, SVN_PROP_EOL_STYLE, "native", "A/mu"));; + SVN_ERR(sbox_file_write(b, "A/mu", "Original content.\n")); + SVN_ERR(sbox_wc_commit(b, "")); + /* Create a copy of node "A". */ + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + SVN_ERR(sbox_wc_copy(b, "A", "A1")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "trunk", move the file. */ + SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "branch", edit the file. */ + SVN_ERR(sbox_file_write(b, "A1/mu", "Modified content.\n")); + SVN_ERR(sbox_wc_commit(b, "")); + + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + opt_rev.kind = svn_opt_revision_head; + opt_rev.value.number = SVN_INVALID_REVNUM; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, pool)); + + /* Merge "A" to "A1". */ + SVN_ERR(svn_client_merge_peg5(svn_path_url_add_component2(b->repos_url, "A", + pool), + NULL, &opt_rev, sbox_wc_path(b, "A1"), + svn_depth_infinity, + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + NULL, ctx, pool)); + + /* We should have a tree conflict in the file "mu". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu"), ctx, + pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(tree_conflicted); + + /* Check available tree conflict resolution options. */ + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_delete_ignore, + svn_client_conflict_option_incoming_delete_accept, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, pool)); + + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_move_file_text_merge, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + /* Resolve the tree conflict by moving "mu" to "mu-moved". */ + SVN_ERR(svn_client_conflict_tree_resolve_by_id( + conflict, svn_client_conflict_option_incoming_move_file_text_merge, + ctx, pool)); + + /* The file should no longer be in conflict, and should not have a + * text conflict, because the contents are identical in "trunk" and + * in the "branch". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"), + ctx, pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(!tree_conflicted); + + /* And it should have expected contents. */ + SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A1/mu-moved"), + pool)); + SVN_TEST_STRING_ASSERT(buf->data, "Modified content." APR_EOL_STR); + + return SVN_NO_ERROR; +} + /* ========================================================================== */ @@ -4764,6 +5058,12 @@ static struct svn_test_descriptor_t test "update incoming add dir merge with obstructions"), SVN_TEST_OPTS_PASS(test_cherry_pick_moved_file_with_propdel, "cherry-pick with moved file and propdel"), + SVN_TEST_OPTS_PASS(test_merge_incoming_move_file_text_merge_crlf, + "merge incoming move file merge with CRLF eols"), + SVN_TEST_OPTS_PASS(test_merge_incoming_move_file_text_merge_native_eol, + "merge incoming move file merge with native eols"), + SVN_TEST_OPTS_XFAIL(test_cherry_pick_post_move_edit, + "cherry-pick edit from moved file"), SVN_TEST_NULL };
Modified: subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_delta/random-test.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_delta/random-test.c?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_delta/random-test.c (original) +++ subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_delta/random-test.c Thu Aug 24 08:42:40 2017 @@ -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/shelve-checkpoint3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c (original) +++ subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c Thu Aug 24 08:42:40 2017 @@ -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); Propchange: subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Thu Aug 24 08:42:40 2017 @@ -10,6 +10,7 @@ Debug Release checksum-test compat-test +compress-test config-test crypto-test error-test Modified: subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/checksum-test.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/checksum-test.c?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/checksum-test.c (original) +++ subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/checksum-test.c Thu Aug 24 08:42:40 2017 @@ -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/shelve-checkpoint3/subversion/tests/libsvn_subr/dirent_uri-test.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/dirent_uri-test.c (original) +++ subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/dirent_uri-test.c Thu Aug 24 08:42:40 2017 @@ -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/shelve-checkpoint3/subversion/tests/libsvn_subr/mergeinfo-test.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/mergeinfo-test.c (original) +++ subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/mergeinfo-test.c Thu Aug 24 08:42:40 2017 @@ -1770,10 +1770,96 @@ test_rangelist_merge_overlap(apr_pool_t 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[] = { @@ -1816,6 +1902,8 @@ static struct svn_test_descriptor_t test "removal of prefix paths from catalog keys"), SVN_TEST_XFAIL2(test_rangelist_merge_overlap, "merge of rangelists with overlaps (issue 4686)"), + SVN_TEST_XFAIL2(test_rangelist_loop, + "test rangelist edgecases via loop"), SVN_TEST_NULL }; Modified: subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/utf-test.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/utf-test.c?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/utf-test.c (original) +++ subversion/branches/shelve-checkpoint3/subversion/tests/libsvn_subr/utf-test.c Thu Aug 24 08:42:40 2017 @@ -664,11 +664,18 @@ test_utf_fuzzy_escape(apr_pool_t *pool) SVN_TEST_ASSERT(0 == strcmp(fuzzy, "Subversi{U+03BF}n")); fuzzy = svn_utf__fuzzy_escape(invalid, sizeof(invalid) - 1, pool); - /*fprintf(stderr, "%s\n", fuzzy);*/ + + /* utf8proc 1.1.15 produces {U?FDD1} while 2.x produces {U+FDD1} */ SVN_TEST_ASSERT(0 == strcmp(fuzzy, "Not Unicode: {U?FDD1};" "Out of range: ?\\F4?\\90?\\80?\\81;" "Not UTF-8: ?\\E6;" + "Null byte: \\0;") + || + 0 == strcmp(fuzzy, + "Not Unicode: {U+FDD1};" + "Out of range: ?\\F4?\\90?\\80?\\81;" + "Not UTF-8: ?\\E6;" "Null byte: \\0;")); return SVN_NO_ERROR; Modified: subversion/branches/shelve-checkpoint3/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh (original) +++ subversion/branches/shelve-checkpoint3/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh Thu Aug 24 08:42:40 2017 @@ -71,6 +71,11 @@ if [ ${svnminor} -gt 8 ]; then optimizeconfig=' --enable-optimize' fi +if [ ${svnminor} -ge 10 ]; then + lz4config='--with-lz4=internal' + utf8proconfig='--with-utf8proc=internal' +fi + # # Step 3: Configure # @@ -88,6 +93,8 @@ ${abssrc}/configure \ --with-berkeley-db=db.h:"${SVNBB_BDB}/include":${SVNBB_BDB}/lib:db \ --enable-javahl \ --without-jikes \ + ${lz4config} \ + ${utf8proconfig} \ --with-junit="${SVNBB_JUNIT}" test -f config.log && mv config.log "${abssrc}/.test-logs/config.log" Modified: subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion (original) +++ subversion/branches/shelve-checkpoint3/tools/client-side/bash_completion Thu Aug 24 08:42:40 2017 @@ -926,11 +926,12 @@ _svn() ;; list|ls) cmdOpts="$rOpts -v --verbose -R --recursive $pOpts \ - --incremental --xml --depth --include-externals" + --incremental --search --xml --depth \ + --include-externals" ;; lock) cmdOpts="-m --message -F --file --encoding --force-log \ - --targets --force $pOpts" + $qOpts --targets --force $pOpts" ;; log) cmdOpts="$rOpts -v --verbose --targets $pOpts --stop-on-copy \ @@ -1011,12 +1012,13 @@ _svn() --ignore-ancestry" ;; unlock) - cmdOpts="--targets --force $pOpts" + cmdOpts="$qOpts --targets --force $pOpts" ;; update|up) cmdOpts="$rOpts $nOpts $qOpts $pOpts --diff3-cmd \ --ignore-externals --force --accept $cOpts \ - --parents --editor-cmd --set-depth" + --parents --editor-cmd --set-depth \ + --adds-as-modification" ;; upgrade) cmdOpts="$qOpts $pOpts" Modified: subversion/branches/shelve-checkpoint3/tools/dev/unix-build/Makefile.svn URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/dev/unix-build/Makefile.svn?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/dev/unix-build/Makefile.svn (original) +++ subversion/branches/shelve-checkpoint3/tools/dev/unix-build/Makefile.svn Thu Aug 24 08:42:40 2017 @@ -100,6 +100,7 @@ BZ2_VER = 1.0.6 PYTHON_VER = 2.7.13 JUNIT_VER = 4.10 GETTEXT_VER = 0.19.8.1 +LZ4_VER = 1.7.5 BDB_DIST = db-$(BDB_VER).tar.gz APR_ICONV_DIST = apr-iconv-$(APR_ICONV_VER).tar.gz @@ -114,6 +115,7 @@ BZ2_DIST = bzip2-$(BZ2_VER).tar.gz PYTHON_DIST = Python-$(PYTHON_VER).tgz JUNIT_DIST = junit-${JUNIT_VER}.jar GETTEXT_DIST = gettext-$(GETTEXT_VER).tar.gz +LZ4_DIST = lz4-$(LZ4_VER).tar.gz SHA256_${BDB_DIST} = f14fd96dd38915a1d63dcb94a63fbb8092334ceba6b5060760427096f631263e SHA256_${APR_ICONV_DIST} = 19381959d50c4a5f3b9c84d594a5f9ffb3809786919b3058281f4c87e1f4b245 @@ -128,6 +130,7 @@ SHA256_${BZ2_DIST} = a2848f34fcd5d6cf47d SHA256_${PYTHON_DIST} = a4f05a0720ce0fd92626f0278b6b433eee9a6173ddf2bced7957dfb599a5ece1 SHA256_${JUNIT_DIST} = 36a747ca1e0b86f6ea88055b8723bb87030d627766da6288bf077afdeeb0f75a SHA256_${GETTEXT_DIST} = ff942af0e438ced4a8b0ea4b0b6e0d6d657157c5e2364de57baa279c1c125c43 +SHA256_${LZ4_DIST} = 0190cacd63022ccb86f44fa5041dc6c3804407ad61550ca21c382827319e7e7e define do_check_sha256 if [ -x /bin/sha256 ]; then \ @@ -176,6 +179,7 @@ BZ2_URL = http://bzip.org/$(BZ2_VER)/$( PYTHON_URL = https://python.org/ftp/python/$(PYTHON_VER)/$(PYTHON_DIST) JUNIT_URL = https://downloads.sourceforge.net/project/junit/junit/$(JUNIT_VER)/$(JUNIT_DIST) GETTEXT_URL = https://ftp.gnu.org/pub/gnu/gettext/$(GETTEXT_DIST) +LZ4_URL = https://github.com/lz4/lz4/archive/v$(LZ4_VER).tar.gz BDB_SRCDIR = $(SRCDIR)/db-$(BDB_VER) @@ -194,6 +198,7 @@ RUBY_SRCDIR = $(SRCDIR)/ruby-$(RUBY_VER) BZ2_SRCDIR = $(SRCDIR)/bzip2-$(BZ2_VER) PYTHON_SRCDIR = $(SRCDIR)/Python-$(PYTHON_VER) GETTEXT_SRCDIR = $(SRCDIR)/gettext-$(GETTEXT_VER) +LZ4_SRCDIR = ${SRCDIR}/lz4-$(LZ4_VER) SVN_SRCDIR = $(SVN_WC) BDB_OBJDIR = $(OBJDIR)/db-$(BDB_VER) @@ -212,6 +217,7 @@ RUBY_OBJDIR = $(OBJDIR)/ruby-$(RUBY_VER) BZ2_OBJDIR = $(OBJDIR)/bzip2-$(BZ2_VER) PYTHON_OBJDIR = $(OBJDIR)/python-$(PYTHON_VER) GETTEXT_OBJDIR = $(OBJDIR)/gettext-$(GETTEXT_VER) +LZ4_OBJDIR = ${OBJDIR}/lz4-$(LZ4_VER) SVN_OBJDIR = $(OBJDIR)/$(SVN_REL_WC) # Tweak this for out-of-tree builds. Note that running individual @@ -236,18 +242,19 @@ all: dirs-create bdb-install apr-install httpd-install neon-install serf-install serf-old-install \ sqlite-install cyrus-sasl-install libmagic-install \ ruby-install bz2-install python-install gettext-install \ - svn-install svn-bindings-install + lz4-install svn-install svn-bindings-install # Use these to start a build from the beginning. reset: dirs-reset bdb-reset apr-reset iconv-reset apr-util-reset \ httpd-reset neon-reset serf-reset serf-old-reset sqlite-reset \ cyrus-sasl-reset libmagic-reset ruby-reset python-reset \ - bz2-reset gettext-reset svn-reset + bz2-reset gettext-reset lz4-reset svn-reset # Use to save disk space. clean: bdb-clean apr-clean iconv-clean apr-util-clean httpd-clean \ neon-clean serf-clean serf-old-clean sqlite-clean cyrus-sasl-clean \ - libmagic-clean ruby-clean bz2-clean python-clean gettext-clean svn-clean + libmagic-clean ruby-clean bz2-clean python-clean gettext-clean \ + lz4-clean svn-clean # Nukes everything (including installed binaries!) # Use this to start ALL OVER AGAIN! Use with caution! @@ -1319,6 +1326,49 @@ $(GETTEXT_OBJDIR)/.installed: $(GETTEXT_ touch $@ ####################################################################### +# lz4 +####################################################################### + +lz4-retrieve: $(LZ4_OBJDIR)/.retrieved +lz4-configure: $(LZ4_OBJDIR)/.configured +lz4-compile: $(LZ4_OBJDIR)/.compiled +lz4-install: $(LZ4_OBJDIR)/.installed +lz4-reset: + $(foreach f, .retrieved .configured .compiled .installed, \ + rm -f $(LZ4_OBJDIR)/$(f);) + +lz4-clean: + -(cd $(LZ4_SRCDIR) && env MAKEFLAGS= $(MAKE) clean) + +# fetch distfile for lz4 +$(DISTDIR)/$(LZ4_DIST): + cd $(DISTDIR) && $(FETCH_CMD) -O $(LZ4_DIST) $(LZ4_URL) + +# retrieve lz4 +$(LZ4_OBJDIR)/.retrieved: $(DISTDIR)/$(LZ4_DIST) + $(call do_check_sha256,$(LZ4_DIST)) + [ -d $(LZ4_OBJDIR) ] || mkdir -p $(LZ4_OBJDIR) + tar -C $(SRCDIR) -zxf $(DISTDIR)/$(LZ4_DIST) + touch $@ + +# configure lz4 +$(LZ4_OBJDIR)/.configured: $(LZ4_OBJDIR)/.retrieved + touch $@ + +# compile lz4 +$(LZ4_OBJDIR)/.compiled: $(LZ4_OBJDIR)/.configured + (cd $(LZ4_SRCDIR)/lib && \ + env MAKEFLAGS= $(MAKE) PREFIX=$(PREFIX)/lz4) + touch $@ + +# install lz4 +$(LZ4_OBJDIR)/.installed: $(LZ4_OBJDIR)/.compiled + mkdir -p $(PREFIX)/lz4/lib + (cd $(LZ4_SRCDIR)/lib && \ + env MAKEFLAGS= $(MAKE) PREFIX=$(PREFIX)/lz4 install) + touch $@ + +####################################################################### # svn ####################################################################### @@ -1393,7 +1443,7 @@ DISABLE_NEON_VERSION_CHECK=--disable-neo W_NO_SYSTEM_HEADERS=-Wno-system-headers NEON_FLAG=--with-neon="$(PREFIX)/neon" JAVAHL_CHECK_TARGET=check-javahl -else # 1.8 +else ifeq ($(BRANCH_MAJOR), $(filter $(BRANCH_MAJOR), 1.8 1.9)) BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER) SERF_FLAG=--with-serf="$(PREFIX)/serf" # serf >= 1.3.0 is built with scons and no longer sets up rpath linker flags, @@ -1404,6 +1454,19 @@ MOD_AUTHZ_SVN=modules/svn-$(WC)/mod_auth MOD_DONTDOTHAT=modules/svn-$(WC)/mod_dontdothat.so LIBMAGIC_FLAG=--with-libmagic=$(PREFIX)/libmagic JAVAHL_CHECK_TARGET=check-all-javahl +else # 1.10 +BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER) +SERF_FLAG=--with-serf="$(PREFIX)/serf" +# serf >= 1.3.0 is built with scons and no longer sets up rpath linker flags, +# so we have to do that ourselves :( +SERF_LDFLAG=-Wl,-rpath,$(PREFIX)/serf/lib -Wl,-rpath,$(PREFIX)/bdb/lib +MOD_DAV_SVN=modules/svn-$(WC)/mod_dav_svn.so +MOD_AUTHZ_SVN=modules/svn-$(WC)/mod_authz_svn.so +MOD_DONTDOTHAT=modules/svn-$(WC)/mod_dontdothat.so +LIBMAGIC_FLAG=--with-libmagic=$(PREFIX)/libmagic +JAVAHL_CHECK_TARGET=check-all-javahl +LZ4_FLAG=--with-lz4=$(PREFIX)/lz4 +UTF8PROC_FLAG=--with-utf8proc=internal endif ifeq ($(ENABLE_JAVA_BINDINGS),yes) @@ -1454,6 +1517,8 @@ $(SVN_OBJDIR)/.configured: $(SVN_OBJDIR) --disable-mod-activation \ $(JAVAHL_FLAG) \ $(LIBMAGIC_FLAG) \ + $(LZ4_FLAG) \ + $(UTF8PROC_FLAG) \ $(SVN_STATIC_FLAG) \ $(DISABLE_NEON_VERSION_CHECK) touch $@ @@ -2019,6 +2084,9 @@ endif @echo "serf: $(SERF_VER)" @echo "cyrus-sasl: $(CYRUS_SASL_VER)" @echo "sqlite: $(SQLITE_VER)" +ifdef LZ4_FLAG + @echo "lz4: $(LZ4_VER)" +endif @echo "libssl: `openssl version`" @echo "swig: `swig -version | grep Version | cut -d' ' -f3`" @echo "python: $(PYTHON_VER)" Modified: subversion/branches/shelve-checkpoint3/tools/dist/checksums.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/dist/checksums.py?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/dist/checksums.py (original) +++ subversion/branches/shelve-checkpoint3/tools/dist/checksums.py Thu Aug 24 08:42:40 2017 @@ -19,12 +19,14 @@ # under the License. # # -# Check MD5 and SHA1 signatures of files, using md5sums and/or -# sha1sums as manifests. Replaces the 'md5sum' and 'sha1sum' commands +# Check MD5 and SHA-1 and SHA-2 signatures of files, using +# md5sums, sha1sums, and/or sha512sums as manifests +# Replaces the 'md5sum', 'sha1sum', and 'sha512sums' commands # on systems that do not have them, such as Mac OS X or Windows. # # Usage: checksums.py [manifest] -# where "os.path.basename(manifest)" is either "md5sums" or "sha1sums" +# where "os.path.basename(manifest)" is either "md5sums", "sha1sums", +# "sha512sums" # # Tested with the following Python versions: # 2.4 2.5 2.6 2.7 3.2 @@ -37,6 +39,7 @@ import sys try: from hashlib import md5 from hashlib import sha1 + from hashlib import sha512 except ImportError: from md5 import md5 from sha import sha as sha1 @@ -67,9 +70,11 @@ def main(manipath): sink = Digester(md5) elif manifest == 'sha1sums': sink = Digester(sha1) + elif manifest == 'sha512sums': + sink = Digester(sha512) else: raise ValueError('The name of the digest manifest must be ' - "'md5sums' or 'sha1sums', not '%s'" % manifest) + "'md5sums', 'sha1sums', or 'sha512sums', not '%s'" % manifest) # No 'with' statement in Python 2.4 ... stream = None Modified: subversion/branches/shelve-checkpoint3/tools/dist/dist.sh URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/dist/dist.sh?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/dist/dist.sh (original) +++ subversion/branches/shelve-checkpoint3/tools/dist/dist.sh Thu Aug 24 08:42:40 2017 @@ -57,6 +57,7 @@ # To build a Windows zip file package, additionally pass -zip and the # path to apr-iconv with -apri. +set -e USAGE="USAGE: ./dist.sh -v VERSION -r REVISION -pr REPOS-PATH \ [-alpha ALPHA_NUM|-beta BETA_NUM|-rc RC_NUM|-pre PRE_NUM] \ @@ -205,7 +206,7 @@ export TZ echo "Exporting $REPOS_PATH r$REVISION into sandbox..." (cd "$DIST_SANDBOX" && \ ${SVN:-svn} export -q $EXTRA_EXPORT_OPTIONS \ - "http://svn.apache.org/repos/asf/subversion/$REPOS_PATH"@"$REVISION" \ + "https://svn.apache.org/repos/asf/subversion/$REPOS_PATH"@"$REVISION" \ "$DISTNAME" --username none --password none) rm -f "$DISTPATH/STATUS" @@ -242,7 +243,7 @@ fi # Instead of attempting to deal with various line ending issues, just export # the find_python script manually. ${svn:-svn} export -q -r "$REVISION" \ - "http://svn.apache.org/repos/asf/subversion/$REPOS_PATH/build/find_python.sh" \ + "https://svn.apache.org/repos/asf/subversion/$REPOS_PATH/build/find_python.sh" \ --username none --password none "$DIST_SANDBOX/find_python.sh" PYTHON="`$DIST_SANDBOX/find_python.sh`" if test -z "$PYTHON"; then @@ -297,7 +298,7 @@ echo "Running po-update.sh in sandbox, t # Can't use the po-update.sh in the packaged export since it might have CRLF # line endings, in which case it won't run. So first we export it again. ${svn:-svn} export -q -r "$REVISION" \ - "http://svn.apache.org/repos/asf/subversion/$REPOS_PATH/tools/po/po-update.sh" \ + "https://svn.apache.org/repos/asf/subversion/$REPOS_PATH/tools/po/po-update.sh" \ --username none --password none "$DIST_SANDBOX/po-update.sh" (cd "$DISTPATH" && ../po-update.sh pot) || exit 1 @@ -369,9 +370,10 @@ sign_file() fi } -# allow md5sum and sha1sum tool names to be overridden +# allow md5sum, sha1sum, and sha512sum tool names to be overridden [ -n "$MD5SUM" ] || MD5SUM=md5sum [ -n "$SHA1SUM" ] || SHA1SUM=sha1sum +[ -n "$SHA512SUM" ] || SHA512SUM=sha512sum echo "" echo "Done:" @@ -387,6 +389,12 @@ if [ -z "$ZIP" ]; then echo "sha1sums:" $SHA1SUM "$DISTNAME.tar.bz2" "$DISTNAME.tar.gz" fi + type $SHA512SUM > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "" + echo "sha512sums:" + $SHA512SUM "$DISTNAME.tar.bz2" "$DISTNAME.tar.gz" + fi else ls -l "$DISTNAME.zip" sign_file $DISTNAME.zip @@ -399,4 +407,10 @@ else echo "sha1sum:" $SHA1SUM "$DISTNAME.zip" fi + type $SHA512SUM > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "" + echo "sha512sum:" + $SHA512SUM "$DISTNAME.zip" + fi fi Modified: subversion/branches/shelve-checkpoint3/tools/dist/release.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/dist/release.py?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/dist/release.py (original) +++ subversion/branches/shelve-checkpoint3/tools/dist/release.py Thu Aug 24 08:42:40 2017 @@ -166,6 +166,27 @@ class Version(object): else: return 'supported-releases' + def get_ver_tags(self, revnum): + # These get substituted into svn_version.h + ver_tag = '' + ver_numtag = '' + if self.pre == 'alpha': + ver_tag = '" (Alpha %d)"' % self.pre_num + ver_numtag = '"-alpha%d"' % self.pre_num + elif self.pre == 'beta': + ver_tag = '" (Beta %d)"' % args.version.pre_num + ver_numtag = '"-beta%d"' % self.pre_num + elif self.pre == 'rc': + ver_tag = '" (Release Candidate %d)"' % self.pre_num + ver_numtag = '"-rc%d"' % self.pre_num + elif self.pre == 'nightly': + ver_tag = '" (Nightly Build r%d)"' % revnum + ver_numtag = '"-nightly-r%d"' % revnum + else: + ver_tag = '" (r%d)"' % revnum + ver_numtag = '""' + return (ver_tag, ver_numtag) + def __serialize(self): return (self.major, self.minor, self.patch, self.pre, self.pre_num) @@ -199,6 +220,7 @@ class Version(object): return self.pre_num < that.pre_num def __str__(self): + "Return an SVN_VER_NUMBER-formatted string, or 'nightly'." if self.pre: if self.pre == 'nightly': return 'nightly' @@ -219,6 +241,18 @@ def get_prefix(base_dir): def get_tempdir(base_dir): return os.path.join(base_dir, 'tempdir') +def get_workdir(base_dir): + return os.path.join(get_tempdir(base_dir), 'working') + +# The name of this directory is also used to name the tarball and for +# the root of paths within the tarball, e.g. subversion-1.9.5 or +# subversion-nightly-r1800000 +def get_exportdir(base_dir, version, revnum): + if version.pre != 'nightly': + return os.path.join(get_tempdir(base_dir), 'subversion-'+str(version)) + return os.path.join(get_tempdir(base_dir), + 'subversion-%s-r%d' % (version, revnum)) + def get_deploydir(base_dir): return os.path.join(base_dir, 'deploy') @@ -242,13 +276,14 @@ def get_tmplfile(filename): def get_nullfile(): return open(os.path.devnull, 'w') -def run_script(verbose, script): +def run_script(verbose, script, hide_stderr=False): + stderr = None if verbose: stdout = None - stderr = None else: stdout = get_nullfile() - stderr = subprocess.STDOUT + if hide_stderr: + stderr = get_nullfile() for l in script.split('\n'): subprocess.check_call(l.split(), stdout=stdout, stderr=stderr) @@ -483,6 +518,16 @@ def check_copyright_year(repos, branch, check_file('NOTICE') check_file('subversion/libsvn_subr/version.c') +def replace_lines(path, actions): + with open(path, 'r') as old_content: + lines = old_content.readlines() + with open(path, 'w') as new_content: + for line in lines: + for start, pattern, repl in actions: + if line.startswith(start): + line = re.sub(pattern, repl, line) + new_content.write(line) + def roll_tarballs(args): 'Create the release artifacts.' @@ -490,6 +535,7 @@ def roll_tarballs(args): args.branch = 'branches/%d.%d.x' % (args.version.major, args.version.minor) branch = args.branch # shorthand + branch = branch.rstrip('/') # canonicalize for later comparisons logging.info('Rolling release %s from branch %s@%d' % (args.version, branch, args.revnum)) @@ -522,40 +568,163 @@ def roll_tarballs(args): os.mkdir(get_deploydir(args.base_dir)) - # For now, just delegate to dist.sh to create the actual artifacts - extra_args = '' - if args.version.is_prerelease(): - if args.version.pre == 'nightly': - extra_args = '-nightly' + logging.info('Preparing working copy source') + shutil.rmtree(get_workdir(args.base_dir), True) + run_script(args.verbose, 'svn checkout %s %s' + % (repos + '/' + branch + '@' + str(args.revnum), + get_workdir(args.base_dir))) + + # Exclude stuff we don't want in the tarball, it will not be present + # in the exported tree. + exclude = ['contrib', 'notes'] + if branch != 'trunk': + exclude += ['STATUS'] + if args.version.minor < 7: + exclude += ['packages', 'www'] + cwd = os.getcwd() + os.chdir(get_workdir(args.base_dir)) + run_script(args.verbose, + 'svn update --set-depth exclude %s' % " ".join(exclude)) + os.chdir(cwd) + + if args.patches: + # Assume patches are independent and can be applied in any + # order, no need to sort. + majmin = '%d.%d' % (args.version.major, args.version.minor) + for name in os.listdir(args.patches): + if name.find(majmin) != -1 and name.endswith('patch'): + logging.info('Applying patch %s' % name) + run_script(args.verbose, + '''svn patch %s %s''' + % (os.path.join(args.patches, name), + get_workdir(args.base_dir))) + + # Massage the new version number into svn_version.h. + ver_tag, ver_numtag = args.version.get_ver_tags(args.revnum) + replacements = [('#define SVN_VER_TAG', + '".*"', ver_tag), + ('#define SVN_VER_NUMTAG', + '".*"', ver_numtag), + ('#define SVN_VER_REVISION', + '[0-9][0-9]*', str(args.revnum))] + if args.version.pre != 'nightly': + # SVN_VER_PATCH might change for security releases, e.g., when + # releasing 1.9.7 from the magic revision of 1.9.6. + # + # ### Would SVN_VER_MAJOR / SVN_VER_MINOR ever change? + # ### Note that SVN_VER_MINOR is duplicated in some places, see + # ### <https://subversion.apache.org/docs/community-guide/releasing.html#release-branches> + replacements += [('#define SVN_VER_MAJOR', + '[0-9][0-9]*', str(args.version.major)), + ('#define SVN_VER_MINOR', + '[0-9][0-9]*', str(args.version.minor)), + ('#define SVN_VER_PATCH', + '[0-9][0-9]*', str(args.version.patch))] + replace_lines(os.path.join(get_workdir(args.base_dir), + 'subversion', 'include', 'svn_version.h'), + replacements) + + # Basename for export and tarballs, e.g. subversion-1.9.5 or + # subversion-nightly-r1800000 + exportdir = get_exportdir(args.base_dir, args.version, args.revnum) + basename = os.path.basename(exportdir) + + def export(windows): + shutil.rmtree(exportdir, True) + if windows: + eol_style = "--native-eol CRLF" else: - extra_args = '-%s %d' % (args.version.pre, args.version.pre_num) - # Build Unix last to leave Unix-style svn_version.h for tagging + eol_style = "--native-eol LF" + run_script(args.verbose, "svn export %s %s %s" + % (eol_style, get_workdir(args.base_dir), exportdir)) + + def transform_sql(): + for root, dirs, files in os.walk(exportdir): + for fname in files: + if fname.endswith('.sql'): + run_script(args.verbose, + 'python build/transform_sql.py %s/%s %s/%s' + % (root, fname, root, fname[:-4] + '.h')) + + def clean_autom4te(): + for root, dirs, files in os.walk(get_workdir(args.base_dir)): + for dname in dirs: + if dname.startswith('autom4te') and dname.endswith('.cache'): + shutil.rmtree(os.path.join(root, dname)) + logging.info('Building Windows tarballs') - run_script(args.verbose, '%s/dist.sh -v %s -pr %s -r %d -zip %s' - % (sys.path[0], args.version.base, branch, args.revnum, - extra_args) ) - logging.info('Building UNIX tarballs') - run_script(args.verbose, '%s/dist.sh -v %s -pr %s -r %d %s' - % (sys.path[0], args.version.base, branch, args.revnum, - extra_args) ) + export(windows=True) + os.chdir(exportdir) + transform_sql() + # Can't use the po-update.sh in the Windows export since it has CRLF + # line endings and won't run, so use the one in the working copy. + run_script(args.verbose, + '%s/tools/po/po-update.sh pot' % get_workdir(args.base_dir)) + os.chdir(cwd) + clean_autom4te() # dist.sh does it but pointless on Windows? + os.chdir(get_tempdir(args.base_dir)) + run_script(args.verbose, + 'zip -q -r %s %s' % (basename + '.zip', basename)) + os.chdir(cwd) + + logging.info('Building Unix tarballs') + export(windows=False) + os.chdir(exportdir) + transform_sql() + run_script(args.verbose, + '''tools/po/po-update.sh pot + ./autogen.sh --release''', + hide_stderr=True) # SWIG is noisy + os.chdir(cwd) + clean_autom4te() # dist.sh does it but probably pointless + + # Do not use tar, it's probably GNU tar which produces tar files + # that are not compliant with POSIX.1 when including filenames + # longer than 100 chars. Platforms without a tar that understands + # the GNU tar extension will not be able to extract the resulting + # tar file. Use pax to produce POSIX.1 tar files. + # + # Use the gzip -n flag - this prevents it from storing the + # original name of the .tar file, and far more importantly, the + # mtime of the .tar file, in the produced .tar.gz file. This is + # important, because it makes the gzip encoding reproducable by + # anyone else who has an similar version of gzip, and also uses + # "gzip -9n". This means that committers who want to GPG-sign both + # the .tar.gz and the .tar.bz2 can download the .tar.bz2 (which is + # smaller), and locally generate an exact duplicate of the + # official .tar.gz file. This metadata is data on the temporary + # uncompressed tarball itself, not any of its contents, so there + # will be no effect on end-users. + os.chdir(get_tempdir(args.base_dir)) + run_script(args.verbose, + '''pax -x ustar -w -f %s %s + bzip2 -9fk %s + gzip -9nf %s''' + % (basename + '.tar', basename, + basename + '.tar', + basename + '.tar')) + os.chdir(cwd) # Move the results to the deploy directory logging.info('Moving artifacts and calculating checksums') for e in extns: - if args.version.pre == 'nightly': - filename = 'subversion-nightly.%s' % e - else: - filename = 'subversion-%s.%s' % (args.version, e) - - shutil.move(filename, get_deploydir(args.base_dir)) - filename = os.path.join(get_deploydir(args.base_dir), filename) + filename = basename + '.' + e + filepath = os.path.join(get_tempdir(args.base_dir), filename) + shutil.move(filepath, get_deploydir(args.base_dir)) + filepath = os.path.join(get_deploydir(args.base_dir), filename) m = hashlib.sha1() - m.update(open(filename, 'r').read()) - open(filename + '.sha1', 'w').write(m.hexdigest()) - - shutil.move('svn_version.h.dist', - get_deploydir(args.base_dir) + '/' + 'svn_version.h.dist' - + '-' + str(args.version)) + m.update(open(filepath, 'r').read()) + open(filepath + '.sha1', 'w').write(m.hexdigest()) + m = hashlib.sha512() + m.update(open(filepath, 'r').read()) + open(filepath + '.sha512', 'w').write(m.hexdigest()) + + # Nightlies do not get tagged so do not need the header + if args.version.pre != 'nightly': + shutil.copy(os.path.join(get_workdir(args.base_dir), + 'subversion', 'include', 'svn_version.h'), + os.path.join(get_deploydir(args.base_dir), + 'svn_version.h.dist-%s' % str(args.version))) # And we're done! @@ -592,9 +761,7 @@ def post_candidates(args): target = get_target(args) logging.info('Importing tarballs to %s' % dist_dev_url) - ver = args.version.base - if args.version.pre: - ver = "%s-%s%d" % (ver, args.version.pre, args.version.pre_num) + ver = str(args.version) svn_cmd = ['svn', 'import', '-m', 'Add Subversion %s candidate release artifacts' % ver, '--auto-props', '--config-option', @@ -617,7 +784,7 @@ def create_tag(args): if not args.branch: args.branch = 'branches/%d.%d.x' % (args.version.major, args.version.minor) - branch = secure_repos + '/' + args.branch + branch = secure_repos + '/' + args.branch.rstrip('/') tag = secure_repos + '/tags/' + str(args.version) @@ -631,7 +798,12 @@ def create_tag(args): tag + '/subversion/include/svn_version.h'] # don't redirect stdout/stderr since svnmucc might ask for a password - subprocess.check_call(svnmucc_cmd) + try: + subprocess.check_call(svnmucc_cmd) + except subprocess.CalledProcessError: + if args.version.is_prerelease(): + logging.error("Do you need to pass --branch=trunk?") + raise if not args.version.is_prerelease(): logging.info('Bumping revisions on the branch') @@ -702,7 +874,9 @@ def clean_dist(args): versions = set(map(Version, filenames)) minor_lines = set(map(minor, versions)) to_keep = set() - for recent_line in sorted(minor_lines, reverse=True)[:2]: + # Keep 3 minor lines: 1.10.0-alpha3, 1.9.7, 1.8.19. + # TODO: When we release 1.A.0 GA we'll have to manually remove 1.(A-2).* artifacts. + for recent_line in sorted(minor_lines, reverse=True)[:3]: to_keep.add(max( x for x in versions if minor(x) == recent_line @@ -763,6 +937,7 @@ def write_news(args): 'version' : str(args.version), 'version_base' : args.version.base, 'anchor': args.version.get_download_anchor(), + 'is_recommended': ezt_bool(args.version.is_recommended()), } if args.version.is_prerelease(): @@ -775,7 +950,7 @@ def write_news(args): template.generate(sys.stdout, data) -def get_sha1info(args, replace=False): +def get_sha1info(args): 'Return a list of sha1 info for the release' target = get_target(args) @@ -789,12 +964,7 @@ def get_sha1info(args, replace=False): for s in sha1s: i = info() # strip ".sha1" - fname = os.path.basename(s)[:-5] - if replace: - # replace the version number with the [version] reference - i.filename = Version.regex.sub('[version]', fname) - else: - i.filename = fname + i.filename = os.path.basename(s)[:-5] i.sha1 = open(s, 'r').read() sha1info.append(i) @@ -837,7 +1007,7 @@ def write_announcement(args): def write_downloads(args): 'Output the download section of the website.' - sha1info = get_sha1info(args, replace=True) + sha1info = get_sha1info(args) data = { 'version' : str(args.version), 'fileinfo' : sha1info, @@ -852,6 +1022,7 @@ def write_downloads(args): # Validate the signatures for a release key_start = '-----BEGIN PGP SIGNATURE-----' +key_end = '-----END PGP SIGNATURE-----' PUBLIC_KEY_ALGORITHMS = { # These values are taken from the RFC's registry at: @@ -886,9 +1057,27 @@ def get_siginfo(args, quiet=False): text = open(filename).read() keys = text.split(key_start) + # Check the keys file syntax. We've been bitten in the past + # with syntax errors in the key delimiters that GPG didn't + # catch for us, but the ASF key checker tool did. + if keys[0]: + sys.stderr.write("SYNTAX ERROR: %s does not start with '%s'\n" + % (filename, key_start)) + sys.exit(1) + keys = keys[1:] + if not quiet: - logging.info("Checking %d sig(s) in %s" % (len(keys[1:]), filename)) - for key in keys[1:]: + logging.info("Checking %d sig(s) in %s" % (len(keys), filename)) + + n = 0 + for key in keys: + n += 1 + if not key.rstrip().endswith(key_end): + sys.stderr.write("SYNTAX ERROR: Key %d in %s" + " does not end with '%s'\n" + % (n, filename, key_end)) + sys.exit(1) + fd, fn = tempfile.mkstemp() os.write(fd, key_start + key) os.close(fd) @@ -898,7 +1087,8 @@ def get_siginfo(args, quiet=False): if verified.valid: good_sigs[verified.fingerprint] = True else: - sys.stderr.write("BAD SIGNATURE for %s\n" % filename) + sys.stderr.write("BAD SIGNATURE: Key %d in %s\n" + % (n, filename)) if verified.key_id: sys.stderr.write(" key id: %s\n" % verified.key_id) sys.exit(1) @@ -1027,7 +1217,10 @@ def main(): subparser.add_argument('revnum', type=lambda arg: int(arg.lstrip('r')), help='''The revision number to base the release on.''') subparser.add_argument('--branch', - help='''The branch to base the release on.''') + help='''The branch to base the release on, + relative to ^/subversion/.''') + subparser.add_argument('--patches', + help='''The path to the directory containing patches.''') # Setup the parser for the sign-candidates subcommand subparser = subparsers.add_parser('sign-candidates', @@ -1061,7 +1254,8 @@ def main(): subparser.add_argument('revnum', type=lambda arg: int(arg.lstrip('r')), help='''The revision number to base the release on.''') subparser.add_argument('--branch', - help='''The branch to base the release on.''') + help='''The branch to base the release on, + relative to ^/subversion/.''') subparser.add_argument('--username', help='''Username for ''' + secure_repos + '''.''') subparser.add_argument('--target', @@ -1162,6 +1356,9 @@ def main(): os.environ['PATH'] = os.path.join(get_prefix(args.base_dir), 'bin') + ':' \ + os.environ['PATH'] + # Make timestamps in tarballs independent of local timezone + os.environ['TZ'] = 'UTC' + # finally, run the subcommand, and give it the parsed arguments args.func(args) Modified: subversion/branches/shelve-checkpoint3/tools/dist/templates/rc-release-ann.ezt URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/dist/templates/rc-release-ann.ezt?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/dist/templates/rc-release-ann.ezt (original) +++ subversion/branches/shelve-checkpoint3/tools/dist/templates/rc-release-ann.ezt Thu Aug 24 08:42:40 2017 @@ -31,7 +31,7 @@ Apache Subversion open source version co issues, a complete list of [major-minor-patch]-blocking issues can be found here: - http://subversion.tigris.org/issues/buglist.cgi?component=subversion&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&target_milestone=[major-minor-patch] + https://issues.apache.org/jira/issues/?jql=project%20%3D%20SVN%20AND%20resolution%20%3D%20Unresolved%20AND%20fixVersion%20%3D%20[major-minor-patch]%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC A pre-release means the Subversion developers feel that this release is ready for widespread testing by the community. There are known issues Modified: subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-news.ezt URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-news.ezt?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-news.ezt (original) +++ subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-news.ezt Thu Aug 24 08:42:40 2017 @@ -5,8 +5,11 @@ </h3> <p>We are pleased to announce the release of Apache Subversion [version]. - This is the most complete Subversion release to date, and we encourage - users of Subversion to upgrade as soon as reasonable. Please see the +[if-any is_recommended] This is the most complete Subversion release to date, and we encourage + users of Subversion to upgrade as soon as reasonable. +[else] This is the most complete release of the [major-minor].x line to date, + and we encourage all users to upgrade as soon as reasonable. +[end] Please see the <a href="" >release announcement</a> and the <a href="http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES" Modified: subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-release-ann.ezt URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-release-ann.ezt?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-release-ann.ezt (original) +++ subversion/branches/shelve-checkpoint3/tools/dist/templates/stable-release-ann.ezt Thu Aug 24 08:42:40 2017 @@ -1,6 +1,6 @@ From: [email protected] To: [email protected], [email protected], [email protected], [email protected] -[if-any security]Cc: [email protected] +[if-any security]Cc: [email protected], [email protected], [email protected] [end][if-any security]Subject: [[]SECURITY][[]ANNOUNCE] Apache Subversion [version] released [else]Subject: [[]ANNOUNCE] Apache Subversion [version] released [end] Modified: subversion/branches/shelve-checkpoint3/win-tests.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint3/win-tests.py?rev=1806008&r1=1806007&r2=1806008&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint3/win-tests.py (original) +++ subversion/branches/shelve-checkpoint3/win-tests.py Thu Aug 24 08:42:40 2017 @@ -113,7 +113,7 @@ def _usage_exit(): print(" --config-file : Configuration file for tests") print(" --fsfs-sharding : Specify shard size (for fsfs)") print(" --fsfs-packing : Run 'svnadmin pack' automatically") - print(" --fsfs-compression=VAL : Set compression level to VAL (for fsfs)") + print(" --fsfs-compression=VAL : Set compression type to VAL (for fsfs)") print(" -q, --quiet : Deprecated; this is the default.") print(" Use --set-log-level instead.") @@ -191,7 +191,7 @@ memcached_server = None memcached_dir = None skip_c_tests = None dump_load_cross_check = None -fsfs_compression_level = None +fsfs_compression = None for opt, val in opts: if opt in ('-h', '--help'): @@ -287,7 +287,7 @@ for opt, val in opts: memcached_dir = val run_memcached = 1 elif opt == '--fsfs-compression': - fsfs_compression_level = int(val) + fsfs_compression = val # Calculate the source and test directory names abs_srcdir = os.path.abspath("") @@ -1017,6 +1017,7 @@ create_target_dir(CMDLINE_TEST_SCRIPT_NA # Ensure the tests directory is correctly cased abs_builddir = fix_case(abs_builddir) +failed = None daemon = None memcached = None # Run the tests @@ -1112,7 +1113,7 @@ if not test_javahl and not test_swig: opts.memcached_server = memcached_server opts.skip_c_tests = skip_c_tests opts.dump_load_cross_check = dump_load_cross_check - opts.fsfs_compression_level = fsfs_compression_level + opts.fsfs_compression = fsfs_compression th = run_tests.TestHarness(abs_srcdir, abs_builddir, log_file, fail_log_file, opts) old_cwd = os.getcwd() @@ -1330,6 +1331,10 @@ elif test_swig == 'ruby': print('[Test runner reported failure]') failed = True +elif test_swig: + print('Unknown Swig binding type: ' + str(test_swig)) + failed = True + # Stop service daemon, if any if daemon: del daemon
