Merge "Refactor import command tests to use scenarios"

This commit is contained in:
Jenkins
2016-04-14 12:47:15 +00:00
committed by Gerrit Code Review
12 changed files with 494 additions and 431 deletions

View File

@@ -100,11 +100,14 @@ def get_scenarios(scenarios_path):
scenarios = [] scenarios = []
for root, dirs, files in os.walk(scenarios_path): for root, dirs, files in os.walk(scenarios_path):
for f in files: for f in files:
if f.endswith('.yaml'): if os.path.splitext(f)[-1] in ['.yaml', '.yml']:
filename = os.path.join(root, f) filename = os.path.join(root, f)
with io.open(filename, 'r', encoding='utf-8') as yaml_file: with io.open(filename, 'r', encoding='utf-8') as yaml_file:
data = yaml.load(yaml_file) data = yaml.load(yaml_file)[0]
scenarios.append((filename, data[0])) test_name = os.path.splitext(
os.path.relpath(filename, scenarios_path))[0]
data['name'] = test_name
scenarios.append((filename, data))
return scenarios return scenarios
@@ -191,7 +194,7 @@ class BaseTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(BaseTestCase, self).setUp() super(BaseTestCase, self).setUp()
self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) self.logger = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG))
self.testrepo = self.useFixture(GitRepo()) self.testrepo = self.useFixture(GitRepo())
repo_path = self.testrepo.path repo_path = self.testrepo.path
self.useFixture(DiveDir(repo_path)) self.useFixture(DiveDir(repo_path))

View File

View File

@@ -0,0 +1,39 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed 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.
#
---
- desc: |
Test that default behaviour and options work
Repository layout being checked (assumed already replayed)
C---D local/master
/
A---B---E---F upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, [B]]
- [D, [C]]
- [E, [B]]
- [F, [E]]
branches:
head: [master, D]
upstream: [upstream/master, F]
parser_args: [-q, import, upstream/master]

View File

@@ -0,0 +1,46 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed 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.
#
---
- desc: |
Test that default behaviour and options work
Repository layout being checked (assumed already replayed)
C---D packaging/master
\
E---F local/master
/
A---B---G---H upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, []]
- [D, [C]]
- [E, [B, D]]
- [F, [E]]
- [G, [B]]
- [H, [G]]
branches:
head: [master, F]
upstream: [upstream/master, H]
packaging: [packaging/master, D]
parser_args: [-q, import, upstream/master, packaging/master]

View File

@@ -0,0 +1,47 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed 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.
#
---
- desc: |
Test that forgetting an additional branch that was previously
included results in a warning to the user.
Repository layout being checked (assumed already replayed)
C---D packaging/master
\
E---F local/master
/
A---B---G---H upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, []]
- [D, [C]]
- [E, [B, D]]
- [F, [E]]
- [G, [B]]
- [H, [G]]
branches:
head: [master, F]
upstream: [upstream/master, H]
packaging: [packaging/master, D]
parser_args: [import, upstream/master]

View File

@@ -0,0 +1,64 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed 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.
#
---
- desc: |
Test the --finish option to the import command
Given manual intervention to resolve conflicts and complete
the import, check that we can finish the import by manually
requesting the merge to be performed by this tool.
Repository layout being checked (assumed already replayed)
C---D local/master
/
/ C1---D1 import/F
/ /
A---B---E---F upstream/master
Test that result is as follows
C---D------- G local/master
/ /
/ C1---D1 import/F
/ /
A---B---E---F upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, [B]]
- [D, [C]]
- [E, [B]]
- [F, [E]]
- [C1, [F]]
- [D1, [C1]]
branches:
head: [master, D]
upstream: [custom/master, F]
import: [import/F, D1]
parser_args:
- -q
- import
- --finish
- --import-branch=import/F
- --into=master

View File

