diff mbox series

[RFC,v2,04/11] qemu-iotests: delay QMP socket timers

Message ID 20210407135021.48330-5-eesposit@redhat.com (mailing list archive)
State New, archived
Headers show
Series qemu_iotests: improve debugging options | expand

Commit Message

Emanuele Giuseppe Esposito April 7, 2021, 1:50 p.m. UTC
Attaching a gdbserver implies that the qmp socket
should wait indefinitely for an answer from QEMU.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 python/qemu/machine.py        |  4 +++-
 tests/qemu-iotests/iotests.py | 21 +++++++++++++++++----
 2 files changed, 20 insertions(+), 5 deletions(-)

Comments

Paolo Bonzini April 8, 2021, 3:40 p.m. UTC | #1
On 07/04/21 15:50, Emanuele Giuseppe Esposito wrote:
>       def get_qmp_events_filtered(self, wait=60.0):
>           result = []
> -        for ev in self.get_qmp_events(wait=wait):
> +        qmp_wait = wait
> +        if qemu_gdb:
> +            qmp_wait = 0.0
> +        for ev in self.get_qmp_events(wait=qmp_wait):
>               result.append(filter_qmp_event(ev))
>           return result

Should this be handled in get_qmp_events instead, since you're basically 
changing all the callers?

Paolo
Emanuele Giuseppe Esposito April 8, 2021, 4:06 p.m. UTC | #2
On 08/04/2021 17:40, Paolo Bonzini wrote:
> On 07/04/21 15:50, Emanuele Giuseppe Esposito wrote:
>>       def get_qmp_events_filtered(self, wait=60.0):
>>           result = []
>> -        for ev in self.get_qmp_events(wait=wait):
>> +        qmp_wait = wait
>> +        if qemu_gdb:
>> +            qmp_wait = 0.0
>> +        for ev in self.get_qmp_events(wait=qmp_wait):
>>               result.append(filter_qmp_event(ev))
>>           return result
> 
> Should this be handled in get_qmp_events instead, since you're basically 
> changing all the callers?

get_qmp_events is in python/machine.py, which as I understand might be 
used also by some other scripts, so I want to keep the changes there to 
the minimum. Also, machine.py has no access to qemu_gdb or 
qemu_valgrind, so passing a boolean or something to delay the timer 
would still require to add a similar check in all sections.

Or do you have a cleaner way to do this?

Emanuele
Paolo Bonzini April 8, 2021, 7:03 p.m. UTC | #3
Il gio 8 apr 2021, 18:06 Emanuele Giuseppe Esposito <eesposit@redhat.com>
ha scritto:

>
>
> On 08/04/2021 17:40, Paolo Bonzini wrote:
> > On 07/04/21 15:50, Emanuele Giuseppe Esposito wrote:
> >>       def get_qmp_events_filtered(self, wait=60.0):
> >>           result = []
> >> -        for ev in self.get_qmp_events(wait=wait):
> >> +        qmp_wait = wait
> >> +        if qemu_gdb:
> >> +            qmp_wait = 0.0
> >> +        for ev in self.get_qmp_events(wait=qmp_wait):
> >>               result.append(filter_qmp_event(ev))
> >>           return result
> >
> > Should this be handled in get_qmp_events instead, since you're basically
> > changing all the callers?
>
> get_qmp_events is in python/machine.py, which as I understand might be
> used also by some other scripts, so I want to keep the changes there to
> the minimum. Also, machine.py has no access to qemu_gdb or
> qemu_valgrind, so passing a boolean or something to delay the timer
> would still require to add a similar check in all sections.
>
> Or do you have a cleaner way to do this?
>

Maybe a subclass IotestsMachine?

Paolo


