📄 random-test.c
字号:
/*
* random-test.c: Test delta generation and application using random data.
*
* ====================================================================
* Copyright (c) 2000-2004 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
*/
#include <assert.h>
#define APR_WANT_STDIO
#define APR_WANT_STRFUNC
#include <apr_want.h>
#include <apr_general.h>
#include <apr_getopt.h>
#include <apr_file_io.h>
#include "svn_delta.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_test.h"
#include "../../libsvn_delta/delta.h"
#include "delta-window-test.h"
#define DEFAULT_ITERATIONS 30
#define DEFAULT_MAXLEN (100 * 1024)
#define DEFAULT_DUMP_FILES 0
#define DEFAULT_PRINT_WINDOWS 0
#define SEEDS 50
#define MAXSEQ 100
/* Initialize parameters for the random tests. */
extern int test_argc;
extern const char **test_argv;
static void init_params (apr_uint32_t *seed,
apr_uint32_t *maxlen, int *iterations,
int *dump_files, int *print_windows,
const char **random_bytes,
apr_uint32_t *bytes_range,
apr_pool_t *pool)
{
apr_getopt_t *opt;
char optch;
const char *opt_arg;
apr_status_t status;
*seed = (apr_uint32_t) apr_time_now();
*maxlen = DEFAULT_MAXLEN;
*iterations = DEFAULT_ITERATIONS;
*dump_files = DEFAULT_DUMP_FILES;
*print_windows = DEFAULT_PRINT_WINDOWS;
*random_bytes = NULL;
*bytes_range = 256;
apr_getopt_init (&opt, pool, test_argc, test_argv);
while (APR_SUCCESS
== (status = apr_getopt (opt, "s:l:n:r:FW", &optch, &opt_arg)))
{
switch (optch)
{
case 's':
*seed = atol (opt_arg);
break;
case 'l':
*maxlen = atoi (opt_arg);
break;
case 'n':
*iterations = atoi (opt_arg);
break;
case 'r':
*random_bytes = opt_arg + 1;
*bytes_range = strlen (*random_bytes);
break;
case 'F':
*dump_files = !*dump_files;
break;
case 'W':
*print_windows = !*print_windows;
break;
}
}
}
/* Open a temporary file. */
static apr_file_t *
open_tempfile (const char *name_template, apr_pool_t *pool)
{
apr_status_t apr_err;
apr_file_t *fp = NULL;
char *templ;
if (!name_template)
templ = apr_pstrdup (pool, "tempfile_XXXXXX");
else
templ = apr_pstrdup (pool, name_template);
apr_err = apr_file_mktemp (&fp, templ, 0, pool);
assert (apr_err == 0);
assert (fp != NULL);
return fp;
}
/* Rewind the file pointer */
static void rewind_file (apr_file_t *fp)
{
apr_off_t offset = 0;
#ifndef NDEBUG
apr_status_t apr_err =
#endif
apr_file_seek (fp, APR_SET, &offset);
assert (apr_err == 0);
assert (offset == 0);
}
static void
dump_file_contents (apr_file_t *fp)
{
static char file_buffer[10240];
apr_size_t length = sizeof file_buffer;
fputs ("--------\n", stdout);
do
{
apr_file_read_full (fp, file_buffer, sizeof file_buffer, &length);
fwrite (file_buffer, 1, length, stdout);
}
while (length == sizeof file_buffer);
putc ('\n', stdout);
rewind_file (fp);
}
/* Generate a temporary file containing sort-of random data. Diffs
between files of random data tend to be pretty boring, so we try to
make sure there are a bunch of common substrings between two runs
of this function with the same seedbase. */
static apr_file_t *
generate_random_file (apr_uint32_t maxlen,
apr_uint32_t subseed_base,
apr_uint32_t *seed,
const char *random_bytes,
apr_uint32_t bytes_range,
int dump_files,
apr_pool_t *pool)
{
static char file_buffer[10240];
char *buf = file_buffer;
char *const end = buf + sizeof file_buffer;
apr_uint32_t len, seqlen;
apr_file_t *fp;
unsigned long r;
fp = open_tempfile ("random_XXXXXX", pool);
len = svn_test_rand (seed) % maxlen; /* We might go over this by a bit. */
while (len > 0)
{
/* Generate a pseudo-random sequence of up to MAXSEQ bytes,
where the seed is in the range [seedbase..seedbase+MAXSEQ-1].
(Use our own pseudo-random number generator here to avoid
clobbering the seed of the libc random number generator.) */
seqlen = svn_test_rand (seed) % MAXSEQ;
if (seqlen > len) seqlen = len;
len -= seqlen;
r = subseed_base + svn_test_rand (seed) % SEEDS;
while (seqlen-- > 0)
{
const int ch = (random_bytes
? (unsigned)random_bytes[r % bytes_range]
: r % bytes_range);
if (buf == end)
{
apr_size_t ignore_length;
apr_file_write_full (fp, file_buffer, sizeof file_buffer,
&ignore_length);
buf = file_buffer;
}
*buf++ = ch;
r = r * 1103515245 + 12345;
}
}
if (buf > file_buffer)
{
apr_size_t ignore_length;
apr_file_write_full (fp, file_buffer, buf - file_buffer, &ignore_length);
buf = file_buffer;
}
rewind_file (fp);
if (dump_files)
dump_file_contents (fp);
return fp;
}
/* Compare two open files. The file positions may change. */
static svn_error_t *
compare_files (apr_file_t *f1, apr_file_t *f2, int dump_files)
{
static char file_buffer_1[10240];
static char file_buffer_2[10240];
char *c1, *c2;
apr_off_t pos = 0;
apr_size_t len1, len2;
rewind_file (f1);
rewind_file (f2);
if (dump_files)
dump_file_contents (f2);
do
{
apr_file_read_full(f1, file_buffer_1, sizeof file_buffer_1, &len1);
apr_file_read_full(f2, file_buffer_2, sizeof file_buffer_2, &len2);
for (c1 = file_buffer_1, c2 = file_buffer_2;
c1 < file_buffer_1 + len1 && c2 < file_buffer_2 + len2;
++c1, ++c2, ++pos)
{
if (*c1 != *c2)
return svn_error_createf (SVN_ERR_TEST_FAILED, NULL,
"mismatch at position %"APR_OFF_T_FMT,
pos);
}
if (len1 != len2)
return svn_error_createf (SVN_ERR_TEST_FAILED, NULL,
"unequal file sizes at position"
" %"APR_OFF_T_FMT, pos);
}
while (len1 == sizeof file_buffer_1);
return SVN_NO_ERROR;
}
static apr_file_t *
copy_tempfile (apr_file_t *fp, apr_pool_t *pool)
{
static char file_buffer[10240];
apr_file_t *newfp;
apr_size_t length1, length2;
newfp = open_tempfile ("copy_XXXXXX", pool);
rewind_file (fp);
do
{
apr_file_read_full (fp, file_buffer, sizeof file_buffer, &length1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -