Merge "Refactor import command tests to use scenarios"
This commit is contained in:
@@ -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))
|
||||||
|
|||||||
0
git_upstream/tests/commands/__init__.py
Normal file
0
git_upstream/tests/commands/__init__.py
Normal file
0
git_upstream/tests/commands/import/__init__.py
Normal file
0
git_upstream/tests/commands/import/__init__.py
Normal file
39
git_upstream/tests/commands/import/scenarios/basic.yaml
Normal file
39
git_upstream/tests/commands/import/scenarios/basic.yaml
Normal 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]
|
||||||
@@ -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]
|
||||||
@@ -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]
|
||||||
@@ -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
|
||||||
@@ -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]
|
||||||
@@ -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]
|
||||||
@@ -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
|
||||||
100
git_upstream/tests/commands/import/test_import.py
Normal file
100
git_upstream/tests/commands/import/test_import.py
Normal 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")
|
||||||
@@ -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")
|
|
||||||
Reference in New Issue
Block a user