On Fri, Sep 24, 2010 at 11:16, Julian Foad <julian.f...@wandisco.com> wrote: >... > I think we should produce a test framework that can give us a WC > containing all the different possible WC states. Then we can write > tests against this framework, some tests that test specific state, and > other tests that apply the same operations to all the states and check > that it works in all the states that it should.
This requires a manual process of thinking of all states and all permutations. I don't trust it. If we could somehow capture working copies from during normal test runs, *then* I think we'd have "everything". We can easily get the terminal state for each test, which is a great first step. It would be great if we could also get the intermediate steps. Haven't thought much about it, but my thoughts were somewhere along that line. > I have been thinking this for a while. As yet I've just got a > rudimentary constructor for a WC containing (nearly) all *base* states. > Not changes, yet. Here it is: Not sure if it solves everything, but it is a good start. Review below: >... >> +++ subversion/tests/cmdline/basic_tests.py (working copy) >> @@ -2551,6 +2551,191 @@ def delete_and_add_same_file(sbox): >> None, >> wc_dir) >> >> + >> +#---------------------------------------------------------------------- >> + >> +# Functions for testing a WC that contains all possible WC states. >> + >> +def add_to_version_control(state_desc, wc_dir): pass sbox rather than wc_dir >> + """Create each item in STATE_DESC as a new versioned node in the existing >> + working copy WC_DIR. >> + STATE_DESC is a dictionary of { path string : StateItem object }.""" >> + >> + # First, the directories. Be sure to create parents before their >> children. >> + dir_fullpaths = [] >> + for path, state in sorted(state_desc.items()): >> + if state.contents is None: # a directory >> + fullpath = os.path.join(wc_dir, path) >> + dir_fullpaths += [fullpath] >> + svntest.actions.run_and_verify_svn(None, None, [], >> + 'mkdir', '--parents', >> *tuple(dir_fullpaths)) sbox.simple_mkdir(*dir_fullpaths) I know that 2.5 does not require conversion to a tuple. 2.4 may, but I don't have that handy. You shouldn't need --parents if you create parents before children (per the comment). >> + # Now all the files. >> + file_fullpaths = [] >> + for path, state in state_desc.items(): >> + if state.contents is not None: # a file >> + fullpath = os.path.join(wc_dir, path) >> + file_fullpaths += [fullpath] >> + open(fullpath, 'wb').write(state.contents) >> + svntest.actions.run_and_verify_svn(None, None, [], >> + 'add', *tuple(file_fullpaths)) sbox.simple_add(*file_fullpaths) >> + >> + # Now set each node's properties. Create a dict {(pname,pval)=>[paths]}, >> + # and run one propset per key, for speed. >> + props_map = {} >> + for path, state in state_desc.items(): >> + fullpath = os.path.join(wc_dir, path) >> + for pname, pval in state.props.items(): >> + props_map[(pname, pval)] = props_map.get((pname, pval), []) + >> [fullpath] >> + for (pname, pval), paths in props_map.items(): >> + svntest.actions.run_and_verify_svn(None, None, [], >> + 'propset', pname, pval, >> *tuple(paths)) sbox.simple_propset(pname, pval, *paths) >> + >> +def get_complex_wc_repository_state(): >> + """Return a repository state suitable for use as a base for a complex WC. Not sure why you have a separate function to build these lists. Just inline this into the single caller. >... >> + >> +def make_complex_wc_base_state(sbox): >> + """Create a repository revision to use as a base for a complex WC. >> + SBOX.repo_url must point to an existing repository. >> + ### Currently, SBOX.wc_dir must point to a WC at rev 1. >> + Return the dictionary of StateItems objects. >> + """ >> + >> + wc_dir = sbox.wc_dir >> + >> + items, authz_rules = get_complex_wc_repository_state() >> + >> + # Make the WC empty, just for ease of checking the expected result. >> + svntest.actions.run_and_verify_update(wc_dir, None, None, None, >> + None, None, None, None, None, False, >> + '-r0', os.path.join(wc_dir, 'A'), >> + os.path.join(wc_dir, 'iota')) >> + >> + # Create the desired state in the WC ... >> + add_to_version_control(items, wc_dir) >> + >> + # ... and commit it to the repository. >> + expected_output = svntest.wc.State(wc_dir, {}) >> + for path in items.keys(): >> + expected_output.add({ path: Item(verb='Adding') }) >> + expected_status = svntest.wc.State(wc_dir, { >> + '': Item(status=' ', wc_rev='1') }) >> + for path in items.keys(): >> + expected_status.add({ path: Item(status=' ', wc_rev='2') }) >> + svntest.actions.run_and_verify_commit(wc_dir, >> + expected_output, expected_status, >> + None, wc_dir) I doubt you need to check commit status here. That's what commit_tests.py is for. I'd suggest omitting the expected_* and just doing: sbox.simple_commit() >... Cheers, -g