[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: CVS update: subversion/subversion/tests/clients/cmdline svn_tree.py svn_wc.py README example_tests1.py svn_output.py svn_test_main.py xml_tests.py

From: Ben Collins-Sussman <sussman_at_collab.net>
Date: 2001-04-26 15:51:45 CEST

Sam TH <sam@uchicago.edu> writes:
 
> How are you planning on handling verification for updates? Since it's
> only going to be a subset of the on-disk tree, we can't just compare
> it against the working copy directly. Comparing it against a set of
> expected results is easy, but that's not enough. Here's my current
> thought - [...]
>
> [...]
>
> At various places, you're constructing trees with entirely different
> property sets, which we are going to want to compare later. For
> example, you can't get the 'verb' from a working copy. Nor can you
> get the text from an import command. How do you plan to do these
> comparisons?

Sam, you're mixing apples and oranges. We have one set of tools for
verifying subcommand output, and another set of tools for verifying
disk contents. I have no intention to mix them. Yes, a single test
might use them both, but not actually compare their trees.

Here's an example:

  1. Checkout a working copy, capture subcommand output into tree1

  2. Compare tree1 against a generated 'expected' tree (this expected
      tree is created by running build_generic_tree() on a specific
      list of lists.)

  3. Create tree2 by scanning the working copy.

  4. Compare tree2 against a different generated 'expected' tree.

Here's a more specific example, for an update test. If we only expect
the update to print:

  _U /foo/bar
  U /foo/baz
  A bop

Then the expected tree we compare against is the return value of this:

  expected_tree = svn_tree.build_generic_tree
                    ([ ['/foo/bar', None, {'status' : '_U'}],
                       ['/foo/baz', None, {'status' : 'U '}],
                       ['bop', None, {'status' : 'A '}] ]

So yes, here's a case where we'll be comparing two stubby little trees
-- but that's ok. Your tree comparison function is general enough.
Not every tree we make has to represent a working copy. :)

Of course, the *next* part of the test would be to examine disk
contents after the update using full-size trees.

Am I making sense?

>
>
> > + if svn_tree.compare_trees(exp_tree, result_tree):
> > + return 0
> > + else:
> > + return 1
>
> Since you changed the return values, these are of course broken. Not
> that this file current runs anyway. Fixes later.

Heh, thanks. Will fix.

> > ###########################################################################
> > # EXPORTED ROUTINES
> >
> >
> > # General utility: change one path into a linked list of nodes.
> > #
> > # (Take the output and .add_child() it to a root node.)
> >
> > def create_from_path(path, contents=None, props={}):
>
> I don't think this should be an exported routine. It would be nice to
> get svn_output to use build_tree_from_paths, if possible. This
> function is really an implementation detail. (As is the neat merging
> features of .add_child, for that matter.)

I want to keep all the subcommand-tree-building routines in
svn_output.py. The problem is that build_tree_from_paths() currently
isn't general enough... if you want to hide create_from_path(), then
build_tree_from_paths() would need to take contents and props for each
node. And then the function would necessarily end up looking exactly
like build_generic_tree()!

So what's the best thing to do? Make every function in svn_output.py
parse subcommand output into a list-of-lists, and then use
build_generic_tree() to parse the list-of-lists into a generic tree?
It seems a little obtuse... do you think it's worth it in exchange for
keeping create_from_path() private?

>
> > def dump_tree(n,indent=""):
> > "Print out a nice representation of the tree's structure."
>
> I think this should at least print some property info, if nothing
> else. And whether the node is a directory or not.

Go for it. Honestly, I don't think this function will ever be used by
our tests. It may be used to test our tree-building ability -- but
not to test subversion. (Though the output looks great! Please make
sure Prof. Beazley doesn't mind us using it.)

>
> > # helper for wc_to_tree() -- callback for os.walk()
> > def visitfunc(baton, dirpath, entrynames):
> > "Callback for os.walk(). Builds a tree of SVNTreeNodes."
>
> Why did you decide to use os.path.walk() instead of the tree walker I
> wrote? I found the one with walk() harder to understand (although
> that may have to do with having written the other one) and the baton
> stuff seems ugly (although we wouldn't want to be the only part of
> subversion without batons).

Ummmmmmm.... I'm quite embarrassed. I didn't see it!

Oh crud. I just realized that the svn_tree.py file that I was hacking
was in fact not the 'latest' version you sent. It didn't contain your
build_tree_from_wc(). Ugh, talk about reinventing the wheel.

Looking at your handle_dir() right now. It looks good. Do you have
strong opinion about switching to it? I think they're both about the
same. Don't really care.

Instead, it's your build_tree_from_entries() function that I just
discovered and am *really* interested in. Let's start a thread on
that... I want to understand exactly what it does, and how it can help
us.

>
> >
> > def wc_to_tree(wc_path, load_props=0):
>
> I think this ought to be called build_tree_from_wc, for consistency.

Good idea.

>
> > svn_tree.dump_tree(wc_to_tree('wc-t1'))
>
> It's a good idea to hide this behind
>
> if __name__ == '__main__':
>
> so that it doesn't get executed on import.

Oh, it will be deleted. It's just a temporary test line.
Received on Sat Oct 21 14:36:29 2006

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.