175
181
/* Function to prepare the whole set of on-disk files to be compared. */
176
182
static svn_error_t *
177
create_comparison_candidates(apr_pool_t *scratch_pool)
183
create_comparison_candidates(struct test_file_definition_t **definitions,
184
const char *testname,
179
187
svn_node_kind_t kind;
180
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
188
apr_pool_t *iterpool = svn_pool_create(pool);
181
189
struct test_file_definition_t *candidate;
182
190
svn_error_t *err = SVN_NO_ERROR;
191
apr_size_t count = 0;
192
const char *test_dir = apr_pstrcat(pool, TEST_DIR_PREFIX,
184
195
/* If there's already a directory named io-test-temp, delete it.
185
196
Doing things this way means that repositories stick around after
186
197
a failure for postmortem analysis, but also that tests can be
187
198
re-run without cleaning out the repositories created by prior
189
SVN_ERR(svn_io_check_path(TEST_DIR, &kind, scratch_pool));
200
SVN_ERR(svn_io_check_path(test_dir, &kind, pool));
191
202
if (kind == svn_node_dir)
192
SVN_ERR(svn_io_remove_dir2(TEST_DIR, TRUE, NULL, NULL, scratch_pool));
203
SVN_ERR(svn_io_remove_dir2(test_dir, TRUE, NULL, NULL, pool));
193
204
else if (kind != svn_node_none)
194
205
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
195
206
"There is already a file named '%s'",
198
SVN_ERR(svn_io_dir_make(TEST_DIR, APR_OS_DEFAULT, scratch_pool));
200
svn_test_add_dir_cleanup(TEST_DIR);
202
for (candidate = test_file_definitions;
209
SVN_ERR(svn_io_dir_make(test_dir, APR_OS_DEFAULT, pool));
211
svn_test_add_dir_cleanup(test_dir);
213
for (candidate = test_file_definitions_template;
203
214
candidate->name != NULL;
218
*definitions = apr_pmemdup(pool, test_file_definitions_template,
219
(count + 1) * sizeof(**definitions));
220
for (candidate = *definitions; candidate->name != NULL; candidate += 1)
206
222
svn_pool_clear(iterpool);
207
err = create_test_file(candidate, scratch_pool, iterpool);
223
err = create_test_file(candidate, testname, pool, iterpool);
507
535
return SVN_NO_ERROR;
538
/* Move the read pointer in FILE to absolute position OFFSET and align
539
* the read buffer to multiples of BLOCK_SIZE. BUFFERED is set only if
540
* FILE actually uses a read buffer. Use POOL for allocations.
543
aligned_seek(apr_file_t *file,
544
apr_size_t block_size,
546
svn_boolean_t buffered,
549
apr_off_t block_start;
552
SVN_ERR(svn_io_file_aligned_seek(file, (apr_off_t)block_size,
553
&block_start, (apr_off_t)offset, pool));
555
/* block start shall be aligned to multiples of block_size.
556
If it isn't, it must be aligned to APR's default block size(pre-1.3 APR)
560
SVN_TEST_ASSERT(block_start % block_size == 0);
561
SVN_TEST_ASSERT(offset - block_start < block_size);
564
/* we must be at the desired offset */
566
SVN_ERR(svn_io_file_seek(file, APR_CUR, ¤t, pool));
567
SVN_TEST_ASSERT(current == (apr_off_t)offset);
572
/* Move the read pointer in FILE to absolute position OFFSET, align the
573
* read buffer to multiples of BLOCK_SIZE and read one byte from that
574
* position. Verify that it matches the CONTENTS for that offset.
575
* BUFFERED is set only if FILE actually uses a read buffer.
576
* Use POOL for allocations.
579
aligned_read_at(apr_file_t *file,
580
svn_stringbuf_t *contents,
581
apr_size_t block_size,
583
svn_boolean_t buffered,
587
SVN_ERR(aligned_seek(file, block_size, offset, buffered, pool));
589
/* the data we read must match whatever we wrote there */
590
SVN_ERR(svn_io_file_getc(&c, file, pool));
591
SVN_TEST_ASSERT(c == contents->data[offset]);
596
/* Verify that aligned seek with the given BLOCK_SIZE works for FILE.
597
* CONTENTS is the data expected from FILE. BUFFERED is set only if FILE
598
* actually uses a read buffer. Use POOL for allocations.
601
aligned_read(apr_file_t *file,
602
svn_stringbuf_t *contents,
603
apr_size_t block_size,
604
svn_boolean_t buffered,
608
apr_size_t offset = 0;
609
const apr_size_t prime = 78427;
611
/* "random" access to different offsets */
612
for (i = 0, offset = prime; i < 10; ++i, offset += prime)
613
SVN_ERR(aligned_read_at(file, contents, block_size,
614
offset % contents->len, buffered, pool));
616
/* we can seek to EOF */
617
SVN_ERR(aligned_seek(file, contents->len, block_size, buffered, pool));
619
/* reversed order access to all bytes */
620
for (i = contents->len; i > 0; --i)
621
SVN_ERR(aligned_read_at(file, contents, block_size, i - 1, buffered,
624
/* forward order access to all bytes */
625
for (i = 0; i < contents->len; ++i)
626
SVN_ERR(aligned_read_at(file, contents, block_size, i, buffered, pool));
632
aligned_seek_test(apr_pool_t *pool)
636
const char *tmp_file;
638
svn_stringbuf_t *contents;
639
const apr_size_t file_size = 100000;
641
/* create a temp folder & schedule it for automatic cleanup */
643
SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "aligned_seek_tmp", pool));
644
SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
645
SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
646
svn_test_add_dir_cleanup(tmp_dir);
648
/* create a temp file with know contents */
650
contents = svn_stringbuf_create_ensure(file_size, pool);
651
for (i = 0; i < file_size; ++i)
652
svn_stringbuf_appendbyte(contents, (char)rand());
654
SVN_ERR(svn_io_write_unique(&tmp_file, tmp_dir, contents->data,
656
svn_io_file_del_on_pool_cleanup, pool));
658
/* now, access read data with varying alignment sizes */
659
SVN_ERR(svn_io_file_open(&f, tmp_file, APR_READ | APR_BUFFERED,
660
APR_OS_DEFAULT, pool));
661
SVN_ERR(aligned_read(f, contents, 0x1000, TRUE, pool)); /* APR default */
662
SVN_ERR(aligned_read(f, contents, 0x8000, TRUE, pool)); /* "unusual" 32K */
663
SVN_ERR(aligned_read(f, contents, 0x10000, TRUE, pool)); /* FSX default */
664
SVN_ERR(aligned_read(f, contents, 0x100000, TRUE, pool)); /* larger than file */
665
SVN_ERR(aligned_read(f, contents, 10001, TRUE, pool)); /* odd, larger than
667
SVN_ERR(aligned_read(f, contents, 1003, TRUE, pool)); /* odd, smaller than
669
SVN_ERR(svn_io_file_close(f, pool));
671
/* now, try read data with buffering disabled.
672
That are a special case because APR reports a buffer size of 0. */
673
SVN_ERR(svn_io_file_open(&f, tmp_file, APR_READ, APR_OS_DEFAULT, pool));
674
SVN_ERR(aligned_read(f, contents, 0x1000, FALSE, pool));
675
SVN_ERR(aligned_read(f, contents, 0x8000, FALSE, pool));
676
SVN_ERR(aligned_read(f, contents, 0x10000, FALSE, pool));
677
SVN_ERR(aligned_read(f, contents, 0x100000, FALSE, pool));
678
SVN_ERR(aligned_read(f, contents, 10001, FALSE, pool));
679
SVN_ERR(aligned_read(f, contents, 1003, FALSE, pool));
680
SVN_ERR(svn_io_file_close(f, pool));
686
ignore_enoent(apr_pool_t *pool)
688
const char *tmp_dir, *path;
689
const svn_io_dirent2_t *dirent_p;
692
/* Create an empty directory. */
693
SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "ignore_enoent", pool));
694
SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
695
SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
696
svn_test_add_dir_cleanup(tmp_dir);
698
/* Path does not exist. */
699
path = svn_dirent_join(tmp_dir, "not-present", pool);
700
SVN_ERR(svn_io_remove_dir2(path, TRUE, NULL, NULL, pool));
701
SVN_ERR(svn_io_remove_file2(path, TRUE, pool));
702
SVN_ERR(svn_io_set_file_read_only(path, TRUE, pool));
703
SVN_ERR(svn_io_set_file_read_write(path, TRUE, pool));
704
SVN_ERR(svn_io_set_file_executable(path, TRUE, TRUE, pool));
705
SVN_ERR(svn_io_set_file_executable(path, FALSE, TRUE, pool));
706
SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, TRUE, TRUE, pool, pool));
707
SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, FALSE, TRUE, pool, pool));
709
/* Neither path nor parent exists. */
710
path = svn_dirent_join(path, "not-present", pool);
711
SVN_ERR(svn_io_remove_dir2(path, TRUE, NULL, NULL, pool));
712
SVN_ERR(svn_io_remove_file2(path, TRUE, pool));
713
SVN_ERR(svn_io_set_file_read_only(path, TRUE, pool));
714
SVN_ERR(svn_io_set_file_read_write(path, TRUE, pool));
715
SVN_ERR(svn_io_set_file_executable(path, TRUE, TRUE, pool));
716
SVN_ERR(svn_io_set_file_executable(path, FALSE, TRUE, pool));
717
SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, TRUE, TRUE, pool, pool));
718
SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, FALSE, TRUE, pool, pool));
720
/* File does exist. */
721
path = svn_dirent_join(tmp_dir, "present", pool);
722
SVN_ERR(svn_io_file_open(&file, path,
723
APR_WRITE | APR_CREATE | APR_TRUNCATE,
726
SVN_ERR(svn_io_file_close(file, pool));
728
/* Path does not exist as child of file. */
729
path = svn_dirent_join(path, "not-present", pool);
730
SVN_ERR(svn_io_remove_dir2(path, TRUE, NULL, NULL, pool));
731
SVN_ERR(svn_io_remove_file2(path, TRUE, pool));
732
SVN_ERR(svn_io_set_file_read_only(path, TRUE, pool));
733
SVN_ERR(svn_io_set_file_read_write(path, TRUE, pool));
734
SVN_ERR(svn_io_set_file_executable(path, TRUE, TRUE, pool));
735
SVN_ERR(svn_io_set_file_executable(path, FALSE, TRUE, pool));
736
SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, TRUE, TRUE, pool, pool));
737
SVN_ERR(svn_io_stat_dirent2(&dirent_p, path, FALSE, TRUE, pool, pool));
743
test_install_stream_to_longpath(apr_pool_t *pool)
746
const char *final_abspath;
747
const char *deep_dir;
748
svn_stream_t *stream;
749
svn_stringbuf_t *actual_content;
752
/* Create an empty directory. */
753
SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "test_install_stream_to_longpath",
755
SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
756
SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
757
svn_test_add_dir_cleanup(tmp_dir);
761
/* Generate very long path (> 260 symbols) */
762
for (i = 0; i < 26; i++)
764
deep_dir = svn_dirent_join(deep_dir, "1234567890", pool);
765
SVN_ERR(svn_io_make_dir_recursively(deep_dir, pool));
768
final_abspath = svn_dirent_join(deep_dir, "stream1", pool);
769
SVN_ERR(svn_stream__create_for_install(&stream, deep_dir, pool, pool));
770
SVN_ERR(svn_stream_puts(stream, "stream1 content"));
771
SVN_ERR(svn_stream_close(stream));
772
SVN_ERR(svn_stream__install_stream(stream,
777
SVN_ERR(svn_stringbuf_from_file2(&actual_content,
781
SVN_TEST_STRING_ASSERT(actual_content->data, "stream1 content");
511
786
/* The test table. */
513
struct svn_test_descriptor_t test_funcs[] =
788
static int max_threads = 3;
790
static struct svn_test_descriptor_t test_funcs[] =
516
793
SVN_TEST_PASS2(test_two_file_size_comparison,