Merge "Regression test for sequence editor causing hang"

This commit is contained in:
Jenkins 2016-11-28 11:23:44 +00:00 committed by Gerrit Code Review
commit 34c72e9e39
3 changed files with 91 additions and 7 deletions

View File

@ -0,0 +1,54 @@
#
# 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 sequence editor is ignored for non-interactive use.
With a simple repository, test that git-upstream ignores sequence
editor by setting sequence editor to a command that will timeout
(and thereby cause a test failure).
Note in this case we need to use the interactive mode tests to
ensure we use a subprocess call with timeouts to confirm that
the process does not hang.
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: [import, upstream/master]
pre-script: |
import os
from git.repo import Repo
repo = Repo(os.path.curdir)
repo.git.config("sequence.editor", "sleep 10; echo")

View File

@ -17,8 +17,10 @@
import os
import subprocess
import threading
import mock
import psutil
from testscenarios import TestWithScenarios
from testtools.content import text_content
from testtools.matchers import Contains
@ -31,7 +33,7 @@ from git_upstream.tests.base import BaseTestCase
from git_upstream.tests.base import get_scenarios
@mock.patch.dict('os.environ', {'GIT_SEQUENCE_EDITOR': 'cat'})
@mock.patch.dict('os.environ', {'GIT_EDITOR': 'cat'})
class TestImportInteractiveCommand(TestWithScenarios, BaseTestCase):
scenarios = get_scenarios(os.path.join(os.path.dirname(__file__),
@ -54,16 +56,43 @@ class TestImportInteractiveCommand(TestWithScenarios, BaseTestCase):
target_branch = self.branches['head'][0]
cmdline = self.parser.get_default('script_cmdline') + self.parser_args
try:
self.output = subprocess.check_output(cmdline,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as cpe:
# ensure interactive mode cannot hang tests
def kill(proc_pid):
process = psutil.Process(proc_pid)
for proc in process.children(recursive=True):
try:
proc.kill()
except OSError:
continue
try:
process.kill()
except OSError:
pass
def get_output(proc):
self.output = proc.communicate()[0]
proc = subprocess.Popen(cmdline,
stdin=open(os.devnull, "r"),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, close_fds=True,
cwd=self.testrepo.path)
proc_thread = threading.Thread(target=get_output, args=[proc])
proc_thread.start()
proc_thread.join(getattr(self, 'timeout', 5))
if proc_thread.is_alive():
kill(proc.pid)
proc_thread.join()
self.addDetail('subprocess-output',
text_content(cpe.output.decode('utf-8')))
raise
text_content(self.output.decode('utf-8')))
raise Exception('Process #%d killed after timeout' % proc.pid)
self.addDetail('subprocess-output',
text_content(self.output.decode('utf-8')))
self.assertThat(proc.returncode, Equals(0))
expected = getattr(self, 'expect_rebased', [])
if expected:
changes = list(Commit.iter_items(

View File

@ -11,3 +11,4 @@ testrepository>=0.0.17
testscenarios>=0.4
testtools>=0.9.32
PyYAML>=3.1.0
psutil>=1.1.1,<2.0.0 # BSD