diff mbox

[RFC,2/4] support/testing: allow to use extra large timeouts

Message ID 20170730044946.11999-2-ricardo.martincoski@gmail.com
State Changes Requested
Headers show

Commit Message

Ricardo Martincoski July 30, 2017, 4:49 a.m. UTC
Add a parameter to run-tests to act as a multiplier for all timeouts of
emulator.
It can be used to avoid sporadic failures on slow host machines as well
in elastic runners on the cloud.

Cc: Arnout Vandecappelle <arnout@mind.be>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com>
---
See also
http://lists.busybox.net/pipermail/buildroot/2017-July/199329.html
---
 support/testing/infra/basetest.py |  4 +++-
 support/testing/infra/emulator.py | 13 ++++++++++---
 support/testing/run-tests         |  9 +++++++++
 3 files changed, 22 insertions(+), 4 deletions(-)

Comments

Thomas Petazzoni July 31, 2017, 7:25 p.m. UTC | #1
Hello,

On Sun, 30 Jul 2017 01:49:44 -0300, Ricardo Martincoski wrote:

> diff --git a/support/testing/run-tests b/support/testing/run-tests
> index 0cb673c61f..33ac60d6b2 100755
> --- a/support/testing/run-tests
> +++ b/support/testing/run-tests
> @@ -28,6 +28,8 @@ def main():
>                          help='number of testcases to run simultaneously')
>      parser.add_argument('-j', '--jlevel', type=int,
>                          help='BR2_JLEVEL to use for each testcase')
> +    parser.add_argument('-e', '--elastic-timeout', type=int, default=1,
> +                        help='increase timeouts (useful for slow machines)')

I find the choice of the "elastic timeout" a bit weird. To me, it feels
like a timeout that will reduce and extend like an elastic, not a
timeout multiplier.

Perhaps we should call this --timeout-multiplier or something like
that ?

Thomas
Ricardo Martincoski July 31, 2017, 11:27 p.m. UTC | #2
Hello,

On Mon, Jul 31, 2017 at 04:25 PM, Thomas Petazzoni wrote:

> On Sun, 30 Jul 2017 01:49:44 -0300, Ricardo Martincoski wrote:
[snip]
>> +    parser.add_argument('-e', '--elastic-timeout', type=int, default=1,
>> +                        help='increase timeouts (useful for slow machines)')
> 
> I find the choice of the "elastic timeout" a bit weird. To me, it feels
> like a timeout that will reduce and extend like an elastic, not a
> timeout multiplier.
> 
> Perhaps we should call this --timeout-multiplier or something like
> that ?

Sure. I will fix and resend.
I will use -m as short name because -t is already in use.

Regards,
Ricardo
Thomas Petazzoni Aug. 1, 2017, 6:01 a.m. UTC | #3
Hello,

On Mon, 31 Jul 2017 20:27:59 -0300, Ricardo Martincoski wrote:

> > Perhaps we should call this --timeout-multiplier or something like
> > that ?  
> 
> Sure. I will fix and resend.
> I will use -m as short name because -t is already in use.

Or perhaps this option is "specialized" enough that it doesn't need a
short name, so that we avoid "polluting" the namespace of short names,
which as you've seen, already has some collisions :)

Best regards,

Thomas
diff mbox

Patch

diff --git a/support/testing/infra/basetest.py b/support/testing/infra/basetest.py
index 431605b23f..1ef76a988b 100644
--- a/support/testing/infra/basetest.py
+++ b/support/testing/infra/basetest.py
@@ -35,6 +35,7 @@  class BRTest(unittest.TestCase):
     logtofile = True
     keepbuilds = False
     jlevel = 0
+    elastic_timeout = 1
 
     def __init__(self, names):
         super(BRTest, self).__init__(names)
@@ -60,7 +61,8 @@  class BRTest(unittest.TestCase):
             self.b.build()
             self.show_msg("Building done")
 
-        self.emulator = Emulator(self.builddir, self.downloaddir, self.logtofile)
+        self.emulator = Emulator(self.builddir, self.downloaddir,
+                                 self.logtofile, self.elastic_timeout)
 
     def tearDown(self):
         self.show_msg("Cleaning up")
diff --git a/support/testing/infra/emulator.py b/support/testing/infra/emulator.py
index 9b079cbf23..7f02a01553 100644
--- a/support/testing/infra/emulator.py
+++ b/support/testing/infra/emulator.py
@@ -5,10 +5,14 @@  import infra
 
 class Emulator(object):
 
-    def __init__(self, builddir, downloaddir, logtofile):
+    def __init__(self, builddir, downloaddir, logtofile, multiplier):
         self.qemu = None
         self.downloaddir = downloaddir
         self.logfile = infra.open_log_file(builddir, "run", logtofile)
+        # We use elastic runners on the cloud to runs our tests. Those runners
+        # can take a long time to run the emulator. Use a timeout multiplier
+        # when running the tests to avoid sporadic failures.
+        self.multiplier = multiplier
 
     # Start Qemu to boot the system
     #
@@ -65,7 +69,8 @@  class Emulator(object):
             qemu_cmd += ["-append", " ".join(kernel_cmdline)]
 
         self.logfile.write("> starting qemu with '%s'\n" % " ".join(qemu_cmd))
-        self.qemu = pexpect.spawn(qemu_cmd[0], qemu_cmd[1:], timeout=5)
+        self.qemu = pexpect.spawn(qemu_cmd[0], qemu_cmd[1:],
+                                  timeout=5 * self.multiplier)
         # We want only stdout into the log to avoid double echo
         self.qemu.logfile_read = self.logfile
 
@@ -75,7 +80,7 @@  class Emulator(object):
         # The login prompt can take some time to appear when running multiple
         # instances in parallel, so set the timeout to a large value
         index = self.qemu.expect(["buildroot login:", pexpect.TIMEOUT],
-                                 timeout=60)
+                                 timeout=60 * self.multiplier)
         if index != 0:
             self.logfile.write("==> System does not boot")
             raise SystemError("System does not boot")
@@ -93,6 +98,8 @@  class Emulator(object):
     # return a tuple (output, exit_code)
     def run(self, cmd, timeout=-1):
         self.qemu.sendline(cmd)
+        if timeout != -1:
+            timeout *= self.multiplier
         self.qemu.expect("# ", timeout=timeout)
         # Remove double carriage return from qemu stdout so str.splitlines()
         # works as expected.
diff --git a/support/testing/run-tests b/support/testing/run-tests
index 0cb673c61f..33ac60d6b2 100755
--- a/support/testing/run-tests
+++ b/support/testing/run-tests
@@ -28,6 +28,8 @@  def main():
                         help='number of testcases to run simultaneously')
     parser.add_argument('-j', '--jlevel', type=int,
                         help='BR2_JLEVEL to use for each testcase')
+    parser.add_argument('-e', '--elastic-timeout', type=int, default=1,
+                        help='increase timeouts (useful for slow machines)')
 
     args = parser.parse_args()
 
@@ -97,6 +99,13 @@  def main():
         # the user can override the auto calculated value
         BRTest.jlevel = args.jlevel
 
+    if args.elastic_timeout < 1:
+        print "Invalid multiplier for timeout values"
+        print ""
+        parser.print_help()
+        return 1
+    BRTest.elastic_timeout = args.elastic_timeout
+
     nose2_args = ["-v",
                   "-N", str(args.testcases),
                   "-s", "support/testing",