> Emanuele
>
>
Emanuele Giuseppe Esposito April 9, 2021, 4:13 p.m. UTC | #4
On 08/04/2021 21:03, Paolo Bonzini wrote:
> 
> 
> Il gio 8 apr 2021, 18:06 Emanuele Giuseppe Esposito <eesposit@redhat.com 
> <mailto:eesposit@redhat.com>> ha scritto:
> 
> 
> 
>     On 08/04/2021 17:40, Paolo Bonzini wrote:
>      > On 07/04/21 15:50, Emanuele Giuseppe Esposito wrote:
>      >>       def get_qmp_events_filtered(self, wait=60.0):
>      >>           result = []
>      >> -        for ev in self.get_qmp_events(wait=wait):
>      >> +        qmp_wait = wait
>      >> +        if qemu_gdb:
>      >> +            qmp_wait = 0.0
>      >> +        for ev in self.get_qmp_events(wait=qmp_wait):
>      >>               result.append(filter_qmp_event(ev))
>      >>           return result
>      >
>      > Should this be handled in get_qmp_events instead, since you're
>     basically
>      > changing all the callers?
> 
>     get_qmp_events is in python/machine.py, which as I understand might be
>     used also by some other scripts, so I want to keep the changes there to
>     the minimum. Also, machine.py has no access to qemu_gdb or
>     qemu_valgrind, so passing a boolean or something to delay the timer
>     would still require to add a similar check in all sections.
> 
>     Or do you have a cleaner way to do this?
> 
> 
> Maybe a subclass IotestsMachine?
> 

I actually figured that I could override get_qmp_events and put the 
check there. Something like (simplified):

class VM(qtest.QEMUQtestMachine):

	...

	def get_qmp_events(self, wait)
		if qemu_gdb or qemu_valgrind:
			wait = 0.0
		return super().get_qmp_events(wait)

Emanuele
diff mbox series

Patch

diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 18d32ebe45..284b73385f 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -408,7 +408,9 @@  def _launch(self) -> None:
                                        stderr=subprocess.STDOUT,
                                        shell=False,
                                        close_fds=False)
-        self._post_launch()
+
+        timer = None if 'gdbserver' in self._wrapper else 15.0
+        self._post_launch(timer)
 
     def _early_cleanup(self) -> None:
         """
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 05d0dc0751..17f07710db 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -686,7 +686,10 @@  def qmp_to_opts(self, obj):
 
     def get_qmp_events_filtered(self, wait=60.0):
         result = []
-        for ev in self.get_qmp_events(wait=wait):
+        qmp_wait = wait
+        if qemu_gdb:
+            qmp_wait = 0.0
+        for ev in self.get_qmp_events(wait=qmp_wait):
             result.append(filter_qmp_event(ev))
         return result
 
@@ -987,13 +990,17 @@  def cancel_and_wait(self, drive='drive0', force=False,
         result = self.vm.qmp('block-job-cancel', device=drive, force=force)
         self.assert_qmp(result, 'return', {})
 
+        qmp_wait = wait
+        if qemu_gdb:
+            qmp_wait = 0.0
+
         if resume:
             self.vm.resume_drive(drive)
 
         cancelled = False
         result = None
         while not cancelled:
-            for event in self.vm.get_qmp_events(wait=wait):
+            for event in self.vm.get_qmp_events(wait=qmp_wait):
                 if event['event'] == 'BLOCK_JOB_COMPLETED' or \
                    event['event'] == 'BLOCK_JOB_CANCELLED':
                     self.assert_qmp(event, 'data/device', drive)
@@ -1009,8 +1016,11 @@  def cancel_and_wait(self, drive='drive0', force=False,
     def wait_until_completed(self, drive='drive0', check_offset=True,
                              wait=60.0, error=None):
         '''Wait for a block job to finish, returning the event'''
+        qmp_wait = wait
+        if qemu_gdb:
+            qmp_wait = 0.0
         while True:
-            for event in self.vm.get_qmp_events(wait=wait):
+            for event in self.vm.get_qmp_events(wait=qmp_wait):
                 if event['event'] == 'BLOCK_JOB_COMPLETED':
                     self.assert_qmp(event, 'data/device', drive)
                     if error is None:
@@ -1054,7 +1064,10 @@  def complete_and_wait(self, drive='drive0', wait_ready=True,
         self.assertTrue(event['data']['type'] in ['mirror', 'commit'])
 
     def pause_wait(self, job_id='job0'):
-        with Timeout(3, "Timeout waiting for job to pause"):
+        def_timeout = 3
+        if qemu_gdb:
+            def_timeout = 3000
+        with Timeout(def_timeout, "Timeout waiting for job to pause"):
             while True:
                 result = self.vm.qmp('query-block-jobs')
                 found = False