Example #1
0
def run_and_verify_unquiet_status(wc_dir_name, output_tree,
                                  singleton_handler_a = None,
                                  a_baton = None,
                                  singleton_handler_b = None,
                                  b_baton = None):
  """Run 'status' on WC_DIR_NAME and compare it with the
  expected OUTPUT_TREE.  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will
  be passed to tree.compare_trees - see that function's doc string for
  more details.
  Returns on success, raises on failure."""

  if isinstance(output_tree, wc.State):
    output_tree = output_tree.old_tree()

  output, errput = main.run_svn (None, 'status', '-v', '-u', wc_dir_name)

  mytree = tree.build_tree_from_status (output)

  # Verify actual output against expected output.
  if (singleton_handler_a or singleton_handler_b):
    tree.compare_trees (mytree, output_tree,
                        singleton_handler_a, a_baton,
                        singleton_handler_b, b_baton)
  else:
    tree.compare_trees (mytree, output_tree)
Example #2
0
def verify_update(actual_output, wc_dir_name, output_tree, disk_tree,
                  status_tree, singleton_handler_a, a_baton,
                  singleton_handler_b, b_baton, check_props):
    """Verify update of WC_DIR_NAME.

  The subcommand output (found in ACTUAL_OUTPUT) will be verified
  against OUTPUT_TREE, and the working copy itself will be verified
  against DISK_TREE.  If optional STATUS_OUTPUT_TREE is given, then
  'svn status' output will be compared.  (This is a good way to check
  that revision numbers were bumped.)  SINGLETON_HANDLER_A and
  SINGLETON_HANDLER_B will be passed to tree.compare_trees - see that
  function's doc string for more details.  If CHECK_PROPS is set, then
  disk comparison will examine props.  Returns if successful, raises
  on failure."""

    # Verify actual output against expected output.
    tree.compare_trees(actual_output, output_tree)

    # Create a tree by scanning the working copy
    mytree = tree.build_tree_from_wc(wc_dir_name, check_props)

    # Verify expected disk against actual disk.
    tree.compare_trees(mytree, disk_tree, singleton_handler_a, a_baton,
                       singleton_handler_b, b_baton)

    # Verify via 'status' command too, if possible.
    if status_tree:
        run_and_verify_status(wc_dir_name, status_tree)
Example #3
0
def run_and_verify_status(wc_dir_name,
                          output_tree,
                          singleton_handler_a=None,
                          a_baton=None,
                          singleton_handler_b=None,
                          b_baton=None):
    """Run 'status' on WC_DIR_NAME and compare it with the
  expected OUTPUT_TREE.  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will
  be passed to tree.compare_trees - see that function's doc string for
  more details.
  Returns on success, raises on failure."""

    if isinstance(output_tree, wc.State):
        output_tree = output_tree.old_tree()

    output, errput = main.run_svn(None, 'status', '-v', '-u', '-q',
                                  '--username', main.wc_author, '--password',
                                  main.wc_passwd, wc_dir_name)

    mytree = tree.build_tree_from_status(output)

    # Verify actual output against expected output.
    try:
        tree.compare_trees(mytree, output_tree, singleton_handler_a, a_baton,
                           singleton_handler_b, b_baton)
    except tree.SVNTreeError:
        display_trees(None, 'STATUS OUTPUT TREE', output_tree, mytree)
        raise
Example #4
0
def run_and_verify_unquiet_status(wc_dir_name,
                                  output_tree,
                                  singleton_handler_a=None,
                                  a_baton=None,
                                  singleton_handler_b=None,
                                  b_baton=None):
    """Run 'status' on WC_DIR_NAME and compare it with the
  expected OUTPUT_TREE.  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will
  be passed to tree.compare_trees - see that function's doc string for
  more details.
  Returns on success, raises on failure."""

    if isinstance(output_tree, wc.State):
        output_tree = output_tree.old_tree()

    output, errput = main.run_svn(None, 'status', '-v', '-u', wc_dir_name)

    mytree = tree.build_tree_from_status(output)

    # Verify actual output against expected output.
    if (singleton_handler_a or singleton_handler_b):
        tree.compare_trees(mytree, output_tree, singleton_handler_a, a_baton,
                           singleton_handler_b, b_baton)
    else:
        tree.compare_trees(mytree, output_tree)
