You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2016/10/11 09:11:54 UTC
svn commit: r1764214 [19/21] - in /subversion/branches/ra-git: ./ build/
build/ac-macros/ build/generator/ build/win32/ contrib/client-side/
contrib/client-side/svnmerge/ contrib/hook-scripts/ contrib/server-side/
contrib/server-side/fsfsfixer/fixer/ c...
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/mergetrees.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/mergetrees.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/mergetrees.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/mergetrees.py Tue Oct 11 09:11:50 2016
@@ -29,7 +29,7 @@ import shutil, sys, re, os
import time
# Our testing module
-import main, wc, verify, actions, testcase
+from svntest import main, wc, verify, actions, testcase
from prop_tests import binary_mime_type_on_text_file_warning
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/objects.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/objects.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/objects.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/objects.py Tue Oct 11 09:11:50 2016
@@ -127,7 +127,7 @@ def locate_db_dump():
try:
if subprocess.Popen([db_dump_name, "-V"]).wait() == 0:
return db_dump_name
- except OSError, e:
+ except OSError as e:
pass
return 'none'
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/sandbox.py Tue Oct 11 09:11:50 2016
@@ -434,7 +434,8 @@ class Sandbox:
def simple_append(self, dest, contents, truncate=False):
"""Append CONTENTS to file DEST, optionally truncating it first.
DEST is a relpath relative to the WC."""
- open(self.ospath(dest), truncate and 'wb' or 'ab').write(contents)
+ svntest.main.file_write(self.ospath(dest), contents,
+ truncate and 'wb' or 'ab')
def simple_lock(self, *targets):
"""Lock TARGETS in the WC.
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/testcase.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/testcase.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/testcase.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/testcase.py Tue Oct 11 09:11:50 2016
@@ -141,9 +141,9 @@ class FunctionTestCase(TestCase):
# docstring on it.
assert isinstance(func, types.FunctionType)
- name = func.func_name
+ name = func.__name__
- assert func.func_code.co_argcount == 1, \
+ assert func.__code__.co_argcount == 1, \
'%s must take an sbox argument' % name
doc = func.__doc__.strip()
@@ -165,13 +165,13 @@ class FunctionTestCase(TestCase):
self.skip_cross_check = skip_cross_check
def get_function_name(self):
- return self.func.func_name
+ return self.func.__name__
def get_sandbox_name(self):
"""Base the sandbox's name on the name of the file in which the
function was defined."""
- filename = self.func.func_code.co_filename
+ filename = self.func.__code__.co_filename
return os.path.splitext(os.path.basename(filename))[0]
def run(self, sandbox):
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/tree.py Tue Oct 11 09:11:50 2016
@@ -499,6 +499,7 @@ def create_from_path(path, contents=None
eol_re = re.compile(r'(\r\n|\r)')
+eol_re_binary = re.compile(br'(\r\n|\r)')
# helper for build_tree_from_wc()
def get_props(paths):
@@ -544,7 +545,10 @@ def get_props(paths):
# contains a CR character XML-encoded as ' '. The XML
# parser converts it back into a CR character. So again convert
# all end-of-line variants into a single LF:
- value = eol_re.sub('\n', value)
+ if isinstance(value, str):
+ value = eol_re.sub('\n', value)
+ else:
+ value = eol_re_binary.sub(b'\n', value)
file_props[name] = value
files[filename] = file_props
@@ -715,7 +719,7 @@ def _dump_tree(n,indent="",stream=sys.st
the SVNTreeNode N. Prefix each line with the string INDENT."""
# Code partially stolen from Dave Beazley
- tmp_children = sorted(n.children or [])
+ tmp_children = sorted(n.children or [], key=SVNTreeNode.get_printable_path)
if n.name == root_node_name:
stream.write("%s%s\n" % (indent, "ROOT"))
@@ -862,10 +866,16 @@ def build_tree_from_diff_summarize(lines
# process for every file and dir in the working copy!
-def build_tree_from_wc(wc_path, load_props=0, ignore_svn=1):
+def build_tree_from_wc(wc_path, load_props=0, ignore_svn=1, keep_eol_style=False):
"""Takes WC_PATH as the path to a working copy. Walks the tree below
that path, and creates the tree based on the actual found
files. If IGNORE_SVN is true, then exclude SVN admin dirs from the tree.
- If LOAD_PROPS is true, the props will be added to the tree."""
+ If LOAD_PROPS is true, the props will be added to the tree.
+
+ If KEEP_EOL_STYLE is set, don't let Python normalize the EOL when
+ reading working copy contents as text files. It has no effect on
+ binary files.
+ """
- return svntest.wc.State.from_wc(wc_path, load_props, ignore_svn).old_tree()
+ return svntest.wc.State.from_wc(wc_path, load_props, ignore_svn,
+ keep_eol_style).old_tree()
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/verify.py Tue Oct 11 09:11:50 2016
@@ -189,7 +189,7 @@ class RegexOutput(ExpectedOutput):
def __init__(self, expected, match_all=True):
"EXPECTED is a regular expression string."
- assert isinstance(expected, str)
+ assert isinstance(expected, str) or isinstance(expected, bytes)
ExpectedOutput.__init__(self, expected, match_all)
self.expected_re = re.compile(expected)
@@ -416,9 +416,10 @@ def compare_and_display_lines(message, l
if not isinstance(expected, ExpectedOutput):
expected = ExpectedOutput(expected)
- if isinstance(actual, str):
- actual = [actual]
- actual = svntest.main.filter_dbg(actual)
+ actual = svntest.main.ensure_list(actual)
+ if len(actual) > 0:
+ is_binary = not isinstance(actual[0], str)
+ actual = svntest.main.filter_dbg(actual, is_binary)
if not expected.matches(actual):
expected.display_differences(message, label, actual)
@@ -484,7 +485,7 @@ class DumpParser:
return m.group(1)
def parse_blank(self, required=True):
- if self.lines[self.current] != '\n': # Works on Windows
+ if self.lines[self.current] != b'\n': # Works on Windows
if required:
raise SVNDumpParseError("expected blank at line %d\n%s"
% (self.current, self.lines[self.current]))
@@ -494,7 +495,7 @@ class DumpParser:
return True
def parse_header(self, header):
- regex = '([^:]*): (.*)$'
+ regex = b'([^:]*): (.*)$'
m = re.match(regex, self.lines[self.current])
if not m:
raise SVNDumpParseError("expected a header at line %d, but found:\n%s"
@@ -504,80 +505,80 @@ class DumpParser:
def parse_headers(self):
headers = []
- while self.lines[self.current] != '\n':
+ while self.lines[self.current] != b'\n':
key, val = self.parse_header(self)
headers.append((key, val))
return headers
def parse_boolean(self, header, required):
- return self.parse_line(header + ': (false|true)$', required)
+ return self.parse_line(header + b': (false|true)$', required)
def parse_format(self):
- return self.parse_line('SVN-fs-dump-format-version: ([0-9]+)$')
+ return self.parse_line(b'SVN-fs-dump-format-version: ([0-9]+)$')
def parse_uuid(self):
- return self.parse_line('UUID: ([0-9a-z-]+)$')
+ return self.parse_line(b'UUID: ([0-9a-z-]+)$')
def parse_revision(self):
- return self.parse_line('Revision-number: ([0-9]+)$')
+ return self.parse_line(b'Revision-number: ([0-9]+)$')
def parse_prop_delta(self):
- return self.parse_line('Prop-delta: (false|true)$', required=False)
+ return self.parse_line(b'Prop-delta: (false|true)$', required=False)
def parse_prop_length(self, required=True):
- return self.parse_line('Prop-content-length: ([0-9]+)$', required)
+ return self.parse_line(b'Prop-content-length: ([0-9]+)$', required)
def parse_content_length(self, required=True):
- return self.parse_line('Content-length: ([0-9]+)$', required)
+ return self.parse_line(b'Content-length: ([0-9]+)$', required)
def parse_path(self):
- path = self.parse_line('Node-path: (.*)$', required=False)
+ path = self.parse_line(b'Node-path: (.*)$', required=False)
return path
def parse_kind(self):
- return self.parse_line('Node-kind: (.+)$', required=False)
+ return self.parse_line(b'Node-kind: (.+)$', required=False)
def parse_action(self):
- return self.parse_line('Node-action: ([0-9a-z-]+)$')
+ return self.parse_line(b'Node-action: ([0-9a-z-]+)$')
def parse_copyfrom_rev(self):
- return self.parse_line('Node-copyfrom-rev: ([0-9]+)$', required=False)
+ return self.parse_line(b'Node-copyfrom-rev: ([0-9]+)$', required=False)
def parse_copyfrom_path(self):
- path = self.parse_line('Node-copyfrom-path: (.+)$', required=False)
+ path = self.parse_line(b'Node-copyfrom-path: (.+)$', required=False)
if not path and self.lines[self.current] == 'Node-copyfrom-path: \n':
self.current += 1
path = ''
return path
def parse_copy_md5(self):
- return self.parse_line('Text-copy-source-md5: ([0-9a-z]+)$', required=False)
+ return self.parse_line(b'Text-copy-source-md5: ([0-9a-z]+)$', required=False)
def parse_copy_sha1(self):
- return self.parse_line('Text-copy-source-sha1: ([0-9a-z]+)$', required=False)
+ return self.parse_line(b'Text-copy-source-sha1: ([0-9a-z]+)$', required=False)
def parse_text_md5(self):
- return self.parse_line('Text-content-md5: ([0-9a-z]+)$', required=False)
+ return self.parse_line(b'Text-content-md5: ([0-9a-z]+)$', required=False)
def parse_text_sha1(self):
- return self.parse_line('Text-content-sha1: ([0-9a-z]+)$', required=False)
+ return self.parse_line(b'Text-content-sha1: ([0-9a-z]+)$', required=False)
def parse_text_delta(self):
- return self.parse_line('Text-delta: (false|true)$', required=False)
+ return self.parse_line(b'Text-delta: (false|true)$', required=False)
def parse_text_delta_base_md5(self):
- return self.parse_line('Text-delta-base-md5: ([0-9a-f]+)$', required=False)
+ return self.parse_line(b'Text-delta-base-md5: ([0-9a-f]+)$', required=False)
def parse_text_delta_base_sha1(self):
- return self.parse_line('Text-delta-base-sha1: ([0-9a-f]+)$', required=False)
+ return self.parse_line(b'Text-delta-base-sha1: ([0-9a-f]+)$', required=False)
def parse_text_length(self):
- return self.parse_line('Text-content-length: ([0-9]+)$', required=False)
+ return self.parse_line(b'Text-content-length: ([0-9]+)$', required=False)
def get_props(self):
props = []
- while not re.match('PROPS-END$', self.lines[self.current]):
+ while not re.match(b'PROPS-END$', self.lines[self.current]):
props.append(self.lines[self.current])
self.current += 1
self.current += 1
@@ -593,7 +594,7 @@ class DumpParser:
curprop[0] += 1
# key / value
- key = ''
+ key = b''
while len(key) != klen + 1:
key += props[curprop[0]]
curprop[0] += 1
@@ -601,10 +602,10 @@ class DumpParser:
return key
- if props[curprop[0]].startswith('K'):
+ if props[curprop[0]].startswith(b'K'):
key = read_key_or_value(curprop)
value = read_key_or_value(curprop)
- elif props[curprop[0]].startswith('D'):
+ elif props[curprop[0]].startswith(b'D'):
key = read_key_or_value(curprop)
value = None
else:
@@ -614,7 +615,7 @@ class DumpParser:
return prophash
def get_content(self, length):
- content = ''
+ content = b''
while len(content) < length:
content += self.lines[self.current]
self.current += 1
@@ -637,22 +638,22 @@ class DumpParser:
headers = dict(headers_list)
# Content-length must be last, if present
- if 'Content-length' in headers and headers_list[-1][0] != 'Content-length':
+ if b'Content-length' in headers and headers_list[-1][0] != b'Content-length':
raise SVNDumpParseError("'Content-length' header is not last, "
"in header block ending at line %d"
% (self.current,))
# parse the remaining optional headers and store in specific keys in NODE
for key, header, regex in [
- ('copyfrom_rev', 'Node-copyfrom-rev', '([0-9]+)$'),
- ('copyfrom_path', 'Node-copyfrom-path', '(.*)$'),
- ('copy_md5', 'Text-copy-source-md5', '([0-9a-z]+)$'),
- ('copy_sha1', 'Text-copy-source-sha1','([0-9a-z]+)$'),
- ('prop_length', 'Prop-content-length', '([0-9]+)$'),
- ('text_length', 'Text-content-length', '([0-9]+)$'),
- ('text_md5', 'Text-content-md5', '([0-9a-z]+)$'),
- ('text_sha1', 'Text-content-sha1', '([0-9a-z]+)$'),
- ('content_length', 'Content-length', '([0-9]+)$'),
+ ('copyfrom_rev', b'Node-copyfrom-rev', b'([0-9]+)$'),
+ ('copyfrom_path', b'Node-copyfrom-path', b'(.*)$'),
+ ('copy_md5', b'Text-copy-source-md5', b'([0-9a-z]+)$'),
+ ('copy_sha1', b'Text-copy-source-sha1',b'([0-9a-z]+)$'),
+ ('prop_length', b'Prop-content-length', b'([0-9]+)$'),
+ ('text_length', b'Text-content-length', b'([0-9]+)$'),
+ ('text_md5', b'Text-content-md5', b'([0-9a-z]+)$'),
+ ('text_sha1', b'Text-content-sha1', b'([0-9a-z]+)$'),
+ ('content_length', b'Content-length', b'([0-9]+)$'),
]:
if not header in headers:
node[key] = None
@@ -743,7 +744,7 @@ def compare_dump_files(message, label, e
for parsed in [parsed_expected, parsed_actual]:
for rev_name, rev_record in parsed.items():
#print "Found %s" % (rev_name,)
- if 'nodes' in rev_record:
+ if b'nodes' in rev_record:
#print "Found %s.%s" % (rev_name, 'nodes')
for path_name, path_record in rev_record['nodes'].items():
#print "Found %s.%s.%s" % (rev_name, 'nodes', path_name)
@@ -765,8 +766,8 @@ def compare_dump_files(message, label, e
action_record['blanks'] = 0
if parsed_expected != parsed_actual:
- print 'DIFF of raw dumpfiles (including expected differences)'
- print ''.join(ndiff(expected, actual))
+ print('DIFF of raw dumpfiles (including expected differences)')
+ print(''.join(ndiff(expected, actual)))
raise svntest.Failure('DIFF of parsed dumpfiles (ignoring expected differences)\n'
+ '\n'.join(ndiff(
pprint.pformat(parsed_expected).splitlines(),
Modified: subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/svntest/wc.py Tue Oct 11 09:11:50 2016
@@ -26,16 +26,17 @@
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
+ from urllib.parse import quote as urllib_quote
else:
# Python <3.0
from cStringIO import StringIO
+ from urllib import quote as urllib_quote
import svntest
@@ -172,7 +173,7 @@ class State:
"Remove PATHS recursively from the state (the paths must exist)."
for subtree_path in paths:
subtree_path = to_relpath(subtree_path)
- for path, item in self.desc.items():
+ for path, item in svntest.main.ensure_list(self.desc.items()):
if path == subtree_path or path[:len(subtree_path) + 1] == subtree_path + '/':
del self.desc[path]
@@ -201,7 +202,7 @@ class State:
for path in args:
try:
path_ref = self.desc[to_relpath(path)]
- except KeyError, e:
+ except KeyError as e:
e.args = ["Path '%s' not present in WC state descriptor" % path]
raise
path_ref.tweak(**kw)
@@ -225,13 +226,13 @@ class State:
"""
temp = {}
- for src, dst in sorted(moves.items(), key=lambda (src, dst): src)[::-1]:
+ for src, dst in sorted(moves.items(), key=lambda pair: pair[0])[::-1]:
temp[src] = {}
- for path, item in self.desc.items():
+ for path, item in svntest.main.ensure_list(self.desc.items()):
if path == src or path[:len(src) + 1] == src + '/':
temp[src][path] = item;
del self.desc[path]
- for src, dst in sorted(moves.items(), key=lambda (src, dst): dst):
+ for src, dst in sorted(moves.items(), key=lambda pair: pair[1]):
for path, item in temp[src].items():
if path == src:
new_path = dst
@@ -273,7 +274,7 @@ class State:
os.makedirs(dirpath)
# write out the file contents now
- open(fullpath, 'wb').write(item.contents)
+ svntest.main.file_write(fullpath, item.contents, 'wb')
def normalize(self):
"""Return a "normalized" version of self.
@@ -380,7 +381,7 @@ class State:
def tweak_for_entries_compare(self):
for path, item in self.desc.copy().items():
- if item.status:
+ if item.status and path in self.desc:
# If this is an unversioned tree-conflict, remove it.
# These are only in their parents' THIS_DIR, they don't have entries.
if item.status[0] in '!?' and item.treeconflict == 'C' and \
@@ -656,13 +657,18 @@ class State:
return cls('', desc)
@classmethod
- def from_wc(cls, base, load_props=False, ignore_svn=True):
+ def from_wc(cls, base, load_props=False, ignore_svn=True,
+ keep_eol_style=False):
"""Create a State object from a working copy.
Walks the tree at PATH, building a State based on the actual files
and directories found. If LOAD_PROPS is True, then the properties
will be loaded for all nodes (Very Expensive!). If IGNORE_SVN is
True, then the .svn subdirectories will be excluded from the State.
+
+ If KEEP_EOL_STYLE is set, don't let Python normalize the EOL when
+ reading working copy contents as text files. It has no effect on
+ binary files.
"""
if not base:
# we're going to walk the base, and the OS wants "."
@@ -678,7 +684,13 @@ class State:
for name in dirs + files:
node = os.path.join(dirpath, name)
if os.path.isfile(node):
- contents = open(node, 'r').read()
+ try:
+ if keep_eol_style:
+ contents = open(node, 'r', newline='').read()
+ else:
+ contents = open(node, 'r').read()
+ except:
+ contents = open(node, 'rb').read()
else:
contents = None
desc[repos_join(parent, name)] = StateItem(contents=contents)
@@ -1073,7 +1085,7 @@ def repos_join(base, path):
def svn_uri_quote(url):
# svn defines a different set of "safe" characters than Python does, so
# we need to avoid escaping them. see subr/path.c:uri_char_validity[]
- return urllib.quote(url, "!$&'()*+,-./:=@_~")
+ return urllib_quote(url, "!$&'()*+,-./:=@_~")
# ------------
Modified: subversion/branches/ra-git/subversion/tests/cmdline/trans_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/trans_tests.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/trans_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/trans_tests.py Tue Oct 11 09:11:50 2016
@@ -562,9 +562,9 @@ def eol_change_is_text_mod(sbox):
foo_path = os.path.join(wc_dir, 'foo')
f = open(foo_path, 'wb')
if svntest.main.windows:
- f.write("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n")
+ f.write(b"1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n")
else:
- f.write("1\n2\n3\n4\n5\n6\n7\n8\n9\n")
+ f.write(b"1\n2\n3\n4\n5\n6\n7\n8\n9\n")
f.close()
# commit the file
@@ -591,10 +591,10 @@ def eol_change_is_text_mod(sbox):
# check 2: do the files have the right contents now?
contents = open(foo_path, 'rb').read()
if svntest.main.windows:
- if contents != "1\n2\n3\n4\n5\n6\n7\n8\n9\n":
+ if contents != b"1\n2\n3\n4\n5\n6\n7\n8\n9\n":
raise svntest.Failure
else:
- if contents != "1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n":
+ if contents != b"1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n":
raise svntest.Failure
foo_base_path = svntest.wc.text_base_path(foo_path)
Modified: subversion/branches/ra-git/subversion/tests/cmdline/tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/tree_conflict_tests.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/tree_conflict_tests.py Tue Oct 11 09:11:50 2016
@@ -1339,7 +1339,7 @@ def actual_only_node_behaviour(sbox):
"relocate", A_copy_url + "/foo", foo_path)
# resolve
- expected_stdout = "Resolved conflicted state of.*foo.*"
+ expected_stdout = "Tree conflict at.*foo.*marked as resolved"
expected_stderr = []
run_and_verify_svn(expected_stdout, expected_stderr,
"resolve", "--accept", "working", foo_path)
Modified: subversion/branches/ra-git/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/update_tests.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/update_tests.py Tue Oct 11 09:11:50 2016
@@ -92,7 +92,7 @@ def update_binary_file(sbox):
# Make a change to the binary file in the original working copy
svntest.main.file_append(theta_path, "revision 3 text")
- theta_contents_r3 = theta_contents + "revision 3 text"
+ theta_contents_r3 = theta_contents + b"revision 3 text"
# Created expected output tree for 'svn ci'
expected_output = svntest.wc.State(wc_dir, {
@@ -113,7 +113,7 @@ def update_binary_file(sbox):
# Make a local mod to theta
svntest.main.file_append(theta_backup_path, "extra theta text")
- theta_contents_local = theta_contents + "extra theta text"
+ theta_contents_local = theta_contents + b"extra theta text"
# Create expected output tree for an update of wc_backup.
expected_output = svntest.wc.State(wc_backup, {
@@ -196,9 +196,9 @@ def update_binary_file_2(sbox):
# Make some mods to the binary files.
svntest.main.file_append(theta_path, "foobar")
- new_theta_contents = theta_contents + "foobar"
+ new_theta_contents = theta_contents + b"foobar"
svntest.main.file_append(zeta_path, "foobar")
- new_zeta_contents = zeta_contents + "foobar"
+ new_zeta_contents = zeta_contents + b"foobar"
# Created expected output tree for 'svn ci'
expected_output = svntest.wc.State(wc_dir, {
@@ -286,7 +286,7 @@ def update_binary_file_3(sbox):
# Make some mods to the binary files.
svntest.main.file_append(theta_path, "foobar")
- new_theta_contents = theta_contents + "foobar"
+ new_theta_contents = theta_contents + b"foobar"
# Created expected output tree for 'svn ci'
expected_output = svntest.wc.State(wc_dir, {
@@ -1657,6 +1657,9 @@ def conflict_markers_matching_eol(sbox):
else:
crlf = '\r\n'
+ # Strict EOL style matching breaks Windows tests at least with Python 2
+ keep_eol_style = not svntest.main.is_os_windows()
+
# Checkout a second working copy
wc_backup = sbox.add_wc_path('backup')
svntest.actions.run_and_verify_svn(None, [], 'checkout',
@@ -1757,10 +1760,11 @@ def conflict_markers_matching_eol(sbox):
expected_backup_status.tweak(wc_rev = cur_rev)
# Do the update and check the results in three ways.
- svntest.actions.run_and_verify_update(wc_backup,
- expected_backup_output,
- expected_backup_disk,
- expected_backup_status)
+ svntest.actions.run_and_verify_update2(wc_backup,
+ expected_backup_output,
+ expected_backup_disk,
+ expected_backup_status,
+ keep_eol_style=keep_eol_style)
# cleanup for next run
svntest.main.run_svn(None, 'revert', '-R', wc_backup)
@@ -1788,6 +1792,9 @@ def update_eolstyle_handling(sbox):
else:
crlf = '\r\n'
+ # Strict EOL style matching breaks Windows tests at least with Python 2
+ keep_eol_style = not svntest.main.is_os_windows()
+
# Checkout a second working copy
wc_backup = sbox.add_wc_path('backup')
svntest.actions.run_and_verify_svn(None, [], 'checkout',
@@ -1814,10 +1821,11 @@ def update_eolstyle_handling(sbox):
expected_backup_status = svntest.actions.get_virginal_state(wc_backup, 2)
expected_backup_status.tweak('A/mu', status='M ')
- svntest.actions.run_and_verify_update(wc_backup,
- expected_backup_output,
- expected_backup_disk,
- expected_backup_status)
+ svntest.actions.run_and_verify_update2(wc_backup,
+ expected_backup_output,
+ expected_backup_disk,
+ expected_backup_status,
+ keep_eol_style=keep_eol_style)
# Test 2: now change the eol-style property to another value and commit,
# update the still changed mu in the second working copy; there should be
@@ -1839,10 +1847,11 @@ def update_eolstyle_handling(sbox):
expected_backup_status = svntest.actions.get_virginal_state(wc_backup, 3)
expected_backup_status.tweak('A/mu', status='M ')
- svntest.actions.run_and_verify_update(wc_backup,
- expected_backup_output,
- expected_backup_disk,
- expected_backup_status)
+ svntest.actions.run_and_verify_update2(wc_backup,
+ expected_backup_output,
+ expected_backup_disk,
+ expected_backup_status,
+ keep_eol_style=keep_eol_style)
# Test 3: now delete the eol-style property and commit, update the still
# changed mu in the second working copy; there should be no conflict!
@@ -1863,10 +1872,11 @@ def update_eolstyle_handling(sbox):
expected_backup_status = svntest.actions.get_virginal_state(wc_backup, 4)
expected_backup_status.tweak('A/mu', status='M ')
- svntest.actions.run_and_verify_update(wc_backup,
- expected_backup_output,
- expected_backup_disk,
- expected_backup_status)
+ svntest.actions.run_and_verify_update2(wc_backup,
+ expected_backup_output,
+ expected_backup_disk,
+ expected_backup_status,
+ keep_eol_style=keep_eol_style)
# Bug in which "update" put a bogus revision number on a schedule-add file,
# causing the wrong version of it to be committed.
@@ -2710,6 +2720,7 @@ def update_with_obstructing_additions(sb
expected_disk,
expected_status,
[], True,
+ '--adds-as-modification', wc_backup,
extra_files=extra_files)
# Some obstructions are still not permitted:
@@ -2820,6 +2831,7 @@ def update_with_obstructing_additions(sb
svntest.actions.run_and_verify_update(wc_dir, expected_output,
expected_disk, expected_status,
[], False,
+ '--adds-as-modification',
A_path)
# Resolve the tree conflict.
@@ -2839,7 +2851,7 @@ def update_with_obstructing_additions(sb
svntest.actions.run_and_verify_update(wc_dir, expected_output,
expected_disk, expected_status,
[], False,
- wc_dir, '-N')
+ wc_dir, '-N', '--adds-as-modification')
# Resolve the tree conflict.
svntest.main.run_svn(None, 'resolved', omicron_path)
@@ -3610,7 +3622,7 @@ def update_output_with_conflicts(rev, ta
lines += ['Updated to revision %d.\n' % rev]
if resolved:
for path in paths:
- lines += ["Resolved conflicted state of '%s'\n" % path]
+ lines += ["Merge conflicts in '%s' marked as resolved.\n" % path]
lines += svntest.main.summary_of_conflicts(text_resolved=len(paths))
else:
lines += svntest.main.summary_of_conflicts(text_conflicts=len(paths))
@@ -6343,28 +6355,37 @@ def windows_update_backslash(sbox):
'mkdir', 'A/completely\\unusable\\dir')
# No error and a proper skip + recording in the working copy would also
- # be a good result. This just verifies current behavior.
-
- if sbox.repo_url.startswith('http'):
- # Apache Httpd doesn't allow paths with '\\' in them on Windows, so the
- # test if a user is allowed to read them returns a failure. This makes
- # mod_dav_svn report the path as server excluded (aka absent), which
- # doesn't produce output when updating.
- expected_output = [
- "Updating '%s':\n" % wc_dir,
- "At revision 2.\n"
- ]
- expected_err = []
- else:
- expected_output = None
- expected_err = 'svn: E155000: .* is not valid.*'
-
- svntest.actions.run_and_verify_svn(expected_output, expected_err,
- 'up', wc_dir)
-
- if sbox.repo_url.startswith('http'):
+ # be a good result. This just verifies current behavior:
+ #
+ # - Error via file://, svn:// or http:// with SVNPathAuthz short_circuit
+ #
+ # - No error via http:// with SVNPathAuthz on
+ # (The reason is that Apache Httpd doesn't allow paths with '\\' in
+ # them on Windows, and a subrequest-based access check returns 404.
+ # This makes mod_dav_svn report the path as server excluded (aka
+ # absent), which doesn't produce output when updating.)
+ #
+ # Since https://issues.apache.org/jira/browse/SVN-3288 is about a crash,
+ # we're fine with either result -- that is, if `svn update' finished
+ # without an error, we expect specific stdout and proper wc state.
+ # If it failed, we expect to get the following error:
+ #
+ # svn: E155000: 'completely\unusable\dir' is not valid as filename
+ # in directory [...]
+ #
+ exit_code, output, errput = svntest.main.run_svn(1, 'up', wc_dir)
+ if exit_code == 0:
+ verify.verify_outputs("Unexpected output", output, errput, [
+ "Updating '%s':\n" % wc_dir,
+ "At revision 2.\n"
+ ], [])
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
svntest.actions.run_and_verify_status(wc_dir, expected_status)
+ elif exit_code == 1:
+ verify.verify_outputs("Unexpected output", output, errput,
+ None, 'svn: E155000: .* is not valid.*')
+ else:
+ raise verify.SVNUnexpectedExitCode(exit_code)
def update_moved_away(sbox):
"update subtree of moved away"
@@ -6614,7 +6635,9 @@ def update_conflict_details(sbox):
prev_status=' ', prev_treeconflict='C'),
})
svntest.actions.run_and_verify_update(wc_dir, expected_output,
- None, expected_status)
+ None, expected_status,
+ [], False,
+ '--adds-as-modification', wc_dir)
# Update can't pass source as none at a specific URL@revision,
# because it doesn't know... the working copy could be mixed
Modified: subversion/branches/ra-git/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/upgrade_tests.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/upgrade_tests.py Tue Oct 11 09:11:50 2016
@@ -36,6 +36,7 @@ import sys
import tarfile
import tempfile
import logging
+import stat
logger = logging.getLogger()
@@ -63,7 +64,7 @@ def replace_sbox_with_tarfile(sbox, tar_
dir=None):
try:
svntest.main.safe_rmtree(sbox.wc_dir)
- except OSError, e:
+ except OSError as e:
pass
if not dir:
@@ -81,7 +82,7 @@ def replace_sbox_with_tarfile(sbox, tar_
def replace_sbox_repo_with_tarfile(sbox, tar_filename, dir=None):
try:
svntest.main.safe_rmtree(sbox.repo_dir)
- except OSError, e:
+ except OSError as e:
pass
if not dir:
@@ -130,7 +131,7 @@ def check_dav_cache(dir_path, wc_id, exp
# Check if python's sqlite can read our db
c.execute('select sqlite_version()')
- sqlite_ver = map(int, c.fetchone()[0].split('.'))
+ sqlite_ver = svntest.main.ensure_list(map(int, c.fetchone()[0].split('.')))
# SQLite versions have 3 or 4 number groups
major = sqlite_ver[0]
@@ -157,7 +158,7 @@ def check_dav_cache(dir_path, wc_id, exp
if row is None:
raise svntest.Failure("no dav cache for '%s'" % (local_relpath))
dav_cache = str(row[0])
- if dav_cache != expected_dav_cache:
+ if dav_cache != str(expected_dav_cache):
raise svntest.Failure(
"wrong dav cache for '%s'\n Found: '%s'\n Expected: '%s'" %
(local_relpath, dav_cache, expected_dav_cache))
@@ -378,9 +379,9 @@ def upgrade_wcprops(sbox):
# to be. (This could be smarter.)
expected_dav_caches = {
'' :
- '(svn:wc:ra_dav:version-url 41 /svn-test-work/local_tmp/repos/!svn/ver/1)',
+ b'(svn:wc:ra_dav:version-url 41 /svn-test-work/local_tmp/repos/!svn/ver/1)',
'iota' :
- '(svn:wc:ra_dav:version-url 46 /svn-test-work/local_tmp/repos/!svn/ver/1/iota)',
+ b'(svn:wc:ra_dav:version-url 46 /svn-test-work/local_tmp/repos/!svn/ver/1/iota)',
}
check_dav_cache(sbox.wc_dir, 1, expected_dav_caches)
@@ -390,7 +391,7 @@ def xml_entries_relocate(path, from_url,
adm_name = svntest.main.get_admin_name()
entries = os.path.join(path, adm_name, 'entries')
txt = open(entries).read().replace('url="' + from_url, 'url="' + to_url)
- os.chmod(entries, 0777)
+ os.chmod(entries, svntest.main.S_ALL_RWX)
open(entries, 'w').write(txt)
for dirent in os.listdir(path):
@@ -408,8 +409,8 @@ def simple_entries_replace(path, from_ur
adm_name = svntest.main.get_admin_name()
entries = os.path.join(path, adm_name, 'entries')
txt = open(entries).read().replace(from_url, to_url)
- os.chmod(entries, 0777)
- open(entries, 'wb').write(txt)
+ os.chmod(entries, svntest.main.S_ALL_RWX)
+ open(entries, 'wb').write(txt.encode())
for dirent in os.listdir(path):
item_path = os.path.join(path, dirent)
@@ -1143,21 +1144,21 @@ def upgrade_file_externals(sbox):
svntest.main.run_svnadmin('setuuid', sbox.repo_dir,
'07146bbd-0b64-4aaf-ab70-cd76a0df2d41')
- expected_output = svntest.verify.RegexOutput('r2 committed.*')
+ expected_output = svntest.verify.RegexOutput(b'r2 committed.*')
svntest.actions.run_and_verify_svnmucc(expected_output, [],
'-m', 'r2',
'propset', 'svn:externals',
'^/A/B/E EX\n^/A/mu muX',
sbox.repo_url + '/A/B/F')
- expected_output = svntest.verify.RegexOutput('r3 committed.*')
+ expected_output = svntest.verify.RegexOutput(b'r3 committed.*')
svntest.actions.run_and_verify_svnmucc(expected_output, [],
'-m', 'r3',
'propset', 'svn:externals',
'^/A/B/F FX\n^/A/B/lambda lambdaX',
sbox.repo_url + '/A/C')
- expected_output = svntest.verify.RegexOutput('r4 committed.*')
+ expected_output = svntest.verify.RegexOutput(b'r4 committed.*')
svntest.actions.run_and_verify_svnmucc(expected_output, [],
'-m', 'r4',
'propset', 'pname1', 'pvalue1',
@@ -1260,12 +1261,17 @@ def upgrade_not_present_replaced(sbox):
sbox.wc_dir)
expected_output = svntest.wc.State(sbox.wc_dir, {
- 'A/B/E' : Item(status='E '),
- 'A/B/E/alpha' : Item(status='A '),
- 'A/B/E/beta' : Item(status='A '),
- 'A/B/lambda' : Item(status='E '),
+ 'A/B/E' : Item(status=' ', treeconflict='C'),
+ 'A/B/E/beta' : Item(status=' ', treeconflict='A'),
+ 'A/B/E/alpha' : Item(status=' ', treeconflict='A'),
+ 'A/B/lambda' : Item(status=' ', treeconflict='C'),
})
expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+ expected_status.tweak('A/B/E', status='R ', treeconflict='C'),
+ expected_status.tweak('A/B/E/beta', status='D '),
+ expected_status.tweak('A/B/E/alpha', status='D '),
+ expected_status.tweak('A/B/lambda', status='R ', treeconflict='C'),
+
svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output,
None, expected_status)
@@ -1462,14 +1468,15 @@ def auto_analyze(sbox):
# svntest.main.chmod_tree will not reset it.)
for path, subdirs, files in os.walk(sbox.wc_dir):
for d in subdirs:
- os.chmod(os.path.join(path, d), 0555)
+ os.chmod(os.path.join(path, d), svntest.main.S_ALL_RX)
for f in files:
- os.chmod(os.path.join(path, f), 0444)
+ os.chmod(os.path.join(path, f), svntest.main.S_ALL_READ)
state = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
svntest.actions.run_and_verify_status(sbox.wc_dir, state)
- svntest.main.chmod_tree(sbox.wc_dir, 0666, 0022)
+ svntest.main.chmod_tree(sbox.wc_dir, svntest.main.S_ALL_RW,
+ stat.S_IWGRP | stat.S_IWOTH)
state = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
svntest.actions.run_and_verify_status(sbox.wc_dir, state)
Modified: subversion/branches/ra-git/subversion/tests/cmdline/wc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/cmdline/wc_tests.py?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/cmdline/wc_tests.py (original)
+++ subversion/branches/ra-git/subversion/tests/cmdline/wc_tests.py Tue Oct 11 09:11:50 2016
@@ -142,7 +142,7 @@ def status_with_corrupt_wc_db(sbox):
sbox.build(read_only = True)
with open(sbox.ospath(".svn/wc.db"), 'wb') as fd:
- fd.write('\0' * 17)
+ fd.write(b'\0' * 17)
svntest.actions.run_and_verify_svn(
None,
r"[^ ]+ E155016: The working copy database at '.*' is corrupt",
@@ -189,7 +189,7 @@ def status_with_missing_wc_db_and_maybe_
sbox.build(read_only = True)
with open(sbox.ospath(".svn/entries"), 'ab') as fd:
- fd.write('something\n')
+ fd.write(b'something\n')
os.remove(sbox.ospath(".svn/wc.db"))
svntest.actions.run_and_verify_svn(
None,
Propchange: subversion/branches/ra-git/subversion/tests/libsvn_client/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Oct 11 09:11:50 2016
@@ -1,3 +1,4 @@
.libs
*-test
*.lo
+svn-test-work
Modified: subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_diff/diff-diff3-test.c Tue Oct 11 09:11:50 2016
@@ -2407,6 +2407,8 @@ merge_with_part_already_present(apr_pool
/* Merge is more "aggressive" about resolving conflicts than traditional
* patch or diff3. Some people consider this behaviour to be a bug, see
* http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=35014
+ *
+ * The original behavior of this test (added in 2003) was tweaked in 2016.
*/
static svn_error_t *
merge_adjacent_changes(apr_pool_t *pool)
@@ -2428,8 +2430,13 @@ merge_adjacent_changes(apr_pool_t *pool)
"zig\n"
"foo\n"
+ "<<<<<<< adj2\n"
"new_bar\n"
- "new_baz\n",
+ "baz\n"
+ "=======\n"
+ "bar\n"
+ "new_baz\n"
+ ">>>>>>> adj3\n",
NULL,
svn_diff_conflict_display_modified_latest,
@@ -2952,6 +2959,124 @@ two_way_issue_3362_v2(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+three_way_double_add(apr_pool_t *pool)
+{
+ SVN_ERR(three_way_merge("doubleadd1", "doubleadd2", "doubleadd3",
+ "A\n"
+ "B\n"
+ "C\n"
+ "J\n"
+ "K\n"
+ "L",
+
+ "A\n"
+ "B\n"
+ "C\n"
+ "D\n" /* New line 1a */
+ "E\n" /* New line 2a */
+ "F\n" /* New line 3a*/
+ "J\n"
+ "K\n"
+ "L",
+
+ "A\n"
+ "B\n"
+ "O\n" /* Change C to O */
+ "P\n" /* New line 1b */
+ "Q\n" /* New line 2b */
+ "R\n" /* New line 3b */
+ "J\n"
+ "K\n"
+ "L",
+
+ /* With s/C/O/ we expect something like this,
+ but the current (1.9/trunk) result is a
+ succeeded merge to a combined result.
+
+ ### I'm guessing this result needs tweaks before it
+ will be a PASS. */
+ "A\n"
+ "B\n"
+ "<<<<<<< doubleadd2\n"
+ "C\n"
+ "D\n" /* New line 1a */
+ "E\n" /* New line 2a */
+ "F\n" /* New line 3a*/
+ "||||||| doubleadd1\n"
+ "C\n"
+ "=======\n"
+ "O\n"
+ "P\n" /* New line 1b */
+ "Q\n" /* New line 2b */
+ "R\n" /* New line 3b */
+ ">>>>>>> doubleadd3\n"
+ "J\n"
+ "K\n"
+ "L",
+ NULL,
+ svn_diff_conflict_display_modified_original_latest,
+ pool));
+
+ SVN_ERR(three_way_merge("doubleadd4", "doubleadd5", "doubleadd6",
+ "A\n"
+ "B\n"
+ "C\n"
+ "J\n"
+ "K\n"
+ "L",
+
+ "A\n"
+ "B\n"
+ "C\n"
+ "D\n" /* New line 1a */
+ "E\n" /* New line 2a */
+ "F\n" /* New line 3a*/
+ "K\n"
+ "L",
+
+ "A\n"
+ "B\n"
+ "O\n" /* Change C to O */
+ "P\n" /* New line 1b */
+ "Q\n" /* New line 2b */
+ "R\n" /* New line 3b */
+ "J\n"
+ "K\n"
+ "L",
+
+ /* With s/C/O/ we expect something like this,
+ but the current (1.9/trunk) result is a
+ succeeded merge to a combined result.
+
+ ### I'm guessing this result needs tweaks before it
+ will be a PASS. */
+ "A\n"
+ "B\n"
+ "<<<<<<< doubleadd5\n"
+ "C\n"
+ "D\n" /* New line 1a */
+ "E\n" /* New line 2a */
+ "F\n" /* New line 3a*/
+ "||||||| doubleadd4\n"
+ "C\n"
+ "J\n"
+ "=======\n"
+ "O\n"
+ "P\n" /* New line 1b */
+ "Q\n" /* New line 2b */
+ "R\n" /* New line 3b */
+ "J\n"
+ ">>>>>>> doubleadd6\n"
+ "K\n"
+ "L",
+ NULL,
+ svn_diff_conflict_display_modified_original_latest,
+ pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ========================================================================== */
@@ -2994,6 +3119,8 @@ static struct svn_test_descriptor_t test
"2-way issue #3362 test v1"),
SVN_TEST_PASS2(two_way_issue_3362_v2,
"2-way issue #3362 test v2"),
+ SVN_TEST_PASS2(three_way_double_add,
+ "3-way merge, double add"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_diff/parse-diff-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_diff/parse-diff-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_diff/parse-diff-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_diff/parse-diff-test.c Tue Oct 11 09:11:50 2016
@@ -471,10 +471,10 @@ test_parse_git_diff(apr_pool_t *pool)
SVN_TEST_STRING_ASSERT(patch->new_filename, "A/C/gamma");
SVN_TEST_ASSERT(patch->operation == svn_diff_op_modified);
SVN_TEST_ASSERT(patch->hunks->nelts == 1);
- SVN_TEST_ASSERT(patch->old_executable_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->new_executable_bit = svn_tristate_true);
- SVN_TEST_ASSERT(patch->old_symlink_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->new_symlink_bit = svn_tristate_false);
+ SVN_TEST_ASSERT(patch->old_executable_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->new_executable_bit == svn_tristate_true);
+ SVN_TEST_ASSERT(patch->old_symlink_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->new_symlink_bit == svn_tristate_false);
hunk = APR_ARRAY_IDX(patch->hunks, 0, svn_diff_hunk_t *);
@@ -510,10 +510,10 @@ test_parse_git_diff(apr_pool_t *pool)
SVN_TEST_STRING_ASSERT(patch->new_filename, "new");
SVN_TEST_ASSERT(patch->operation == svn_diff_op_added);
SVN_TEST_ASSERT(patch->hunks->nelts == 0);
- SVN_TEST_ASSERT(patch->old_executable_bit = svn_tristate_unknown);
- SVN_TEST_ASSERT(patch->new_executable_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->old_symlink_bit = svn_tristate_unknown);
- SVN_TEST_ASSERT(patch->new_symlink_bit = svn_tristate_false);
+ SVN_TEST_ASSERT(patch->old_executable_bit == svn_tristate_unknown);
+ SVN_TEST_ASSERT(patch->new_executable_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->old_symlink_bit == svn_tristate_unknown);
+ SVN_TEST_ASSERT(patch->new_symlink_bit == svn_tristate_false);
SVN_ERR(svn_diff_close_patch_file(patch_file, pool));
@@ -539,10 +539,10 @@ test_parse_git_tree_and_text_diff(apr_po
SVN_TEST_ASSERT(patch);
SVN_TEST_STRING_ASSERT(patch->old_filename, "iota");
SVN_TEST_STRING_ASSERT(patch->new_filename, "iota.copied");
- SVN_TEST_ASSERT(patch->old_executable_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->new_executable_bit = svn_tristate_true);
- SVN_TEST_ASSERT(patch->old_symlink_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->new_symlink_bit = svn_tristate_false);
+ SVN_TEST_ASSERT(patch->old_executable_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->new_executable_bit == svn_tristate_true);
+ SVN_TEST_ASSERT(patch->old_symlink_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->new_symlink_bit == svn_tristate_false);
SVN_TEST_ASSERT(patch->operation == svn_diff_op_copied);
SVN_TEST_ASSERT(patch->hunks->nelts == 1);
@@ -565,10 +565,10 @@ test_parse_git_tree_and_text_diff(apr_po
SVN_TEST_ASSERT(patch);
SVN_TEST_STRING_ASSERT(patch->old_filename, "A/mu");
SVN_TEST_STRING_ASSERT(patch->new_filename, "A/mu.moved");
- SVN_TEST_ASSERT(patch->old_executable_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->new_executable_bit = svn_tristate_true);
- SVN_TEST_ASSERT(patch->old_symlink_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->new_symlink_bit = svn_tristate_false);
+ SVN_TEST_ASSERT(patch->old_executable_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->new_executable_bit == svn_tristate_true);
+ SVN_TEST_ASSERT(patch->old_symlink_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->new_symlink_bit == svn_tristate_false);
SVN_TEST_ASSERT(patch->operation == svn_diff_op_moved);
SVN_TEST_ASSERT(patch->hunks->nelts == 1);
@@ -612,10 +612,10 @@ test_parse_git_tree_and_text_diff(apr_po
SVN_TEST_STRING_ASSERT(patch->new_filename, "/dev/null");
SVN_TEST_ASSERT(patch->operation == svn_diff_op_deleted);
SVN_TEST_ASSERT(patch->hunks->nelts == 1);
- SVN_TEST_ASSERT(patch->old_executable_bit = svn_tristate_true);
- SVN_TEST_ASSERT(patch->new_executable_bit = svn_tristate_unknown);
- SVN_TEST_ASSERT(patch->old_symlink_bit = svn_tristate_false);
- SVN_TEST_ASSERT(patch->new_symlink_bit = svn_tristate_unknown);
+ SVN_TEST_ASSERT(patch->old_executable_bit == svn_tristate_true);
+ SVN_TEST_ASSERT(patch->new_executable_bit == svn_tristate_unknown);
+ SVN_TEST_ASSERT(patch->old_symlink_bit == svn_tristate_false);
+ SVN_TEST_ASSERT(patch->new_symlink_bit == svn_tristate_unknown);
hunk = APR_ARRAY_IDX(patch->hunks, 0, svn_diff_hunk_t *);
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs/fs-test.c Tue Oct 11 09:11:50 2016
@@ -43,6 +43,7 @@
#include "private/svn_fs_util.h"
#include "private/svn_fs_private.h"
#include "private/svn_fspath.h"
+#include "private/svn_sqlite.h"
#include "../svn_test_fs.h"
@@ -3592,17 +3593,11 @@ get_file_checksum(svn_checksum_t **check
apr_pool_t *pool)
{
svn_stream_t *stream;
- svn_stream_t *checksum_stream;
/* Get a stream for the file contents. */
SVN_ERR(svn_fs_file_contents(&stream, root, path, pool));
-
- /* Get a checksummed stream for the contents. */
- checksum_stream = svn_stream_checksummed2(stream, checksum, NULL,
- checksum_kind, TRUE, pool);
-
- /* Close the stream, forcing a complete read and copy the digest. */
- SVN_ERR(svn_stream_close(checksum_stream));
+ SVN_ERR(svn_stream_contents_checksum(checksum, stream, checksum_kind,
+ pool, pool));
return SVN_NO_ERROR;
}
@@ -6701,6 +6696,9 @@ test_fsfs_config_opts(const svn_test_opt
svn_fs_t *fs;
const svn_fs_info_placeholder_t *fs_info;
const svn_fs_fsfs_info_t *fsfs_info;
+ const char *dir_name = "test-repo-fsfs-config-opts";
+ const char *repo_name_default = "test-repo-fsfs-config-opts/default";
+ const char *repo_name_custom = "test-repo-fsfs-config-opts/custom";
/* Bail (with SKIP) on known-untestable scenarios */
if (strcmp(opts->fs_type, SVN_FS_TYPE_FSFS) != 0)
@@ -6708,20 +6706,19 @@ test_fsfs_config_opts(const svn_test_opt
"this will test FSFS repositories only");
/* Remove the test directory from previous runs. */
- SVN_ERR(svn_io_remove_dir2("test-repo-fsfs-config-opts", TRUE, NULL, NULL,
- pool));
+ SVN_ERR(svn_io_remove_dir2(dir_name, TRUE, NULL, NULL, pool));
/* Create the test directory and add it to the test cleanup list. */
- SVN_ERR(svn_io_dir_make("test-fsfs-config-opts", APR_OS_DEFAULT, pool));
- svn_test_add_dir_cleanup("test-fsfs-config-opts");
+ SVN_ERR(svn_io_dir_make(dir_name, APR_OS_DEFAULT, pool));
+ svn_test_add_dir_cleanup(dir_name);
/* Create an FSFS filesystem with default config.*/
fs_config = apr_hash_make(pool);
svn_hash_sets(fs_config, SVN_FS_CONFIG_FS_TYPE, SVN_FS_TYPE_FSFS);
- SVN_ERR(svn_fs_create(&fs, "test-fsfs-config-opts/default", fs_config, pool));
+ SVN_ERR(svn_fs_create(&fs, repo_name_default, fs_config, pool));
/* Re-open FS to test the data on disk. */
- SVN_ERR(svn_fs_open2(&fs, "test-fsfs-config-opts/default", NULL, pool, pool));
+ SVN_ERR(svn_fs_open2(&fs, repo_name_default, NULL, pool, pool));
SVN_ERR(svn_fs_info(&fs_info, fs, pool, pool));
SVN_TEST_STRING_ASSERT(fs_info->fs_type, SVN_FS_TYPE_FSFS);
@@ -6738,10 +6735,10 @@ test_fsfs_config_opts(const svn_test_opt
svn_hash_sets(fs_config, SVN_FS_CONFIG_FS_TYPE, SVN_FS_TYPE_FSFS);
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_LOG_ADDRESSING, "false");
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_SHARD_SIZE, "123");
- SVN_ERR(svn_fs_create(&fs, "test-fsfs-config-opts/custom", fs_config, pool));
+ SVN_ERR(svn_fs_create(&fs, repo_name_custom, fs_config, pool));
/* Re-open FS to test the data on disk. */
- SVN_ERR(svn_fs_open2(&fs, "test-fsfs-config-opts/custom", NULL, pool, pool));
+ SVN_ERR(svn_fs_open2(&fs, repo_name_custom, NULL, pool, pool));
SVN_ERR(svn_fs_info(&fs_info, fs, pool, pool));
SVN_TEST_STRING_ASSERT(fs_info->fs_type, SVN_FS_TYPE_FSFS);
@@ -6982,13 +6979,13 @@ freeze_and_commit(const svn_test_opts_t
svn_fs_root_t *txn_root;
svn_revnum_t new_rev = 0;
apr_pool_t *subpool = svn_pool_create(pool);
+ const char *repo_name = "test-repo-freeze-and-commit";
if (!strcmp(opts->fs_type, "bdb"))
return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
"this will not test BDB repositories");
- SVN_ERR(svn_test__create_fs(&fs, "test-repo-freeze-and-commit", opts,
- subpool));
+ SVN_ERR(svn_test__create_fs(&fs, repo_name, opts, subpool));
/* This test used to FAIL with an SQLite error since svn_fs_freeze()
* wouldn't unlock rep-cache.db. Therefore, part of the role of creating
@@ -7020,7 +7017,7 @@ freeze_and_commit(const svn_test_opts_t
SVN_ERR(test_commit_txn(&new_rev, txn, NULL, pool));
/* Re-open FS and make another commit. */
- SVN_ERR(svn_fs_open(&fs, "test-freeze-and-commit", NULL, subpool));
+ SVN_ERR(svn_fs_open(&fs, repo_name, NULL, subpool));
SVN_ERR(svn_fs_begin_txn(&txn, fs, new_rev, pool));
SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
SVN_ERR(svn_fs_change_node_prop(txn_root, "/", "temperature",
@@ -7031,6 +7028,165 @@ freeze_and_commit(const svn_test_opts_t
return SVN_NO_ERROR;
}
+/* Number of changes in a revision.
+ * Should be > 100 to span multiple blocks. */
+#define CHANGES_COUNT 1017
+
+/* Check that REVISION in FS reports the expected changes. */
+static svn_error_t *
+verify_added_files_list(svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ svn_fs_root_t *root;
+ apr_hash_t *changed_paths;
+ svn_fs_path_change_iterator_t *iterator;
+ svn_fs_path_change3_t *change;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ /* Collect changes and test that no path gets reported twice. */
+ SVN_ERR(svn_fs_revision_root(&root, fs, revision, scratch_pool));
+ SVN_ERR(svn_fs_paths_changed3(&iterator, root, scratch_pool, scratch_pool));
+
+ changed_paths = apr_hash_make(scratch_pool);
+ SVN_ERR(svn_fs_path_change_get(&change, iterator));
+ while (change)
+ {
+ const char *path = apr_pstrmemdup(scratch_pool, change->path.data,
+ change->path.len);
+ SVN_TEST_ASSERT(change->change_kind == svn_fs_path_change_add);
+ SVN_TEST_ASSERT(!apr_hash_get(changed_paths, path, change->path.len));
+
+ apr_hash_set(changed_paths, path, change->path.len, path);
+ SVN_ERR(svn_fs_path_change_get(&change, iterator));
+ }
+
+ /* Verify that we've got exactly all paths that we added. */
+ SVN_TEST_ASSERT(CHANGES_COUNT == apr_hash_count(changed_paths));
+ for (i = 0; i < CHANGES_COUNT; ++i)
+ {
+ const char *file_name;
+ svn_pool_clear(iterpool);
+
+ file_name = apr_psprintf(iterpool, "/file-%d", i);
+ SVN_TEST_ASSERT(svn_hash_gets(changed_paths, file_name));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_large_changed_paths_list(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ int i;
+ svn_revnum_t rev = 0;
+ apr_pool_t *iterpool = svn_pool_create(pool);
+ const char *repo_name = "test-repo-changed-paths-list";
+
+ SVN_ERR(svn_test__create_fs(&fs, repo_name, opts, pool));
+
+ /* r1: Add many empty files - just to amass a long list of changes. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+ for (i = 0; i < CHANGES_COUNT; ++i)
+ {
+ const char *file_name;
+ svn_pool_clear(iterpool);
+
+ file_name = apr_psprintf(iterpool, "/file-%d", i);
+ SVN_ERR(svn_fs_make_file(txn_root, file_name, iterpool));
+ }
+
+ SVN_ERR(test_commit_txn(&rev, txn, NULL, pool));
+
+ /* Now, read the change list.
+ * Do it twice to cover cached data as well. */
+ svn_pool_clear(iterpool);
+ SVN_ERR(verify_added_files_list(fs, rev, iterpool));
+ svn_pool_clear(iterpool);
+ SVN_ERR(verify_added_files_list(fs, rev, iterpool));
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+#undef CHANGES_COUNT
+
+static svn_error_t *
+commit_with_locked_rep_cache(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_revnum_t new_rev;
+ svn_sqlite__db_t *sdb;
+ svn_error_t *err;
+ const char *fs_path;
+ const char *statements[] = { "SELECT MAX(revision) FROM rep_cache", NULL };
+
+ if (strcmp(opts->fs_type, SVN_FS_TYPE_BDB) == 0)
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "this will not test BDB repositories");
+
+ if (opts->server_minor_version && (opts->server_minor_version < 6))
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "pre-1.6 SVN doesn't support FSFS rep-sharing");
+
+ fs_path = "test-repo-commit-with-locked-rep-cache";
+ SVN_ERR(svn_test__create_fs(&fs, fs_path, opts, pool));
+
+ /* r1: Add a file. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "/foo", pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "/foo", "a", pool));
+ SVN_ERR(test_commit_txn(&new_rev, txn, NULL, pool));
+ SVN_TEST_INT_ASSERT(new_rev, 1);
+
+ /* Begin a new transaction based on r1. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 1, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "/foo", "b", pool));
+
+ /* Obtain a shared lock on the rep-cache.db by starting a new read
+ * transaction. */
+ SVN_ERR(svn_sqlite__open(&sdb,
+ svn_dirent_join(fs_path, "rep-cache.db", pool),
+ svn_sqlite__mode_readonly, statements, 0, NULL,
+ 0, pool, pool));
+ SVN_ERR(svn_sqlite__begin_transaction(sdb));
+ SVN_ERR(svn_sqlite__exec_statements(sdb, 0));
+
+ /* Attempt to commit fs transaction. This should result in a commit
+ * post-processing error due to us still holding the shared lock on the
+ * rep-cache.db. */
+ err = svn_fs_commit_txn(NULL, &new_rev, txn, pool);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_SQLITE_BUSY);
+ SVN_TEST_INT_ASSERT(new_rev, 2);
+
+ /* Release the shared lock. */
+ SVN_ERR(svn_sqlite__finish_transaction(sdb, SVN_NO_ERROR));
+ SVN_ERR(svn_sqlite__close(sdb));
+
+ /* Try an operation that reads from rep-cache.db.
+ *
+ * XFAIL: Around r1740802, this call was producing an error due to the
+ * svn_fs_t keeping an unusable db connection (and associated file
+ * locks) within it.
+ */
+ SVN_ERR(svn_fs_verify(fs_path, NULL, 0, SVN_INVALID_REVNUM, NULL, NULL,
+ NULL, NULL, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ------------------------------------------------------------------------ */
/* The test table. */
@@ -7165,6 +7321,10 @@ static struct svn_test_descriptor_t test
"test svn_fs_check_related for transactions"),
SVN_TEST_OPTS_PASS(freeze_and_commit,
"freeze and commit"),
+ SVN_TEST_OPTS_PASS(test_large_changed_paths_list,
+ "test reading a large changed paths list"),
+ SVN_TEST_OPTS_PASS(commit_with_locked_rep_cache,
+ "test commit with locked rep-cache"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c Tue Oct 11 09:11:50 2016
@@ -86,6 +86,7 @@ fuzzing_1_byte_1_rev(const char *repo_na
fs_config = apr_hash_make(pool);
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_DELTAS, "1");
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS, "1");
+ svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS, "1");
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS, "2");
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ, "0");
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c Tue Oct 11 09:11:50 2016
@@ -29,6 +29,7 @@
#include "../../libsvn_fs_fs/fs.h"
#include "../../libsvn_fs_fs/fs_fs.h"
#include "../../libsvn_fs_fs/low_level.h"
+#include "../../libsvn_fs_fs/pack.h"
#include "../../libsvn_fs_fs/util.h"
#include "svn_hash.h"
@@ -101,17 +102,16 @@ pack_notify(void *baton,
#define R1_LOG_MSG "Let's serf"
-/* Create a packed filesystem in DIR. Set the shard size to
- SHARD_SIZE and create NUM_REVS number of revisions (in addition to
- r0). Use POOL for allocations. After this function successfully
- completes, the filesystem's youngest revision number will be the
- same as NUM_REVS. */
-static svn_error_t *
-create_packed_filesystem(const char *dir,
- const svn_test_opts_t *opts,
- svn_revnum_t num_revs,
- int shard_size,
- apr_pool_t *pool)
+/* Create a filesystem in DIR. Set the shard size to SHARD_SIZE and create
+ NUM_REVS number of revisions (in addition to r0). Use POOL for
+ allocations. After this function successfully completes, the filesystem's
+ youngest revision number will be NUM_REVS. */
+static svn_error_t *
+create_non_packed_filesystem(const char *dir,
+ const svn_test_opts_t *opts,
+ svn_revnum_t num_revs,
+ int shard_size,
+ apr_pool_t *pool)
{
svn_fs_t *fs;
svn_fs_txn_t *txn;
@@ -119,7 +119,6 @@ create_packed_filesystem(const char *dir
const char *conflict;
svn_revnum_t after_rev;
apr_pool_t *subpool = svn_pool_create(pool);
- struct pack_notify_baton pnb;
apr_pool_t *iterpool;
apr_hash_t *fs_config;
@@ -166,6 +165,28 @@ create_packed_filesystem(const char *dir
svn_pool_destroy(iterpool);
svn_pool_destroy(subpool);
+ /* Done */
+ return SVN_NO_ERROR;
+}
+
+/* Create a packed filesystem in DIR. Set the shard size to
+ SHARD_SIZE and create NUM_REVS number of revisions (in addition to
+ r0). Use POOL for allocations. After this function successfully
+ completes, the filesystem's youngest revision number will be the
+ same as NUM_REVS. */
+static svn_error_t *
+create_packed_filesystem(const char *dir,
+ const svn_test_opts_t *opts,
+ svn_revnum_t num_revs,
+ int shard_size,
+ apr_pool_t *pool)
+{
+ struct pack_notify_baton pnb;
+
+ /* Create the repo and fill it. */
+ SVN_ERR(create_non_packed_filesystem(dir, opts, num_revs, shard_size,
+ pool));
+
/* Now pack the FS */
pnb.expected_shard = 0;
pnb.expected_action = svn_fs_pack_notify_start;
@@ -669,7 +690,7 @@ recover_fully_packed(const svn_test_opts
/* ------------------------------------------------------------------------ */
/* Regression test for issue #4320 (fsfs file-hinting fails when reading a rep
- from the transaction that is commiting rev = SHARD_SIZE). */
+ from the transaction that is committing rev = SHARD_SIZE). */
#define REPO_NAME "test-repo-file-hint-at-shard-boundary"
#define SHARD_SIZE 4
#define MAX_REV (SHARD_SIZE - 1)
@@ -1672,7 +1693,7 @@ compare_0_length_rep(const svn_test_opts
enum { COUNT = 5 };
const char *file_names[COUNT] = { no_rep_file,
- empty_delta_file,
+ empty_plain_file,
plain_file,
empty_delta_file,
delta_file };
@@ -1740,6 +1761,56 @@ compare_0_length_rep(const svn_test_opts
#undef REPO_NAME
+/* ------------------------------------------------------------------------ */
+/* Verify that the format 7 pack logic works even if we can't fit all index
+ metadata into memory. */
+#define REPO_NAME "test-repo-pack-with-limited-memory"
+#define SHARD_SIZE 4
+#define MAX_REV (2 * SHARD_SIZE - 1)
+static svn_error_t *
+pack_with_limited_memory(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ apr_size_t max_mem;
+ apr_pool_t *iterpool = svn_pool_create(pool);
+
+ /* Bail (with success) on known-untestable scenarios */
+ if (opts->server_minor_version && (opts->server_minor_version < 9))
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "pre-1.9 SVN doesn't support reordering packs");
+
+ /* Run with an increasing memory allowance such that we cover all
+ splitting scenarios. */
+ for (max_mem = 350; max_mem < 8000; max_mem += max_mem / 2)
+ {
+ const char *dir;
+ svn_fs_t *fs;
+
+ svn_pool_clear(iterpool);
+
+ /* Create a filesystem. */
+ dir = apr_psprintf(iterpool, "%s-%d", REPO_NAME, (int)max_mem);
+ SVN_ERR(create_non_packed_filesystem(dir, opts, MAX_REV, SHARD_SIZE,
+ iterpool));
+
+ /* Pack it with a narrow memory budget. */
+ SVN_ERR(svn_fs_open2(&fs, dir, NULL, iterpool, iterpool));
+ SVN_ERR(svn_fs_fs__pack(fs, max_mem, NULL, NULL, NULL, NULL,
+ iterpool));
+
+ /* To be sure: Verify that we didn't break the repo. */
+ SVN_ERR(svn_fs_verify(dir, NULL, 0, MAX_REV, NULL, NULL, NULL, NULL,
+ iterpool));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+#undef REPO_NAME
+#undef MAX_REV
+#undef SHARD_SIZE
+
/* The test table. */
@@ -1790,6 +1861,8 @@ static struct svn_test_descriptor_t test
"delta chains starting with PLAIN, issue #4577"),
SVN_TEST_OPTS_PASS(compare_0_length_rep,
"compare empty PLAIN and non-existent reps"),
+ SVN_TEST_OPTS_PASS(pack_with_limited_memory,
+ "pack with limited memory for metadata"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_fs_x/fs-x-pack-test.c Tue Oct 11 09:11:50 2016
@@ -737,7 +737,7 @@ test_info(const svn_test_opts_t *opts,
apr_pool_t *pool)
{
svn_fs_t *fs;
- const svn_fs_fsfs_info_t *fsfs_info;
+ const svn_fs_fsx_info_t *fsx_info;
const svn_fs_info_placeholder_t *info;
SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE,
@@ -753,9 +753,9 @@ test_info(const svn_test_opts_t *opts,
if (strcmp(opts->fs_type, "fsx") != 0)
return SVN_NO_ERROR;
- fsfs_info = (const void *)info;
- SVN_TEST_ASSERT(fsfs_info->shard_size == SHARD_SIZE);
- SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev
+ fsx_info = (const void *)info;
+ SVN_TEST_ASSERT(fsx_info->shard_size == SHARD_SIZE);
+ SVN_TEST_ASSERT(fsx_info->min_unpacked_rev
== (MAX_REV + 1) / SHARD_SIZE * SHARD_SIZE);
return SVN_NO_ERROR;
@@ -873,7 +873,7 @@ test_batch_fsync(const svn_test_opts_t *
SVN_ERR(svn_fs_x__batch_fsync_init());
/* We use and re-use the same batch object throughout this test. */
- SVN_ERR(svn_fs_x__batch_fsync_create(&batch, pool));
+ SVN_ERR(svn_fs_x__batch_fsync_create(&batch, TRUE, pool));
/* The working directory is new. */
SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, abspath, pool));
Modified: subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_ra/ra-test.c Tue Oct 11 09:11:50 2016
@@ -603,6 +603,7 @@ get_dir_test(const svn_test_opts_t *opts
{
svn_ra_session_t *session;
apr_hash_t *dirents;
+ svn_dirent_t *ent;
SVN_ERR(make_and_open_repos(&session, "test-get-dir", opts, pool));
SVN_ERR(commit_tree(session, pool));
@@ -613,6 +614,19 @@ get_dir_test(const svn_test_opts_t *opts
SVN_DIRENT_KIND, pool),
SVN_ERR_FS_NOT_FOUND);
+ /* Test fetching SVN_DIRENT_SIZE without SVN_DIRENT_KIND. */
+ SVN_ERR(svn_ra_get_dir2(session, &dirents, NULL, NULL, "", 1,
+ SVN_DIRENT_SIZE, pool));
+ SVN_TEST_INT_ASSERT(apr_hash_count(dirents), 1);
+ ent = svn_hash_gets(dirents, "A");
+ SVN_TEST_ASSERT(ent);
+
+#if 0
+ /* ra_serf has returns SVN_INVALID_SIZE instead of documented zero for
+ * for directories. */
+ SVN_TEST_INT_ASSERT(ent->size, 0);
+#endif
+
return SVN_NO_ERROR;
}
@@ -1632,12 +1646,9 @@ commit_empty_last_change(const svn_test_
SVN_TEST_ASSERT(dirent != NULL);
SVN_TEST_STRING_ASSERT(dirent->last_author, "jrandom");
- /* BDB only updates last_changed on the repos_root when there is an
- actual change. Our other filesystems handle this differently */
- if (!opts->fs_type || !strcasecmp(opts->fs_type, "BDB"))
- SVN_TEST_INT_ASSERT(dirent->created_rev, 1);
- else
- SVN_TEST_INT_ASSERT(dirent->created_rev, 2+i);
+ /* BDB used to only updates last_changed on the repos_root when there
+ was an actual change. Now all filesystems behave in the same way */
+ SVN_TEST_INT_ASSERT(dirent->created_rev, 2+i);
}
svn_pool_clear(tmp_pool);
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/io-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/io-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/io-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/io-test.c Tue Oct 11 09:11:50 2016
@@ -674,6 +674,68 @@ test_file_readline(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_open_uniquely_named(apr_pool_t *pool)
+{
+ const char *tmp_dir;
+ apr_file_t *file;
+ const char *path;
+ svn_error_t *err;
+
+ SVN_ERR(svn_test_make_sandbox_dir(&tmp_dir, "test_open_uniquely_named",
+ pool));
+
+ /* Test #1: File 'foo.tmp' doesn't exist. */
+ SVN_ERR(svn_io_open_uniquely_named(&file, &path, tmp_dir, "foo", ".tmp",
+ svn_io_file_del_none, pool, pool));
+ SVN_TEST_STRING_ASSERT(path, svn_dirent_join(tmp_dir, "foo.tmp", pool));
+ SVN_ERR(svn_io_file_close(file, pool));
+
+ /* Test #2: File 'foo.tmp' is already exist. */
+ SVN_ERR(svn_io_open_uniquely_named(NULL, &path, tmp_dir, "foo", ".tmp",
+ svn_io_file_del_none, pool, pool));
+ SVN_TEST_STRING_ASSERT(path, svn_dirent_join(tmp_dir, "foo.2.tmp", pool));
+
+ /* Test #3: Directory named 'bar.tmp' is already exist. */
+ SVN_ERR(svn_io_dir_make(svn_dirent_join(tmp_dir, "bar.tmp", pool),
+ APR_OS_DEFAULT, pool));
+ SVN_ERR(svn_io_open_uniquely_named(NULL, &path, tmp_dir, "bar", ".tmp",
+ svn_io_file_del_none, pool, pool));
+ SVN_TEST_STRING_ASSERT(path, svn_dirent_join(tmp_dir, "bar.2.tmp", pool));
+
+
+ /* Test #4: Attempt create file in non-existing directory. */
+ err = svn_io_open_uniquely_named(NULL, &path,
+ svn_dirent_join(tmp_dir, "non-existing", pool),
+ NULL, NULL, svn_io_file_del_none, pool, pool);
+ if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ svn_error_clear(err);
+ }
+ else if (err)
+ {
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected error APR_STATUS_IS_ENOTDIR() but "
+ "got %s",
+ svn_error_symbolic_name(err->apr_err));
+ }
+ else
+ {
+ SVN_TEST_ASSERT_ANY_ERROR(err);
+ }
+
+ /* Test #5: File 'yota.tmp' is already exist and readonly. */
+ SVN_ERR(svn_io_file_create_empty(svn_dirent_join(tmp_dir, "yota.tmp", pool),
+ pool));
+ SVN_ERR(svn_io_set_file_read_only(svn_dirent_join(tmp_dir, "yota.tmp", pool),
+ FALSE, pool));
+ SVN_ERR(svn_io_open_uniquely_named(NULL, &path, tmp_dir, "yota", ".tmp",
+ svn_io_file_del_none, pool, pool));
+ SVN_TEST_STRING_ASSERT(path, svn_dirent_join(tmp_dir, "yota.2.tmp", pool));
+
+ return SVN_NO_ERROR;
+}
+
/* Move the read pointer in FILE to absolute position OFFSET and align
* the read buffer to multiples of BLOCK_SIZE. BUFFERED is set only if
* FILE actually uses a read buffer. Use POOL for allocations.
@@ -803,7 +865,7 @@ aligned_seek_test(apr_pool_t *pool)
SVN_ERR(svn_io_file_close(f, pool));
/* now, try read data with buffering disabled.
- That are a special case because APR reports a buffer size of 0. */
+ That is a special case because APR reports a buffer size of 0. */
SVN_ERR(svn_io_file_open(&f, tmp_file, APR_READ, APR_OS_DEFAULT, pool));
SVN_ERR(aligned_read(f, contents, 0x1000, FALSE, pool));
SVN_ERR(aligned_read(f, contents, 0x8000, FALSE, pool));
@@ -1040,6 +1102,51 @@ test_file_rename2(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_apr_trunc_workaround(apr_pool_t *pool)
+{
+ const char *tmp_dir;
+ const char *tmp_file;
+ apr_file_t *f;
+ apr_size_t len;
+ apr_off_t offset;
+ char dummy;
+
+ /* create a temp folder & schedule it for automatic cleanup */
+ SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "test_apr_trunc_workaround",
+ pool));
+ SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
+ SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
+ svn_test_add_dir_cleanup(tmp_dir);
+
+ /* create an r/w file */
+ tmp_file = svn_dirent_join(tmp_dir, "file", pool);
+ SVN_ERR(svn_io_file_open(&f, tmp_file,
+ APR_READ | APR_WRITE | APR_BUFFERED | APR_CREATE |
+ APR_TRUNCATE,
+ APR_OS_DEFAULT, pool));
+
+ /* write some content and put it internally into read mode */
+ len = 10;
+ SVN_ERR(svn_io_file_write(f, "0123456789", &len, pool));
+
+ offset = 0;
+ SVN_ERR(svn_io_file_seek(f, APR_SET, &offset, pool));
+ SVN_ERR(svn_io_file_getc(&dummy, f, pool));
+
+ /* clear the file and write some new content */
+ SVN_ERR(svn_io_file_trunc(f, 0, pool));
+ len = 3;
+ SVN_ERR(svn_io_file_write(f, "abc", &len, pool));
+
+ /* we should now be positioned at the end of the new content */
+ offset = 0;
+ SVN_ERR(svn_io_file_seek(f, APR_CUR, &offset, pool));
+ SVN_TEST_ASSERT(offset == (int)len);
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
static int max_threads = 3;
@@ -1073,6 +1180,10 @@ static struct svn_test_descriptor_t test
"test svn_io_read_length_line()"),
SVN_TEST_PASS2(test_file_readline,
"test svn_io_file_readline()"),
+ SVN_TEST_PASS2(test_open_uniquely_named,
+ "test svn_io_open_uniquely_named()"),
+ SVN_TEST_PASS2(test_apr_trunc_workaround,
+ "test workaround for APR in svn_io_file_trunc"),
SVN_TEST_NULL
};
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/packed-data-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/packed-data-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/packed-data-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/packed-data-test.c Tue Oct 11 09:11:50 2016
@@ -222,6 +222,7 @@ test_byte_stream(apr_pool_t *pool)
/* the stream shall contain exactly the items we put into it */
SVN_TEST_ASSERT(svn_packed__byte_count(stream) == 20);
+ SVN_TEST_ASSERT(svn_packed__byte_block_count(stream) == COUNT);
for (i = 0; i < COUNT; ++i)
{
svn_string_t string;
Modified: subversion/branches/ra-git/subversion/tests/libsvn_subr/sqlite-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_subr/sqlite-test.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_subr/sqlite-test.c (original)
+++ subversion/branches/ra-git/subversion/tests/libsvn_subr/sqlite-test.c Tue Oct 11 09:11:50 2016
@@ -26,8 +26,10 @@
static svn_error_t *
open_db(svn_sqlite__db_t **sdb,
+ const char **db_abspath_p,
const char *db_name,
const char *const *statements,
+ apr_int32_t timeout,
apr_pool_t *pool)
{
const char *db_dir, *db_abspath;
@@ -40,8 +42,10 @@ open_db(svn_sqlite__db_t **sdb,
db_abspath = svn_dirent_join(db_dir, db_name, pool);
SVN_ERR(svn_sqlite__open(sdb, db_abspath, svn_sqlite__mode_rwcreate,
- statements, 0, NULL, 0, pool, pool));
+ statements, 0, NULL, timeout, pool, pool));
+ if (db_abspath_p)
+ *db_abspath_p = db_abspath;
return SVN_NO_ERROR;
}
@@ -83,7 +87,7 @@ test_sqlite_reset(apr_pool_t *pool)
NULL
};
- SVN_ERR(open_db(&sdb, "reset", statements, pool));
+ SVN_ERR(open_db(&sdb, NULL, "reset", statements, 0, pool));
SVN_ERR(svn_sqlite__create_scalar_function(sdb, "error_second",
1, FALSE /* deterministic */,
error_second, NULL));
@@ -113,6 +117,59 @@ test_sqlite_reset(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_sqlite_txn_commit_busy(apr_pool_t *pool)
+{
+ svn_sqlite__db_t *sdb1;
+ svn_sqlite__db_t *sdb2;
+ const char *db_abspath;
+ svn_error_t *err;
+
+ static const char *const statements[] = {
+ "CREATE TABLE test (one TEXT NOT NULL PRIMARY KEY)",
+
+ "INSERT INTO test(one) VALUES ('foo')",
+
+ "SELECT one from test",
+
+ NULL
+ };
+
+ /* Open two db connections.
+
+ Use a small busy_timeout of 250ms, since we're about to receive an
+ SVN_ERR_SQLITE_BUSY error, and retrying for the default 10 seconds
+ would be a waste of time. */
+ SVN_ERR(open_db(&sdb1, &db_abspath, "txn_commit_busy",
+ statements, 250, pool));
+ SVN_ERR(svn_sqlite__open(&sdb2, db_abspath, svn_sqlite__mode_readwrite,
+ statements, 0, NULL, 250, pool, pool));
+ SVN_ERR(svn_sqlite__exec_statements(sdb1, 0));
+
+ /* Begin two deferred transactions. */
+ SVN_ERR(svn_sqlite__begin_transaction(sdb1));
+ SVN_ERR(svn_sqlite__exec_statements(sdb1, 1 /* INSERT */));
+ SVN_ERR(svn_sqlite__begin_transaction(sdb2));
+ SVN_ERR(svn_sqlite__exec_statements(sdb2, 2 /* SELECT */));
+
+ /* Try to COMMIT the first write transaction; this should fail due to
+ the concurrent read transaction that holds a shared lock on the db. */
+ err = svn_sqlite__finish_transaction(sdb1, SVN_NO_ERROR);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_SQLITE_BUSY);
+
+ /* We failed to COMMIT the first transaction, but COMMIT-ting the
+ second transaction through a different db connection should succeed.
+ Upgrade it to a write transaction by executing the INSERT statement,
+ and then commit. */
+ SVN_ERR(svn_sqlite__exec_statements(sdb2, 1 /* INSERT */));
+ SVN_ERR(svn_sqlite__finish_transaction(sdb2, SVN_NO_ERROR));
+
+ SVN_ERR(svn_sqlite__close(sdb2));
+ SVN_ERR(svn_sqlite__close(sdb1));
+
+ return SVN_NO_ERROR;
+}
+
static int max_threads = 1;
@@ -121,6 +178,8 @@ static struct svn_test_descriptor_t test
SVN_TEST_NULL,
SVN_TEST_PASS2(test_sqlite_reset,
"sqlite reset"),
+ SVN_TEST_PASS2(test_sqlite_txn_commit_busy,
+ "sqlite busy on transaction commit"),
SVN_TEST_NULL
};