[U-Boot] [PATCH v4 1/6] common: command: Fix command auto-completion

Boris Brezillon boris.brezillon at bootlin.com
Tue Dec 11 11:24:01 UTC 2018


Hi Simon,

On Mon, 10 Dec 2018 18:04:20 -0700
Simon Glass <sjg at chromium.org> wrote:

> Hi Boris,
> 
> On Mon, 3 Dec 2018 at 14:54, Boris Brezillon
> <boris.brezillon at bootlin.com> wrote:
> >
> > When auto-completing command arguments, the last argument is not
> > necessarily the one we need to auto-complete. When the last character is
> > a space, a tab or '\0' what we want instead is list all possible values,
> > or if there's only one possible value, place this value on the command
> > line instead of trying to suffix the last valid argument with missing
> > chars.
> >
> > Signed-off-by: Boris Brezillon <boris.brezillon at bootlin.com>
> > Reviewed-by: Tom Rini <trini at konsulko.com>
> > ---
> > Changes in v4:
> > -None
> >
> > Changes in v3:
> > - Add Tom's R-b
> >
> > Changes in v2:
> > - None
> > ---
> >  common/command.c | 12 ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)  
> 
> I wonder if you might be able to add a test for this into test/py/tests ?

This is what I made, but I'm really bad at writing python scripts, so
don't hesitate to propose propose something else (especially for the
autocomp_command() method).

Regards,

Boris

--->8---
diff --git a/test/py/tests/test_autocomp.py b/test/py/tests/test_autocomp.py
new file mode 100644
index 000000000000..cb93cf7e8a87
--- /dev/null
+++ b/test/py/tests/test_autocomp.py
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2018 Bootlin
+
+import pytest
+import u_boot_utils
+
+ at pytest.mark.buildconfigspec('auto_complete', 'cmd_memory', 'cmd_importenv')
+def test_env_print_autocomp(u_boot_console):
+    """Test that env print auto-completion works as expected."""
+
+    ram_base = u_boot_utils.find_ram_base(u_boot_console)
+    addr = '%08x' % ram_base
+    u_boot_console.run_command('mw.l ' + addr + ' 0x0')
+    u_boot_console.run_command('env import -d -b ' + addr)
+    u_boot_console.run_command('env set foo bar')
+    expected_response = 'foo'
+    response = u_boot_console.autocomp_command('printenv ', 'foo')
+    assert(expected_response in response)
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index 326b2ac51fbf..b8a2d0c84cda 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -137,6 +137,53 @@ class ConsoleBase(object):
             self.p.close()
         self.logstream.close()
 
+    def autocomp_command(self, cmd, expect):
+        """Try to auto-complete a command
+
+        The command is not executed, we just try to auto-complete it by
+        appending a \t at the end.
+
+        Args:
+            cmd: The command to auto-complete.
+            expect: The expected auto-completion.
+        """
+
+        if self.at_prompt and \
+                self.at_prompt_logevt != self.logstream.logfile.cur_evt:
+            self.logstream.write(self.prompt, implicit=True)
+
+        try:
+            self.at_prompt = False
+            cmd += '\t'
+            while cmd:
+                # Limit max outstanding data, so UART FIFOs don't overflow
+                chunk = cmd[:self.max_fifo_fill]
+                cmd = cmd[self.max_fifo_fill:]
+                self.p.send(chunk)
+                escchunk = chunk.replace('\t', '')
+                m = self.p.expect([escchunk] + self.bad_patterns)
+                if m != 0:
+                    self.at_prompt = False
+                    raise Exception('Bad pattern found on console: ' +
+                                    self.bad_pattern_ids[m - 1])
+
+            m = self.p.expect([expect])
+            if m != 0:
+                self.at_prompt = False
+                raise Exception('Bad pattern found on console: ' +
+                                self.bad_pattern_ids[m - 1])
+            self.at_prompt = True
+            self.at_prompt_logevt = self.logstream.logfile.cur_evt
+            # Only strip \r\n; space/TAB might be significant if testing
+            # indentation.
+            return self.p.after.strip('\r\n')
+        except Exception as ex:
+            self.log.error(str(ex))
+            self.cleanup_spawn()
+            raise
+        finally:
+            self.log.timestamp()
+
     def run_command(self, cmd, wait_for_echo=True, send_nl=True,
             wait_for_prompt=True):
         """Execute a command via the U-Boot console.


More information about the U-Boot mailing list