@@ -0,0 +1,62 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed 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.
#
---
- desc: |
Test that the import sub-command finds additional changes when
not given a search-ref to look under.
Repository layout being checked (assumed already replayed)
E---F local/master
/
C---D upstream/stable
/
A---B---G---H upstream/master
New branch to be tracked will be upstream/master, so the resulting
commits found will be C, D, E & F because of not telling the searcher
to look under all of the namespace.
Test that result is as follows
E---F-------------I local/master
/ /
C---D / upstream/stable
/ /
/ C1---D1---E1--F1
/ /
A---B---G---H upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, [B]]
- [D, [C]]
- [E, [D]]
- [F, [E]]
- [G, [B]]
- [H, [G]]
# use 'custom/*' to ensure defaults are overridden correctly
branches:
head: [master, F]
upstream: [custom/master, H]
stable: [custom/stable, D]
parser_args: [-q, import, --into=master, custom/master]

View File

@@ -0,0 +1,62 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed 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.
#
---
- desc: |
Test that the import sub-command can correctly switch branches when
importing from upstream when given a usable search-ref.
Repository layout being checked (assumed already replayed)
E---F local/master
/
C---D upstream/stable
/
A---B---G---H upstream/master
New branch to be tracked will be upstream/master, so the resulting
commits found should just be E & F.
Test that result is as follows
E---F---I local/master
/ /
C---D / upstream/stable
/ /
/ E1--F1
/ /
A---B---G---H upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, [B]]
- [D, [C]]
- [E, [D]]
- [F, [E]]
- [G, [B]]
- [H, [G]]
branches:
head: [master, F]
upstream: [upstream/master, H]
stable: [upstream/stable, D]
parser_args: [-q, import]
expect_rebased: [E, F]

View File