Example #5
0
def verify_update(actual_output, wc_dir_name,
                  output_tree, disk_tree, status_tree,
                  singleton_handler_a, a_baton,
                  singleton_handler_b, b_baton,
                  check_props):
  """Verify update of WC_DIR_NAME.
  
  The subcommand output (found in ACTUAL_OUTPUT) will be verified
  against OUTPUT_TREE, and the working copy itself will be verified
  against DISK_TREE.  If optional STATUS_OUTPUT_TREE is given, then
  'svn status' output will be compared.  (This is a good way to check
  that revision numbers were bumped.)  SINGLETON_HANDLER_A and
  SINGLETON_HANDLER_B will be passed to tree.compare_trees - see that
  function's doc string for more details.  If CHECK_PROPS is set, then
  disk comparison will examine props.  Returns if successful, raises
  on failure."""

  # Verify actual output against expected output.
  tree.compare_trees (actual_output, output_tree)

  # Create a tree by scanning the working copy
  mytree = tree.build_tree_from_wc (wc_dir_name, check_props)

  # Verify expected disk against actual disk.
  tree.compare_trees (mytree, disk_tree,
                      singleton_handler_a, a_baton,
                      singleton_handler_b, b_baton)

  # Verify via 'status' command too, if possible.
  if status_tree:
    run_and_verify_status(wc_dir_name, status_tree)
def run_and_verify_update(wc_dir_name,
                          output_tree, disk_tree, status_tree,
                          singleton_handler_a = None,
                          a_baton = None,
                          singleton_handler_b = None,
                          b_baton = None,
                          check_props = 0,
                          *args):
  """Update WC_DIR_NAME into a new directory WC_DIR_NAME.  *ARGS are
  any extra optional args to the update subcommand.

  The subcommand output will be verified against OUTPUT_TREE, and the
  working copy itself will be verified against DISK_TREE.  If optional
  STATUS_OUTPUT_TREE is given, then 'svn status' output will be
  compared.  (This is a good way to check that revision numbers were
  bumped.)  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more details.
  If CHECK_PROPS is set, then disk comparison will examine props.
  Return 0 if successful."""

  # Update and make a tree of the output.
  output, errput = main.run_svn (None, 'up', wc_dir_name, *args)
  mytree = tree.build_tree_from_checkout (output)

  # Verify actual output against expected output.
  if tree.compare_trees (mytree, output_tree):
    return 1

  # Create a tree by scanning the working copy
  mytree = tree.build_tree_from_wc (wc_dir_name, check_props)

  # Verify expected disk against actual disk.
  if tree.compare_trees (mytree, disk_tree,
                         singleton_handler_a, a_baton,
                         singleton_handler_b, b_baton):
    return 1

  # Verify via 'status' command too, if possible.
  if status_tree:
    if run_and_verify_status(wc_dir_name, status_tree):
      return 1
  
  return 0
Example #7
0
def run_and_verify_export(URL,
                          export_dir_name,
                          output_tree,
                          disk_tree,
                          singleton_handler_a=None,
                          a_baton=None,
                          singleton_handler_b=None,
                          b_baton=None,
                          *args):
    """Export the URL into a new directory WC_DIR_NAME.

  The subcommand output will be verified against OUTPUT_TREE,
  and the exported copy itself will be verified against DISK_TREE.
  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more details.
  Returns if successful and raise on failure."""

    if isinstance(output_tree, wc.State):
        output_tree = output_tree.old_tree()
    if isinstance(disk_tree, wc.State):
        disk_tree = disk_tree.old_tree()

    # Export and make a tree of the output, using l:foo/p:bar
    ### todo: svn should not be prompting for auth info when using
    ### repositories with no auth/auth requirements
    output, errput = main.run_svn(None, 'export', '--username', main.wc_author,
                                  '--password', main.wc_passwd, URL,
                                  export_dir_name, *args)
    mytree = tree.build_tree_from_checkout(output)

    # Verify actual output against expected output.
    tree.compare_trees(mytree, output_tree)

    # Create a tree by scanning the working copy.  Don't ignore
    # the .svn directories so that we generate an error if they
    # happen to show up.
    mytree = tree.build_tree_from_wc(export_dir_name, ignore_svn=0)

    # Verify expected disk against actual disk.
    tree.compare_trees(mytree, disk_tree, singleton_handler_a, a_baton,
                       singleton_handler_b, b_baton)
