[PATCH v4 3/3] iotests: modify test 040 to use JobRunner

John Snow posted 3 patches 5 years, 8 months ago
Maintainers: Cleber Rosa <crosa@redhat.com>, Kevin Wolf <kwolf@redhat.com>, Max Reitz <mreitz@redhat.com>, Eduardo Habkost <ehabkost@redhat.com>
[PATCH v4 3/3] iotests: modify test 040 to use JobRunner
Posted by John Snow 5 years, 8 months ago
Instead of having somewhat reproduced it for itself.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/qemu-iotests/040 | 51 +++++++++++++++++++++---------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index 90b59081ff..e2ef3bb812 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -483,34 +483,33 @@ class TestErrorHandling(iotests.QMPTestCase):
                           file=('top-dbg' if top_debug else 'top-file'),
                           backing='mid-fmt')
 
+
+    class TestJobRunner(iotests.JobRunner):
+        expected_events = ('BLOCK_JOB_COMPLETED',
+                           'BLOCK_JOB_ERROR',
+                           'BLOCK_JOB_READY')
+
+        def __init__(self, *args, test, **kwargs):
+            super().__init__(*args, **kwargs)
+            self.log = []
+            self.test = test
+
+        def on_pause(self, event):
+            super().on_pause(event)
+            result = self._vm.qmp('block-job-resume', device=self._id)
+            self.test.assert_qmp(result, 'return', {})
+
+        def on_block_job_event(self, event):
+            if event['event'] not in self.expected_events:
+                self.test.fail("Unexpected event: %s" % event)
+            super().on_block_job_event(event)
+            self.log.append(event)
+
     def run_job(self, expected_events, error_pauses_job=False):
-        match_device = {'data': {'device': 'job0'}}
-        events = {
-            'BLOCK_JOB_COMPLETED': match_device,
-            'BLOCK_JOB_CANCELLED': match_device,
-            'BLOCK_JOB_ERROR': match_device,
-            'BLOCK_JOB_READY': match_device,
-        }
-
-        completed = False
-        log = []
-        while not completed:
-            ev = self.vm.events_wait(events, timeout=5.0)
-            if ev['event'] == 'BLOCK_JOB_COMPLETED':
-                completed = True
-            elif ev['event'] == 'BLOCK_JOB_ERROR':
-                if error_pauses_job:
-                    result = self.vm.qmp('block-job-resume', device='job0')
-                    self.assert_qmp(result, 'return', {})
-            elif ev['event'] == 'BLOCK_JOB_READY':
-                result = self.vm.qmp('block-job-complete', device='job0')
-                self.assert_qmp(result, 'return', {})
-            else:
-                self.fail("Unexpected event: %s" % ev)
-            log.append(iotests.filter_qmp_event(ev))
-
+        job = self.TestJobRunner(self.vm, 'job0', test=self)
+        job.run()
         self.maxDiff = None
-        self.assertEqual(expected_events, log)
+        self.assertEqual(expected_events, job.log)
 
     def event_error(self, op, action):
         return {
-- 
2.21.1


Re: [PATCH v4 3/3] iotests: modify test 040 to use JobRunner
Posted by Kevin Wolf 5 years, 8 months ago
Am 14.05.2020 um 04:25 hat John Snow geschrieben:
> Instead of having somewhat reproduced it for itself.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

I think you should pass auto_dismiss=True to the JobRunner, or (probably
preferable) change prepare_and_start_job() to start the job with
auto_dismiss=False.

Kevin


Re: [PATCH v4 3/3] iotests: modify test 040 to use JobRunner
Posted by John Snow 5 years, 8 months ago

On 5/14/20 11:53 AM, Kevin Wolf wrote:
> Am 14.05.2020 um 04:25 hat John Snow geschrieben:
>> Instead of having somewhat reproduced it for itself.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
> 
> I think you should pass auto_dismiss=True to the JobRunner, or (probably
> preferable) change prepare_and_start_job() to start the job with
> auto_dismiss=False.
> 
> Kevin
> 

okay, I'll try that out and see if I like it.


Wild tangents, as is my normal:

I also think it would be neat, in some sense, to provide a job creation
abstraction where creating the QMP command in python also creates the
runner with the right parameters based on how you initialized it.

I've not given these even a proper three minutes think, but some
generalized interface for managing the creation of jobs to use in
concert with the job runner would be slick.

(What reminds me of this is needing to remember and understand if I
started something with auto_dismiss or not, which jobs it defaults to
which for, etc. Streamlining the creation and runner could be slick for
faster test-writing in normative cases.)


Re: [PATCH v4 3/3] iotests: modify test 040 to use JobRunner
Posted by Kevin Wolf 5 years, 8 months ago
Am 14.05.2020 um 21:37 hat John Snow geschrieben:
> 
> 
> On 5/14/20 11:53 AM, Kevin Wolf wrote:
> > Am 14.05.2020 um 04:25 hat John Snow geschrieben:
> >> Instead of having somewhat reproduced it for itself.
> >>
> >> Signed-off-by: John Snow <jsnow@redhat.com>
> > 
> > I think you should pass auto_dismiss=True to the JobRunner, or (probably
> > preferable) change prepare_and_start_job() to start the job with
> > auto_dismiss=False.
> > 
> > Kevin
> > 
> 
> okay, I'll try that out and see if I like it.
> 
> 
> Wild tangents, as is my normal:
> 
> I also think it would be neat, in some sense, to provide a job creation
> abstraction where creating the QMP command in python also creates the
> runner with the right parameters based on how you initialized it.
> 
> I've not given these even a proper three minutes think, but some
> generalized interface for managing the creation of jobs to use in
> concert with the job runner would be slick.

JobRunner could have a static method that starts a job (it would take
the same options as qmp() and forward everything to qmp(), except that
it parses auto_* first) and returns a JobRunner object that you can run
later.

> (What reminds me of this is needing to remember and understand if I
> started something with auto_dismiss or not, which jobs it defaults to
> which for, etc. Streamlining the creation and runner could be slick for
> faster test-writing in normative cases.)

Yes.

In general, I think we should keep tests simple (even if that means some
duplication) and avoid overengineering testing infrastructure because we
could well sink more time there than we'll ever get back, but I guess
small and simple wrappers like in this case can't hurt.

Kevin