blob: 6e6d9de0fb7d78d83474108a71028d0477689e7d [file]
# Copyright 2016 gRPC authors.
#
# 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 clean exit of server/client on Python Interpreter exit/sigint.
The tests in this module spawn a subprocess for each test case, the
test is considered successful if it doesn't hang/timeout.
"""
import atexit
import os
import signal
import six
import subprocess
import sys
import threading
import time
import unittest
from tests.unit import _exit_scenarios
SCENARIO_FILE = os.path.abspath(
os.path.join(
os.path.dirname(os.path.realpath(__file__)), '_exit_scenarios.py'))
INTERPRETER = sys.executable
BASE_COMMAND = [INTERPRETER, SCENARIO_FILE]
BASE_SIGTERM_COMMAND = BASE_COMMAND + ['--wait_for_interrupt']
INIT_TIME = 1.0
processes = []
process_lock = threading.Lock()
# Make sure we attempt to clean up any
# processes we may have left running
def cleanup_processes():
with process_lock:
for process in processes:
try:
process.kill()
except Exception:
pass
atexit.register(cleanup_processes)
def interrupt_and_wait(process):
with process_lock:
processes.append(process)
time.sleep(INIT_TIME)
os.kill(process.pid, signal.SIGINT)
process.wait()
def wait(process):
with process_lock:
processes.append(process)
process.wait()
@unittest.skip('https://github.com/grpc/grpc/issues/7311')
class ExitTest(unittest.TestCase):
def test_unstarted_server(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.UNSTARTED_SERVER],
stdout=sys.stdout,
stderr=sys.stderr)
wait(process)
def test_unstarted_server_terminate(self):
process = subprocess.Popen(
BASE_SIGTERM_COMMAND + [_exit_scenarios.UNSTARTED_SERVER],
stdout=sys.stdout)
interrupt_and_wait(process)
def test_running_server(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.RUNNING_SERVER],
stdout=sys.stdout,
stderr=sys.stderr)
wait(process)
def test_running_server_terminate(self):
process = subprocess.Popen(
BASE_SIGTERM_COMMAND + [_exit_scenarios.RUNNING_SERVER],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
def test_poll_connectivity_no_server(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY_NO_SERVER],
stdout=sys.stdout,
stderr=sys.stderr)
wait(process)
def test_poll_connectivity_no_server_terminate(self):
process = subprocess.Popen(
BASE_SIGTERM_COMMAND +
[_exit_scenarios.POLL_CONNECTIVITY_NO_SERVER],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
def test_poll_connectivity(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY],
stdout=sys.stdout,
stderr=sys.stderr)
wait(process)
def test_poll_connectivity_terminate(self):
process = subprocess.Popen(
BASE_SIGTERM_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
def test_in_flight_unary_unary_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
def test_in_flight_unary_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
def test_in_flight_stream_unary_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
def test_in_flight_stream_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
def test_in_flight_partial_unary_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND +
[_exit_scenarios.IN_FLIGHT_PARTIAL_UNARY_STREAM_CALL],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
def test_in_flight_partial_stream_unary_call(self):
process = subprocess.Popen(
BASE_COMMAND +
[_exit_scenarios.IN_FLIGHT_PARTIAL_STREAM_UNARY_CALL],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
def test_in_flight_partial_stream_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND +
[_exit_scenarios.IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL],
stdout=sys.stdout,
stderr=sys.stderr)
interrupt_and_wait(process)
if __name__ == '__main__':
unittest.main(verbosity=2)