Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / targets / stm32f429i-disc1 / py / stm32f429i_disc1_utils / unit_test_server.py
1 #!/usr/bin/env python3
2 # Copyright 2019 The Pigweed Authors
3 #
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
6 # the License at
7 #
8 #     https://www.apache.org/licenses/LICENSE-2.0
9 #
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
14 # the License.
15 """Launch a pw_test_server server to use for multi-device testing."""
16
17 import argparse
18 import logging
19 import sys
20 import tempfile
21 from typing import IO, List, Optional
22
23 import pw_cli.process
24 import pw_cli.log
25
26 from stm32f429i_disc1_utils import stm32f429i_detector
27
28 _LOG = logging.getLogger('unit_test_server')
29
30 _TEST_RUNNER_COMMAND = 'stm32f429i_disc1_unit_test_runner'
31
32 _TEST_SERVER_COMMAND = 'pw_target_runner_server'
33
34
35 def parse_args():
36     """Parses command-line arguments."""
37
38     parser = argparse.ArgumentParser(description=__doc__)
39     parser.add_argument('--server-port',
40                         type=int,
41                         default=8080,
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',
47                         '-v',
48                         dest='verbose',
49                         action="store_true",
50                         help='Output additional logs as the script runs')
51
52     return parser.parse_args()
53
54
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
58     # one set up.
59     for i, arg in enumerate(arguments):
60         arguments[i] = f'  args: "{arg}"'
61     runner = ['runner {', f'  command:"{command}"']
62     runner.extend(arguments)
63     runner.append('}\n')
64     return '\n'.join(runner)
65
66
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()
70     if not boards:
71         _LOG.critical('No attached boards detected')
72         sys.exit(1)
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))
76     for board in boards:
77         test_runner_args = [
78             '--stlink-serial', board.serial_number, '--port', board.dev_name
79         ]
80         config_file.write(
81             generate_runner(_TEST_RUNNER_COMMAND,
82                             test_runner_args).encode('utf-8'))
83     config_file.flush()
84     return config_file
85
86
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()
93
94     cmd = [_TEST_SERVER_COMMAND, '-config', server_config.name]
95
96     if server_port is not None:
97         cmd.extend(['-port', str(server_port)])
98
99     return pw_cli.process.run(*cmd, log_output=True).returncode
100
101
102 def main():
103     """Launch a device test server with the provided arguments."""
104     args = parse_args()
105
106     # Try to use pw_cli logs, else default to something reasonable.
107     pw_cli.log.install()
108     if args.verbose:
109         _LOG.setLevel(logging.DEBUG)
110
111     exit_code = launch_server(args.server_config, args.server_port)
112     sys.exit(exit_code)
113
114
115 if __name__ == '__main__':
116     main()