Example #8
0
def run_and_verify_diff_summarize(output_tree,
                                  error_re_string=None,
                                  singleton_handler_a=None,
                                  a_baton=None,
                                  singleton_handler_b=None,
                                  b_baton=None,
                                  *args):
    """Run 'diff --summarize' with the arguments *ARGS.
  If ERROR_RE_STRING, the command must exit with error, and the error
  message must match regular expression ERROR_RE_STRING.

  Else if ERROR_RE_STRING is None, the subcommand output will be
  verified against OUTPUT_TREE.  SINGLETON_HANDLER_A and
  SINGLETON_HANDLER_B will be passed to tree.compare_trees - see that
  function's doc string for more details.  Returns on success, raises
  on failure."""

    if isinstance(output_tree, wc.State):
        output_tree = output_tree.old_tree()

    output, errput = main.run_svn(None, 'diff', '--summarize', '--username',
                                  main.wc_author, '--password', main.wc_passwd,
                                  *args)

    if (error_re_string):
        rm = re.compile(error_re_string)
        for line in errput:
            match = rm.search(line)
            if match:
                return
        raise main.SVNUnmatchedError

    mytree = tree.build_tree_from_diff_summarize(output)

    # Verify actual output against expected output.
    try:
        tree.compare_trees(mytree, output_tree, singleton_handler_a, a_baton,
                           singleton_handler_b, b_baton)
    except tree.SVNTreeError:
        display_trees(None, 'DIFF OUTPUT TREE', output_tree, mytree)
        raise
Example #9
0
def run_and_verify_export(URL, export_dir_name, output_tree, disk_tree,
                          singleton_handler_a = None,
                          a_baton = None,
                          singleton_handler_b = None,
                          b_baton = None,
                          *args):
  """Export the URL into a new directory WC_DIR_NAME.

  The subcommand output will be verified against OUTPUT_TREE,
  and the exported copy itself will be verified against DISK_TREE.
  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more details.
  Returns if successful and raise on failure."""

  if isinstance(output_tree, wc.State):
    output_tree = output_tree.old_tree()
  if isinstance(disk_tree, wc.State):
    disk_tree = disk_tree.old_tree()

  # Export and make a tree of the output, using l:foo/p:bar
  ### todo: svn should not be prompting for auth info when using
  ### repositories with no auth/auth requirements
  output, errput = main.run_svn (None, 'export',
                                 '--username', main.wc_author,
                                 '--password', main.wc_passwd,
                                 URL, export_dir_name, *args)
  mytree = tree.build_tree_from_checkout (output)

  # Verify actual output against expected output.
  tree.compare_trees (mytree, output_tree)

  # Create a tree by scanning the working copy.  Don't ignore
  # the .svn directories so that we generate an error if they
  # happen to show up.
  mytree = tree.build_tree_from_wc (export_dir_name, ignore_svn=0)

  # Verify expected disk against actual disk.
  tree.compare_trees (mytree, disk_tree,
                      singleton_handler_a, a_baton,
                      singleton_handler_b, b_baton)
def run_and_verify_checkout(URL, wc_dir_name, output_tree, disk_tree,
                            singleton_handler_a = None,
                            a_baton = None,
                            singleton_handler_b = None,
                            b_baton = None):
  """Checkout the the URL into a new directory WC_DIR_NAME.

  The subcommand output will be verified against OUTPUT_TREE,
  and the working copy itself will be verified against DISK_TREE.
  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more details.
  Return 0 if successful."""

  # Remove dir if it's already there.
  main.remove_wc(wc_dir_name)

  # Checkout and make a tree of the output, using l:foo/p:bar
  ### todo: svn should not be prompting for auth info when using
  ### repositories with no auth/auth requirements
  output, errput = main.run_svn (None, 'co',
                                 '--username', main.wc_author,
                                 '--password', main.wc_passwd,
                                 URL, '-d', wc_dir_name)
  mytree = tree.build_tree_from_checkout (output)

  # Verify actual output against expected output.
  if tree.compare_trees (mytree, output_tree):
    return 1

  # Create a tree by scanning the working copy
  mytree = tree.build_tree_from_wc (wc_dir_name)

  # Verify expected disk against actual disk.
  if tree.compare_trees (mytree, disk_tree,
                                 singleton_handler_a, a_baton,
                                 singleton_handler_b, b_baton):
    return 1

  return 0
