2 # Copyright 2019 The Pigweed Authors
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 # use this file except in compliance with the License. You may obtain a copy of
8 # https://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations under
15 """Launch a pw_test_server server to use for multi-device testing."""
21 from typing import IO, List, Optional
26 from stm32f429i_disc1_utils import stm32f429i_detector
28 _LOG = logging.getLogger('unit_test_server')
30 _TEST_RUNNER_COMMAND = 'stm32f429i_disc1_unit_test_runner'
32 _TEST_SERVER_COMMAND = 'pw_target_runner_server'
36 """Parses command-line arguments."""
38 parser = argparse.ArgumentParser(description=__doc__)
39 parser.add_argument('--server-port',
42 help='Port to launch the pw_target_runner_server on')
43 parser.add_argument('--server-config',
44 type=argparse.FileType('r'),
45 help='Path to server config file')
46 parser.add_argument('--verbose',
50 help='Output additional logs as the script runs')
52 return parser.parse_args()
55 def generate_runner(command: str, arguments: List[str]) -> str:
56 """Generates a text-proto style pw_target_runner_server configuration."""
57 # TODO(amontanez): Use a real proto library to generate this when we have
59 for i, arg in enumerate(arguments):
60 arguments[i] = f' args: "{arg}"'
61 runner = ['runner {', f' command:"{command}"']
62 runner.extend(arguments)
64 return '\n'.join(runner)
67 def generate_server_config() -> IO[bytes]:
68 """Returns a temporary generated file for use as the server config."""
69 boards = stm32f429i_detector.detect_boards()
71 _LOG.critical('No attached boards detected')
73 config_file = tempfile.NamedTemporaryFile()
74 _LOG.debug('Generating test server config at %s', config_file.name)
75 _LOG.debug('Found %d attached devices', len(boards))
78 '--stlink-serial', board.serial_number, '--port', board.dev_name
81 generate_runner(_TEST_RUNNER_COMMAND,
82 test_runner_args).encode('utf-8'))
87 def launch_server(server_config: Optional[IO[bytes]],
88 server_port: Optional[int]) -> int:
89 """Launch a device test server with the provided arguments."""
90 if server_config is None:
91 # Auto-detect attached boards if no config is provided.
92 server_config = generate_server_config()
94 cmd = [_TEST_SERVER_COMMAND, '-config', server_config.name]
96 if server_port is not None:
97 cmd.extend(['-port', str(server_port)])
99 return pw_cli.process.run(*cmd, log_output=True).returncode
103 """Launch a device test server with the provided arguments."""
106 # Try to use pw_cli logs, else default to something reasonable.
109 _LOG.setLevel(logging.DEBUG)
111 exit_code = launch_server(args.server_config, args.server_port)
115 if __name__ == '__main__':