blob: df62466fcb522e1dc8499c7804d8a6e2b46a887b [file] [log] [blame]
# Copyright 2021 The Pigweed 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
#
# https://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.
"""Utilities for testing pw_rpc."""
import argparse
import subprocess
import sys
import tempfile
import time
from typing import Optional, Sequence
TEMP_DIR_MARKER = '(pw_rpc:CREATE_TEMP_DIR)'
def parse_test_server_args(
parser: argparse.ArgumentParser = None) -> argparse.Namespace:
"""Parses arguments for running a Python-based integration test."""
if parser is None:
parser = argparse.ArgumentParser(
description=sys.modules['__main__'].__doc__)
parser.add_argument('--test-server-command',
nargs='+',
required=True,
help='Command that starts the test server.')
parser.add_argument(
'--port',
type=int,
required=True,
help=('The port to use to connect to the test server. This value is '
'passed to the test server as the last argument.'))
parser.add_argument('unittest_args',
nargs=argparse.REMAINDER,
help='Arguments after "--" are passed to unittest.')
args = parser.parse_args()
# Append the port number to the test server command.
args.test_server_command.append(str(args.port))
# Make the script name argv[0] and drop the "--".
args.unittest_args = sys.argv[:1] + args.unittest_args[1:]
return args
def _parse_subprocess_integration_test_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description='Executes a test between two subprocesses')
parser.add_argument('--client', required=True, help='Client binary to run')
parser.add_argument('--server', required=True, help='Server binary to run')
parser.add_argument(
'common_args',
metavar='-- ...',
nargs=argparse.REMAINDER,
help=('Arguments to pass to both the server and client; '
f'pass {TEMP_DIR_MARKER} to generate a temporary directory'))
args = parser.parse_args()
if not args.common_args or args.common_args[0] != '--':
parser.error('The common arguments must start with "--"')
args.common_args.pop(0)
return args
def execute_integration_test(server: str,
client: str,
common_args: Sequence[str],
setup_time_s: float = 0.2) -> int:
temp_dir: Optional[tempfile.TemporaryDirectory] = None
if TEMP_DIR_MARKER in common_args:
temp_dir = tempfile.TemporaryDirectory(prefix='pw_rpc_test_')
common_args = [
temp_dir.name if a == TEMP_DIR_MARKER else a for a in common_args
]
try:
server_process = subprocess.Popen([server, *common_args])
# TODO(b/234879791): Replace this delay with some sort of IPC.
time.sleep(setup_time_s)
result = subprocess.run([client, *common_args]).returncode
server_process.terminate()
server_process.communicate()
finally:
if temp_dir:
temp_dir.cleanup()
return result
if __name__ == '__main__':
sys.exit(
execute_integration_test(
**vars(_parse_subprocess_integration_test_args())))