Merge lp:~vila/bzr/537956-parent-loop-incomplete into lp:bzr
| Status: | Merged |
|---|---|
| Approved by: | Martin Pool on 2010-03-24 |
| Approved revision: | 4639 |
| Merged at revision: | not available |
| Proposed branch: | lp:~vila/bzr/537956-parent-loop-incomplete |
| Merge into: | lp:bzr |
| Prerequisite: | lp:~vila/bzr/531967-unify-name-conflicts |
| Diff against target: |
469 lines (+180/-134) (has conflicts) 6 files modified
NEWS (+4/-0) bzrlib/atomicfile.py (+1/-1) bzrlib/conflicts.py (+2/-2) bzrlib/tests/test_conflicts.py (+171/-129) bzrlib/tests/test_transform.py (+1/-1) bzrlib/trace.py (+1/-1) Text conflict in NEWS |
| To merge this branch: | bzr merge lp:~vila/bzr/537956-parent-loop-incomplete |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Andrew Bennetts | Approve on 2010-03-25 | ||
| Martin Pool | 2010-03-12 | Approve on 2010-03-24 | |
|
Review via email:
|
|||
Description of the Change
As explained in bug #537956, ParentLoop objects doesn't carry enough information to
implement bzr resolve --take-other.
This patch fixes ParentLoop.format and add tests expected to fail.
This was built on top of https:/
| Vincent Ladeuil (vila) wrote : | # |
- 4639. By Vincent Ladeuil on 2010-03-12
-
The ParentLoop.format has been updated, fix fallouts.
| Vincent Ladeuil (vila) wrote : | # |
Waiting for the pre-requisite branch to land.
| Andrew Bennetts (spiv) wrote : | # |
(following on from the discussion in the pre-requisite branch, as this branch
has an updated version of that test code)
Vincent Ladeuil wrote:
[...]
> + def do_nothing(self):
> + return (None, None, [])
>
> def do_create_
> return ('file', 'file-id',
> [('add', ('file', 'file-id', 'file', 'trunk content\n'))])
>
> + def do_create_
> + return ('file', 'file-a-id',
> + [('add', ('file', 'file-a-id', 'file', 'file a content\n'))])
> +
> + def check_file_
> + self.assertFile
> +
> + def do_create_
> + return ('file', 'file-b-id',
> + [('add', ('file', 'file-b-id', 'file', 'file b content\n'))])
> +
> + def check_file_
> + self.assertFile
The repetition here is pretty ugly. I think what would be better is a more
data-driven description of the scenarios.
So, instead of specifying e.g.:
_actions_
Why not specify the build_snapshot recipe directly in the scenario, and have a
module-global set of canned recipe items to keep it short:
base_
(Note how more complex snapshots with multiple elements are still easy to
assemble, because you specify the whole snapshot list in the scenario.)
I think this would be easier and clearer than your zoo of do_* methods.
I think your check_* methods could be similarly transformed, e.g. to:
check=
Let's look at the bigger picture. I think that all conflict scenarios have this
shape:
-----
Define scenario template "S" that describes:
* how to create 'base' tree (and revision)
* how to create 'left' tree (and revision, parent rev 'base')
* how to create 'right' tree (and revision, parent rev 'base')
* the conflict(s) expected
* how to check that changes in 'base'->'left' have been taken
* how to check that changes in 'base'->'right' have been taken
From that template S, we generate two concrete scenarios from S, "Sl" and "Sr":
Sl: define this=left, other=right
Sr: define this=right, other=left
Then the test case verifies each scenario by:
* creating the 'base', 'this' and 'other' trees
* performing the merge of 'other' into 'this'
* verifying the expected conflicts were generated
* resolving with --take-this or --take-other, and running the corresponding
checks (for either 'base'->'this', or 'base'->'other')
-----
Have I missed anything?
If I got that right, please add that high-level description to this test module,
it will make the implementation details less of a concern for me because at
least the intent will be clear, which helps understand the implementation. But
I do think that structure could be expressed more clearly and succintly than
your current code.
(Also, if I'm right, that suggests to me that the tests for --take-this vs.
--take-other could just as easily be another scenario multiplication rather two
test methods, so leaving a TestCase with one test method but many scenarios!)
I don't want to sound too critic...
| Andrew Bennetts (spiv) wrote : | # |
One more thing:
I wrote:
>
> Let's look at the bigger picture. I think that all conflict scenarios have this
> shape:
I'll add that it took me *many* rereadings of the code to get this summary as
correct as it is. This is part of my fundamental concern with the existing
tests, it's been very hard for me to figure out exactly what the tests are
doing. I'd love for the code to be so simple that this is instantly obvious
(which may be an unattainable goal?) but I'll happily settle for explanatory
comments.
-Andrew.
| Martin Pool (mbp) wrote : | # |
On 25 March 2010 17:09, Andrew Bennetts <email address hidden> wrote:
> One more thing:
>
> I wrote:
>>
>> Let's look at the bigger picture. I think that all conflict scenarios have this
>> shape:
>
> I'll add that it took me *many* rereadings of the code to get this summary as
> correct as it is. This is part of my fundamental concern with the existing
> tests, it's been very hard for me to figure out exactly what the tests are
> doing. I'd love for the code to be so simple that this is instantly obvious
> (which may be an unattainable goal?) but I'll happily settle for explanatory
> comments.
I agree, I partially rubberstamped it because it was not obviously
wrong more than being obviously correct. I don't want to block
changes to this on getting all the existing tests to be very clear,
but we should move in that direction.
Thanks for reviewing it so thoroughly, Andrew.
--
Martin <http://
| Andrew Bennetts (spiv) wrote : | # |
Martin Pool wrote:
> I agree, I partially rubberstamped it because it was not obviously
> wrong more than being obviously correct. I don't want to block
> changes to this on getting all the existing tests to be very clear,
> but we should move in that direction.
Right, and with a large comment like the one I suggested I'd be very happy to
see this land, so I should have said:
review approve
But I'd really like to see this testing improvement polished soon after it lands
:)
| Vincent Ladeuil (vila) wrote : | # |
>>>>> Andrew Bennetts <email address hidden> writes:
> Review: Approve
> Martin Pool wrote:
>> I agree, I partially rubberstamped it because it was not obviously
>> wrong more than being obviously correct. I don't want to block
>> changes to this on getting all the existing tests to be very clear,
>> but we should move in that direction.
> Right, and with a large comment like the one I suggested I'd be very happy to
> see this land, so I should have said:
> review approve
Thanks.
> But I'd really like to see this testing improvement
> polished soon after it lands :)
Given that these two branches are sons of 'please put your
blackbox tests into the proper file' review comment from John and
that from there I decided to rewrite them as whitebox ones and
entered a mine field from where these two bugs (and one in
dirstate) showed up, rest assured that your remarks will be
promptly taken into account :)
Vincent
| Vincent Ladeuil (vila) wrote : | # |
>>>>> Andrew Bennetts <email address hidden> writes:
> (following on from the discussion in the pre-requisite branch, as this branch
> has an updated version of that test code)
> Vincent Ladeuil wrote:
> [...]
>> + def do_nothing(self):
>> + return (None, None, [])
>>
>> def do_create_
>> return ('file', 'file-id',
>> [('add', ('file', 'file-id', 'file', 'trunk content\n'))])
>>
>> + def do_create_
>> + return ('file', 'file-a-id',
>> + [('add', ('file', 'file-a-id', 'file', 'file a content\n'))])
>> +
>> + def check_file_
>> + self.assertFile
>> +
>> + def do_create_
>> + return ('file', 'file-b-id',
>> + [('add', ('file', 'file-b-id', 'file', 'file b content\n'))])
>> +
>> + def check_file_
>> + self.assertFile
> The repetition here is pretty ugly.
Yes.
> I think what would be better is a more data-driven
> description of the scenarios.
> So, instead of specifying e.g.:
> _actions_
> Why not specify the build_snapshot recipe directly in the scenario, and have a
> module-global set of canned recipe items to keep it short:
> base_snapshot=
I went away from centralizing all recipes in the base class in a
later iteration as it broke the locality and there was almost no
reuse cases (but again I'm referring to later work, so now that I
can push my loom again, take a look at
lp:~vila/bzr/conflict-manager). Revno 4639 in particular goes
into the direction you're asking for (but still miss some
points).
One point worth noting there too is that conflating the actions
modifying the working tree with the info needed to characterized
the conflict object needs to be class specific. But in light of
your remarks, I now think that I should just have separate dicts
for each side and let the parametrization assign these dicts to
the right attribute (instead of trying to flatten them which make
mirror_scenarios more complex than it could be).
> (Note how more complex snapshots with multiple elements are
> still easy to assemble, because you specify the whole
> snapshot list in the scenario.)
That's not the problem and as explained below I think it's even
YAGNI.
The problem is more around defining which information is needed
to check the conflict object (path, file-id) in which branch.
That's also why I refrained from trying to address multiple
conflicts tests at that point.
> I think this would be easier and clearer than your zoo of
> do_* methods.
Hehe, hello bialix's zoo :)
While working with these tests having the actions defined in the
right class made it easier to get them right (it's amazing how
hard it was to predict the correct conflict type when defining a
scenario, even with blackbox ones already available...). Well,
the actions themselves wasn't that hard, but what info was used
to create the conflict object ...
- 4640. By Vincent Ladeuil on 2010-03-25
-
Merge fixes from review from the pre-requisite branch

Despite my usage of the pre-requisite branch, the patch is a bit more verbose than I wished.
Apologies to reviewers.
The relevant stuff is in conflicts.py and class TestResolvePare ntLoop in test_conflicts.py.
The other parts aren't wrong in themselves either, and worth merging anyway.