def guarantee_greek_repository(path):
  """Guarantee that a local svn repository exists at PATH, containing
  nothing but the greek-tree at revision 1."""

  if path == main.pristine_dir:
    print "ERROR:  attempt to overwrite the pristine repos!  Aborting."
    sys.exit(1)

  # If there's no pristine repos, create one.
  if not os.path.exists(main.pristine_dir):
    main.create_repos(main.pristine_dir)
    
    # dump the greek tree to disk.
    main.write_tree(main.greek_dump_dir,
                    [[x[0], x[1]] for x in main.greek_tree])

    # build a URL for doing an import.
    url = main.test_area_url + '/' + main.pristine_dir

    # import the greek tree, using l:foo/p:bar
    ### todo: svn should not be prompting for auth info when using
    ### repositories with no auth/auth requirements
    output, errput = main.run_svn(None, 'import',
                                  '--username', main.wc_author,
                                  '--password', main.wc_passwd,
                                  '-m', 'Log message for revision 1.',
                                  url, main.greek_dump_dir)

    # check for any errors from the import
    if len(errput):
      print "Errors during initial 'svn import':"
      print errput
      sys.exit(1)

    # verify the printed output of 'svn import'.
    lastline = string.strip(output.pop())
    cm = re.compile ("(Committed|Imported) revision [0-9]+.")
    match = cm.search (lastline)
    if not match:
      print "ERROR:  import did not succeed, while creating greek repos."
      print "The final line from 'svn import' was:"
      print lastline
      sys.exit(1)
    output_tree = tree.build_tree_from_commit(output)

    output_list = []
    path_list = [x[0] for x in main.greek_tree]
    for apath in path_list:
      item = [ os.path.join(".", apath), None, {}, {'verb' : 'Adding'}]
      output_list.append(item)
    expected_output_tree = tree.build_generic_tree(output_list)
      
    if tree.compare_trees(output_tree, expected_output_tree):
      print "ERROR:  output of import command is unexpected."
      sys.exit(1)

  # Now that the pristine repos exists, copy it to PATH.
  if os.path.exists(path):
    shutil.rmtree(path)
  if not os.path.exists(os.path.dirname(path)):
    os.makedirs(os.path.dirname(path))
  shutil.copytree(main.pristine_dir, path)
  if os.path.exists(main.current_repo_dir):
    os.unlink(main.current_repo_dir)                              
  os.symlink(os.path.basename(path), main.current_repo_dir)
