#!/usr/bin/env python
# py:encoding=utf-8
#
#  backport_tests.py:  Test backport.pl or backport.py
#
#  Subversion is a tool for revision control.
#  See http://subversion.apache.org for more information.
#
# ====================================================================
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you under the Apache License, Version 2.0 (the
#    "License"); you may not use this file except in compliance
#    with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing,
#    software distributed under the License is distributed on an
#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#    KIND, either express or implied.  See the License for the
#    specific language governing permissions and limitations
#    under the License.
######################################################################

# We'd like to test backport.pl and backport.py the same way, and to reuse
# the svntest Python harness.  Since the latter standardizes argv parsing,
# we can't use argv to determine whether .py or .pl should be tested.  Thus,
# we implement the tests themselves in this file, while two driver files
# (backport_tests_pl.py and backport_tests_py.py) invoke this file set
# to run either backport-suite implementation.
#
# ### Note: the two driver scripts use the same repository names in
# ### svn-test-work.  This is not ideal, but hopefully acceptable
# ### temporarily until we switch over to backport.py and remove backport.pl.
# ###
# ### See svntest.testcase.FunctionTestCase.get_sandbox_name().
try:
  run_backport, run_conflicter
except NameError:
  raise Exception("Failure: %s should not be run directly, or the wrapper "
                  "does not define both run_backport() and run_conflicter()"
                  % __file__)

# General modules
import contextlib
import functools
import os
import re
import sys

@contextlib.contextmanager
def chdir(dir):
  try:
    saved_dir = os.getcwd()
    os.chdir(dir)
    yield
  finally:
    os.chdir(saved_dir)

# Our testing module
# HACK: chdir to cause svntest.main.svn_binary to be set correctly
sys.path.insert(0, os.path.abspath('../../subversion/tests/cmdline'))
with chdir('../../subversion/tests/cmdline'):
  import svntest

# (abbreviations)
Skip = svntest.testcase.Skip_deco
SkipUnless = svntest.testcase.SkipUnless_deco
XFail = svntest.testcase.XFail_deco
Issues = svntest.testcase.Issues_deco
Issue = svntest.testcase.Issue_deco
Wimp = svntest.testcase.Wimp_deco

######################################################################
# Helper functions

STATUS = 'branch/STATUS'

class BackportTest(object):
  """Decorator.  See self.__call__()."""

  def __init__(self, uuid):
    """The argument is the UUID embedded in the dump file.
    If the argument is None, then there is no dump file."""
    self.uuid = uuid

  def __call__(self, test_func):
    """Return a decorator that: builds TEST_FUNC's sbox, creates
    ^/subversion/trunk, and calls TEST_FUNC, then compare its output to the
    expected dump file named after TEST_FUNC."""

    # .wraps() propagates the wrappee's docstring to the wrapper.
    @functools.wraps(test_func)
    def wrapped_test_func(sbox):
      expected_dump_file = './%s.dump' % (test_func.func_name,)

      sbox.build()

      # r2: prepare ^/subversion/ tree
      sbox.simple_mkdir('subversion', 'subversion/trunk')
      sbox.simple_mkdir('subversion/tags', 'subversion/branches')
      sbox.simple_move('A', 'subversion/trunk')
      sbox.simple_move('iota', 'subversion/trunk')
      sbox.simple_commit(message='Create trunk')

      # r3: branch
      sbox.simple_copy('subversion/trunk', 'branch')
      sbox.simple_append('branch/STATUS', '')
      sbox.simple_add('branch/STATUS')
      sbox.simple_commit(message='Create branch, with STATUS file')

      # r4: random change on trunk
      sbox.simple_append('subversion/trunk/iota', 'First change\n')
      sbox.simple_commit(message='First change')

      # r5: random change on trunk
      sbox.simple_append('subversion/trunk/A/mu', 'Second change\n')
      sbox.simple_commit(message='Second change')

      # Do the work.
      test_func(sbox)

      # Verify it.
      verify_backport(sbox, expected_dump_file, self.uuid)
    return wrapped_test_func

def make_entry(revisions=None, logsummary=None, notes=None, branch=None,
               depends=None, votes=None):
  assert revisions
  if logsummary is None:
    logsummary = "default logsummary"
  if votes is None:
    votes = {+1 : ['jrandom']}

  entry = {
    'revisions': revisions,
    'logsummary': logsummary,
    'notes': notes,
    'branch': branch,
    'depends': depends,
    'votes': votes,
  }

  return entry

def serialize_entry(entry):
  return ''.join([

    # revisions,
    ' * %s\n'
    % (", ".join("r%ld" % revision for revision in entry['revisions'])),

    # logsummary
    '   %s\n' % (entry['logsummary'],),

    # notes
    '   Notes: %s\n' % (entry['notes'],) if entry['notes'] else '',

    # branch
    '   Branch: %s\n' % (entry['branch'],) if entry['branch'] else '',

    # depends
    '   Depends: %s\n' % (entry['depends'],) if entry['depends'] else '',

    # votes
    '   Votes:\n',
    ''.join('     '
        '%s: %s\n' % ({1: '+1', 0: '+0', -1: '-1', -0: '-0'}[vote],
                      ", ".join(entry['votes'][vote]))
        for vote in entry['votes']),

    '\n', # empty line after entry
  ])

def serialize_STATUS(approveds,
                     candidates=[],
                     serialize_entry=serialize_entry):
  """Construct and return the contents of a STATUS file.

  APPROVEDS is an iterable of ENTRY dicts.  The dicts are defined
  to have the following keys: 'revisions', a list of revision numbers (ints);
  'logsummary'; and 'votes', a dict mapping ±1/±0 (int) to list of voters.

  CANDIDATES is like APPROVEDS, except added to a different section of the file.
  """

  strings = []
  strings.append("Status of 1.8.x:\n\n")

  strings.append("Candidate changes:\n")
  strings.append("==================\n\n")

  strings.extend(map(serialize_entry, candidates))

  strings.append("Random new subheading:\n")
  strings.append("======================\n\n")

  strings.append("Veto-blocked changes:\n")
  strings.append("=====================\n\n")

  strings.append("Approved changes:\n")
  strings.append("=================\n\n")

  strings.extend(map(serialize_entry, approveds))

  return "".join(strings)

def verify_backport(sbox, expected_dump_file, uuid):
  """Compare the contents of the SBOX repository with EXPECTED_DUMP_FILE.
  Set the UUID of SBOX to UUID beforehand.
  Based on svnsync_tests.py:verify_mirror."""

  if uuid is None:
    # There is no expected dump file.
    return

  # Remove some SVNSync-specific housekeeping properties from the
  # mirror repository in preparation for the comparison dump.
  svntest.actions.enable_revprop_changes(sbox.repo_dir)
  for revnum in range(0, 1+int(sbox.youngest())):
    svntest.actions.run_and_verify_svnadmin([], [],
      "delrevprop", "-r", revnum, sbox.repo_dir, "svn:date")

  # Create a dump file from the mirror repository.
  dest_dump = open(expected_dump_file).readlines()
  svntest.actions.run_and_verify_svnadmin(None, [],
                                          'setuuid', '--', sbox.repo_dir, uuid)
  src_dump = svntest.actions.run_and_verify_dump(sbox.repo_dir)

  svntest.verify.compare_dump_files(
    "Dump files", "DUMP", dest_dump, src_dump)

######################################################################
# Tests
#
#   Each test must return on success or raise on failure.

#----------------------------------------------------------------------
@BackportTest('76cee987-25c9-4d6c-ad40-000000000001')
def backport_indented_entry(sbox):
  "parsing of entries with nonstandard indentation"

  # r6: nominate r4
  approved_entries = [
    make_entry([4]),
  ]
  def reindenting_serialize_entry(*args, **kwargs):
    entry = serialize_entry(*args, **kwargs)
    return ('\n' + entry).replace('\n ', '\n')[1:]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries,
                                              serialize_entry=reindenting_serialize_entry))
  sbox.simple_commit(message='Nominate r4')

  # Run it.
  run_backport(sbox)


