blob: 76a550d45a17a694bfdb27c132d6d15e0e310490 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0
Stephen Warren10e50632016-01-15 11:15:24 -07002# Copyright (c) 2015 Stephen Warren
3# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
Stephen Warren10e50632016-01-15 11:15:24 -07004
5# Common logic to interact with U-Boot via the console. This class provides
6# the interface that tests use to execute U-Boot shell commands and wait for
7# their results. Sub-classes exist to perform board-type-specific setup
8# operations, such as spawning a sub-process for Sandbox, or attaching to the
9# serial console of real hardware.
10
11import multiplexed_log
12import os
13import pytest
14import re
15import sys
Stephen Warren97a54662016-01-22 12:30:09 -070016import u_boot_spawn
Stephen Warren10e50632016-01-15 11:15:24 -070017
18# Regexes for text we expect U-Boot to send to the console.
Heiko Schocherce251232018-12-05 11:29:54 +010019pattern_u_boot_spl_signon = re.compile('(U-Boot SPL \\d{4}\\.\\d{2}[^\r\n]*\\))')
Stephen Warren5af83c42016-02-05 18:04:43 -070020pattern_u_boot_main_signon = re.compile('(U-Boot \\d{4}\\.\\d{2}[^\r\n]*\\))')
Stephen Warren10e50632016-01-15 11:15:24 -070021pattern_stop_autoboot_prompt = re.compile('Hit any key to stop autoboot: ')
22pattern_unknown_command = re.compile('Unknown command \'.*\' - try \'help\'')
23pattern_error_notification = re.compile('## Error: ')
Stephen Warren3bd79d32016-01-27 23:57:50 -070024pattern_error_please_reset = re.compile('### ERROR ### Please RESET the board ###')
Stephen Warren10e50632016-01-15 11:15:24 -070025
Stephen Warren1115a972016-01-27 23:57:48 -070026PAT_ID = 0
27PAT_RE = 1
28
29bad_pattern_defs = (
30 ('spl_signon', pattern_u_boot_spl_signon),
31 ('main_signon', pattern_u_boot_main_signon),
32 ('stop_autoboot_prompt', pattern_stop_autoboot_prompt),
33 ('unknown_command', pattern_unknown_command),
34 ('error_notification', pattern_error_notification),
Stephen Warren3bd79d32016-01-27 23:57:50 -070035 ('error_please_reset', pattern_error_please_reset),
Stephen Warren1115a972016-01-27 23:57:48 -070036)
37
Stephen Warren10e50632016-01-15 11:15:24 -070038class ConsoleDisableCheck(object):
Stephen Warren75e731e2016-01-26 13:41:30 -070039 """Context manager (for Python's with statement) that temporarily disables
Stephen Warren10e50632016-01-15 11:15:24 -070040 the specified console output error check. This is useful when deliberately
41 executing a command that is known to trigger one of the error checks, in
42 order to test that the error condition is actually raised. This class is
43 used internally by ConsoleBase::disable_check(); it is not intended for
Stephen Warren75e731e2016-01-26 13:41:30 -070044 direct usage."""
Stephen Warren10e50632016-01-15 11:15:24 -070045
46 def __init__(self, console, check_type):
47 self.console = console
48 self.check_type = check_type
49
50 def __enter__(self):
51 self.console.disable_check_count[self.check_type] += 1
Stephen Warren1115a972016-01-27 23:57:48 -070052 self.console.eval_bad_patterns()
Stephen Warren10e50632016-01-15 11:15:24 -070053
54 def __exit__(self, extype, value, traceback):
55 self.console.disable_check_count[self.check_type] -= 1
Stephen Warren1115a972016-01-27 23:57:48 -070056 self.console.eval_bad_patterns()
Stephen Warren10e50632016-01-15 11:15:24 -070057
Love Kumarc35e66e2024-05-22 18:45:13 +053058class ConsoleEnableCheck(object):
59 """Context manager (for Python's with statement) that temporarily enables
60 the specified console output error check. This is useful when executing a
61 command that might raise an extra bad pattern, beyond the default bad
62 patterns, in order to validate that the extra bad pattern is actually
63 detected. This class is used internally by ConsoleBase::enable_check(); it
64 is not intended for direct usage."""
65
66 def __init__(self, console, check_type, check_pattern):
67 self.console = console
68 self.check_type = check_type
69 self.check_pattern = check_pattern
70
71 def __enter__(self):
72 global bad_pattern_defs
73 self.default_bad_patterns = bad_pattern_defs
74 bad_pattern_defs += ((self.check_type, self.check_pattern),)
75 self.console.disable_check_count = {pat[PAT_ID]: 0 for pat in bad_pattern_defs}
76 self.console.eval_bad_patterns()
77
78 def __exit__(self, extype, value, traceback):
79 global bad_pattern_defs
80 bad_pattern_defs = self.default_bad_patterns
81 self.console.disable_check_count = {pat[PAT_ID]: 0 for pat in bad_pattern_defs}
82 self.console.eval_bad_patterns()
83
Michal Simek6b463182016-05-19 07:57:41 +020084class ConsoleSetupTimeout(object):
85 """Context manager (for Python's with statement) that temporarily sets up
86 timeout for specific command. This is useful when execution time is greater
87 then default 30s."""
88
89 def __init__(self, console, timeout):
90 self.p = console.p
91 self.orig_timeout = self.p.timeout
92 self.p.timeout = timeout
93
94 def __enter__(self):
95 return self
96
97 def __exit__(self, extype, value, traceback):
98 self.p.timeout = self.orig_timeout
99
Stephen Warren10e50632016-01-15 11:15:24 -0700100class ConsoleBase(object):
Stephen Warren75e731e2016-01-26 13:41:30 -0700101 """The interface through which test functions interact with the U-Boot
Stephen Warren10e50632016-01-15 11:15:24 -0700102 console. This primarily involves executing shell commands, capturing their
103 results, and checking for common error conditions. Some common utilities
Stephen Warren75e731e2016-01-26 13:41:30 -0700104 are also provided too."""
Stephen Warren10e50632016-01-15 11:15:24 -0700105
106 def __init__(self, log, config, max_fifo_fill):
Stephen Warren75e731e2016-01-26 13:41:30 -0700107 """Initialize a U-Boot console connection.
Stephen Warren10e50632016-01-15 11:15:24 -0700108
109 Can only usefully be called by sub-classes.
110
111 Args:
112 log: A mulptiplex_log.Logfile object, to which the U-Boot output
113 will be logged.
114 config: A configuration data structure, as built by conftest.py.
115 max_fifo_fill: The maximum number of characters to send to U-Boot
116 command-line before waiting for U-Boot to echo the characters
117 back. For UART-based HW without HW flow control, this value
118 should be set less than the UART RX FIFO size to avoid
119 overflow, assuming that U-Boot can't keep up with full-rate
120 traffic at the baud rate.
121
122 Returns:
123 Nothing.
Stephen Warren75e731e2016-01-26 13:41:30 -0700124 """
Stephen Warren10e50632016-01-15 11:15:24 -0700125
126 self.log = log
127 self.config = config
128 self.max_fifo_fill = max_fifo_fill
129
130 self.logstream = self.log.get_stream('console', sys.stdout)
131
132 # Array slice removes leading/trailing quotes
133 self.prompt = self.config.buildconfig['config_sys_prompt'][1:-1]
Stephen Warren6d083402016-08-16 19:58:59 -0600134 self.prompt_compiled = re.compile('^' + re.escape(self.prompt), re.MULTILINE)
Stephen Warren10e50632016-01-15 11:15:24 -0700135 self.p = None
Stephen Warren1115a972016-01-27 23:57:48 -0700136 self.disable_check_count = {pat[PAT_ID]: 0 for pat in bad_pattern_defs}
137 self.eval_bad_patterns()
Stephen Warren10e50632016-01-15 11:15:24 -0700138
139 self.at_prompt = False
140 self.at_prompt_logevt = None
Stephen Warren10e50632016-01-15 11:15:24 -0700141
Simon Glassf7990762022-02-11 13:23:23 -0700142 def get_spawn(self):
143 # This is not called, ssubclass must define this.
144 # Return a value to avoid:
145 # u_boot_console_base.py:348:12: E1128: Assigning result of a function
146 # call, where the function returns None (assignment-from-none)
147 return u_boot_spawn.Spawn([])
148
149
Stephen Warren1115a972016-01-27 23:57:48 -0700150 def eval_bad_patterns(self):
151 self.bad_patterns = [pat[PAT_RE] for pat in bad_pattern_defs \
152 if self.disable_check_count[pat[PAT_ID]] == 0]
153 self.bad_pattern_ids = [pat[PAT_ID] for pat in bad_pattern_defs \
154 if self.disable_check_count[pat[PAT_ID]] == 0]
155
Stephen Warren10e50632016-01-15 11:15:24 -0700156 def close(self):
Stephen Warren75e731e2016-01-26 13:41:30 -0700157 """Terminate the connection to the U-Boot console.
Stephen Warren10e50632016-01-15 11:15:24 -0700158
159 This function is only useful once all interaction with U-Boot is
160 complete. Once this function is called, data cannot be sent to or
161 received from U-Boot.
162
163 Args:
164 None.
165
166 Returns:
167 Nothing.
Stephen Warren75e731e2016-01-26 13:41:30 -0700168 """
Stephen Warren10e50632016-01-15 11:15:24 -0700169
170 if self.p:
171 self.p.close()
172 self.logstream.close()
173
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900174 def wait_for_boot_prompt(self, loop_num = 1):
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900175 """Wait for the boot up until command prompt. This is for internal use only.
176 """
177 try:
178 bcfg = self.config.buildconfig
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900179 config_spl_serial = bcfg.get('config_spl_serial', 'n') == 'y'
180 env_spl_skipped = self.config.env.get('env__spl_skipped', False)
Tom Rinidec7ea02024-05-20 13:35:03 -0600181 env_spl_banner_times = self.config.env.get('env__spl_banner_times', 1)
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900182
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900183 while loop_num > 0:
184 loop_num -= 1
Tom Rinidec7ea02024-05-20 13:35:03 -0600185 while config_spl_serial and not env_spl_skipped and env_spl_banner_times > 0:
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900186 m = self.p.expect([pattern_u_boot_spl_signon] +
187 self.bad_patterns)
188 if m != 0:
189 raise Exception('Bad pattern found on SPL console: ' +
190 self.bad_pattern_ids[m - 1])
Tom Rinidec7ea02024-05-20 13:35:03 -0600191 env_spl_banner_times -= 1
192
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900193 m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900194 if m != 0:
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900195 raise Exception('Bad pattern found on console: ' +
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900196 self.bad_pattern_ids[m - 1])
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900197 self.u_boot_version_string = self.p.after
198 while True:
199 m = self.p.expect([self.prompt_compiled,
200 pattern_stop_autoboot_prompt] + self.bad_patterns)
201 if m == 0:
202 break
203 if m == 1:
204 self.p.send(' ')
205 continue
206 raise Exception('Bad pattern found on console: ' +
207 self.bad_pattern_ids[m - 2])
208
209 except Exception as ex:
210 self.log.error(str(ex))
211 self.cleanup_spawn()
212 raise
213 finally:
214 self.log.timestamp()
215
Stephen Warren10e50632016-01-15 11:15:24 -0700216 def run_command(self, cmd, wait_for_echo=True, send_nl=True,
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900217 wait_for_prompt=True, wait_for_reboot=False):
Stephen Warren75e731e2016-01-26 13:41:30 -0700218 """Execute a command via the U-Boot console.
Stephen Warren10e50632016-01-15 11:15:24 -0700219
220 The command is always sent to U-Boot.
221
222 U-Boot echoes any command back to its output, and this function
223 typically waits for that to occur. The wait can be disabled by setting
224 wait_for_echo=False, which is useful e.g. when sending CTRL-C to
225 interrupt a long-running command such as "ums".
226
227 Command execution is typically triggered by sending a newline
228 character. This can be disabled by setting send_nl=False, which is
229 also useful when sending CTRL-C.
230
231 This function typically waits for the command to finish executing, and
232 returns the console output that it generated. This can be disabled by
233 setting wait_for_prompt=False, which is useful when invoking a long-
234 running command such as "ums".
235
236 Args:
237 cmd: The command to send.
Heinrich Schuchardtbec160a2017-09-14 12:27:07 +0200238 wait_for_echo: Boolean indicating whether to wait for U-Boot to
Stephen Warren10e50632016-01-15 11:15:24 -0700239 echo the command text back to its output.
240 send_nl: Boolean indicating whether to send a newline character
241 after the command string.
242 wait_for_prompt: Boolean indicating whether to wait for the
243 command prompt to be sent by U-Boot. This typically occurs
244 immediately after the command has been executed.
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900245 wait_for_reboot: Boolean indication whether to wait for the
246 reboot U-Boot. If this sets True, wait_for_prompt must also
247 be True.
Stephen Warren10e50632016-01-15 11:15:24 -0700248
249 Returns:
250 If wait_for_prompt == False:
251 Nothing.
252 Else:
253 The output from U-Boot during command execution. In other
254 words, the text U-Boot emitted between the point it echod the
255 command string and emitted the subsequent command prompts.
Stephen Warren75e731e2016-01-26 13:41:30 -0700256 """
Stephen Warren10e50632016-01-15 11:15:24 -0700257
Stephen Warren10e50632016-01-15 11:15:24 -0700258 if self.at_prompt and \
259 self.at_prompt_logevt != self.logstream.logfile.cur_evt:
260 self.logstream.write(self.prompt, implicit=True)
261
Stephen Warren10e50632016-01-15 11:15:24 -0700262 try:
263 self.at_prompt = False
264 if send_nl:
265 cmd += '\n'
266 while cmd:
267 # Limit max outstanding data, so UART FIFOs don't overflow
268 chunk = cmd[:self.max_fifo_fill]
269 cmd = cmd[self.max_fifo_fill:]
270 self.p.send(chunk)
271 if not wait_for_echo:
272 continue
273 chunk = re.escape(chunk)
274 chunk = chunk.replace('\\\n', '[\r\n]')
Stephen Warren1115a972016-01-27 23:57:48 -0700275 m = self.p.expect([chunk] + self.bad_patterns)
Stephen Warren10e50632016-01-15 11:15:24 -0700276 if m != 0:
277 self.at_prompt = False
278 raise Exception('Bad pattern found on console: ' +
Stephen Warren1115a972016-01-27 23:57:48 -0700279 self.bad_pattern_ids[m - 1])
Stephen Warren10e50632016-01-15 11:15:24 -0700280 if not wait_for_prompt:
281 return
Masami Hiramatsu0ff22782022-02-16 15:15:52 +0900282 if wait_for_reboot:
283 self.wait_for_boot_prompt()
284 else:
285 m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
286 if m != 0:
287 self.at_prompt = False
288 raise Exception('Bad pattern found on console: ' +
289 self.bad_pattern_ids[m - 1])
Stephen Warren10e50632016-01-15 11:15:24 -0700290 self.at_prompt = True
291 self.at_prompt_logevt = self.logstream.logfile.cur_evt
292 # Only strip \r\n; space/TAB might be significant if testing
293 # indentation.
294 return self.p.before.strip('\r\n')
295 except Exception as ex:
296 self.log.error(str(ex))
297 self.cleanup_spawn()
298 raise
Stephen Warrenb1c556a2017-10-27 11:04:08 -0600299 finally:
300 self.log.timestamp()
Stephen Warren10e50632016-01-15 11:15:24 -0700301
Simon Glass2436bb02016-07-03 09:40:42 -0600302 def run_command_list(self, cmds):
303 """Run a list of commands.
304
305 This is a helper function to call run_command() with default arguments
306 for each command in a list.
307
308 Args:
Simon Glassd5deca02016-07-31 17:35:04 -0600309 cmd: List of commands (each a string).
Simon Glass2436bb02016-07-03 09:40:42 -0600310 Returns:
Simon Glass2ca73112016-07-31 17:35:09 -0600311 A list of output strings from each command, one element for each
312 command.
Simon Glass2436bb02016-07-03 09:40:42 -0600313 """
Simon Glass2ca73112016-07-31 17:35:09 -0600314 output = []
Simon Glass2436bb02016-07-03 09:40:42 -0600315 for cmd in cmds:
Simon Glass2ca73112016-07-31 17:35:09 -0600316 output.append(self.run_command(cmd))
Simon Glass2436bb02016-07-03 09:40:42 -0600317 return output
318
Stephen Warren10e50632016-01-15 11:15:24 -0700319 def ctrlc(self):
Stephen Warren75e731e2016-01-26 13:41:30 -0700320 """Send a CTRL-C character to U-Boot.
Stephen Warren10e50632016-01-15 11:15:24 -0700321
322 This is useful in order to stop execution of long-running synchronous
323 commands such as "ums".
324
325 Args:
326 None.
327
328 Returns:
329 Nothing.
Stephen Warren75e731e2016-01-26 13:41:30 -0700330 """
Stephen Warren10e50632016-01-15 11:15:24 -0700331
Stephen Warrena88c4172016-01-22 12:30:10 -0700332 self.log.action('Sending Ctrl-C')
Stephen Warren10e50632016-01-15 11:15:24 -0700333 self.run_command(chr(3), wait_for_echo=False, send_nl=False)
334
Stephen Warrenef824f52016-01-22 12:30:12 -0700335 def wait_for(self, text):
Stephen Warren75e731e2016-01-26 13:41:30 -0700336 """Wait for a pattern to be emitted by U-Boot.
Stephen Warrenef824f52016-01-22 12:30:12 -0700337
338 This is useful when a long-running command such as "dfu" is executing,
339 and it periodically emits some text that should show up at a specific
340 location in the log file.
341
342 Args:
343 text: The text to wait for; either a string (containing raw text,
344 not a regular expression) or an re object.
345
346 Returns:
347 Nothing.
Stephen Warren75e731e2016-01-26 13:41:30 -0700348 """
Stephen Warrenef824f52016-01-22 12:30:12 -0700349
350 if type(text) == type(''):
351 text = re.escape(text)
Stephen Warren68a9bb62016-01-27 23:57:49 -0700352 m = self.p.expect([text] + self.bad_patterns)
353 if m != 0:
354 raise Exception('Bad pattern found on console: ' +
355 self.bad_pattern_ids[m - 1])
Stephen Warrenef824f52016-01-22 12:30:12 -0700356
Stephen Warren97a54662016-01-22 12:30:09 -0700357 def drain_console(self):
Stephen Warren75e731e2016-01-26 13:41:30 -0700358 """Read from and log the U-Boot console for a short time.
Stephen Warren97a54662016-01-22 12:30:09 -0700359
360 U-Boot's console output is only logged when the test code actively
361 waits for U-Boot to emit specific data. There are cases where tests
362 can fail without doing this. For example, if a test asks U-Boot to
363 enable USB device mode, then polls until a host-side device node
364 exists. In such a case, it is useful to log U-Boot's console output
365 in case U-Boot printed clues as to why the host-side even did not
366 occur. This function will do that.
367
368 Args:
369 None.
370
371 Returns:
372 Nothing.
Stephen Warren75e731e2016-01-26 13:41:30 -0700373 """
Stephen Warren97a54662016-01-22 12:30:09 -0700374
375 # If we are already not connected to U-Boot, there's nothing to drain.
376 # This should only happen when a previous call to run_command() or
377 # wait_for() failed (and hence the output has already been logged), or
378 # the system is shutting down.
379 if not self.p:
380 return
381
382 orig_timeout = self.p.timeout
383 try:
384 # Drain the log for a relatively short time.
385 self.p.timeout = 1000
386 # Wait for something U-Boot will likely never send. This will
387 # cause the console output to be read and logged.
388 self.p.expect(['This should never match U-Boot output'])
Stephen Warren677b9cc2018-09-20 16:55:03 -0600389 except:
390 # We expect a timeout, since U-Boot won't print what we waited
391 # for. Squash it when it happens.
392 #
393 # Squash any other exception too. This function is only used to
394 # drain (and log) the U-Boot console output after a failed test.
395 # The U-Boot process will be restarted, or target board reset, once
396 # this function returns. So, we don't care about detecting any
397 # additional errors, so they're squashed so that the rest of the
398 # post-test-failure cleanup code can continue operation, and
399 # correctly terminate any log sections, etc.
Stephen Warren97a54662016-01-22 12:30:09 -0700400 pass
401 finally:
402 self.p.timeout = orig_timeout
403
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900404 def ensure_spawned(self, expect_reset=False):
Stephen Warren75e731e2016-01-26 13:41:30 -0700405 """Ensure a connection to a correctly running U-Boot instance.
Stephen Warren10e50632016-01-15 11:15:24 -0700406
407 This may require spawning a new Sandbox process or resetting target
408 hardware, as defined by the implementation sub-class.
409
410 This is an internal function and should not be called directly.
411
412 Args:
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900413 expect_reset: Boolean indication whether this boot is expected
414 to be reset while the 1st boot process after main boot before
415 prompt. False by default.
Stephen Warren10e50632016-01-15 11:15:24 -0700416
417 Returns:
418 Nothing.
Stephen Warren75e731e2016-01-26 13:41:30 -0700419 """
Stephen Warren10e50632016-01-15 11:15:24 -0700420
421 if self.p:
Bin Meng739b3862022-05-17 23:24:43 +0800422 # Reset the console timeout value as some tests may change
423 # its default value during the execution
424 if not self.config.gdbserver:
425 self.p.timeout = 30000
Stephen Warren10e50632016-01-15 11:15:24 -0700426 return
427 try:
Stephen Warren80eea632016-02-11 11:46:12 -0700428 self.log.start_section('Starting U-Boot')
Stephen Warren10e50632016-01-15 11:15:24 -0700429 self.at_prompt = False
Stephen Warren10e50632016-01-15 11:15:24 -0700430 self.p = self.get_spawn()
431 # Real targets can take a long time to scroll large amounts of
432 # text if LCD is enabled. This value may need tweaking in the
433 # future, possibly per-test to be optimal. This works for 'help'
434 # on board 'seaboard'.
Stephen Warren33db1ee2016-02-04 16:11:50 -0700435 if not self.config.gdbserver:
436 self.p.timeout = 30000
Stephen Warren10e50632016-01-15 11:15:24 -0700437 self.p.logfile_read = self.logstream
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900438 if expect_reset:
439 loop_num = 2
440 else:
441 loop_num = 1
442 self.wait_for_boot_prompt(loop_num = loop_num)
Stephen Warren10e50632016-01-15 11:15:24 -0700443 self.at_prompt = True
444 self.at_prompt_logevt = self.logstream.logfile.cur_evt
445 except Exception as ex:
446 self.log.error(str(ex))
447 self.cleanup_spawn()
448 raise
Stephen Warren80eea632016-02-11 11:46:12 -0700449 finally:
Stephen Warrenb1c556a2017-10-27 11:04:08 -0600450 self.log.timestamp()
Stephen Warren80eea632016-02-11 11:46:12 -0700451 self.log.end_section('Starting U-Boot')
Stephen Warren10e50632016-01-15 11:15:24 -0700452
453 def cleanup_spawn(self):
Stephen Warren75e731e2016-01-26 13:41:30 -0700454 """Shut down all interaction with the U-Boot instance.
Stephen Warren10e50632016-01-15 11:15:24 -0700455
456 This is used when an error is detected prior to re-establishing a
457 connection with a fresh U-Boot instance.
458
459 This is an internal function and should not be called directly.
460
461 Args:
462 None.
463
464 Returns:
465 Nothing.
Stephen Warren75e731e2016-01-26 13:41:30 -0700466 """
Stephen Warren10e50632016-01-15 11:15:24 -0700467
468 try:
469 if self.p:
470 self.p.close()
471 except:
472 pass
473 self.p = None
474
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900475 def restart_uboot(self, expect_reset=False):
Simon Glass37c2ce12016-07-31 17:35:08 -0600476 """Shut down and restart U-Boot."""
477 self.cleanup_spawn()
Masami Hiramatsu4d3b9962022-02-16 15:16:02 +0900478 self.ensure_spawned(expect_reset)
Simon Glass37c2ce12016-07-31 17:35:08 -0600479
Simon Glass9bc20832016-07-04 11:58:39 -0600480 def get_spawn_output(self):
481 """Return the start-up output from U-Boot
482
483 Returns:
484 The output produced by ensure_spawed(), as a string.
485 """
486 if self.p:
487 return self.p.get_expect_output()
488 return None
489
Stephen Warren10e50632016-01-15 11:15:24 -0700490 def validate_version_string_in_text(self, text):
Stephen Warren75e731e2016-01-26 13:41:30 -0700491 """Assert that a command's output includes the U-Boot signon message.
Stephen Warren10e50632016-01-15 11:15:24 -0700492
493 This is primarily useful for validating the "version" command without
494 duplicating the signon text regex in a test function.
495
496 Args:
497 text: The command output text to check.
498
499 Returns:
500 Nothing. An exception is raised if the validation fails.
Stephen Warren75e731e2016-01-26 13:41:30 -0700501 """
Stephen Warren10e50632016-01-15 11:15:24 -0700502
503 assert(self.u_boot_version_string in text)
504
505 def disable_check(self, check_type):
Stephen Warren75e731e2016-01-26 13:41:30 -0700506 """Temporarily disable an error check of U-Boot's output.
Stephen Warren10e50632016-01-15 11:15:24 -0700507
508 Create a new context manager (for use with the "with" statement) which
509 temporarily disables a particular console output error check.
510
511 Args:
512 check_type: The type of error-check to disable. Valid values may
513 be found in self.disable_check_count above.
514
515 Returns:
516 A context manager object.
Stephen Warren75e731e2016-01-26 13:41:30 -0700517 """
Stephen Warren10e50632016-01-15 11:15:24 -0700518
519 return ConsoleDisableCheck(self, check_type)
Michal Simek6b463182016-05-19 07:57:41 +0200520
Love Kumarc35e66e2024-05-22 18:45:13 +0530521 def enable_check(self, check_type, check_pattern):
522 """Temporarily enable an error check of U-Boot's output.
523
524 Create a new context manager (for use with the "with" statement) which
525 temporarily enables a particular console output error check. The
526 arguments form a new element of bad_pattern_defs defined above.
527
528 Args:
529 check_type: The type of error-check or bad pattern to enable.
530 check_pattern: The regexes for text error pattern or bad pattern
531 to be checked.
532
533 Returns:
534 A context manager object.
535 """
536
537 return ConsoleEnableCheck(self, check_type, check_pattern)
538
Michal Simek6b463182016-05-19 07:57:41 +0200539 def temporary_timeout(self, timeout):
540 """Temporarily set up different timeout for commands.
541
542 Create a new context manager (for use with the "with" statement) which
543 temporarily change timeout.
544
545 Args:
546 timeout: Time in milliseconds.
547
548 Returns:
549 A context manager object.
550 """
551
552 return ConsoleSetupTimeout(self, timeout)