Example #12
0
def run_and_verify_merge(dir, rev1, rev2, url,
                         output_tree, disk_tree, status_tree, skip_tree,
                         error_re_string = None,
                         singleton_handler_a = None,
                         a_baton = None,
                         singleton_handler_b = None,
                         b_baton = None,
                         check_props = 0,
                         dry_run = 1,
                         *args):

  """Run 'svn merge -rREV1:REV2 URL DIR'

  If ERROR_RE_STRING, the merge must exit with error, and the error
  message must match regular expression ERROR_RE_STRING.

  Else if ERROR_RE_STRING is None, then:

  The subcommand output will be verified against OUTPUT_TREE, and the
  working copy itself will be verified against DISK_TREE.  If optional
  STATUS_TREE is given, then 'svn status' output will be compared.
  The 'skipped' merge output will be compared to SKIP_TREE.
  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more
  details.
  
  If CHECK_PROPS is set, then disk comparison will examine props.

  If DRY_RUN is set then a --dry-run merge will be carried out first and
  the output compared with that of the full merge.
  
  Returns if successful, raises on failure."""

  if isinstance(output_tree, wc.State):
    output_tree = output_tree.old_tree()
  if isinstance(disk_tree, wc.State):
    disk_tree = disk_tree.old_tree()
  if isinstance(status_tree, wc.State):
    status_tree = status_tree.old_tree()
  if isinstance(skip_tree, wc.State):
    skip_tree = skip_tree.old_tree()

  merge_command = ('merge', '-r', rev1 + ':' + rev2, url, dir)

  if dry_run:
    pre_disk = tree.build_tree_from_wc(dir)
    dry_run_command = merge_command + ('--dry-run',)
    dry_run_command = dry_run_command + args
    out_dry, err_dry = main.run_svn(error_re_string, *dry_run_command)
    post_disk = tree.build_tree_from_wc(dir)
    try:
      tree.compare_trees(post_disk, pre_disk)
    except tree.SVNTreeError:
      print "============================================================="
      print "Dry-run merge altered working copy"
      print "============================================================="
      raise
      

  # Update and make a tree of the output.
  merge_command = merge_command + args
  out, err = main.run_svn (error_re_string, *merge_command)

  if (error_re_string):
    rm = re.compile(error_re_string)
    for line in err:
      match = rm.search(line)
      if match:
        return
    raise main.SVNUnmatchedError
  elif err:
    ### we should raise a less generic error here. which?
    raise Failure(err)

  if dry_run and out != out_dry:
    print "============================================================="
    print "Merge outputs differ"
    print "The dry-run merge output:"
    map(sys.stdout.write, out_dry)
    print "The full merge output:"
    map(sys.stdout.write, out)
    print "============================================================="
    raise main.SVNUnmatchedError

  def missing_skip(a, b):
    print "============================================================="
    print "Merge failed to skip: " + a.path
    print "============================================================="
    raise Failure
  def extra_skip(a, b):
    print "============================================================="
    print "Merge unexpectedly skipped: " + a.path
    print "============================================================="
    raise Failure

  myskiptree = tree.build_tree_from_skipped(out)
  tree.compare_trees(myskiptree, skip_tree,
                     extra_skip, None, missing_skip, None)

  mytree = tree.build_tree_from_checkout(out)
  verify_update (mytree, dir,
                 output_tree, disk_tree, status_tree,
                 singleton_handler_a, a_baton,
                 singleton_handler_b, b_baton,
                 check_props)
Example #13
0
def run_and_verify_commit(wc_dir_name, output_tree, status_output_tree,
                          error_re_string = None,
                          singleton_handler_a = None,
                          a_baton = None,
                          singleton_handler_b = None,
                          b_baton = None,
                          *args):
  """Commit and verify results within working copy WC_DIR_NAME,
  sending ARGS to the commit subcommand.

  The subcommand output will be verified against OUTPUT_TREE.  If
  optional STATUS_OUTPUT_TREE is given, then 'svn status' output will
  be compared.  (This is a good way to check that revision numbers
  were bumped.)

  If ERROR_RE_STRING is None, the commit must not exit with error.  If
  ERROR_RE_STRING is a string, the commit must exit with error, and
  the error message must match regular expression ERROR_RE_STRING.

  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more
  details.  Returns if successful, raises on failure."""

  if isinstance(output_tree, wc.State):
    output_tree = output_tree.old_tree()
  if isinstance(status_output_tree, wc.State):
    status_output_tree = status_output_tree.old_tree()

  # Commit.
  output, errput = main.run_svn(error_re_string, 'ci', '-m', 'log msg', *args)

  if (error_re_string):
    rm = re.compile(error_re_string)
    for line in errput:
      match = rm.search(line)
      if match:
        return
    raise main.SVNUnmatchedError

  # Else not expecting error:

  # Remove the final output line, and verify that the commit succeeded.
  lastline = ""
  if len(output):
    lastline = string.strip(output.pop())
    
    cm = re.compile("(Committed|Imported) revision [0-9]+.")
    match = cm.search(lastline)
    if not match:
      print "ERROR:  commit did not succeed."
      print "The final line from 'svn ci' was:"
      print lastline
      raise main.SVNCommitFailure

  # The new 'final' line in the output is either a regular line that
  # mentions {Adding, Deleting, Sending, ...}, or it could be a line
  # that says "Transmitting file data ...".  If the latter case, we
  # want to remove the line from the output; it should be ignored when
  # building a tree.
  if len(output):
    lastline = output.pop()

    tm = re.compile("Transmitting file data.+")
    match = tm.search(lastline)
    if not match:
      # whoops, it was important output, put it back.
      output.append(lastline)
    
  # Convert the output into a tree.
  mytree = tree.build_tree_from_commit (output)
    
  # Verify actual output against expected output.
  try:
    tree.compare_trees (mytree, output_tree)
  except tree.SVNTreeError:
      display_trees("Output of commit is unexpected.",
                    "OUTPUT TREE", output_tree, mytree)
      raise
    
  # Verify via 'status' command too, if possible.
  if status_output_tree:
    run_and_verify_status(wc_dir_name, status_output_tree)