@@ -0,0 +1,67 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed 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.
#
---
- desc: |
Test that the import sub-command can correctly switch branches when
importing from upstream when given a usable search-ref.
Repository layout being checked (assumed already replayed)
E---F local/master
/
C---D upstream/stable
/
A---B---G---H upstream/master
New branch to be tracked will be upstream/master, so the resulting
commits found should just be E & F.
Test that result is as follows
E---F---I local/master
/ /
C---D / upstream/stable
/ /
/ E1--F1
/ /
A---B---G---H upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, [B]]
- [D, [C]]
- [E, [D]]
- [F, [E]]
- [G, [B]]
- [H, [G]]
# use 'custom/*' to ensure defaults are overridden correctly
branches:
head: [master, F]
upstream: [custom/master, H]
stable: [custom/stable, D]
parser_args:
- -q
- import
- --search-refs=custom/*
- --search-refs=custom-d/*
- --into=master
- custom/master

View File

@@ -0,0 +1,100 @@
# Copyright (c) 2012, 2013, 2014 Hewlett-Packard Development Company, L.P.
#
# Licensed 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.
"""Tests for the 'import' command"""
import inspect
import os
from testscenarios import TestWithScenarios
from testtools.content import text_content
from testtools.matchers import Contains
from testtools.matchers import Equals
from git_upstream.lib.pygitcompat import Commit
from git_upstream import main
from git_upstream.tests.base import BaseTestCase
from git_upstream.tests.base import get_scenarios
class TestImportCommand(TestWithScenarios, BaseTestCase):
commands, parser = main.build_parsers()
scenarios = get_scenarios(os.path.join(os.path.dirname(__file__),
"scenarios"))
def setUp(self):
# add description in case parent setup fails.
self.addDetail('description', text_content(self.desc))
# builds the tree to be tested
super(TestImportCommand, self).setUp()
def test_command(self):
upstream_branch = self.branches['upstream'][0]
target_branch = self.branches['head'][0]
self.git.tag(inspect.currentframe().f_code.co_name, upstream_branch)
args = self.parser.parse_args(self.parser_args)
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
expected = getattr(self, 'expect_rebased', [])
if expected:
changes = list(Commit.iter_items(
self.repo, '%s..%s^2' % (upstream_branch, target_branch)))
self.assertThat(
len(changes), Equals(len(expected)),
"should only have seen %s changes, got: %s" %
(len(expected),
", ".join(["%s:%s" % (commit.hexsha,
commit.message.splitlines()[0])
for commit in changes])))
# expected should be listed in order from oldest to newest, so
# reverse changes to match as it would be newest to oldest.
changes.reverse()
for commit, node in zip(changes, expected):
subject = commit.message.splitlines()[0]
node_subject = self._graph[node].message.splitlines()[0]
self.assertThat(subject, Equals(node_subject),
"subject '%s' of commit '%s' does not match "
"subject '%s' of node '%s'" % (
subject, commit.hexsha, node_subject,
node))
# allow additional test specific verification methods below
extra_test_func = getattr(self, '_verify_%s' % self.name, None)
if extra_test_func:
extra_test_func()
def _verify_basic_additional_missed(self):
"""Additional verification that test produces a warning"""
self.assertThat(self.logger.output,
Contains("Previous import merged additional"))
def _verify_import_finish(self):
"""Additional verification for the finished results"""
self.assertThat(self.repo.git.rev_parse('master^{tree}'),
Equals(self.repo.git.rev_parse('import/F^{tree}')),
"--finish option failed to merge correctly")
commit = self.git.rev_list('master', parents=True, max_count=1).split()
parents = commit[1:]
self.assertThat(parents, Equals([self._graph['D'].hexsha,
self._graph['D1'].hexsha]),
"import --finish merge does contain the correct "
"parents")

View File

@@ -1,427 +0,0 @@
# Copyright (c) 2012, 2013, 2014 Hewlett-Packard Development Company, L.P.
#
# Licensed 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.
"""Tests for the 'import' command"""
import inspect
from string import lower
import mock
from testtools.matchers import Equals
from git_upstream.lib.pygitcompat import Commit
from git_upstream import main
from git_upstream.tests.base import BaseTestCase
class SubstringMatcher(object):
def __init__(self, containing):
self.containing = lower(containing)
def __eq__(self, other):
return lower(other).find(self.containing) > -1
def __unicode__(self):
return 'a string containing "%s"' % self.containing
def __str__(self):
return unicode(self).encode('utf-8')
__repr__ = __unicode__
class TestImportCommand(BaseTestCase):
commands, parser = main.build_parsers()
def test_basic(self):
"""Test that default behaviour and options work
Repository layout being checked (assumed already replayed)
C---D local/master
/
A---B---E---F upstream/master
"""
tree = [
('A', []),
('B', ['A']),
('C', ['B']),
('D', ['C']),
('E', ['B']),
('F', ['E'])
]
branches = {
'head': ('master', 'D'),
'upstream': ('upstream/master', 'F')
}
self._build_git_tree(tree, branches.values())
self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master')
args = self.parser.parse_args(['-q', 'import', 'upstream/master'])
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
def test_basic_additional(self):
"""Test that default behaviour and options work
Repository layout being checked (assumed already replayed)
C---D packaging/master
\
E---F local/master
/
A---B---G---H upstream/master
"""
tree = [
('A', []),
('B', ['A']),
('C', []),
('D', ['C']),
('E', ['B', 'D']),
('F', ['E']),
('G', ['B']),
('H', ['G'])
]
branches = {
'head': ('master', 'F'),
'upstream': ('upstream/master', 'H'),
'packaging': ('packaging/master', 'D')
}
self._build_git_tree(tree, branches.values())
self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master')
args = self.parser.parse_args(['-q', 'import', 'upstream/master',
'packaging/master'])
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
def test_basic_additional_missed(self):
"""Test that forgetting an additional branch that was previously
included results in a warning to the user.
Repository layout being checked (assumed already replayed)
C---D packaging/master
\
E---F local/master
/
A---B---G---H upstream/master
"""
tree = [
('A', []),
('B', ['A']),
('C', []),
('D', ['C']),
('E', ['B', 'D']),
('F', ['E']),
('G', ['B']),
('H', ['G'])
]
branches = {
'head': ('master', 'F'),
'upstream': ('upstream/master', 'H'),
'packaging': ('packaging/master', 'D')
}
self._build_git_tree(tree, branches.values())
self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master')
args = self.parser.parse_args(['import', 'upstream/master'])
with mock.patch.object(args.cmd.log, 'warning') as mock_logger:
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
mock_logger.assert_called_with(
SubstringMatcher(
containing="Previous import merged additional"))
def test_import_switch_branches_search(self):
"""Test that the import sub-command can correctly switch branches when
importing from upstream when given a usable search-ref.
Repository layout being checked (assumed already replayed)
E---F local/master
/
C---D upstream/stable
/
A---B---G---H upstream/master
New branch to be tracked will be upstream/master, so the resulting
commits found should just be E & F.
Test that result is as follows
E---F---I local/master
/ /
C---D / upstream/stable
/ /
/ E1--F1
/ /
A---B---G---H upstream/master
"""
tree = [
('A', []),
('B', ['A']),
('C', ['B']),
('D', ['C']),
('E', ['D']),
('F', ['E']),
('G', ['B']),
('H', ['G'])
]
branches = {
'head': ('master', 'F'),
'upstream': ('upstream/master', 'H'),
'stable': ('upstream/stable', 'D')
}
self._build_git_tree(tree, branches.values())
self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master')
args = self.parser.parse_args(['-q', 'import'])
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
changes = list(Commit.iter_items(
self.repo, 'upstream/master..master^2'))
self.assertThat(len(changes), Equals(2),
"should only have seen two changes, got: %s" %
", ".join(["%s:%s" % (commit.hexsha,
commit.message.splitlines()[0])
for commit in changes]))
for commit, node in zip(changes, ['F', 'E']):
subject = commit.message.splitlines()[0]
node_subject = self._graph[node].message.splitlines()[0]
self.assertThat(subject, Equals(node_subject),
"subject '%s' of commit '%s' does not match "
"subject '%s' of node '%s'" % (
subject, commit.hexsha, node_subject, node))
def test_import_switch_branches_fails_without_search_ref(self):
"""Test that the import sub-command finds additional changes when
not given a search-ref to look under.
Repository layout being checked (assumed already replayed)
E---F local/master
/
C---D upstream/stable
/
A---B---G---H upstream/master
New branch to be tracked will be upstream/master, so the resulting
commits found will be C, D, E & F because of not telling the searcher
to look under all of the namespace.
Test that result is as follows
E---F-------------I local/master
/ /
C---D / upstream/stable
/ /
/ C1---D1---E1--F1
/ /
A---B---G---H upstream/master
"""
tree = [
('A', []),
('B', ['A']),
('C', ['B']),
('D', ['C']),
('E', ['D']),
('F', ['E']),
('G', ['B']),
('H', ['G'])
]
# use 'custom/*' to ensure defaults are overridden correctly
branches = {
'head': ('master', 'F'),
'upstream': ('custom/master', 'H'),
'stable': ('custom/stable', 'D')
}
self._build_git_tree(tree, branches.values())
self.git.tag(inspect.currentframe().f_code.co_name, 'custom/master')
args = self.parser.parse_args(['-q', 'import',
'--into=master', 'custom/master'])
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
changes = list(Commit.iter_items(
self.repo, 'custom/master..master^2'))
local_rebased = ['F', 'E', 'D', 'C']
self.assertThat(len(changes), Equals(len(local_rebased)),
"should only have seen two changes, got: %s" %
", ".join(["%s:%s" % (commit.hexsha,
commit.message.splitlines()[0])
for commit in changes]))
for commit, node in zip(changes, local_rebased):
subject = commit.message.splitlines()[0]
node_subject = self._graph[node].message.splitlines()[0]
self.assertThat(subject, Equals(node_subject),
"subject '%s' of commit '%s' does not match "
"subject '%s' of node '%s'" % (
subject, commit.hexsha, node_subject, node))
def test_import_switch_branches_search_ref_custom_namespace(self):
"""Test that the import sub-command can correctly switch branches when
importing from upstream when given a usable search-ref.
Repository layout being checked (assumed already replayed)
E---F local/master
/
C---D upstream/stable
/
A---B---G---H upstream/master
New branch to be tracked will be upstream/master, so the resulting
commits found should just be E & F.
Test that result is as follows
E---F---I local/master
/ /
C---D / upstream/stable
/ /
/ E1--F1
/ /
A---B---G---H upstream/master
"""
tree = [
('A', []),
('B', ['A']),
('C', ['B']),
('D', ['C']),
('E', ['D']),
('F', ['E']),
('G', ['B']),
('H', ['G'])
]
# use 'custom/*' to ensure defaults are overridden correctly
branches = {
'head': ('master', 'F'),
'upstream': ('custom/master', 'H'),
'stable': ('custom/stable', 'D')
}
self._build_git_tree(tree, branches.values())
self.git.tag(inspect.currentframe().f_code.co_name, 'custom/master')
args = self.parser.parse_args(['-q', 'import',
'--search-refs=custom/*',
'--search-refs=custom-d/*',
'--into=master', 'custom/master'])
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
changes = list(Commit.iter_items(
self.repo, 'custom/master..master^2'))
self.assertThat(len(changes), Equals(2),
"should only have seen two changes, got: %s" %
", ".join(["%s:%s" % (commit.hexsha,
commit.message.splitlines()[0])
for commit in changes]))
for commit, node in zip(changes, ['F', 'E']):
subject = commit.message.splitlines()[0]
node_subject = self._graph[node].message.splitlines()[0]
self.assertThat(subject, Equals(node_subject),
"subject '%s' of commit '%s' does not match "
"subject '%s' of node '%s'" % (
subject, commit.hexsha, node_subject, node))
def test_import_finish(self):
"""Test the --finish option to the import command
Given manual intervention to resolve conflicts and complete
the import, check that we can finish the import by manually
requesting the merge to be performed by this tool.
Repository layout being checked (assumed already replayed)
C---D local/master
/
/ C1---D1 import/F
/ /
A---B---E---F upstream/master
Test that result is as follows
C---D------- G local/master
/ /
/ C1---D1 import/F
/ /
A---B---E---F upstream/master
"""
tree = [
('A', []),
('B', ['A']),
('C', ['B']),
('D', ['C']),
('E', ['B']),
('F', ['E']),
('C1', ['F']),
('D1', ['C1'])
]
branches = {
'head': ('master', 'D'),
'upstream': ('custom/master', 'F'),
'import': ('import/F', 'D1')
}
self._build_git_tree(tree, branches.values())
self.git.tag(inspect.currentframe().f_code.co_name, 'custom/master')
args = self.parser.parse_args(['-q', 'import', '--finish',
'--import-branch=import/F',
'--into=master'])
self.assertThat(args.cmd.run(args), Equals(True),
"import command failed to complete successfully")
changes = list(Commit.iter_items(
self.repo, 'custom/master..master^2'))
self.assertThat(len(changes), Equals(2),
"should only have seen two changes, got: %s" %
", ".join(["%s:%s" % (commit.hexsha,
commit.message.splitlines()[0])
for commit in changes]))
self.assertThat(self.repo.git.rev_parse('master^{tree}'),
Equals(self.repo.git.rev_parse('import/F^{tree}')),
"--finish option failed to merge correctly")
commit = self.git.rev_list('master', parents=True, max_count=1).split()
parents = commit[1:]
self.assertThat(parents, Equals([self._graph['D'].hexsha,
self._graph['D1'].hexsha]),
"import --finish merge does contain the correct "
"parents")