#----------------------------------------------------------------------
@BackportTest('76cee987-25c9-4d6c-ad40-000000000002')
def backport_two_approveds(sbox):
  "backport with two approveds"

  # r6: Enter votes
  approved_entries = [
    make_entry([4]),
    make_entry([5]),
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate r4.  Nominate r5.')

  # r7, r8: Run it.
  run_backport(sbox)

  # Now back up and do three entries.
  # r9: revert r7, r8
  svntest.actions.run_and_verify_svnlook(["8\n"], [],
                                         'youngest', sbox.repo_dir)
  sbox.simple_update()
  svntest.main.run_svn(None, 'merge', '-r8:6',
                       '^/branch', sbox.ospath('branch'))
  sbox.simple_commit(message='Revert the merges.')

  # r10: Another change on trunk.
  # (Note that this change must be merged after r5.)
  sbox.simple_rm('subversion/trunk/A')
  sbox.simple_commit(message='Third change on trunk.')

  # r11: Nominate r10.
  sbox.simple_append(STATUS, serialize_entry(make_entry([10])))
  sbox.simple_commit(message='Nominate r10.')

  # r12, r13, r14: Run it.
  run_backport(sbox)



#----------------------------------------------------------------------
@BackportTest('76cee987-25c9-4d6c-ad40-000000000003')
def backport_accept(sbox):
  "test --accept parsing"

  # r6: conflicting change on branch
  sbox.simple_append('branch/iota', 'Conflicts with first change\n')
  sbox.simple_commit(message="Conflicting change on iota")

  # r7: nominate r4 with --accept (because of r6)
  approved_entries = [
    make_entry([4], notes="Merge with --accept=theirs-conflict."),
  ]
  def reindenting_serialize_entry(*args, **kwargs):
    entry = serialize_entry(*args, **kwargs)
    return ('\n' + entry).replace('\n ', '\n')[1:]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries,
                                              serialize_entry=reindenting_serialize_entry))
  sbox.simple_commit(message='Nominate r4')

  # Run it.
  run_backport(sbox)