Example #14
0
def guarantee_greek_repository(path):
    """Guarantee that a local svn repository exists at PATH, containing
  nothing but the greek-tree at revision 1."""

    if path == main.pristine_dir:
        print "ERROR:  attempt to overwrite the pristine repos!  Aborting."
        sys.exit(1)

    # If there's no pristine repos, create one.
    if not os.path.exists(main.pristine_dir):
        main.create_repos(main.pristine_dir)

        # dump the greek tree to disk.
        main.greek_state.write_to_disk(main.greek_dump_dir)

        # build a URL for doing an import.
        url = main.test_area_url + '/' + main.pristine_dir
        if main.windows == 1:
            url = string.replace(url, '\\', '/')

        # import the greek tree, using l:foo/p:bar
        ### todo: svn should not be prompting for auth info when using
        ### repositories with no auth/auth requirements
        output, errput = main.run_svn(None, 'import', '--username',
                                      main.wc_author, '--password',
                                      main.wc_passwd, '-m',
                                      'Log message for revision 1.',
                                      main.greek_dump_dir, url)

        # check for any errors from the import
        if len(errput):
            display_lines("Errors during initial 'svn import':", 'STDERR',
                          None, errput)
            sys.exit(1)

        # verify the printed output of 'svn import'.
        lastline = string.strip(output.pop())
        cm = re.compile("(Committed|Imported) revision [0-9]+.")
        match = cm.search(lastline)
        if not match:
            print "ERROR:  import did not succeed, while creating greek repos."
            print "The final line from 'svn import' was:"
            print lastline
            sys.exit(1)
        output_tree = tree.build_tree_from_commit(output)

        ### due to path normalization in the .old_tree() method, we cannot
        ### prepend the necessary '.' directory. thus, let's construct an old
        ### tree manually from the greek_state.
        output_list = []
        for greek_path in main.greek_state.desc.keys():
            output_list.append([
                os.path.join(main.greek_dump_dir, greek_path), None, {}, {
                    'verb': 'Adding'
                }
            ])
        expected_output_tree = tree.build_generic_tree(output_list)

        try:
            tree.compare_trees(output_tree, expected_output_tree)
        except tree.SVNTreeUnequal:
            display_trees("ERROR:  output of import command is unexpected.",
                          'OUTPUT TREE', expected_output_tree, output_tree)
            sys.exit(1)

    # Now that the pristine repos exists, copy it to PATH.
    main.safe_rmtree(path)
    if main.copy_repos(main.pristine_dir, path, 1):
        print "ERROR:  copying repository failed."
        sys.exit(1)

    # make the repos world-writeable, for mod_dav_svn's sake.
    main.chmod_tree(path, 0666, 0666)
