You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/04/03 15:32:54 UTC
svn commit: r1308894 [11/14] - in /subversion/branches/ev2-export: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/ notes/
notes/directory-index/ notes/wc-ng/ subversion/bindings/javahl/
subversion/bindings/swig/perl/native/t/ sub...
Modified: subversion/branches/ev2-export/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/svntest/main.py?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/svntest/main.py Tue Apr 3 13:32:48 2012
@@ -23,18 +23,18 @@
# under the License.
######################################################################
-import sys # for argv[]
+import sys
import os
-import shutil # for rmtree()
+import shutil
import re
-import stat # for ST_MODE
+import stat
import subprocess
-import time # for time()
-import traceback # for print_exc()
+import time
import threading
-import optparse # for argument parsing
+import optparse
import xml
import urllib
+import logging
try:
# Python >=3.0
@@ -78,6 +78,22 @@ SVN_VER_MINOR = 8
default_num_threads = 5
+# This enables both a time stamp prefix on all log lines and a
+# '<TIME = 0.042552>' line after running every external command.
+log_with_timestamps = True
+
+# Set up logging
+logger = logging.getLogger()
+handler = logging.StreamHandler(sys.stdout)
+if log_with_timestamps:
+ formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s',
+ '%Y-%m-%d %H:%M:%S')
+else:
+ formatter = logging.Formatter('[%(levelname)s] %(message)s')
+handler.setFormatter(formatter)
+logger.addHandler(handler)
+
+
class SVNProcessTerminatedBySignal(Failure):
"Exception raised if a spawned process segfaulted, aborted, etc."
pass
@@ -105,7 +121,7 @@ class SVNRepositoryCreateFailure(Failure
# Windows specifics
if sys.platform == 'win32':
windows = True
- file_scheme_prefix = 'file:///'
+ file_scheme_prefix = 'file:'
_exe = '.exe'
_bat = '.bat'
os.environ['SVN_DBG_STACKTRACES_TO_STDERR'] = 'y'
@@ -132,23 +148,6 @@ wc_author2 = 'jconstant' # use the same
# Set C locale for command line programs
os.environ['LC_ALL'] = 'C'
-# This function mimics the Python 2.3 urllib function of the same name.
-def pathname2url(path):
- """Convert the pathname PATH from the local syntax for a path to the form
- used in the path component of a URL. This does not produce a complete URL.
- The return value will already be quoted using the quote() function."""
-
- # Don't leave ':' in file://C%3A/ escaped as our canonicalization
- # rules will replace this with a ':' on input.
- return urllib_parse_quote(path.replace('\\', '/')).replace('%3A', ':')
-
-# This function mimics the Python 2.3 urllib function of the same name.
-def url2pathname(path):
- """Convert the path component PATH from an encoded URL to the local syntax
- for a path. This does not accept a complete URL. This function uses
- unquote() to decode PATH."""
- return os.path.normpath(urllib_parse_unquote(path))
-
######################################################################
# The locations of the svn, svnadmin and svnlook binaries, relative to
# the only scripts that import this file right now (they live in ../).
@@ -444,22 +443,16 @@ def wait_on_pipe(waiter, binary_mode, st
exit_signal = exit_code
if stdout_lines is not None:
- sys.stdout.write("".join(stdout_lines))
- sys.stdout.flush()
+ logger.info("".join(stdout_lines))
if stderr_lines is not None:
- sys.stderr.write("".join(stderr_lines))
- sys.stderr.flush()
- if options.verbose:
- # show the whole path to make it easier to start a debugger
- sys.stderr.write("CMD: %s terminated by signal %d\n"
- % (command_string, exit_signal))
- sys.stderr.flush()
+ logger.warning("".join(stderr_lines))
+ # show the whole path to make it easier to start a debugger
+ logger.warning("CMD: %s terminated by signal %d"
+ % (command_string, exit_signal))
raise SVNProcessTerminatedBySignal
else:
- if exit_code and options.verbose:
- sys.stderr.write("CMD: %s exited with %d\n"
- % (command_string, exit_code))
- sys.stderr.flush()
+ if exit_code:
+ logger.info("CMD: %s exited with %d" % (command_string, exit_code))
return stdout_lines, stderr_lines, exit_code
def spawn_process(command, bufsize=0, binary_mode=0, stdin_lines=None,
@@ -477,10 +470,9 @@ def spawn_process(command, bufsize=0, bi
raise TypeError("stdin_lines should have list type")
# Log the command line
- if options.verbose and not command.endswith('.py'):
- sys.stdout.write('CMD: %s %s\n' % (os.path.basename(command),
- ' '.join([_quote_arg(x) for x in varargs])))
- sys.stdout.flush()
+ if not command.endswith('.py'):
+ logger.info('CMD: %s %s' % (os.path.basename(command),
+ ' '.join([_quote_arg(x) for x in varargs])))
infile, outfile, errfile, kid = open_pipe([command] + list(varargs), bufsize)
@@ -511,8 +503,7 @@ def run_command_stdin(command, error_exp
If ERROR_EXPECTED is None, any stderr output will be printed and any
stderr output or a non-zero exit code will raise an exception."""
- if options.verbose:
- start = time.time()
+ start = time.time()
exit_code, stdout_lines, stderr_lines = spawn_process(command,
bufsize,
@@ -520,18 +511,17 @@ def run_command_stdin(command, error_exp
stdin_lines,
*varargs)
- if options.verbose:
+ if log_with_timestamps:
stop = time.time()
- print('<TIME = %.6f>' % (stop - start))
- for x in stdout_lines:
- sys.stdout.write(x)
- for x in stderr_lines:
- sys.stdout.write(x)
+ logger.info('<TIME = %.6f>' % (stop - start))
+ for x in stdout_lines:
+ logger.info(x.rstrip())
+ for x in stderr_lines:
+ logger.info(x.rstrip())
if (not error_expected) and ((stderr_lines) or (exit_code != 0)):
- if not options.verbose:
- for x in stderr_lines:
- sys.stdout.write(x)
+ for x in stderr_lines:
+ logger.warning(x.rstrip())
raise Failure
return exit_code, \
@@ -873,11 +863,10 @@ def copy_repos(src_path, dst_path, head_
if ignore_uuid:
load_args = load_args + ['--ignore-uuid']
- if options.verbose:
- sys.stdout.write('CMD: %s %s | %s %s\n' %
+
+ logger.info('CMD: %s %s | %s %s' %
(os.path.basename(svnadmin_binary), ' '.join(dump_args),
os.path.basename(svnadmin_binary), ' '.join(load_args)))
- sys.stdout.flush()
start = time.time()
dump_in, dump_out, dump_err, dump_kid = open_pipe(
@@ -886,10 +875,6 @@ def copy_repos(src_path, dst_path, head_
[svnadmin_binary] + load_args,
stdin=dump_out) # Attached to dump_kid
- stop = time.time()
- if options.verbose:
- print('<TIME = %.6f>' % (stop - start))
-
load_stdout, load_stderr, load_exit_code = wait_on_pipe(load_kid, True)
dump_stdout, dump_stderr, dump_exit_code = wait_on_pipe(dump_kid, True)
@@ -900,6 +885,10 @@ def copy_repos(src_path, dst_path, head_
load_out.close()
load_err.close()
+ if log_with_timestamps:
+ stop = time.time()
+ logger.info('<TIME = %.6f>' % (stop - start))
+
if saved_quiet is None:
del os.environ['SVN_DBG_QUIET']
else:
@@ -1145,6 +1134,9 @@ def is_os_darwin():
def is_fs_case_insensitive():
return (is_os_darwin() or is_os_windows())
+def is_threaded_python():
+ return True
+
def server_has_mergeinfo():
return options.server_minor_version >= 5
@@ -1201,7 +1193,7 @@ class TestSpawningThread(threading.Threa
args.append('--fs-type=' + options.fs_type)
if options.test_area_url:
args.append('--url=' + options.test_area_url)
- if options.verbose:
+ if logger.getEffectiveLevel() <= logging.DEBUG:
args.append('-v')
if options.cleanup:
args.append('--cleanup')
@@ -1275,7 +1267,7 @@ class TestRunner:
# If there is no filter or this test made if through
# the filter then print it!
if options.milestone_filter is None or len(issues):
- if options.verbose and self.pred.inprogress:
+ if self.pred.inprogress:
tail += " [[%s]]" % self.pred.inprogress
else:
print(" %3d %-5s %s%s" % (self.index,
@@ -1347,32 +1339,29 @@ class TestRunner:
result = svntest.testcase.RESULT_SKIP
except Failure, ex:
result = svntest.testcase.RESULT_FAIL
+ msg = ''
# We captured Failure and its subclasses. We don't want to print
# anything for plain old Failure since that just indicates test
# failure, rather than relevant information. However, if there
# *is* information in the exception's arguments, then print it.
if ex.__class__ != Failure or ex.args:
ex_args = str(ex)
- print('CWD: %s' % os.getcwd())
+ logger.warn('CWD: %s' % os.getcwd())
if ex_args:
- print('EXCEPTION: %s: %s' % (ex.__class__.__name__, ex_args))
+ msg = 'EXCEPTION: %s: %s' % (ex.__class__.__name__, ex_args)
else:
- print('EXCEPTION: %s' % ex.__class__.__name__)
- traceback.print_exc(file=sys.stdout)
- sys.stdout.flush()
+ msg = 'EXCEPTION: %s' % ex.__class__.__name__
+ logger.warn(msg, exc_info=True)
except KeyboardInterrupt:
- print('Interrupted')
+ logger.error('Interrupted')
sys.exit(0)
except SystemExit, ex:
- print('EXCEPTION: SystemExit(%d), skipping cleanup' % ex.code)
+ logger.error('EXCEPTION: SystemExit(%d), skipping cleanup' % ex.code)
self._print_name(ex.code and 'FAIL: ' or 'PASS: ')
raise
except:
result = svntest.testcase.RESULT_FAIL
- print('CWD: %s' % os.getcwd())
- print('UNEXPECTED EXCEPTION:')
- traceback.print_exc(file=sys.stdout)
- sys.stdout.flush()
+ logger.warn('CWD: %s' % os.getcwd(), exc_info=True)
os.chdir(saved_dir)
exit_code, result_text, result_benignity = self.pred.results(result)
@@ -1490,6 +1479,12 @@ def create_default_options():
def _create_parser():
"""Return a parser for our test suite."""
+ def set_log_level(option, opt, value, parser, level=None):
+ if level:
+ logger.setLevel(level)
+ else:
+ logger.setLevel(value)
+
# set up the parser
_default_http_library = 'serf'
usage = 'usage: %prog [options] [<test> ...]'
@@ -1498,8 +1493,10 @@ def _create_parser():
help='Print test doc strings instead of running them')
parser.add_option('--milestone-filter', action='store', dest='milestone_filter',
help='Limit --list to those with target milestone specified')
- parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
- help='Print binary command-lines (not with --quiet)')
+ parser.add_option('-v', '--verbose', action='callback',
+ callback=set_log_level, callback_args=(logging.DEBUG, ),
+ help='Print binary command-lines (same as ' +
+ '"--set-log-level logging.DEBUG")')
parser.add_option('-q', '--quiet', action='store_true',
help='Print only unexpected results (not with --verbose)')
parser.add_option('-p', '--parallel', action='store_const',
@@ -1537,6 +1534,8 @@ def _create_parser():
help='Default shard size (for fsfs)')
parser.add_option('--config-file', action='store',
help="Configuration file for tests.")
+ parser.add_option('--set-log-level', action='callback', type='str',
+ callback=set_log_level)
parser.add_option('--keep-local-tmp', action='store_true',
help="Don't remove svn-test-work/local_tmp after test " +
"run is complete. Useful for debugging failures.")
@@ -1551,7 +1550,8 @@ def _create_parser():
# most of the defaults are None, but some are other values, set them here
parser.set_defaults(
server_minor_version=SVN_VER_MINOR,
- url=file_scheme_prefix + pathname2url(os.path.abspath(os.getcwd())),
+ url=file_scheme_prefix + \
+ urllib.pathname2url(os.path.abspath(os.getcwd())),
http_library=_default_http_library)
return parser
@@ -1567,8 +1567,6 @@ def _parse_options(arglist=sys.argv[1:])
(options, args) = parser.parse_args(arglist)
# some sanity checking
- if options.verbose and options.quiet:
- parser.error("'verbose' and 'quiet' are incompatible")
if options.fsfs_packing and not options.fsfs_sharding:
parser.error("--fsfs-packing requires --fsfs-sharding")
@@ -1719,7 +1717,8 @@ def execute_tests(test_list, serial_only
"or function '%s'\n" % arg)
# Calculate pristine_greek_repos_url from test_area_url.
- pristine_greek_repos_url = options.test_area_url + '/' + pathname2url(pristine_greek_repos_dir)
+ pristine_greek_repos_url = options.test_area_url + '/' + \
+ urllib.pathname2url(pristine_greek_repos_dir)
if options.use_jsvn:
if options.svn_bin is None:
Modified: subversion/branches/ev2-export/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/svntest/sandbox.py?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/svntest/sandbox.py Tue Apr 3 13:32:48 2012
@@ -24,9 +24,13 @@
import os
import shutil
import copy
+import urllib
+import logging
import svntest
+logger = logging.getLogger()
+
class Sandbox:
"""Manages a sandbox (one or more repository/working copy pairs) for
@@ -35,10 +39,16 @@ class Sandbox:
dependents = None
def __init__(self, module, idx):
+ self.test_paths = []
+
self._set_name("%s-%d" % (module, idx))
# This flag is set to True by build() and returned by is_built()
self._is_built = False
+ # Create an empty directory for temporary files
+ self.tmp_dir = self.add_wc_path('tmp', remove=True)
+ os.mkdir(self.tmp_dir)
+
def _set_name(self, name, read_only=False):
"""A convenience method for renaming a sandbox, useful when
working with multiple repositories in the same unit test."""
@@ -46,10 +56,12 @@ class Sandbox:
self.name = name
self.read_only = read_only
self.wc_dir = os.path.join(svntest.main.general_wc_dir, self.name)
+ self.add_test_path(self.wc_dir)
if not read_only:
self.repo_dir = os.path.join(svntest.main.general_repo_dir, self.name)
self.repo_url = (svntest.main.options.test_area_url + '/'
- + svntest.main.pathname2url(self.repo_dir))
+ + urllib.pathname2url(self.repo_dir))
+ self.add_test_path(self.repo_dir)
else:
self.repo_dir = svntest.main.pristine_greek_repos_dir
self.repo_url = svntest.main.pristine_greek_repos_url
@@ -73,8 +85,6 @@ class Sandbox:
elif self.repo_url.startswith("svn"):
self.authz_file = os.path.join(self.repo_dir, "conf", "authz")
- self.test_paths = [self.wc_dir, self.repo_dir]
-
def clone_dependent(self, copy_wc=False):
"""A convenience method for creating a near-duplicate of this
sandbox, useful when working with multiple repositories in the
@@ -126,7 +136,7 @@ class Sandbox:
path = (os.path.join(svntest.main.general_repo_dir, self.name)
+ '.' + suffix)
url = svntest.main.options.test_area_url + \
- '/' + svntest.main.pathname2url(path)
+ '/' + urllib.pathname2url(path)
self.add_test_path(path, remove)
return path, url
@@ -147,13 +157,9 @@ class Sandbox:
"""Get a stable name for a temporary file that will be removed after
running the test"""
- dir = self.add_wc_path('tmp')
- if not os.path.exists(dir):
- os.mkdir(dir)
-
self.tempname_offs = self.tempname_offs + 1
- return os.path.join(dir, '%s-%s' % (prefix, self.tempname_offs))
+ return os.path.join(self.tmp_dir, '%s-%s' % (prefix, self.tempname_offs))
def cleanup_test_paths(self):
"Clean up detritus from this sandbox, and any dependents."
@@ -196,17 +202,18 @@ class Sandbox:
temporary and 'TEMP' or 'PERM',
parts[1])
- def simple_update(self, target=None):
+ def simple_update(self, target=None, revision='HEAD'):
"""Update the WC or TARGET.
TARGET is a relpath relative to the WC."""
if target is None:
target = self.wc_dir
else:
target = self.ospath(target)
- svntest.main.run_svn(False, 'update', target)
+ svntest.main.run_svn(False, 'update', target, '-r', revision)
def simple_switch(self, url, target=None):
- """Switch a TARGET to URL"""
+ """Switch the WC or TARGET to URL.
+ TARGET is a relpath relative to the WC."""
if target is None:
target = self.wc_dir
else:
@@ -228,61 +235,72 @@ class Sandbox:
target)
def simple_rm(self, *targets):
- """TARGET is a relpath relative to the WC."""
+ """Schedule TARGETS for deletion.
+ TARGETS are relpaths relative to the WC."""
assert len(targets) > 0
targets = self.ospaths(targets)
svntest.main.run_svn(False, 'rm', *targets)
def simple_mkdir(self, *targets):
- """TARGET is a relpath relative to the WC."""
+ """Create TARGETS as directories scheduled for addition.
+ TARGETS are relpaths relative to the WC."""
assert len(targets) > 0
targets = self.ospaths(targets)
svntest.main.run_svn(False, 'mkdir', *targets)
def simple_add(self, *targets):
- """TARGET is a relpath relative to the WC."""
+ """Schedule TARGETS for addition.
+ TARGETS are relpaths relative to the WC."""
assert len(targets) > 0
targets = self.ospaths(targets)
svntest.main.run_svn(False, 'add', *targets)
def simple_revert(self, *targets):
- """TARGET is a relpath relative to the WC."""
+ """Revert TARGETS.
+ TARGETS are relpaths relative to the WC."""
assert len(targets) > 0
targets = self.ospaths(targets)
svntest.main.run_svn(False, 'revert', *targets)
def simple_propset(self, name, value, *targets):
- """TARGET is a relpath relative to the WC."""
+ """Set property NAME to VALUE on TARGETS.
+ TARGETS are relpaths relative to the WC."""
assert len(targets) > 0
targets = self.ospaths(targets)
svntest.main.run_svn(False, 'propset', name, value, *targets)
def simple_propdel(self, name, *targets):
- """TARGET is a relpath relative to the WC."""
+ """Delete property NAME from TARGETS.
+ TARGETS are relpaths relative to the WC."""
assert len(targets) > 0
targets = self.ospaths(targets)
svntest.main.run_svn(False, 'propdel', name, *targets)
def simple_copy(self, source, dest):
- """SOURCE and DEST are relpaths relative to the WC."""
+ """Copy SOURCE to DEST in the WC.
+ SOURCE and DEST are relpaths relative to the WC."""
source = self.ospath(source)
dest = self.ospath(dest)
svntest.main.run_svn(False, 'copy', source, dest)
def simple_move(self, source, dest):
- """SOURCE and DEST are relpaths relative to the WC."""
+ """Move SOURCE to DEST in the WC.
+ SOURCE and DEST are relpaths relative to the WC."""
source = self.ospath(source)
dest = self.ospath(dest)
svntest.main.run_svn(False, 'move', source, dest)
def simple_repo_copy(self, source, dest):
- """SOURCE and DEST are relpaths relative to the repo root."""
+ """Copy SOURCE to DEST in the repository, committing the result with a
+ default log message.
+ SOURCE and DEST are relpaths relative to the repo root."""
svntest.main.run_svn(False, 'copy', '-m', svntest.main.make_log_msg(),
self.repo_url + '/' + source,
self.repo_url + '/' + dest)
def simple_append(self, dest, contents, truncate=False):
- """Append CONTENTS to file DEST, optionally truncating it first."""
+ """Append CONTENTS to file DEST, optionally truncating it first.
+ DEST is a relpath relative to the WC."""
open(self.ospath(dest), truncate and 'w' or 'a').write(contents)
@@ -306,14 +324,13 @@ def cleanup_deferred_test_paths():
def _cleanup_test_path(path, retrying=False):
- if svntest.main.options.verbose:
- if retrying:
- print("CLEANUP: RETRY: %s" % path)
- else:
- print("CLEANUP: %s" % path)
+ if retrying:
+ logger.info("CLEANUP: RETRY: %s", path)
+ else:
+ logger.info("CLEANUP: %s", path)
+
try:
svntest.main.safe_rmtree(path)
except:
- if svntest.main.options.verbose:
- print("WARNING: cleanup failed, will try again later")
+ logger.info("WARNING: cleanup failed, will try again later")
_deferred_test_paths.append(path)
Modified: subversion/branches/ev2-export/subversion/tests/cmdline/svntest/tree.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/svntest/tree.py?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/svntest/tree.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/svntest/tree.py Tue Apr 3 13:32:48 2012
@@ -31,12 +31,15 @@ if sys.version_info[0] >= 3:
from io import StringIO
else:
# Python <3.0
- from StringIO import StringIO
+ from cStringIO import StringIO
from xml.dom.minidom import parseString
import base64
+import logging
import svntest
+logger = logging.getLogger()
+
# Tree Exceptions.
# All tree exceptions should inherit from SVNTreeError
@@ -569,7 +572,7 @@ def get_child(node, name):
"""If SVNTreeNode NODE contains a child named NAME, return child;
else, return None. If SVNTreeNode is not a directory, exit completely."""
if node.children == None:
- print("Error: Foolish call to get_child.")
+ logger.error("Foolish call to get_child.")
sys.exit(1)
for n in node.children:
if name == n.name:
@@ -581,8 +584,8 @@ def get_child(node, name):
def default_singleton_handler(node, description):
"""Print SVNTreeNode NODE's name, describing it with the string
DESCRIPTION, then raise SVNTreeUnequal."""
- print("Couldn't find node '%s' in %s tree" % (node.name, description))
- node.pprint()
+ logger.warn("Couldn't find node '%s' in %s tree" % (node.name, description))
+ logger.warn(str(node))
raise SVNTreeUnequal
# A test helper function implementing the singleton_handler_a API.
@@ -599,8 +602,8 @@ def detect_conflict_files(node, extra_fi
break
else:
msg = "Encountered unexpected disk path '" + node.name + "'"
- print(msg)
- node.pprint()
+ logger.warn(msg)
+ logger.warn(str(node))
raise SVNTreeUnequal(msg)
###########################################################################
@@ -634,17 +637,20 @@ def compare_trees(label,
def display_nodes(a, b):
'Display two nodes, expected and actual.'
- print("=============================================================")
- print("Expected '%s' and actual '%s' in %s tree are different!"
- % (b.name, a.name, label))
- print("=============================================================")
- print("EXPECTED NODE TO BE:")
- print("=============================================================")
- b.pprint()
- print("=============================================================")
- print("ACTUAL NODE FOUND:")
- print("=============================================================")
- a.pprint()
+ o = StringIO()
+ o.write("=============================================================\n")
+ o.write("Expected '%s' and actual '%s' in %s tree are different!\n"
+ % (b.name, a.name, label))
+ o.write("=============================================================\n")
+ o.write("EXPECTED NODE TO BE:\n")
+ o.write("=============================================================\n")
+ b.pprint(o)
+ o.write("=============================================================\n")
+ o.write("ACTUAL NODE FOUND:\n")
+ o.write("=============================================================\n")
+ a.pprint(o)
+ logger.warn(o.getvalue())
+ o.close()
# Setup singleton handlers
if singleton_handler_a is None:
@@ -690,21 +696,21 @@ def compare_trees(label,
if b_child not in accounted_for:
singleton_handler_b(b_child, b_baton)
except SVNTypeMismatch:
- print('Unequal Types: one Node is a file, the other is a directory')
+ logger.warn('Unequal Types: one Node is a file, the other is a directory')
raise SVNTreeUnequal
except IndexError:
- print("Error: unequal number of children")
+ logger.warn("Error: unequal number of children")
raise SVNTreeUnequal
except SVNTreeUnequal:
if a.name != root_node_name:
- print("Unequal at node %s" % a.name)
+ logger.warn("Unequal at node %s" % a.name)
raise
# Visually show a tree's structure
-def dump_tree(n,indent=""):
+def _dump_tree(n,indent="",stream=sys.stdout):
"""Print out a nice representation of the structure of the tree in
the SVNTreeNode N. Prefix each line with the string INDENT."""
@@ -712,18 +718,25 @@ def dump_tree(n,indent=""):
tmp_children = sorted(n.children or [])
if n.name == root_node_name:
- print("%s%s" % (indent, "ROOT"))
+ stream.write("%s%s\n" % (indent, "ROOT"))
else:
- print("%s%s" % (indent, n.name))
+ stream.write("%s%s\n" % (indent, n.name))
indent = indent.replace("-", " ")
indent = indent.replace("+", " ")
for i in range(len(tmp_children)):
c = tmp_children[i]
if i == len(tmp_children)-1:
- dump_tree(c,indent + " +-- ")
+ _dump_tree(c,indent + " +-- ",stream)
else:
- dump_tree(c,indent + " |-- ")
+ _dump_tree(c,indent + " |-- ",stream)
+
+
+def dump_tree(n):
+ output = StringIO()
+ _dump_tree(n,stream=output)
+ logger.warn(output.getvalue())
+ output.close()
def dump_tree_script__crawler(n, subtree="", stream=sys.stdout):
Modified: subversion/branches/ev2-export/subversion/tests/cmdline/svntest/verify.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/svntest/verify.py?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/svntest/verify.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/svntest/verify.py Tue Apr 3 13:32:48 2012
@@ -27,9 +27,12 @@
import re, sys
from difflib import unified_diff, ndiff
import pprint
+import logging
import svntest
+logger = logging.getLogger()
+
######################################################################
# Exception types
@@ -230,7 +233,7 @@ class AnyOutput(ExpectedOutput):
def display_differences(self, message, label, actual):
if message:
- print(message)
+ logger.warn(message)
class RegexOutput(ExpectedOutput):
@@ -296,12 +299,12 @@ class UnorderedRegexOutput(UnorderedOutp
def display_trees(message, label, expected, actual):
'Print two trees, expected and actual.'
if message is not None:
- print(message)
+ logger.warn(message)
if expected is not None:
- print('EXPECTED %s:' % label)
+ logger.warn('EXPECTED %s:', label)
svntest.tree.dump_tree(expected)
if actual is not None:
- print('ACTUAL %s:' % label)
+ logger.warn('ACTUAL %s:', label)
svntest.tree.dump_tree(actual)
@@ -311,7 +314,7 @@ def display_lines(message, label, expect
with LABEL) followed by ACTUAL (also labeled with LABEL).
Both EXPECTED and ACTUAL may be strings or lists of strings."""
if message is not None:
- print(message)
+ logger.warn(message)
if expected is not None:
output = 'EXPECTED %s' % label
if expected_is_regexp:
@@ -320,17 +323,17 @@ def display_lines(message, label, expect
if expected_is_unordered:
output += ' (unordered)'
output += ':'
- print(output)
+ logger.warn(output)
for x in expected:
sys.stdout.write(x)
if actual is not None:
- print('ACTUAL %s:' % label)
+ logger.warn('ACTUAL %s:', label)
for x in actual:
sys.stdout.write(x)
# Additionally print unified diff
if not expected_is_regexp:
- print('DIFF ' + ' '.join(output.split(' ')[1:]))
+ logger.warn('DIFF ' + ' '.join(output.split(' ')[1:]))
if type(expected) is str:
expected = [expected]
Modified: subversion/branches/ev2-export/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/svntest/wc.py?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/svntest/wc.py Tue Apr 3 13:32:48 2012
@@ -27,9 +27,20 @@ import os
import sys
import re
import urllib
+import logging
+import pprint
+
+if sys.version_info[0] >= 3:
+ # Python >=3.0
+ from io import StringIO
+else:
+ # Python <3.0
+ from cStringIO import StringIO
import svntest
+logger = logging.getLogger()
+
#
# 'status -v' output looks like this:
@@ -362,9 +373,8 @@ class State:
if 0:
check = tree.as_state()
if self != check:
- import pprint
- pprint.pprint(self.desc)
- pprint.pprint(check.desc)
+ logger.warn(pprint.pformat(self.desc))
+ logger.warn(pprint.pformat(check.desc))
# STATE -> TREE -> STATE is lossy.
# In many cases, TREE -> STATE -> TREE is not.
# Even though our conversion from a TREE has lost some information, we
@@ -894,21 +904,29 @@ def display_nodes(label, path, expected,
'Display two nodes, expected and actual.'
expected = item_to_node(path, expected)
actual = item_to_node(path, actual)
- print("=============================================================")
- print("Expected '%s' and actual '%s' in %s tree are different!"
- % (expected.name, actual.name, label))
- print("=============================================================")
- print("EXPECTED NODE TO BE:")
- print("=============================================================")
- expected.pprint()
- print("=============================================================")
- print("ACTUAL NODE FOUND:")
- print("=============================================================")
- actual.pprint()
+
+ o = StringIO()
+ o.write("=============================================================\n")
+ o.write("Expected '%s' and actual '%s' in %s tree are different!\n"
+ % (expected.name, actual.name, label))
+ o.write("=============================================================\n")
+ o.write("EXPECTED NODE TO BE:\n")
+ o.write("=============================================================\n")
+ expected.pprint(o)
+ o.write("=============================================================\n")
+ o.write("ACTUAL NODE FOUND:\n")
+ o.write("=============================================================\n")
+ actual.pprint(o)
+
+ logger.warn(o.getvalue())
+ o.close()
### yanked from tree.py
def default_singleton_handler(description, path, item):
node = item_to_node(path, item)
- print("Couldn't find node '%s' in %s tree" % (node.name, description))
- node.pprint()
+ logger.warn("Couldn't find node '%s' in %s tree" % (node.name, description))
+ o = StringIO()
+ node.pprint(o)
+ logger.warn(o.getvalue())
+ o.close()
raise svntest.tree.SVNTreeUnequal
Modified: subversion/branches/ev2-export/subversion/tests/cmdline/tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/tree_conflict_tests.py?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/tree_conflict_tests.py Tue Apr 3 13:32:48 2012
@@ -38,6 +38,7 @@ from svntest.actions import run_and_veri
from svntest.actions import run_and_verify_info
from svntest.actions import get_virginal_state
import shutil
+import logging
# (abbreviation)
Skip = svntest.testcase.Skip_deco
@@ -49,16 +50,7 @@ Wimp = svntest.testcase.Wimp_deco
Item = svntest.wc.StateItem
AnyOutput = svntest.verify.AnyOutput
-# If verbose mode is enabled, print the LINE and a newline.
-def verbose_print(line):
- if main.options.verbose:
- print(line)
-
-# If verbose mode is enabled, print the (assumed newline-terminated) LINES.
-def verbose_printlines(lines):
- if main.options.verbose:
- for line in lines:
- sys.stdout.write(line)
+logger = logging.getLogger()
######################################################################
# Tests
@@ -388,14 +380,14 @@ def ensure_tree_conflict(sbox, operation
def url_of(repo_relative_path):
return sbox.repo_url + '/' + repo_relative_path
- verbose_print("")
- verbose_print("=== Starting a set of '" + operation + "' tests.")
+ logger.debug("")
+ logger.debug("=== Starting a set of '" + operation + "' tests.")
# Path to source branch, relative to wc_dir.
# Source is where the "incoming" mods are made.
source_br = "branch1"
- verbose_print("--- Creating changes in repos")
+ logger.debug("--- Creating changes in repos")
source_wc_dir = os.path.join(wc_dir, source_br)
source_left_rev, source_right_rev = set_up_repos(wc_dir, source_wc_dir,
incoming_scenarios)
@@ -430,9 +422,9 @@ def ensure_tree_conflict(sbox, operation
source_url = url_of(source_br + '/' + scen_name)
target_path = os.path.join(target_br, scen_name)
- verbose_print("=== " + str(inc_action) + " onto " + str(loc_action))
+ logger.debug("=== " + str(inc_action) + " onto " + str(loc_action))
- verbose_print("--- Making local mods")
+ logger.debug("--- Making local mods")
for modaction in loc_action:
modify(modaction, localmod_paths(".", target_path), is_init=False)
if commit_local_mods:
@@ -444,7 +436,7 @@ def ensure_tree_conflict(sbox, operation
# For update, verify the pre-condition that WC is out of date.
# For switch/merge, there is no such precondition.
if operation == 'update':
- verbose_print("--- Trying to commit (expecting 'out-of-date' error)")
+ logger.debug("--- Trying to commit (expecting 'out-of-date' error)")
run_and_verify_commit(".", None, None, "Commit failed",
target_path)
@@ -462,15 +454,15 @@ def ensure_tree_conflict(sbox, operation
match_all=False)
# Do the main action
if operation == 'update':
- verbose_print("--- Updating")
+ logger.debug("--- Updating")
run_and_verify_svn(None, expected_stdout, [],
'update', target_path)
elif operation == 'switch':
- verbose_print("--- Switching")
+ logger.debug("--- Switching")
run_and_verify_svn(None, expected_stdout, [],
'switch', source_url, target_path)
elif operation == 'merge':
- verbose_print("--- Merging")
+ logger.debug("--- Merging")
run_and_verify_svn(None, expected_stdout, [],
'merge', '--ignore-ancestry',
'--allow-mixed-revisions',
@@ -479,7 +471,7 @@ def ensure_tree_conflict(sbox, operation
else:
raise Exception("unknown operation: '" + operation + "'")
- verbose_print("--- Checking that 'info' reports the conflict")
+ logger.debug("--- Checking that 'info' reports the conflict")
if operation == 'update' or operation == 'switch':
incoming_left_rev = target_start_rev
else:
@@ -495,39 +487,39 @@ def ensure_tree_conflict(sbox, operation
re.escape(victim_name + '@' + str(incoming_right_rev)) + r')' }
run_and_verify_info([expected_info], victim_path)
- verbose_print("--- Trying to commit (expecting 'conflict' error)")
+ logger.debug("--- Trying to commit (expecting 'conflict' error)")
### run_and_verify_commit() requires an "output_tree" argument, but
# here we get away with passing None because we know an implementation
# detail: namely that it's not going to look at that argument if it
# gets the stderr that we're expecting.
run_and_verify_commit(".", None, None, ".*conflict.*", victim_path)
- verbose_print("--- Checking that 'status' reports the conflict")
+ logger.debug("--- Checking that 'status' reports the conflict")
expected_stdout = svntest.verify.RegexOutput("^......C.* " +
re.escape(victim_path) + "$",
match_all=False)
run_and_verify_svn(None, expected_stdout, [],
'status', victim_path)
- verbose_print("--- Resolving the conflict")
+ logger.debug("--- Resolving the conflict")
# Make sure resolving the parent does nothing.
run_and_verify_resolved([], os.path.dirname(victim_path))
# The real resolved call.
run_and_verify_resolved([victim_path])
- verbose_print("--- Checking that 'status' does not report a conflict")
+ logger.debug("--- Checking that 'status' does not report a conflict")
exitcode, stdout, stderr = run_and_verify_svn(None, None, [],
'status', victim_path)
for line in stdout:
if line[6] == 'C': # and line.endswith(victim_path + '\n'):
raise svntest.Failure("unexpected status C") # on victim_path
- # verbose_print("--- Committing (should now succeed)")
+ # logger.debug("--- Committing (should now succeed)")
# run_and_verify_svn(None, None, [],
# 'commit', '-m', '', target_path)
# target_start_rev += 1
- verbose_print("")
+ logger.debug("")
os.chdir(saved_cwd)
@@ -1224,7 +1216,7 @@ def actual_only_node_behaviour(sbox):
"export", foo_path, sbox.get_tempname())
# import
expected_stdout = None
- expected_stderr = ".*foo.*does not exist.*"
+ expected_stderr = ".*(foo.*does not exist|Can't stat.*foo).*"
run_and_verify_svn(None, expected_stdout, expected_stderr,
"import", '-m', svntest.main.make_log_msg(),
foo_path, sbox.repo_url + '/foo_imported')
Modified: subversion/branches/ev2-export/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/update_tests.py?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/update_tests.py Tue Apr 3 13:32:48 2012
@@ -5696,6 +5696,101 @@ def update_moved_dir_file_move(sbox):
None, None, None,
None, None, 1)
+@XFail()
+def update_move_text_mod(sbox):
+ "text mod to moved files"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ svntest.main.file_append(sbox.ospath('A/B/lambda'), "modified\n")
+ svntest.main.file_append(sbox.ospath('A/B/E/beta'), "modified\n")
+ sbox.simple_commit()
+ sbox.simple_update(revision=1)
+
+ sbox.simple_move("A/B/E", "A/E2")
+ sbox.simple_move("A/B/lambda", "A/lambda2")
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', 'A/B/lambda',
+ status='D ')
+ expected_status.add({
+ 'A/E2' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/E2/alpha' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/lambda2' : Item(status='A ', copied='+', wc_rev='-'),
+ })
+
+ svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/lambda2' : Item(status='U '),
+ 'A/E2/beta' : Item(status='U '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E', 'A/B/lambda')
+ expected_disk.add({
+ 'A/E2' : Item(),
+ 'A/E2/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ 'A/E2/beta' : Item(contents="This is the file 'beta'.\nmodified\n"),
+ 'A/lambda2' : Item(contents="This is the file 'lambda'.\nmodified\n"),
+ })
+ expected_status.tweak(wc_rev=2)
+ expected_status.tweak('A/E2', 'A/E2/alpha', 'A/E2/beta', 'A/lambda2',
+ wc_rev='-')
+ ### XFAIL 'A/E2/beta' is status R but should be ' '
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
+
+@XFail()
+def update_nested_move_text_mod(sbox):
+ "text mod to moved file in moved dir"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ svntest.main.file_append(sbox.ospath('A/B/E/alpha'), "modified\n")
+ sbox.simple_commit()
+ sbox.simple_update(revision=1)
+
+ sbox.simple_move("A/B/E", "A/E2")
+ sbox.simple_move("A/E2/alpha", "A/alpha2")
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+ expected_status.add({
+ 'A/E2' : Item(status='A ', copied='+', wc_rev='-'),
+ 'A/E2/alpha' : Item(status='D ', copied='+', wc_rev='-'),
+ 'A/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/alpha2' : Item(status='A ', copied='+', wc_rev='-'),
+ })
+
+ svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/alpha2' : Item(status='U '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+ expected_disk.add({
+ 'A/E2' : Item(),
+ 'A/E2/beta' : Item(contents="This is the file 'beta'.\n"),
+ 'A/alpha2' : Item(contents="This is the file 'alpha'.\nmodified\n"),
+ })
+ expected_status.tweak(wc_rev=2)
+ expected_status.tweak('A/E2', 'A/E2/alpha', 'A/E2/beta', 'A/alpha2',
+ wc_rev='-')
+ ### XFAIL update fails 'No such file'
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None,
+ None, None, 1)
+
+
#######################################################################
# Run the tests
@@ -5768,6 +5863,8 @@ test_list = [ None,
update_moved_dir_dir_add,
update_moved_dir_file_move,
update_binary_file_3,
+ update_move_text_mod,
+ update_nested_move_text_mod,
]
if __name__ == '__main__':
Propchange: subversion/branches/ev2-export/subversion/tests/libsvn_client/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Apr 3 13:32:48 2012
@@ -4,3 +4,4 @@ client-test
test-patch*
test-wc*
test-copy-crash
+test-youngest-common-ancestor
Modified: subversion/branches/ev2-export/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_client/client-test.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/ev2-export/subversion/tests/libsvn_client/client-test.c Tue Apr 3 13:32:48 2012
@@ -572,7 +572,7 @@ test_copy_crash(const svn_test_opts_t *o
/* Create a filesytem and repository containing the Greek tree. */
SVN_ERR(create_greek_repos(&repos_url, "test-copy-crash", opts, pool));
- svn_client_create_context(&ctx, pool);
+ SVN_ERR(svn_client_create_context(&ctx, pool));
rev.kind = svn_opt_revision_head;
dest = svn_path_url_add_component2(repos_url, "A/E", pool);
@@ -668,7 +668,7 @@ test_youngest_common_ancestor(const svn_
/* Create a filesytem and repository containing the Greek tree. */
SVN_ERR(create_greek_repos(&repos_url, "test-youngest-common-ancestor", opts, pool));
- svn_client_create_context(&ctx, pool);
+ SVN_ERR(svn_client_create_context(&ctx, pool));
/* Copy a file into dir 'A', keeping its own basename. */
sources = apr_array_make(pool, 1, sizeof(svn_client_copy_source_t *));
Modified: subversion/branches/ev2-export/subversion/tests/libsvn_delta/random-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_delta/random-test.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/libsvn_delta/random-test.c (original)
+++ subversion/branches/ev2-export/subversion/tests/libsvn_delta/random-test.c Tue Apr 3 13:32:48 2012
@@ -57,7 +57,7 @@ static void init_params(apr_uint32_t *se
apr_uint32_t *maxlen, int *iterations,
int *dump_files, int *print_windows,
const char **random_bytes,
- apr_uint32_t *bytes_range,
+ apr_size_t *bytes_range,
apr_pool_t *pool)
{
apr_getopt_t *opt;
@@ -80,7 +80,7 @@ static void init_params(apr_uint32_t *se
switch (optch)
{
case 's':
- *seed = atol(opt_arg);
+ *seed = (apr_uint32_t) atol(opt_arg);
break;
case 'l':
*maxlen = atoi(opt_arg);
@@ -160,7 +160,7 @@ 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,
+ apr_size_t bytes_range,
int dump_files,
apr_pool_t *pool)
{
@@ -287,7 +287,8 @@ copy_tempfile(apr_file_t *fp, apr_pool_t
static svn_error_t *
random_test(apr_pool_t *pool)
{
- apr_uint32_t seed, bytes_range, maxlen;
+ apr_uint32_t seed, maxlen;
+ apr_size_t bytes_range;
int i, iterations, dump_files, print_windows;
const char *random_bytes;
@@ -365,7 +366,8 @@ static svn_error_t *
do_random_combine_test(apr_pool_t *pool,
apr_uint32_t *last_seed)
{
- apr_uint32_t seed, bytes_range, maxlen;
+ apr_uint32_t seed, maxlen;
+ apr_size_t bytes_range;
int i, iterations, dump_files, print_windows;
const char *random_bytes;
Propchange: subversion/branches/ev2-export/subversion/tests/libsvn_subr/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Apr 3 13:32:48 2012
@@ -11,6 +11,7 @@ Release
checksum-test
compat-test
config-test
+crypto-test
error-test
hashdump-test
hashdump.out
Modified: subversion/branches/ev2-export/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_subr/cache-test.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/ev2-export/subversion/tests/libsvn_subr/cache-test.c Tue Apr 3 13:32:48 2012
@@ -36,7 +36,7 @@
/* Implements svn_cache__serialize_func_t */
static svn_error_t *
-serialize_revnum(char **data,
+serialize_revnum(void **data,
apr_size_t *data_len,
void *in,
apr_pool_t *pool)
@@ -51,7 +51,7 @@ serialize_revnum(char **data,
/* Implements svn_cache__deserialize_func_t */
static svn_error_t *
deserialize_revnum(void **out,
- char *data,
+ void *data,
apr_size_t data_len,
apr_pool_t *pool)
{
Modified: subversion/branches/ev2-export/subversion/tests/libsvn_subr/spillbuf-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_subr/spillbuf-test.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/libsvn_subr/spillbuf-test.c (original)
+++ subversion/branches/ev2-export/subversion/tests/libsvn_subr/spillbuf-test.c Tue Apr 3 13:32:48 2012
@@ -33,42 +33,55 @@ static const char basic_data[] = ("abcde
"0123456789");
+/* Validate that BUF is STARTING_SIZE in length. Then read some data from
+ the buffer, which should match EXPECTED. The EXPECTED value must be
+ NUL-terminated, but the NUL is not part of the expected/verified value. */
+#define CHECK_READ(b, s, e, p) SVN_ERR(check_read(b, s, e, p))
+static svn_error_t *
+check_read(svn_spillbuf_t *buf,
+ svn_filesize_t starting_size,
+ const char *expected,
+ apr_pool_t *scratch_pool)
+{
+ apr_size_t expected_len = strlen(expected);
+ const char *readptr;
+ apr_size_t readlen;
+
+ SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) == starting_size);
+ SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, scratch_pool));
+ SVN_TEST_ASSERT(readptr != NULL
+ && readlen == expected_len
+ && memcmp(readptr, expected, expected_len) == 0);
+ return SVN_NO_ERROR;
+}
+
+
static svn_error_t *
test_spillbuf_basic(apr_pool_t *pool)
{
- svn_spillbuf_t *buf = svn_spillbuf__create(
- sizeof(basic_data) /* blocksize */,
- 10 * sizeof(basic_data) /* maxsize */,
- pool);
+ apr_size_t len = strlen(basic_data); /* Don't include basic_data's NUL */
+ svn_spillbuf_t *buf = svn_spillbuf__create(len, 10 * len, pool);
int i;
+ const char *readptr;
+ apr_size_t readlen;
/* It starts empty. */
SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) == 0);
/* Place enough data into the buffer to cause a spill to disk. */
for (i = 20; i--; )
- SVN_ERR(svn_spillbuf__write(buf, basic_data, sizeof(basic_data), pool));
+ SVN_ERR(svn_spillbuf__write(buf, basic_data, len, pool));
/* And now has content. */
SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) > 0);
- while (TRUE)
- {
- const char *readptr;
- apr_size_t readlen;
-
- SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, pool));
- if (readptr == NULL)
- break;
-
- /* We happen to know that the spill buffer reads data in lengths
- of BLOCKSIZE. */
- SVN_TEST_ASSERT(readlen == sizeof(basic_data));
-
- /* And it should match each block of data we put in. */
- SVN_TEST_ASSERT(memcmp(readptr, basic_data, readlen) == 0);
- }
+ /* Verify that we can read 20 copies of basic_data from the buffer. */
+ for (i = 20; i--; )
+ CHECK_READ(buf, (i + 1) * len, basic_data, pool);
+ /* And after precisely 20 reads, it should be empty. */
+ SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, pool));
+ SVN_TEST_ASSERT(readptr == NULL);
SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) == 0);
return SVN_NO_ERROR;
@@ -197,48 +210,29 @@ test_spillbuf_interleaving(apr_pool_t *p
svn_spillbuf_t *buf = svn_spillbuf__create(8 /* blocksize */,
15 /* maxsize */,
pool);
- const char *readptr;
- apr_size_t readlen;
SVN_ERR(svn_spillbuf__write(buf, "abcdef", 6, pool));
SVN_ERR(svn_spillbuf__write(buf, "ghijkl", 6, pool));
- /* now: two blocks of 8 and 4 bytes */
+ /* now: two blocks: 8 and 4 bytes */
- SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, pool));
- SVN_TEST_ASSERT(readptr != NULL
- && readlen == 8
- && memcmp(readptr, "abcdefgh", 8) == 0);
- /* now: one block of 4 bytes */
+ CHECK_READ(buf, 12, "abcdefgh", pool);
+ /* now: one block: 4 bytes */
SVN_ERR(svn_spillbuf__write(buf, "mnopqr", 6, pool));
- /* now: two blocks of 8 and 2 bytes */
+ /* now: two blocks: 8 and 2 bytes */
- SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, pool));
- SVN_TEST_ASSERT(readptr != NULL
- && readlen == 8
- && memcmp(readptr, "ijklmnop", 8) == 0);
- /* now: one block of 2 bytes */
+ CHECK_READ(buf, 10, "ijklmnop", pool);
+ /* now: one block: 2 bytes */
SVN_ERR(svn_spillbuf__write(buf, "stuvwx", 6, pool));
SVN_ERR(svn_spillbuf__write(buf, "ABCDEF", 6, pool));
SVN_ERR(svn_spillbuf__write(buf, "GHIJKL", 6, pool));
- /* now: two blocks of 8 and 6 bytes, and 6 bytes spilled to a file */
+ /* now: two blocks: 8 and 6 bytes, and 6 bytes spilled to a file */
+
+ CHECK_READ(buf, 20, "qrstuvwx", pool);
+ CHECK_READ(buf, 12, "ABCDEF", pool);
+ CHECK_READ(buf, 6, "GHIJKL", pool);
- SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) > 0);
- SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, pool));
- SVN_TEST_ASSERT(readptr != NULL
- && readlen == 8
- && memcmp(readptr, "qrstuvwx", 8) == 0);
- SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) > 0);
- SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, pool));
- SVN_TEST_ASSERT(readptr != NULL
- && readlen == 6
- && memcmp(readptr, "ABCDEF", 6) == 0);
- SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) > 0);
- SVN_ERR(svn_spillbuf__read(&readptr, &readlen, buf, pool));
- SVN_TEST_ASSERT(readptr != NULL
- && readlen == 6
- && memcmp(readptr, "GHIJKL", 6) == 0);
SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) == 0);
return SVN_NO_ERROR;
@@ -290,26 +284,26 @@ test_spillbuf_stream(apr_pool_t *pool)
writelen = 6;
SVN_ERR(svn_stream_write(stream, "abcdef", &writelen));
SVN_ERR(svn_stream_write(stream, "ghijkl", &writelen));
- /* now: two blocks of 8 and 4 bytes */
+ /* now: two blocks: 8 and 4 bytes */
readlen = 8;
SVN_ERR(svn_stream_read(stream, readbuf, &readlen));
SVN_TEST_ASSERT(readlen == 8
&& memcmp(readbuf, "abcdefgh", 8) == 0);
- /* now: one block of 4 bytes */
+ /* now: one block: 4 bytes */
SVN_ERR(svn_stream_write(stream, "mnopqr", &writelen));
- /* now: two blocks of 8 and 2 bytes */
+ /* now: two blocks: 8 and 2 bytes */
SVN_ERR(svn_stream_read(stream, readbuf, &readlen));
SVN_TEST_ASSERT(readlen == 8
&& memcmp(readbuf, "ijklmnop", 8) == 0);
- /* now: one block of 2 bytes */
+ /* now: one block: 2 bytes */
SVN_ERR(svn_stream_write(stream, "stuvwx", &writelen));
SVN_ERR(svn_stream_write(stream, "ABCDEF", &writelen));
SVN_ERR(svn_stream_write(stream, "GHIJKL", &writelen));
- /* now: two blocks of 8 and 6 bytes, and 6 bytes spilled to a file */
+ /* now: two blocks: 8 and 6 bytes, and 6 bytes spilled to a file */
SVN_ERR(svn_stream_read(stream, readbuf, &readlen));
SVN_TEST_ASSERT(readlen == 8
@@ -326,6 +320,102 @@ test_spillbuf_stream(apr_pool_t *pool)
}
+static svn_error_t *
+test_spillbuf_rwfile(apr_pool_t *pool)
+{
+ svn_spillbuf_t *buf = svn_spillbuf__create(4 /* blocksize */,
+ 10 /* maxsize */,
+ pool);
+
+ SVN_ERR(svn_spillbuf__write(buf, "abcdef", 6, pool));
+ SVN_ERR(svn_spillbuf__write(buf, "ghijkl", 6, pool));
+ SVN_ERR(svn_spillbuf__write(buf, "mnopqr", 6, pool));
+ /* now: two blocks: 4 and 2 bytes, and 12 bytes in spill file. */
+
+ CHECK_READ(buf, 18, "abcd", pool);
+ /* now: one block: 2 bytes, and 12 bytes in spill file. */
+
+ CHECK_READ(buf, 14, "ef", pool);
+ /* now: no blocks, and 12 bytes in spill file. */
+
+ CHECK_READ(buf, 12, "ghij", pool);
+ /* now: no blocks, and 8 bytes in spill file. */
+
+ /* Write more data. It should be appended to the spill file. */
+ SVN_ERR(svn_spillbuf__write(buf, "stuvwx", 6, pool));
+ /* now: no blocks, and 14 bytes in spill file. */
+
+ CHECK_READ(buf, 14, "klmn", pool);
+ /* now: no blocks, and 10 bytes in spill file. */
+
+ CHECK_READ(buf, 10, "opqr", pool);
+ /* now: no blocks, and 6 bytes in spill file. */
+
+ CHECK_READ(buf, 6, "stuv", pool);
+ /* now: no blocks, and 2 bytes in spill file. */
+
+ CHECK_READ(buf, 2, "wx", pool);
+ /* now: no blocks, and no spill file. */
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+test_spillbuf_eof(apr_pool_t *pool)
+{
+ svn_spillbuf_t *buf = svn_spillbuf__create(4 /* blocksize */,
+ 10 /* maxsize */,
+ pool);
+
+ SVN_ERR(svn_spillbuf__write(buf, "abcdef", 6, pool));
+ SVN_ERR(svn_spillbuf__write(buf, "ghijkl", 6, pool));
+ /* now: two blocks: 4 and 2 bytes, and 6 bytes in spill file. */
+
+ CHECK_READ(buf, 12, "abcd", pool);
+ CHECK_READ(buf, 8, "ef", pool);
+ CHECK_READ(buf, 6, "ghij", pool);
+ CHECK_READ(buf, 2, "kl", pool);
+ /* The spill file should have been emptied and forgotten. */
+
+ /* Assuming the spill file has been forgotten, this should result in
+ precisely the same behavior. Specifically: the initial write should
+ create two blocks, and the second write should be spilled. If there
+ *was* a spill file, then this written data would go into the file. */
+ SVN_ERR(svn_spillbuf__write(buf, "abcdef", 6, pool));
+ SVN_ERR(svn_spillbuf__write(buf, "ghijkl", 6, pool));
+ CHECK_READ(buf, 12, "abcd", pool);
+ CHECK_READ(buf, 8, "ef", pool);
+ CHECK_READ(buf, 6, "ghij", pool);
+ CHECK_READ(buf, 2, "kl", pool);
+ /* The spill file should have been emptied and forgotten. */
+
+ /* Now, let's do a sequence where we arrange to hit EOF precisely on
+ a block-sized read. Note: the second write must be more than 4 bytes,
+ or it will not cause a spill. We use 8 to get the right boundary. */
+ SVN_ERR(svn_spillbuf__write(buf, "abcdef", 6, pool));
+ SVN_ERR(svn_spillbuf__write(buf, "ghijklmn", 8, pool));
+ CHECK_READ(buf, 14, "abcd", pool);
+ CHECK_READ(buf, 10, "ef", pool);
+ CHECK_READ(buf, 8, "ghij", pool);
+ CHECK_READ(buf, 4, "klmn", pool);
+ /* We discard the spill file when we know it has no data, rather than
+ upon hitting EOF (upon a read attempt). Thus, the spill file should
+ be gone. */
+
+ /* Verify the forgotten spill file. */
+ SVN_ERR(svn_spillbuf__write(buf, "abcdef", 6, pool));
+ SVN_ERR(svn_spillbuf__write(buf, "ghijkl", 6, pool));
+ CHECK_READ(buf, 12, "abcd", pool);
+ CHECK_READ(buf, 8, "ef", pool);
+ CHECK_READ(buf, 6, "ghij", pool);
+ /* Two unread bytes remaining in the spill file. */
+ SVN_TEST_ASSERT(svn_spillbuf__get_size(buf) == 2);
+
+ return SVN_NO_ERROR;
+}
+
+
/* The test table. */
struct svn_test_descriptor_t test_funcs[] =
{
@@ -337,5 +427,7 @@ struct svn_test_descriptor_t test_funcs[
"interleaving reads and writes"),
SVN_TEST_PASS2(test_spillbuf_reader, "spill buffer reader test"),
SVN_TEST_PASS2(test_spillbuf_stream, "spill buffer stream test"),
+ SVN_TEST_PASS2(test_spillbuf_rwfile, "read/write spill file"),
+ SVN_TEST_PASS2(test_spillbuf_eof, "validate reaching EOF of spill file"),
SVN_TEST_NULL
};
Modified: subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/branches/ev2-export/subversion/tests/libsvn_wc/db-test.c Tue Apr 3 13:32:48 2012
@@ -228,8 +228,12 @@ static const char * const TESTING_DATA =
" 1, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
" 10, null, null, null);"
"insert into nodes values ("
- " 1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'base-deleted',"
- " 0, 'J/J-d', 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
+ " 1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'normal',"
+ " 0, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
+ " 10, null, null, null);"
+ "insert into nodes values ("
+ " 1, 'moved/file', 2, 'moved', 2, 'moved/file', 2, 'base-deleted',"
+ " 0, 'J/J-d', 'file', '()', null, null, null, null, null, null,"
" 10, null, null, null);"
"insert into nodes values ("
" 1, 'J/J-e', 1, 'J', null, null, null, 'normal',"