blob: 26b6de07f88faab105da816e0dcee577e23a8cbd [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0
Stephen Warrend2015062016-01-15 11:15:24 -07002# Copyright (c) 2015 Stephen Warren
3# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
Stephen Warrend2015062016-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 Warrenc10eb9d2016-01-22 12:30:09 -070016import u_boot_spawn
Stephen Warrend2015062016-01-15 11:15:24 -070017
18# Regexes for text we expect U-Boot to send to the console.
Heiko Schocher8fb23912018-12-05 11:29:54 +010019pattern_u_boot_spl_signon = re.compile('(U-Boot SPL \\d{4}\\.\\d{2}[^\r\n]*\\))')
Yan Liuc9db1a12020-07-21 11:12:05 -040020pattern_u_boot_spl2_signon = re.compile('(U-Boot SPL \\d{4}\\.\\d{2}[^\r\n]*\\))')
Stephen Warrenc82ce042016-02-05 18:04:43 -070021pattern_u_boot_main_signon = re.compile('(U-Boot \\d{4}\\.\\d{2}[^\r\n]*\\))')
Stephen Warrend2015062016-01-15 11:15:24 -070022pattern_stop_autoboot_prompt = re.compile('Hit any key to stop autoboot: ')
23pattern_unknown_command = re.compile('Unknown command \'.*\' - try \'help\'')
24pattern_error_notification = re.compile('## Error: ')
Stephen Warren9129d9f2016-01-27 23:57:50 -070025pattern_error_please_reset = re.compile('### ERROR ### Please RESET the board ###')
Stephen Warrend2015062016-01-15 11:15:24 -070026
Stephen Warrene4119eb2016-01-27 23:57:48 -070027PAT_ID = 0
28PAT_RE = 1
29
30bad_pattern_defs = (
31 ('spl_signon', pattern_u_boot_spl_signon),
Yan Liuc9db1a12020-07-21 11:12:05 -040032 ('spl2_signon', pattern_u_boot_spl2_signon),
Stephen Warrene4119eb2016-01-27 23:57:48 -070033 ('main_signon', pattern_u_boot_main_signon),
34 ('stop_autoboot_prompt', pattern_stop_autoboot_prompt),
35 ('unknown_command', pattern_unknown_command),
36 ('error_notification', pattern_error_notification),
Stephen Warren9129d9f2016-01-27 23:57:50 -070037 ('error_please_reset', pattern_error_please_reset),
Stephen Warrene4119eb2016-01-27 23:57:48 -070038)
39
Stephen Warrend2015062016-01-15 11:15:24 -070040class ConsoleDisableCheck(object):
Stephen Warrene8debf32016-01-26 13:41:30 -070041 """Context manager (for Python's with statement) that temporarily disables
Stephen Warrend2015062016-01-15 11:15:24 -070042 the specified console output error check. This is useful when deliberately
43 executing a command that is known to trigger one of the error checks, in
44 order to test that the error condition is actually raised. This class is
45 used internally by ConsoleBase::disable_check(); it is not intended for
Stephen Warrene8debf32016-01-26 13:41:30 -070046 direct usage."""
Stephen Warrend2015062016-01-15 11:15:24 -070047
48 def __init__(self, console, check_type):
49 self.console = console
50 self.check_type = check_type
51
52 def __enter__(self):
53 self.console.disable_check_count[self.check_type] += 1
Stephen Warrene4119eb2016-01-27 23:57:48 -070054 self.console.eval_bad_patterns()
Stephen Warrend2015062016-01-15 11:15:24 -070055
56 def __exit__(self, extype, value, traceback):
57 self.console.disable_check_count[self.check_type] -= 1
Stephen Warrene4119eb2016-01-27 23:57:48 -070058 self.console.eval_bad_patterns()
Stephen Warrend2015062016-01-15 11:15:24 -070059
Michal Simek87861c12016-05-19 07:57:41 +020060class ConsoleSetupTimeout(object):
61 """Context manager (for Python's with statement) that temporarily sets up
62 timeout for specific command. This is useful when execution time is greater
63 then default 30s."""
64
65 def __init__(self, console, timeout):
66 self.p = console.p
67 self.orig_timeout = self.p.timeout
68 self.p.timeout = timeout
69
70 def __enter__(self):
71 return self
72
73 def __exit__(self, extype, value, traceback):
74 self.p.timeout = self.orig_timeout
75
Stephen Warrend2015062016-01-15 11:15:24 -070076class ConsoleBase(object):
Stephen Warrene8debf32016-01-26 13:41:30 -070077 """The interface through which test functions interact with the U-Boot
Stephen Warrend2015062016-01-15 11:15:24 -070078 console. This primarily involves executing shell commands, capturing their
79 results, and checking for common error conditions. Some common utilities
Stephen Warrene8debf32016-01-26 13:41:30 -070080 are also provided too."""
Stephen Warrend2015062016-01-15 11:15:24 -070081
82 def __init__(self, log, config, max_fifo_fill):
Stephen Warrene8debf32016-01-26 13:41:30 -070083 """Initialize a U-Boot console connection.
Stephen Warrend2015062016-01-15 11:15:24 -070084
85 Can only usefully be called by sub-classes.
86
87 Args:
88 log: A mulptiplex_log.Logfile object, to which the U-Boot output
89 will be logged.
90 config: A configuration data structure, as built by conftest.py.
91 max_fifo_fill: The maximum number of characters to send to U-Boot
92 command-line before waiting for U-Boot to echo the characters
93 back. For UART-based HW without HW flow control, this value
94 should be set less than the UART RX FIFO size to avoid
95 overflow, assuming that U-Boot can't keep up with full-rate
96 traffic at the baud rate.
97
98 Returns:
99 Nothing.
Stephen Warrene8debf32016-01-26 13:41:30 -0700100 """
Stephen Warrend2015062016-01-15 11:15:24 -0700101
102 self.log = log
103 self.config = config
104 self.max_fifo_fill = max_fifo_fill
105
106 self.logstream = self.log.get_stream('console', sys.stdout)
107
108 # Array slice removes leading/trailing quotes
109 self.prompt = self.config.buildconfig['config_sys_prompt'][1:-1]
Stephen Warren4ba58bd2016-08-16 19:58:59 -0600110 self.prompt_compiled = re.compile('^' + re.escape(self.prompt), re.MULTILINE)
Stephen Warrend2015062016-01-15 11:15:24 -0700111 self.p = None
Stephen Warrene4119eb2016-01-27 23:57:48 -0700112 self.disable_check_count = {pat[PAT_ID]: 0 for pat in bad_pattern_defs}
113 self.eval_bad_patterns()
Stephen Warrend2015062016-01-15 11:15:24 -0700114
115 self.at_prompt = False
116 self.at_prompt_logevt = None
Stephen Warrend2015062016-01-15 11:15:24 -0700117
Simon Glass9e007772022-02-11 13:23:23 -0700118 def get_spawn(self):
119 # This is not called, ssubclass must define this.
120 # Return a value to avoid:
121 # u_boot_console_base.py:348:12: E1128: Assigning result of a function
122 # call, where the function returns None (assignment-from-none)
123 return u_boot_spawn.Spawn([])
124
125
Stephen Warrene4119eb2016-01-27 23:57:48 -0700126 def eval_bad_patterns(self):
127 self.bad_patterns = [pat[PAT_RE] for pat in bad_pattern_defs \
128 if self.disable_check_count[pat[PAT_ID]] == 0]
129 self.bad_pattern_ids = [pat[PAT_ID] for pat in bad_pattern_defs \
130 if self.disable_check_count[pat[PAT_ID]] == 0]
131
Stephen Warrend2015062016-01-15 11:15:24 -0700132 def close(self):
Stephen Warrene8debf32016-01-26 13:41:30 -0700133 """Terminate the connection to the U-Boot console.
Stephen Warrend2015062016-01-15 11:15:24 -0700134
135 This function is only useful once all interaction with U-Boot is
136 complete. Once this function is called, data cannot be sent to or
137 received from U-Boot.
138
139 Args:
140 None.
141
142 Returns:
143 Nothing.
Stephen Warrene8debf32016-01-26 13:41:30 -0700144 """
Stephen Warrend2015062016-01-15 11:15:24 -0700145
146 if self.p:
147 self.p.close()
148 self.logstream.close()
149
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900150 def wait_for_boot_prompt(self, loop_num = 1):
Masami Hiramatsu06396e22022-02-16 15:15:52 +0900151 """Wait for the boot up until command prompt. This is for internal use only.
152 """
153 try:
154 bcfg = self.config.buildconfig
155 config_spl = bcfg.get('config_spl', 'n') == 'y'
156 config_spl_serial = bcfg.get('config_spl_serial', 'n') == 'y'
157 env_spl_skipped = self.config.env.get('env__spl_skipped', False)
158 env_spl2_skipped = self.config.env.get('env__spl2_skipped', True)
159
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900160 while loop_num > 0:
161 loop_num -= 1
162 if config_spl and config_spl_serial and not env_spl_skipped:
163 m = self.p.expect([pattern_u_boot_spl_signon] +
164 self.bad_patterns)
165 if m != 0:
166 raise Exception('Bad pattern found on SPL console: ' +
167 self.bad_pattern_ids[m - 1])
168 if not env_spl2_skipped:
169 m = self.p.expect([pattern_u_boot_spl2_signon] +
170 self.bad_patterns)
171 if m != 0:
172 raise Exception('Bad pattern found on SPL2 console: ' +
173 self.bad_pattern_ids[m - 1])
174 m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
Masami Hiramatsu06396e22022-02-16 15:15:52 +0900175 if m != 0:
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900176 raise Exception('Bad pattern found on console: ' +
Masami Hiramatsu06396e22022-02-16 15:15:52 +0900177 self.bad_pattern_ids[m - 1])
Masami Hiramatsu06396e22022-02-16 15:15:52 +0900178 self.u_boot_version_string = self.p.after
179 while True:
180 m = self.p.expect([self.prompt_compiled,
181 pattern_stop_autoboot_prompt] + self.bad_patterns)
182 if m == 0:
183 break
184 if m == 1:
185 self.p.send(' ')
186 continue
187 raise Exception('Bad pattern found on console: ' +
188 self.bad_pattern_ids[m - 2])
189
190 except Exception as ex:
191 self.log.error(str(ex))
192 self.cleanup_spawn()
193 raise
194 finally:
195 self.log.timestamp()
196
Stephen Warrend2015062016-01-15 11:15:24 -0700197 def run_command(self, cmd, wait_for_echo=True, send_nl=True,
Masami Hiramatsu06396e22022-02-16 15:15:52 +0900198 wait_for_prompt=True, wait_for_reboot=False):
Stephen Warrene8debf32016-01-26 13:41:30 -0700199 """Execute a command via the U-Boot console.
Stephen Warrend2015062016-01-15 11:15:24 -0700200
201 The command is always sent to U-Boot.
202
203 U-Boot echoes any command back to its output, and this function
204 typically waits for that to occur. The wait can be disabled by setting
205 wait_for_echo=False, which is useful e.g. when sending CTRL-C to
206 interrupt a long-running command such as "ums".
207
208 Command execution is typically triggered by sending a newline
209 character. This can be disabled by setting send_nl=False, which is
210 also useful when sending CTRL-C.
211
212 This function typically waits for the command to finish executing, and
213 returns the console output that it generated. This can be disabled by
214 setting wait_for_prompt=False, which is useful when invoking a long-
215 running command such as "ums".
216
217 Args:
218 cmd: The command to send.
Heinrich Schuchardtcd3e8a72017-09-14 12:27:07 +0200219 wait_for_echo: Boolean indicating whether to wait for U-Boot to
Stephen Warrend2015062016-01-15 11:15:24 -0700220 echo the command text back to its output.
221 send_nl: Boolean indicating whether to send a newline character
222 after the command string.
223 wait_for_prompt: Boolean indicating whether to wait for the
224 command prompt to be sent by U-Boot. This typically occurs
225 immediately after the command has been executed.
Masami Hiramatsu06396e22022-02-16 15:15:52 +0900226 wait_for_reboot: Boolean indication whether to wait for the
227 reboot U-Boot. If this sets True, wait_for_prompt must also
228 be True.
Stephen Warrend2015062016-01-15 11:15:24 -0700229
230 Returns:
231 If wait_for_prompt == False:
232 Nothing.
233 Else:
234 The output from U-Boot during command execution. In other
235 words, the text U-Boot emitted between the point it echod the
236 command string and emitted the subsequent command prompts.
Stephen Warrene8debf32016-01-26 13:41:30 -0700237 """
Stephen Warrend2015062016-01-15 11:15:24 -0700238
Stephen Warrend2015062016-01-15 11:15:24 -0700239 if self.at_prompt and \
240 self.at_prompt_logevt != self.logstream.logfile.cur_evt:
241 self.logstream.write(self.prompt, implicit=True)
242
Stephen Warrend2015062016-01-15 11:15:24 -0700243 try:
244 self.at_prompt = False
245 if send_nl:
246 cmd += '\n'
247 while cmd:
248 # Limit max outstanding data, so UART FIFOs don't overflow
249 chunk = cmd[:self.max_fifo_fill]
250 cmd = cmd[self.max_fifo_fill:]
251 self.p.send(chunk)
252 if not wait_for_echo:
253 continue
254 chunk = re.escape(chunk)
255 chunk = chunk.replace('\\\n', '[\r\n]')
Stephen Warrene4119eb2016-01-27 23:57:48 -0700256 m = self.p.expect([chunk] + self.bad_patterns)
Stephen Warrend2015062016-01-15 11:15:24 -0700257 if m != 0:
258 self.at_prompt = False
259 raise Exception('Bad pattern found on console: ' +
Stephen Warrene4119eb2016-01-27 23:57:48 -0700260 self.bad_pattern_ids[m - 1])
Stephen Warrend2015062016-01-15 11:15:24 -0700261 if not wait_for_prompt:
262 return
Masami Hiramatsu06396e22022-02-16 15:15:52 +0900263 if wait_for_reboot:
264 self.wait_for_boot_prompt()
265 else:
266 m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
267 if m != 0:
268 self.at_prompt = False
269 raise Exception('Bad pattern found on console: ' +
270 self.bad_pattern_ids[m - 1])
Stephen Warrend2015062016-01-15 11:15:24 -0700271 self.at_prompt = True
272 self.at_prompt_logevt = self.logstream.logfile.cur_evt
273 # Only strip \r\n; space/TAB might be significant if testing
274 # indentation.
275 return self.p.before.strip('\r\n')
276 except Exception as ex:
277 self.log.error(str(ex))
278 self.cleanup_spawn()
279 raise
Stephen Warren9679d332017-10-27 11:04:08 -0600280 finally:
281 self.log.timestamp()
Stephen Warrend2015062016-01-15 11:15:24 -0700282
Simon Glass73a90542016-07-03 09:40:42 -0600283 def run_command_list(self, cmds):
284 """Run a list of commands.
285
286 This is a helper function to call run_command() with default arguments
287 for each command in a list.
288
289 Args:
Simon Glass72f52262016-07-31 17:35:04 -0600290 cmd: List of commands (each a string).
Simon Glass73a90542016-07-03 09:40:42 -0600291 Returns:
Simon Glassf6d34652016-07-31 17:35:09 -0600292 A list of output strings from each command, one element for each
293 command.
Simon Glass73a90542016-07-03 09:40:42 -0600294 """
Simon Glassf6d34652016-07-31 17:35:09 -0600295 output = []
Simon Glass73a90542016-07-03 09:40:42 -0600296 for cmd in cmds:
Simon Glassf6d34652016-07-31 17:35:09 -0600297 output.append(self.run_command(cmd))
Simon Glass73a90542016-07-03 09:40:42 -0600298 return output
299
Stephen Warrend2015062016-01-15 11:15:24 -0700300 def ctrlc(self):
Stephen Warrene8debf32016-01-26 13:41:30 -0700301 """Send a CTRL-C character to U-Boot.
Stephen Warrend2015062016-01-15 11:15:24 -0700302
303 This is useful in order to stop execution of long-running synchronous
304 commands such as "ums".
305
306 Args:
307 None.
308
309 Returns:
310 Nothing.
Stephen Warrene8debf32016-01-26 13:41:30 -0700311 """
Stephen Warrend2015062016-01-15 11:15:24 -0700312
Stephen Warren783cbcd2016-01-22 12:30:10 -0700313 self.log.action('Sending Ctrl-C')
Stephen Warrend2015062016-01-15 11:15:24 -0700314 self.run_command(chr(3), wait_for_echo=False, send_nl=False)
315
Stephen Warren76b46932016-01-22 12:30:12 -0700316 def wait_for(self, text):
Stephen Warrene8debf32016-01-26 13:41:30 -0700317 """Wait for a pattern to be emitted by U-Boot.
Stephen Warren76b46932016-01-22 12:30:12 -0700318
319 This is useful when a long-running command such as "dfu" is executing,
320 and it periodically emits some text that should show up at a specific
321 location in the log file.
322
323 Args:
324 text: The text to wait for; either a string (containing raw text,
325 not a regular expression) or an re object.
326
327 Returns:
328 Nothing.
Stephen Warrene8debf32016-01-26 13:41:30 -0700329 """
Stephen Warren76b46932016-01-22 12:30:12 -0700330
331 if type(text) == type(''):
332 text = re.escape(text)
Stephen Warren0c6189b2016-01-27 23:57:49 -0700333 m = self.p.expect([text] + self.bad_patterns)
334 if m != 0:
335 raise Exception('Bad pattern found on console: ' +
336 self.bad_pattern_ids[m - 1])
Stephen Warren76b46932016-01-22 12:30:12 -0700337
Stephen Warrenc10eb9d2016-01-22 12:30:09 -0700338 def drain_console(self):
Stephen Warrene8debf32016-01-26 13:41:30 -0700339 """Read from and log the U-Boot console for a short time.
Stephen Warrenc10eb9d2016-01-22 12:30:09 -0700340
341 U-Boot's console output is only logged when the test code actively
342 waits for U-Boot to emit specific data. There are cases where tests
343 can fail without doing this. For example, if a test asks U-Boot to
344 enable USB device mode, then polls until a host-side device node
345 exists. In such a case, it is useful to log U-Boot's console output
346 in case U-Boot printed clues as to why the host-side even did not
347 occur. This function will do that.
348
349 Args:
350 None.
351
352 Returns:
353 Nothing.
Stephen Warrene8debf32016-01-26 13:41:30 -0700354 """
Stephen Warrenc10eb9d2016-01-22 12:30:09 -0700355
356 # If we are already not connected to U-Boot, there's nothing to drain.
357 # This should only happen when a previous call to run_command() or
358 # wait_for() failed (and hence the output has already been logged), or
359 # the system is shutting down.
360 if not self.p:
361 return
362
363 orig_timeout = self.p.timeout
364 try:
365 # Drain the log for a relatively short time.
366 self.p.timeout = 1000
367 # Wait for something U-Boot will likely never send. This will
368 # cause the console output to be read and logged.
369 self.p.expect(['This should never match U-Boot output'])
Stephen Warrendddea0d2018-09-20 16:55:03 -0600370 except:
371 # We expect a timeout, since U-Boot won't print what we waited
372 # for. Squash it when it happens.
373 #
374 # Squash any other exception too. This function is only used to
375 # drain (and log) the U-Boot console output after a failed test.
376 # The U-Boot process will be restarted, or target board reset, once
377 # this function returns. So, we don't care about detecting any
378 # additional errors, so they're squashed so that the rest of the
379 # post-test-failure cleanup code can continue operation, and
380 # correctly terminate any log sections, etc.
Stephen Warrenc10eb9d2016-01-22 12:30:09 -0700381 pass
382 finally:
383 self.p.timeout = orig_timeout
384
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900385 def ensure_spawned(self, expect_reset=False):
Stephen Warrene8debf32016-01-26 13:41:30 -0700386 """Ensure a connection to a correctly running U-Boot instance.
Stephen Warrend2015062016-01-15 11:15:24 -0700387
388 This may require spawning a new Sandbox process or resetting target
389 hardware, as defined by the implementation sub-class.
390
391 This is an internal function and should not be called directly.
392
393 Args:
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900394 expect_reset: Boolean indication whether this boot is expected
395 to be reset while the 1st boot process after main boot before
396 prompt. False by default.
Stephen Warrend2015062016-01-15 11:15:24 -0700397
398 Returns:
399 Nothing.
Stephen Warrene8debf32016-01-26 13:41:30 -0700400 """
Stephen Warrend2015062016-01-15 11:15:24 -0700401
402 if self.p:
Bin Meng7bb68352022-05-17 23:24:43 +0800403 # Reset the console timeout value as some tests may change
404 # its default value during the execution
405 if not self.config.gdbserver:
406 self.p.timeout = 30000
Stephen Warrend2015062016-01-15 11:15:24 -0700407 return
408 try:
Stephen Warren97255432016-02-11 11:46:12 -0700409 self.log.start_section('Starting U-Boot')
Stephen Warrend2015062016-01-15 11:15:24 -0700410 self.at_prompt = False
Stephen Warrend2015062016-01-15 11:15:24 -0700411 self.p = self.get_spawn()
412 # Real targets can take a long time to scroll large amounts of
413 # text if LCD is enabled. This value may need tweaking in the
414 # future, possibly per-test to be optimal. This works for 'help'
415 # on board 'seaboard'.
Stephen Warren89ab8412016-02-04 16:11:50 -0700416 if not self.config.gdbserver:
417 self.p.timeout = 30000
Stephen Warrend2015062016-01-15 11:15:24 -0700418 self.p.logfile_read = self.logstream
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900419 if expect_reset:
420 loop_num = 2
421 else:
422 loop_num = 1
423 self.wait_for_boot_prompt(loop_num = loop_num)
Stephen Warrend2015062016-01-15 11:15:24 -0700424 self.at_prompt = True
425 self.at_prompt_logevt = self.logstream.logfile.cur_evt
426 except Exception as ex:
427 self.log.error(str(ex))
428 self.cleanup_spawn()
429 raise
Stephen Warren97255432016-02-11 11:46:12 -0700430 finally:
Stephen Warren9679d332017-10-27 11:04:08 -0600431 self.log.timestamp()
Stephen Warren97255432016-02-11 11:46:12 -0700432 self.log.end_section('Starting U-Boot')
Stephen Warrend2015062016-01-15 11:15:24 -0700433
434 def cleanup_spawn(self):
Stephen Warrene8debf32016-01-26 13:41:30 -0700435 """Shut down all interaction with the U-Boot instance.
Stephen Warrend2015062016-01-15 11:15:24 -0700436
437 This is used when an error is detected prior to re-establishing a
438 connection with a fresh U-Boot instance.
439
440 This is an internal function and should not be called directly.
441
442 Args:
443 None.
444
445 Returns:
446 Nothing.
Stephen Warrene8debf32016-01-26 13:41:30 -0700447 """
Stephen Warrend2015062016-01-15 11:15:24 -0700448
449 try:
450 if self.p:
451 self.p.close()
452 except:
453 pass
454 self.p = None
455
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900456 def restart_uboot(self, expect_reset=False):
Simon Glass27c087d2016-07-31 17:35:08 -0600457 """Shut down and restart U-Boot."""
458 self.cleanup_spawn()
Masami Hiramatsue7233c92022-02-16 15:16:02 +0900459 self.ensure_spawned(expect_reset)
Simon Glass27c087d2016-07-31 17:35:08 -0600460
Simon Glassebec58f2016-07-04 11:58:39 -0600461 def get_spawn_output(self):
462 """Return the start-up output from U-Boot
463
464 Returns:
465 The output produced by ensure_spawed(), as a string.
466 """
467 if self.p:
468 return self.p.get_expect_output()
469 return None
470
Stephen Warrend2015062016-01-15 11:15:24 -0700471 def validate_version_string_in_text(self, text):
Stephen Warrene8debf32016-01-26 13:41:30 -0700472 """Assert that a command's output includes the U-Boot signon message.
Stephen Warrend2015062016-01-15 11:15:24 -0700473
474 This is primarily useful for validating the "version" command without
475 duplicating the signon text regex in a test function.
476
477 Args:
478 text: The command output text to check.
479
480 Returns:
481 Nothing. An exception is raised if the validation fails.
Stephen Warrene8debf32016-01-26 13:41:30 -0700482 """
Stephen Warrend2015062016-01-15 11:15:24 -0700483
484 assert(self.u_boot_version_string in text)
485
486 def disable_check(self, check_type):
Stephen Warrene8debf32016-01-26 13:41:30 -0700487 """Temporarily disable an error check of U-Boot's output.
Stephen Warrend2015062016-01-15 11:15:24 -0700488
489 Create a new context manager (for use with the "with" statement) which
490 temporarily disables a particular console output error check.
491
492 Args:
493 check_type: The type of error-check to disable. Valid values may
494 be found in self.disable_check_count above.
495
496 Returns:
497 A context manager object.
Stephen Warrene8debf32016-01-26 13:41:30 -0700498 """
Stephen Warrend2015062016-01-15 11:15:24 -0700499
500 return ConsoleDisableCheck(self, check_type)
Michal Simek87861c12016-05-19 07:57:41 +0200501
502 def temporary_timeout(self, timeout):
503 """Temporarily set up different timeout for commands.
504
505 Create a new context manager (for use with the "with" statement) which
506 temporarily change timeout.
507
508 Args:
509 timeout: Time in milliseconds.
510
511 Returns:
512 A context manager object.
513 """
514
515 return ConsoleSetupTimeout(self, timeout)