Example #15
0
def run_and_verify_commit(wc_dir_name,
                          output_tree,
                          status_output_tree,
                          error_re_string=None,
                          singleton_handler_a=None,
                          a_baton=None,
                          singleton_handler_b=None,
                          b_baton=None,
                          *args):
    """Commit and verify results within working copy WC_DIR_NAME,
  sending ARGS to the commit subcommand.

  The subcommand output will be verified against OUTPUT_TREE.  If
  optional STATUS_OUTPUT_TREE is given, then 'svn status' output will
  be compared.  (This is a good way to check that revision numbers
  were bumped.)

  If ERROR_RE_STRING is None, the commit must not exit with error.  If
  ERROR_RE_STRING is a string, the commit must exit with error, and
  the error message must match regular expression ERROR_RE_STRING.

  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more
  details.  Returns if successful, raises on failure."""

    if isinstance(output_tree, wc.State):
        output_tree = output_tree.old_tree()
    if isinstance(status_output_tree, wc.State):
        status_output_tree = status_output_tree.old_tree()

    # Commit.
    output, errput = main.run_svn(error_re_string, 'ci', '--username',
                                  main.wc_author, '--password', main.wc_passwd,
                                  '-m', 'log msg', *args)

    if (error_re_string):
        rm = re.compile(error_re_string)
        for line in errput:
            match = rm.search(line)
            if match:
                return
        raise main.SVNUnmatchedError

    # Else not expecting error:

    # Remove the final output line, and verify that the commit succeeded.
    lastline = ""
    if len(output):
        lastline = string.strip(output.pop())

        cm = re.compile("(Committed|Imported) revision [0-9]+.")
        match = cm.search(lastline)
        if not match:
            print "ERROR:  commit did not succeed."
            print "The final line from 'svn ci' was:"
            print lastline
            raise main.SVNCommitFailure

    # The new 'final' line in the output is either a regular line that
    # mentions {Adding, Deleting, Sending, ...}, or it could be a line
    # that says "Transmitting file data ...".  If the latter case, we
    # want to remove the line from the output; it should be ignored when
    # building a tree.
    if len(output):
        lastline = output.pop()

        tm = re.compile("Transmitting file data.+")
        match = tm.search(lastline)
        if not match:
            # whoops, it was important output, put it back.
            output.append(lastline)

    # Convert the output into a tree.
    mytree = tree.build_tree_from_commit(output)

    # Verify actual output against expected output.
    try:
        tree.compare_trees(mytree, output_tree)
    except tree.SVNTreeError:
        display_trees("Output of commit is unexpected.", "OUTPUT TREE",
                      output_tree, mytree)
        raise

    # Verify via 'status' command too, if possible.
    if status_output_tree:
        run_and_verify_status(wc_dir_name, status_output_tree)
Example #16
0
def run_and_verify_merge2(dir,
                          rev1,
                          rev2,
                          url1,
                          url2,
                          output_tree,
                          disk_tree,
                          status_tree,
                          skip_tree,
                          error_re_string=None,
                          singleton_handler_a=None,
                          a_baton=None,
                          singleton_handler_b=None,
                          b_baton=None,
                          check_props=0,
                          dry_run=1,
                          *args):
    """Run 'svn merge URL1@REV1 URL2@REV2 DIR' if URL2 is not None
  (for a three-way merge between URLs and WC).

  If URL2 is None, run 'svn merge -rREV1:REV2 URL1 DIR'.

  If ERROR_RE_STRING, the merge must exit with error, and the error
  message must match regular expression ERROR_RE_STRING.

  Else if ERROR_RE_STRING is None, then:

  The subcommand output will be verified against OUTPUT_TREE, and the
  working copy itself will be verified against DISK_TREE.  If optional
  STATUS_TREE is given, then 'svn status' output will be compared.
  The 'skipped' merge output will be compared to SKIP_TREE.
  SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will be passed to
  tree.compare_trees - see that function's doc string for more
  details.

  If CHECK_PROPS is set, then disk comparison will examine props.

  If DRY_RUN is set then a --dry-run merge will be carried out first and
  the output compared with that of the full merge.

  Returns if successful, raises on failure."""

    if isinstance(output_tree, wc.State):
        output_tree = output_tree.old_tree()
    if isinstance(disk_tree, wc.State):
        disk_tree = disk_tree.old_tree()
    if isinstance(status_tree, wc.State):
        status_tree = status_tree.old_tree()
    if isinstance(skip_tree, wc.State):
        skip_tree = skip_tree.old_tree()

    if url2:
        merge_command = ("merge", url1 + "@" + str(rev1),
                         url2 + "@" + str(rev2), dir)
    else:
        merge_command = ("merge", "-r", str(rev1) + ":" + str(rev2), url1, dir)

    if dry_run:
        pre_disk = tree.build_tree_from_wc(dir)
        dry_run_command = merge_command + ('--dry-run', )
        dry_run_command = dry_run_command + args
        out_dry, err_dry = main.run_svn(error_re_string, *dry_run_command)
        post_disk = tree.build_tree_from_wc(dir)
        try:
            tree.compare_trees(post_disk, pre_disk)
        except tree.SVNTreeError:
            print "============================================================="
            print "Dry-run merge altered working copy"
            print "============================================================="
            raise

    # Update and make a tree of the output.
    merge_command = merge_command + args
    out, err = main.run_svn(error_re_string, *merge_command)

    if (error_re_string):
        rm = re.compile(error_re_string)
        for line in err:
            match = rm.search(line)
            if match:
                return
        raise main.SVNUnmatchedError
    elif err:
        ### we should raise a less generic error here. which?
        raise Failure(err)

    if dry_run and out != out_dry:
        print "============================================================="
        print "Merge outputs differ"
        print "The dry-run merge output:"
        map(sys.stdout.write, out_dry)
        print "The full merge output:"
        map(sys.stdout.write, out)
        print "============================================================="
        raise main.SVNUnmatchedError

    def missing_skip(a, b):
        print "============================================================="
        print "Merge failed to skip: " + a.path
        print "============================================================="
        raise Failure

    def extra_skip(a, b):
        print "============================================================="
        print "Merge unexpectedly skipped: " + a.path
        print "============================================================="
        raise Failure

    myskiptree = tree.build_tree_from_skipped(out)
    tree.compare_trees(myskiptree, skip_tree, extra_skip, None, missing_skip,
                       None)

    mytree = tree.build_tree_from_checkout(out)
    verify_update(mytree, dir, output_tree, disk_tree, status_tree,
                  singleton_handler_a, a_baton, singleton_handler_b, b_baton,
                  check_props)
