alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir
@ 2012-08-14  9:55 David Henningsson
  2012-08-14  9:55 ` [PATCH 2/2] hda-emu: Add more functionality to test suite David Henningsson
  2012-08-14 10:28 ` [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir Takashi Iwai
  0 siblings, 2 replies; 3+ messages in thread
From: David Henningsson @ 2012-08-14  9:55 UTC (permalink / raw)
  To: tiwai, alsa-devel; +Cc: David Henningsson

Previously, adding a path that was relative could fail because
the symlinks created were broken.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 configure.ac |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/configure.ac b/configure.ac
index 315e759..18118f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,8 @@ AC_ARG_WITH(hdadir,
     [path where HD-audio kernel files are stored]),
   hdadir="$withval", hdadir="")
 
+hdadir="$( cd "$hdadir" && pwd )"
+
 if test -n "$hdadir"; then
 
 test -d "$hdadir" || \
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] hda-emu: Add more functionality to test suite
  2012-08-14  9:55 [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir David Henningsson
@ 2012-08-14  9:55 ` David Henningsson
  2012-08-14 10:28 ` [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir Takashi Iwai
  1 sibling, 0 replies; 3+ messages in thread
From: David Henningsson @ 2012-08-14  9:55 UTC (permalink / raw)
  To: tiwai, alsa-devel; +Cc: David Henningsson

Now also test jack plug/unplug, and get/set of some controls.
Add option to log communication, and make it work regardless of whether
hda-emu was compiled with readline or not.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 tester/hda-emu-tester.py |    6 ++
 tester/runner.py         |  185 +++++++++++++++++++++++++++++++++++++++-------
 tester/summary.py        |   52 +++++++++++++
 3 files changed, 218 insertions(+), 25 deletions(-)
 create mode 100755 tester/summary.py

diff --git a/tester/hda-emu-tester.py b/tester/hda-emu-tester.py
index a931651..4782a97 100755
--- a/tester/hda-emu-tester.py
+++ b/tester/hda-emu-tester.py
@@ -22,11 +22,17 @@ def handle_argv():
     import argparse
     parser = argparse.ArgumentParser(description='Hda-emu automated test wrapper.')
     parser.add_argument('--file', dest='file', required=True, help='alsa-info filename')
+    parser.add_argument('--print-errors', dest='print_errors', action="store_true", 
+        default=False, help='print errors, and the command that caused it')
+    parser.add_argument('--comm-log', dest='comm_log', action="store_true", 
+        default=False, help='print communication with hda-emu')
     return parser.parse_args()
 
 def run_test(argv):
     import runner
     result = runner.HdaEmuRunner()
+    result.set_print_errors(argv.print_errors)
+    result.set_comm_log_enabled(argv.comm_log)
     result.set_alsa_info_file(argv.file)
     result.run_standard()
     return result
diff --git a/tester/runner.py b/tester/runner.py
index 28953be..dc9f6fd 100644
--- a/tester/runner.py
+++ b/tester/runner.py
@@ -19,6 +19,28 @@
 import subprocess
 import os
 
+class ControlInfo():
+    def __init__(self, runner, list_info):
+        self.runner = runner
+        carr = list_info.split(":")
+        self.numid = carr[1]
+        self.name = carr[2]
+
+    def add_info(self, get_info):
+        import re
+        minmax_regex = re.compile("MIN/MAX: (\d+)/(\d+),\s+VAL:(( \\[\d+\\])+)")
+        val_regex = re.compile(" \\[(\d+)\\]")
+
+        if self.name.endswith("Volume") or self.name.endswith("Switch"):
+            match = minmax_regex.search("".join(get_info))
+            if match is None:
+                self.runner.add_error("Could not find MIN/MAX values for '" + self.name + "' (" + "".join(get_info) + ")", "Error")
+                return
+            self.minval = match.group(1)
+            self.maxval = match.group(2)
+            cval = val_regex.split(match.group(3))
+            self.values = [int(v) for v in cval if v != ""]
+
 class HdaEmuRunner():
 
     def __init__(self):
@@ -26,10 +48,19 @@ class HdaEmuRunner():
         self.alsa_info = "/proc/asound/card0/codec#0"
         self.errors = 0
         self.warnings = 0
+        self.print_errors = False
+        self.comm_log_enabled = False
+        self.last_command = None
 
     def set_alsa_info_file(self, filename):
         self.alsa_info = filename
 
+    def set_print_errors(self, print_errors):
+        self.print_errors = print_errors
+
+    def set_comm_log_enabled(self, value):
+        self.comm_log_enabled = value
+
     def start_process(self):
         import shlex
         from subprocess import PIPE, STDOUT
@@ -45,65 +76,169 @@ class HdaEmuRunner():
         self.child.wait()
         self.child = None
 
+    def add_error(self, message, severity):
+        if severity == "Warning":
+            self.warnings += 1
+        else:
+            self.errors += 1
+        if self.print_errors:
+            if not self.last_command_printed:
+                if self.last_command:
+                    print "Encountered while running '" + self.last_command + "':"
+                else:
+                    print "Encountered during initial parsing:"
+                self.last_command_printed = True
+            print "  ", message
 
     def check_stdout(self):
         s = os.read(self.child.stdout.fileno(), 65536)
-        # print "Stdout received (", len(s), ")"
+
+        if self.comm_log_enabled:
+            if len(s) < 150:
+                print "Stdout received (", len(s), ")", s
+            else:
+                print "Stdout received (", len(s), ")", s[:70], " ... ", s[-70:]
+
         if s == "":
-            print "Unexpected EOF of stdout (hda-emu crashed?)"
-            self.errors += 1
+            self.add_error("Unexpected EOF of stdout (hda-emu crashed?)", "Fatal")
             return
         self.stdout_total += s
 
         q, _, self.stdout_total = self.stdout_total.rpartition('\n')
-        for s in q.splitlines():
+        l = q.splitlines()
+        self.stdout_lines += l
+        for s in l:
             if s.startswith("Error:"):
-                self.errors += 1
-                # print s
+                self.add_error(s, "Error")
             if s.startswith("Warning:"):
-                self.warnings += 1
-                # print s
+                self.add_error(s, "Warning")
 
     def check_stderr(self):
         s = os.read(self.child.stderr.fileno(), 65536)
-        # print "Stderr received (", len(s), ")"
+
+        if self.comm_log_enabled:
+            print "Stderr received (", len(s), ")", s
+
         if s == "":
-            print "Unexpected EOF of stderr (hda-emu crashed?)"
-            self.errors += 1
+            self.add_error("Unexpected EOF of stderr (hda-emu crashed?)", "Fatal")
             return False
-        if s == "> ":
-            return True
-        print "Unexpected stderr output: '" + prompt + "'"
-        self.errors += 1
-        return False
+        # consume readline echo
+        while len(s) > 0 and self.readline_echo.startswith(s[0]):
+            self.readline_echo = self.readline_echo[1:]
+            s = s[1:]
+
+        # detect prompts and half prompts
+        fullprompt = False
+        if self.has_partial_stderr_prompt:
+             if s.startswith(" "):
+                  fullprompt = True
+                  s = s[1:]
+             else:
+                  s = ">" + s
+             self.has_partial_stderr_prompt = False
+        if s.endswith("> "):
+            fullprompt = True
+            s = s[:-2]
+        elif s.endswith(">"):
+            self.has_partial_stderr_prompt = True
+            s = s[:-1]
+
+        if s != "":
+            self.add_error("Unexpected stderr output: '" + s + "'", "Error")
+        return fullprompt
+
 
     def run_command(self, command=None):
+        self.last_command_printed = False
+        self.has_partial_stderr_prompt = False
+
         if command:
+            self.readline_echo = command + '\n'
+            self.last_command = command
+            if self.comm_log_enabled:
+                print "Sending command: ", command
             self.child.stdin.write(command + '\n')
             self.child.stdin.flush()
+        else:
+            self.readline_echo = ""
 
         import select
         self.stdout_total = ""
+        self.stderr_total = ""
+        self.stdout_lines = []
         pipelist = [self.child.stdout, self.child.stderr]
+        timeout = 3
         while True:
-            readable, _, broken = select.select(pipelist, [], pipelist, 3)
+            readable, _, broken = select.select(pipelist, [], pipelist, timeout)
             for q in broken:
-                print "Broken pipe (hda-emu crashed?)"
-                self.errors += 1
-                return
-            if readable == []:
-                print "Timeout waiting for hda-emu"
-                self.errors += 1
-                return
+                self.add_error("Broken pipe (hda-emu crashed?)", "Fatal")
+                return None
             if self.child.stdout in readable:
                 self.check_stdout()
             if self.child.stderr in readable:
                 if self.check_stderr():
-                    return
+                    timeout = 0 # One more check round to help against races between stderr and stdout
+
+            if readable == [] and timeout > 0:
+                self.add_error("Timeout waiting for hda-emu", "Fatal")
+                return None
+            elif readable == [] and timeout == 0:
+                return self.stdout_lines
+
+    def find_jack_pins(self):
+        dump = self.run_command("dump")
+        pins = []
+
+        import re
+        pinregex = re.compile("^Node (0x\w\w+) \\[Pin Complex\\].*")
+        jackregex = re.compile("Pin Default.*\\[Jack\\]")
+        for s in dump:
+            g = pinregex.match(s)
+            if g:
+                currentpin = g.group(1)
+            elif jackregex.search(s):
+                pins.append(currentpin)
+        return pins
+
+    def run_jack_plug_test(self):
+        pins = self.find_jack_pins()
+        for pin in pins:
+            self.run_command("jack " + pin + " 1")
+        for pin in pins:
+            self.run_command("jack " + pin + " 0")
+
+    def run_set_kcontrol_test(self, c, values):
+        if len(c.values) < len(values):
+            values = values[:len(c.values)]
+        self.run_command("set " + c.numid + " " + " ".join(values))
+        c.add_info(self.run_command("get " + c.numid))
+        for a, b in zip(values, c.values):
+            if (int(a) != int(b)):
+                self.add_error("Tried to set " + c.name + " to " + str([int(x) for x in values]) + ", but got " + str(c.values) + " instead", "Error")
+
+    def run_kcontrol_test(self):
+        import re
+        minmax_regex = re.compile("MIN/MAX: (\d+)/(\d+),\s+VAL:(( \\[\d+\\])+)")
+        val_regex = re.compile(" \\[(\d+)\\]")
+
+        controls = self.run_command("list")
+        for control in controls:
+            c = ControlInfo(self, control)
+            c.add_info(self.run_command("get " + c.numid))
+            if "minval" in c.__dict__:
+                minval = c.minval
+                maxval = c.maxval
+                # Set to: 1) min, max 2) max, min 3) min, min 4) max, max
+                self.run_set_kcontrol_test(c, [minval, maxval])
+                self.run_set_kcontrol_test(c, [maxval, minval])
+                self.run_set_kcontrol_test(c, [minval, minval])
+                self.run_set_kcontrol_test(c, [maxval, maxval])
 
     def run_standard(self):
         self.start_process()
         self.run_command() # Initial parsing
         self.run_command("pm") # S3 test
+        self.run_jack_plug_test()
+        self.run_kcontrol_test()
         self.stop_process()
 
diff --git a/tester/summary.py b/tester/summary.py
new file mode 100755
index 0000000..cd66df7
--- /dev/null
+++ b/tester/summary.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+# hda-emu-tester - a test framework around hda-emu
+#
+# Written by David Henningsson <david.henningsson@canonical.com>
+#
+#    Copyright 2012 Canonical Ltd.
+#
+#    This program is free software: you can redistribute it and/or modify it 
+#    under the terms of the GNU General Public License version 3, as published 
+#    by the Free Software Foundation.
+#
+#    This program is distributed in the hope that it will be useful, but 
+#    WITHOUT ANY WARRANTY; without even the implied warranties of 
+#    MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+#    PURPOSE.  See the GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License along 
+#    with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+def main():
+    import os
+    import os.path
+    import runner
+
+    os.chdir(os.path.dirname(os.path.realpath(__file__)))
+    directory = "../codecs/canonical/"
+    files = os.listdir(directory)
+
+    successes = 0
+    fails = 0
+    warnings = 0
+    errors = 0
+    for f in files:
+        try:
+            r = runner.HdaEmuRunner()
+            r.set_alsa_info_file(os.path.join(directory, f))
+            r.run_standard()
+            if r.errors > 0 or r.warnings > 0:
+                fails += 1
+                errors += r.errors
+                warnings += r.warnings
+            else:
+                successes += 1
+        except:
+            errors += 1
+            fails += 1
+
+    print "Test run of %d machines: %d failing with %d errors and %d warnings." % (successes + fails, fails, errors, warnings)
+
+if __name__ == "__main__":
+    main()
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir
  2012-08-14  9:55 [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir David Henningsson
  2012-08-14  9:55 ` [PATCH 2/2] hda-emu: Add more functionality to test suite David Henningsson
@ 2012-08-14 10:28 ` Takashi Iwai
  1 sibling, 0 replies; 3+ messages in thread
From: Takashi Iwai @ 2012-08-14 10:28 UTC (permalink / raw)
  To: David Henningsson; +Cc: alsa-devel

At Tue, 14 Aug 2012 11:55:43 +0200,
David Henningsson wrote:
> 
> Previously, adding a path that was relative could fail because
> the symlinks created were broken.
> 
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>

Thanks, applied both patches.


Takashi

> ---
>  configure.ac |    2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/configure.ac b/configure.ac
> index 315e759..18118f3 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -51,6 +51,8 @@ AC_ARG_WITH(hdadir,
>      [path where HD-audio kernel files are stored]),
>    hdadir="$withval", hdadir="")
>  
> +hdadir="$( cd "$hdadir" && pwd )"
> +
>  if test -n "$hdadir"; then
>  
>  test -d "$hdadir" || \
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-08-14  9:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-14  9:55 [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir David Henningsson
2012-08-14  9:55 ` [PATCH 2/2] hda-emu: Add more functionality to test suite David Henningsson
2012-08-14 10:28 ` [PATCH 1/2] hda-emu: configure.ac: Allow relative paths in hdadir Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).