Re: [Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-09-15 Thread Sascha Silbe
Dear Eric,

Eric Blake  writes:

> arglist = (all other parameters)
> if self.device_name:
> arglist.append(id=self.device_name)
> else:
> arglist.append(device='drive0')
> invoke(self.vm.qmp, arglist)

That would be:

qmp_args = {'cmd': 'blockdev-change-medium', 'filename': new_img,
'format': iotests.imgfmt}
if self.device_name is not None:
qmp_args['id'] = self.device_name
else:
qmp_args['device'] = 'drive0'
result = self.vm.qmp(**qmp_args)

Or:

qmp_args = {'filename': new_img, 'format': iotests.imgfmt}
if self.device_name is not None:
qmp_args['id'] = self.device_name
else:
qmp_args['device'] = 'drive0'
result = self.vm.qmp('blockdev-change-medium', **qmp_args)


FWIW these days I tend to use Python magics (like *args / **kwargs) only
if there's a _significant_ improvement in either functionality or
readability; especially for code bases that are being worked on by
developers who don't speak Python "natively". Using magics sparingly
also makes it easier for static analysis tools like pylint.

Sascha
-- 
Softwareentwicklung Sascha Silbe, Niederhofenstraße 5/1, 71229 Leonberg
https://se-silbe.de/
USt-IdNr. DE281696641




Re: [Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-09-15 Thread Eric Blake
On 09/15/2016 11:28 AM, Sascha Silbe wrote:
> Dear Eric,
> 
> Sascha Silbe  writes:
> 
>> result = self.vm.qmp('blockdev-change-medium',
>>  id=self.device_name or 'drive0', 
>> filename=new_img,
>>  format=iotests.imgfmt)
> 
> Sorry, my eyes deceived me. I thought the original code was setting the
> "id" parameter in both cases. QEMUMachine.qmp() and
> QEMUMonitorProtocol.cmd() together translate the keyword arguments
> directly into QMP arguments, so passing None is different from not
> passing anything at all. The if/else is probably the best approach in
> that case; everything else I can think of would just be more
> complicated.

If there were some way to do:

arglist = (all other parameters)
if self.device_name:
arglist.append(id=self.device_name)
else:
arglist.append(device='drive0')
invoke(self.vm.qmp, arglist)

that might be a little cleaner (no repetition on all the other
parameters); but I don't know enough python to know if there is some
sort of invoke() mechanism for pairing a method object and an arbitrary
list as though it were a normal method call (I suspect there is, and I
just don't know it).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-09-15 Thread Sascha Silbe
Dear Eric,

Sascha Silbe  writes:

> result = self.vm.qmp('blockdev-change-medium',
>  id=self.device_name or 'drive0', 
> filename=new_img,
>  format=iotests.imgfmt)

Sorry, my eyes deceived me. I thought the original code was setting the
"id" parameter in both cases. QEMUMachine.qmp() and
QEMUMonitorProtocol.cmd() together translate the keyword arguments
directly into QMP arguments, so passing None is different from not
passing anything at all. The if/else is probably the best approach in
that case; everything else I can think of would just be more
complicated.

Sascha
-- 
Softwareentwicklung Sascha Silbe, Niederhofenstraße 5/1, 71229 Leonberg
https://se-silbe.de/
USt-IdNr. DE281696641




Re: [Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-09-15 Thread Eric Blake
On 09/15/2016 11:16 AM, Sascha Silbe wrote:

>>> +if self.device_name is not None:
>>> +result = self.vm.qmp('blockdev-change-medium',
>>> + id=self.device_name, filename=new_img,
>>> + format=iotests.imgfmt)
>>> +else:
>>> +result = self.vm.qmp('blockdev-change-medium',
>>> + device='drive0', filename=new_img,
>>> + format=iotests.imgfmt)
>>
>> I'm not enough of a python guru to know if there is any way to compress
>> this to a shorter format (I do know, however, that the lack of an
>> obvious ?: operator in python can indeed result in verbose if/else
>> clauses compared to other languages).
> 
> Actually there is a direct equivalent of "?:" (which unfortunately isn't
> in C11) in Python: "or". So you can use:
> 
> result = self.vm.qmp('blockdev-change-medium',
>  id=self.device_name or 'drive0', 
> filename=new_img,

Not what we want.  We want to use a different parameter, based on the
overall condition (so it is NOT as simple as a conditional assignment to
the 'id' parameter, but an actual swap between whether we have the 'id'
or the 'device' parameter).  It's not obvious whether:

result = foo(id=self.device_name,
 device='drive0' if not self.device_name else None)

would have the same semantics as:

if self.device_name:
result = foo(id=self.device_name)
else
result = foo(device='drive0')

and even if it does have the same semantics, it's not obvious if there's
a shorter way to write it.  So we end up with verbose duplication of all
the remaining parameters.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-09-15 Thread Sascha Silbe
Dear Eric,

(replying only to the Python coding part, haven't looked at the patch
itself)

Eric Blake  writes:

> On 08/19/2016 11:50 AM, Kevin Wolf wrote:
>> @@ -76,9 +79,15 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
>>  self.assert_qmp(result, 'return[0]/inserted/image/filename', 
>> new_img)
>>  
>>  def test_blockdev_change_medium(self):
>> -result = self.vm.qmp('blockdev-change-medium', device='drive0',
>> -   filename=new_img,
>> -   
>> format=iotests.imgfmt)
>> +if self.device_name is not None:
>> +result = self.vm.qmp('blockdev-change-medium',
>> + id=self.device_name, filename=new_img,
>> + format=iotests.imgfmt)
>> +else:
>> +result = self.vm.qmp('blockdev-change-medium',
>> + device='drive0', filename=new_img,
>> + format=iotests.imgfmt)
>
> I'm not enough of a python guru to know if there is any way to compress
> this to a shorter format (I do know, however, that the lack of an
> obvious ?: operator in python can indeed result in verbose if/else
> clauses compared to other languages).

Actually there is a direct equivalent of "?:" (which unfortunately isn't
in C11) in Python: "or". So you can use:

result = self.vm.qmp('blockdev-change-medium',
 id=self.device_name or 'drive0', filename=new_img,
 format=iotests.imgfmt)

Sascha
-- 
Softwareentwicklung Sascha Silbe, Niederhofenstraße 5/1, 71229 Leonberg
https://se-silbe.de/
USt-IdNr. DE281696641




Re: [Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-09-15 Thread Kevin Wolf
Am 15.09.2016 um 00:13 hat Eric Blake geschrieben:
> On 08/19/2016 11:50 AM, Kevin Wolf wrote:
> > We just added the option to use qdev device names in all device related
> > block QMP commands. This patch converts some of the test cases in 118 to
> > use qdev device names instead of BlockBackend names to cover the new
> > way. It converts cases for each of the media change commands, but only
> > for CD-ROM and not everywhere, so that the old way is still tested, too.
> > 
> > Signed-off-by: Kevin Wolf 
> > ---
> >  tests/qemu-iotests/118| 85 
> > ++-
> >  tests/qemu-iotests/iotests.py |  5 +++
> >  2 files changed, 73 insertions(+), 17 deletions(-)
> > 
> 
> > @@ -76,9 +79,15 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
> >  self.assert_qmp(result, 'return[0]/inserted/image/filename', 
> > new_img)
> >  
> >  def test_blockdev_change_medium(self):
> > -result = self.vm.qmp('blockdev-change-medium', device='drive0',
> > -   filename=new_img,
> > -   
> > format=iotests.imgfmt)
> > +if self.device_name is not None:
> > +result = self.vm.qmp('blockdev-change-medium',
> > + id=self.device_name, filename=new_img,
> > + format=iotests.imgfmt)
> > +else:
> > +result = self.vm.qmp('blockdev-change-medium',
> > + device='drive0', filename=new_img,
> > + format=iotests.imgfmt)
> 
> I'm not enough of a python guru to know if there is any way to compress
> this to a shorter format (I do know, however, that the lack of an
> obvious ?: operator in python can indeed result in verbose if/else
> clauses compared to other languages).

Not a Python guru either, but it does have an equivalent for the ?:
operator, just with a weird syntax:

 if  else 

However, I'm not sure if that would be applicable here. It depends on
whether not passing an option at all and passing None does the same
thing, or if None sends something like an empty object or JSON null.

> At any rate, the ultimate test is whether the change still passes; and
> looks like you have good coverage of using exactly one or the other
> argument.  Do you also want to add tests (either here, or in 11/10) that
> validate that providing neither 'device' nor 'id' gives a sane error,
> likewise that providing both has sane behavior?  (For now, our behavior
> is that we fail, although it could also be argued that sane behavior
> would validate that 'id' happens to be currently in use by 'device' and
> only fail if they are not pointing to the same backend).

I think failure is right. If you're using the new interface, you should
be using the new interface only.

Anyway, adding tests for this probably makes sense, I'll have a look.

Kevin


pgpITYGaXaWoN.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-09-14 Thread Eric Blake
On 08/19/2016 11:50 AM, Kevin Wolf wrote:
> We just added the option to use qdev device names in all device related
> block QMP commands. This patch converts some of the test cases in 118 to
> use qdev device names instead of BlockBackend names to cover the new
> way. It converts cases for each of the media change commands, but only
> for CD-ROM and not everywhere, so that the old way is still tested, too.
> 
> Signed-off-by: Kevin Wolf 
> ---
>  tests/qemu-iotests/118| 85 
> ++-
>  tests/qemu-iotests/iotests.py |  5 +++
>  2 files changed, 73 insertions(+), 17 deletions(-)
> 

> @@ -76,9 +79,15 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
>  self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
>  
>  def test_blockdev_change_medium(self):
> -result = self.vm.qmp('blockdev-change-medium', device='drive0',
> -   filename=new_img,
> -   format=iotests.imgfmt)
> +if self.device_name is not None:
> +result = self.vm.qmp('blockdev-change-medium',
> + id=self.device_name, filename=new_img,
> + format=iotests.imgfmt)
> +else:
> +result = self.vm.qmp('blockdev-change-medium',
> + device='drive0', filename=new_img,
> + format=iotests.imgfmt)

I'm not enough of a python guru to know if there is any way to compress
this to a shorter format (I do know, however, that the lack of an
obvious ?: operator in python can indeed result in verbose if/else
clauses compared to other languages).

At any rate, the ultimate test is whether the change still passes; and
looks like you have good coverage of using exactly one or the other
argument.  Do you also want to add tests (either here, or in 11/10) that
validate that providing neither 'device' nor 'id' gives a sane error,
likewise that providing both has sane behavior?  (For now, our behavior
is that we fail, although it could also be argued that sane behavior
would validate that 'id' happens to be currently in use by 'device' and
only fail if they are not pointing to the same backend).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH 10/10] qemu-iotests/118: Test media change with qdev name

2016-08-19 Thread Kevin Wolf
We just added the option to use qdev device names in all device related
block QMP commands. This patch converts some of the test cases in 118 to
use qdev device names instead of BlockBackend names to cover the new
way. It converts cases for each of the media change commands, but only
for CD-ROM and not everywhere, so that the old way is still tested, too.

Signed-off-by: Kevin Wolf 
---
 tests/qemu-iotests/118| 85 ++-
 tests/qemu-iotests/iotests.py |  5 +++
 2 files changed, 73 insertions(+), 17 deletions(-)

diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118
index 9e5951f..0380069 100755
--- a/tests/qemu-iotests/118
+++ b/tests/qemu-iotests/118
@@ -62,6 +62,9 @@ class ChangeBaseClass(iotests.QMPTestCase):
 self.fail('Timeout while waiting for the tray to close')
 
 class GeneralChangeTestsBaseClass(ChangeBaseClass):
+
+device_name = None
+
 def test_change(self):
 result = self.vm.qmp('change', device='drive0', target=new_img,
arg=iotests.imgfmt)
@@ -76,9 +79,15 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
 
 def test_blockdev_change_medium(self):
-result = self.vm.qmp('blockdev-change-medium', device='drive0',
-   filename=new_img,
-   format=iotests.imgfmt)
+if self.device_name is not None:
+result = self.vm.qmp('blockdev-change-medium',
+ id=self.device_name, filename=new_img,
+ format=iotests.imgfmt)
+else:
+result = self.vm.qmp('blockdev-change-medium',
+ device='drive0', filename=new_img,
+ format=iotests.imgfmt)
+
 self.assert_qmp(result, 'return', {})
 
 self.wait_for_open()
@@ -90,7 +99,10 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
 
 def test_eject(self):
-result = self.vm.qmp('eject', device='drive0', force=True)
+if self.device_name is not None:
+result = self.vm.qmp('eject', id=self.device_name, force=True)
+else:
+result = self.vm.qmp('eject', device='drive0', force=True)
 self.assert_qmp(result, 'return', {})
 
 self.wait_for_open()
@@ -101,7 +113,10 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 self.assert_qmp_absent(result, 'return[0]/inserted')
 
 def test_tray_eject_change(self):
-result = self.vm.qmp('eject', device='drive0', force=True)
+if self.device_name is not None:
+result = self.vm.qmp('eject', id=self.device_name, force=True)
+else:
+result = self.vm.qmp('eject', device='drive0', force=True)
 self.assert_qmp(result, 'return', {})
 
 self.wait_for_open()
@@ -111,9 +126,12 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 self.assert_qmp(result, 'return[0]/tray_open', True)
 self.assert_qmp_absent(result, 'return[0]/inserted')
 
-result = self.vm.qmp('blockdev-change-medium', device='drive0',
-   filename=new_img,
-   format=iotests.imgfmt)
+if self.device_name is not None:
+result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
+ filename=new_img, format=iotests.imgfmt)
+else:
+result = self.vm.qmp('blockdev-change-medium', device='drive0',
+ filename=new_img, format=iotests.imgfmt)
 self.assert_qmp(result, 'return', {})
 
 self.wait_for_close()
@@ -124,7 +142,12 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
 
 def test_tray_open_close(self):
-result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True)
+if self.device_name is not None:
+result = self.vm.qmp('blockdev-open-tray',
+ id=self.device_name, force=True)
+else:
+result = self.vm.qmp('blockdev-open-tray',
+ device='drive0', force=True)
 self.assert_qmp(result, 'return', {})
 
 self.wait_for_open()
@@ -137,7 +160,10 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 else:
 self.assert_qmp(result, 'return[0]/inserted/image/filename', 
old_img)
 
-result = self.vm.qmp('blockdev-close-tray', device='drive0')
+if self.device_name is not None:
+result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
+else:
+