Example #17
0
def guarantee_greek_repository(path):
  """Guarantee that a local svn repository exists at PATH, containing
  nothing but the greek-tree at revision 1."""

  if path == main.pristine_dir:
    print "ERROR:  attempt to overwrite the pristine repos!  Aborting."
    sys.exit(1)

  # If there's no pristine repos, create one.
  if not os.path.exists(main.pristine_dir):
    main.create_repos(main.pristine_dir)
    
    # dump the greek tree to disk.
    main.greek_state.write_to_disk(main.greek_dump_dir)

    # build a URL for doing an import.
    url = main.test_area_url + '/' + main.pristine_dir
    if main.windows == 1:
      url = string.replace(url, '\\', '/')

    # import the greek tree, using l:foo/p:bar
    ### todo: svn should not be prompting for auth info when using
    ### repositories with no auth/auth requirements
    output, errput = main.run_svn(None, 'import',
                                  '--username', main.wc_author,
                                  '--password', main.wc_passwd,
                                  '-m', 'Log message for revision 1.',
                                  main.greek_dump_dir, url)

    # check for any errors from the import
    if len(errput):
      display_lines("Errors during initial 'svn import':",
                    'STDERR', None, errput)
      sys.exit(1)

    # verify the printed output of 'svn import'.
    lastline = string.strip(output.pop())
    cm = re.compile ("(Committed|Imported) revision [0-9]+.")
    match = cm.search (lastline)
    if not match:
      print "ERROR:  import did not succeed, while creating greek repos."
      print "The final line from 'svn import' was:"
      print lastline
      sys.exit(1)
    output_tree = tree.build_tree_from_commit(output)

    ### due to path normalization in the .old_tree() method, we cannot
    ### prepend the necessary '.' directory. thus, let's construct an old
    ### tree manually from the greek_state.
    output_list = []
    for greek_path in main.greek_state.desc.keys():
      output_list.append([ os.path.join(main.greek_dump_dir, greek_path),
                           None, {}, {'verb' : 'Adding'}])
    expected_output_tree = tree.build_generic_tree(output_list)

    try:
      tree.compare_trees(output_tree, expected_output_tree)
    except tree.SVNTreeUnequal:
      display_trees("ERROR:  output of import command is unexpected.",
                    'OUTPUT TREE', expected_output_tree, output_tree)
      sys.exit(1)

  # Now that the pristine repos exists, copy it to PATH.
  main.safe_rmtree(path)
  if main.copy_repos(main.pristine_dir, path, 1):
    print "ERROR:  copying repository failed."
    sys.exit(1)

  # make the repos world-writeable, for mod_dav_svn's sake.
  main.chmod_tree(path, 0666, 0666)