#----------------------------------------------------------------------
@BackportTest('76cee987-25c9-4d6c-ad40-000000000004')
def backport_branches(sbox):
  "test branches"

  # r6: conflicting change on branch
  sbox.simple_append('branch/iota', 'Conflicts with first change')
  sbox.simple_commit(message="Conflicting change on iota")

  # r7: backport branch
  sbox.simple_update()
  sbox.simple_copy('branch', 'subversion/branches/r4')
  sbox.simple_commit(message='Create a backport branch')

  # r8: merge into backport branch
  sbox.simple_update()
  svntest.main.run_svn(None, 'merge', '--record-only', '-c4',
                       '^/subversion/trunk', sbox.ospath('subversion/branches/r4'))
  sbox.simple_mkdir('subversion/branches/r4/A_resolved')
  sbox.simple_append('subversion/branches/r4/iota', "resolved\n", truncate=1)
  sbox.simple_commit(message='Conflict resolution via mkdir')

  # r9: nominate r4 with branch
  approved_entries = [
    make_entry([4], branch="r4")
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate r4')

  # Run it.
  run_backport(sbox)

  # This also serves as the 'success mode' part of backport_branch_contains().


#----------------------------------------------------------------------
@BackportTest('76cee987-25c9-4d6c-ad40-000000000005')
def backport_multirevisions(sbox):
  "test multirevision entries"

  # r6: nominate r4,r5
  approved_entries = [
    make_entry([4,5])
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate a group.')

  # Run it.
  run_backport(sbox)


#----------------------------------------------------------------------
@BackportTest(None) # would be 000000000006
def backport_conflicts_detection(sbox):
  "test the conflicts detector"

  # r6: conflicting change on branch
  sbox.simple_append('branch/iota', 'Conflicts with first change\n')
  sbox.simple_commit(message="Conflicting change on iota")

  # r7: nominate r4, but without the requisite --accept
  candidate_entries = [
    make_entry([4], notes="This will conflict."),
  ]
  sbox.simple_append(STATUS, serialize_STATUS([], candidate_entries))
  sbox.simple_commit(message='Nominate r4')

  # Run it.
  exit_code, output, errput = run_conflicter(sbox, True)

  # Verify the conflict is detected.
  expected_output = svntest.verify.RegexOutput(
    'Index: iota',
    match_all=False,
  )
  expected_errput = (
    r'(?ms)' # re.MULTILINE | re.DOTALL
    r'.*Warning summary.*'
    r'^r4 [(]default logsummary[)]: Conflicts on iota.*'
  )
  expected_errput = svntest.verify.RegexListOutput(
                      [
                        r'Warning summary',
                        r'===============',
                        r'r4 [(]default logsummary[)]: Conflicts on iota',
                      ],
                      match_all=False)
  svntest.verify.verify_outputs(None, output, errput,
                                expected_output, expected_errput)
  svntest.verify.verify_exit_code(None, exit_code, 1)

  ## Now, let's test the "Depends:" annotation silences the error.

  # Re-nominate.
  approved_entries = [
    make_entry([4], depends="World peace."),
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries), truncate=True)
  sbox.simple_commit(message='Re-nominate r4')

  # Detect conflicts.
  exit_code, output, errput = run_conflicter(sbox)

  # Verify stdout.  (exit_code and errput were verified by run_conflicter().)
  svntest.verify.verify_outputs(None, output, errput,
                                "Conflicts found.*, as expected.", [])


#----------------------------------------------------------------------
@BackportTest(None) # would be 000000000007
def backport_branch_contains(sbox):
  "branch must contain the revisions"

  # r6: conflicting change on branch
  sbox.simple_append('branch/iota', 'Conflicts with first change')
  sbox.simple_commit(message="Conflicting change on iota")

  # r7: backport branch
  sbox.simple_update()
  sbox.simple_copy('branch', 'subversion/branches/r4')
  sbox.simple_commit(message='Create a backport branch')

  # r8: merge into backport branch
  sbox.simple_update()
  svntest.main.run_svn(None, 'merge', '--record-only', '-c4',
                       '^/subversion/trunk', sbox.ospath('subversion/branches/r4'))
  sbox.simple_mkdir('subversion/branches/r4/A_resolved')
  sbox.simple_append('subversion/branches/r4/iota', "resolved\n", truncate=1)
  sbox.simple_commit(message='Conflict resolution via mkdir')

  # r9: nominate r4,r5 with branch that contains not all of them
  approved_entries = [
    make_entry([4,5], branch="r4")
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate r4')

  # Run it.
  exit_code, output, errput = run_backport(sbox, error_expected=True)

  # Verify the error message.
  expected_errput = svntest.verify.RegexOutput(
    ".*Revisions 'r5' nominated but not included in branch",
    match_all=False,
  )
  svntest.verify.verify_outputs(None, output, errput,
                                [], expected_errput)
  svntest.verify.verify_exit_code(None, exit_code, 1)

  # Verify no commit occurred.
  svntest.actions.run_and_verify_svnlook(["9\n"], [],
                                         'youngest', sbox.repo_dir)

  # Verify the working copy has been reverted.
  svntest.actions.run_and_verify_svn([], [], 'status', '-q',
                                     sbox.repo_dir)

  # The sibling test backport_branches() verifies the success mode.




#----------------------------------------------------------------------
@BackportTest(None) # would be 000000000008
def backport_double_conflict(sbox):
  "two-revisioned entry with two conflicts"

  # r6: conflicting change on branch
  sbox.simple_append('branch/iota', 'Conflicts with first change')
  sbox.simple_commit(message="Conflicting change on iota")

  # r7: further conflicting change to same file
  sbox.simple_update()
  sbox.simple_append('subversion/trunk/iota', 'Third line\n')
  sbox.simple_commit(message="iota's third line")

  # r8: nominate
  approved_entries = [
    make_entry([4,7], depends="World peace.")
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate the r4 group')

  # Run it, in conflicts mode.
  exit_code, output, errput = run_conflicter(sbox, True)

  # Verify the failure mode: "merge conflict" error on stderr, but backport.pl
  # itself exits with code 0, since conflicts were confined to Depends:-ed
  # entries.
  #
  # The error only happens with multi-pass merges where the first pass
  # conflicts and the second pass touches the conflict victim.
  #
  # The error would be:
  #    subversion/libsvn_client/merge.c:5499: (apr_err=SVN_ERR_WC_FOUND_CONFLICT)
  #    svn: E155015: One or more conflicts were produced while merging r3:4
  #    into '/tmp/stw/working_copies/backport_tests-8/branch' -- resolve all
  #    conflicts and rerun the merge to apply the remaining unmerged revisions
  #    ...
  #    Warning summary
  #    ===============
  #    
  #    r4 (default logsummary): subshell exited with code 256
  # And backport.pl would exit with exit code 1.

  expected_output = 'Conflicts found.*, as expected.'
  expected_errput = svntest.verify.RegexOutput(
      ".*svn: E155015:.*", # SVN_ERR_WC_FOUND_CONFLICT
      match_all=False,
  )
  svntest.verify.verify_outputs(None, output, errput,
                                expected_output, expected_errput)
  svntest.verify.verify_exit_code(None, exit_code, 0)
  if any("Warning summary" in line for line in errput):
    raise svntest.verify.SVNUnexpectedStderr(errput)

  ## Now, let's ensure this does get detected if not silenced.
  # r9: Re-nominate
  approved_entries = [
    make_entry([4,7]) # no depends=
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries), truncate=True)
  sbox.simple_commit(message='Re-nominate the r4 group')

  exit_code, output, errput = run_conflicter(sbox, True)

  ## An unexpected non-zero exit code is treated as a fatal error.
  # [1-9]\d+ matches non-zero exit codes
  expected_stdout = None
  expected_errput = r'r4 .*: subshell exited with code (?:[1-9]\d+)' \
                   r"|.*subprocess.CalledProcessError.*'merge'.*exit status 1"
  svntest.verify.verify_exit_code(None, exit_code, 1)
  svntest.verify.verify_outputs(None, output, errput,
                                expected_stdout, expected_errput)



#----------------------------------------------------------------------
@BackportTest('76cee987-25c9-4d6c-ad40-000000000009')
def backport_branch_with_original_revision(sbox):
  "branch with original revision"

  # r6: conflicting change on branch
  sbox.simple_append('branch/iota', 'Conflicts with first change')
  sbox.simple_commit(message="Conflicting change on iota")

  # r7: backport branch
  sbox.simple_update()
  sbox.simple_copy('branch', 'subversion/branches/r4')
  sbox.simple_commit(message='Create a backport branch')

  # r8: merge into backport branch
  sbox.simple_update()
  svntest.main.run_svn(None, 'merge', '--record-only', '-c4',
                       '^/subversion/trunk', sbox.ospath('subversion/branches/r4'))
  sbox.simple_mkdir('subversion/branches/r4/A_resolved')
  sbox.simple_append('subversion/branches/r4/iota', "resolved\n", truncate=1)
  sbox.simple_commit(message='Conflict resolution via mkdir')

  # r9: original revision on branch
  sbox.simple_update()
  sbox.simple_mkdir('subversion/branches/r4/dir-created-on-backport-branch')
  sbox.simple_commit(message='An original revision on the backport branch')

  # r10: nominate the branch with r9 listed
  approved_entries = [
    make_entry([4, 9], branch="r4")
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate r4+r9')

  # r11, r12: Run it.
  run_backport(sbox)


#----------------------------------------------------------------------
@BackportTest(None)
def backport_otherproject_change(sbox):
  "inoperative revision"

  # r6: a change outside ^/subversion
  sbox.simple_mkdir('elsewhere')
  sbox.simple_commit()

  # r7: Nominate r6 by mistake
  approved_entries = [
    make_entry([6])
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate r6 by mistake')

  # Run it.
  exit_code, output, errput = run_backport(sbox, error_expected=True)

  # Verify no commit occurred.
  svntest.actions.run_and_verify_svnlook(["7\n"], [],
                                         'youngest', sbox.repo_dir)

  # Verify the failure mode.
  expected_stdout = None
  expected_stderr = ".*only svn:mergeinfo changes.*"
  if exit_code == 0:
    # Can't use verify_exit_code() since the exact code used varies.
    raise svntest.Failure("exit_code should be non-zero")
  svntest.verify.verify_outputs(None, output, errput,
                                expected_stdout, expected_stderr)

#----------------------------------------------------------------------
@BackportTest(None)
def backport_STATUS_mods(sbox):
  "local mods to STATUS"

  # Introduce a local mod.
  sbox.simple_append(STATUS, "\n")

  exit_code, output, errput = run_backport(sbox, error_expected=True)
  expected_stdout = None
  expected_stderr = ".*Local mods.*STATUS.*"
  if exit_code == 0:
    # Can't use verify_exit_code() since the exact code used varies.
    raise svntest.Failure("exit_code should be non-zero")
  svntest.verify.verify_outputs(None, output, errput,
                                expected_stdout, expected_stderr)

#----------------------------------------------------------------------
@BackportTest('76cee987-25c9-4d6c-ad40-000000000012')
def backport_unicode_entry(sbox):
  "an entry containing literal UTF-8"

  # r6: nominate r4
  approved_entries = [
    make_entry([4], notes="Hello 🗺"),
  ]
  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
  sbox.simple_commit(message='Nominate r4')

  # Run it.
  run_backport(sbox)


#----------------------------------------------------------------------

########################################################################
# Run the tests

# list all tests here, starting with None:
test_list = [ None,
              backport_indented_entry,
              backport_two_approveds,
              backport_accept,
              backport_branches,
              backport_multirevisions,
              backport_conflicts_detection,
              backport_branch_contains,
              backport_double_conflict,
              backport_branch_with_original_revision,
              backport_otherproject_change,
              backport_STATUS_mods,
              backport_unicode_entry,
              # When adding a new test, include the test number in the last
              # 6 bytes of the UUID, in decimal.
             ]

if __name__ == '__main__':
  # Using putenv() here is fine because this file is never run as a module.
  os.putenv('SVN_BACKPORT_DONT_SLEEP', '1')
  svntest.main.run_tests(test_list)
  # NOTREACHED


### End of file.
