On 9/13/19 8:47 AM, Max Reitz wrote:
> On 20.08.19 23:32, John Snow wrote:
>>
>>
>> On 8/19/19 4:18 PM, Max Reitz wrote:
>>> null-aio may not be whitelisted.  Skip all test cases that require it.
>>>
>>> Signed-off-by: Max Reitz <mre...@redhat.com>
>>> ---
>>>  tests/qemu-iotests/093 | 12 +++++++++---
>>>  1 file changed, 9 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
>>> index 50c1e7f2ec..f03fa24a07 100755
>>> --- a/tests/qemu-iotests/093
>>> +++ b/tests/qemu-iotests/093
>>> @@ -24,7 +24,7 @@ import iotests
>>>  nsec_per_sec = 1000000000
>>>  
>>>  class ThrottleTestCase(iotests.QMPTestCase):
>>> -    test_img = "null-aio://"
>>> +    test_driver = "null-aio"
>>>      max_drives = 3
>>>  
>>>      def blockstats(self, device):
>>> @@ -35,10 +35,14 @@ class ThrottleTestCase(iotests.QMPTestCase):
>>>                  return stat['rd_bytes'], stat['rd_operations'], 
>>> stat['wr_bytes'], stat['wr_operations']
>>>          raise Exception("Device not found for blockstats: %s" % device)
>>>  
>>> +    def required_drivers(self):
>>> +        return [self.test_driver]
>>> +
>>> +    @iotests.skip_if_unsupported(required_drivers)
>>
>> Oh, I see why you're passing args[0] back to the callback now. Why not
>> just pass self.required_drivers and call it with no arguments instead?
>>
>> You can get a bound version that way that doesn't need additional
>> arguments, and then the callback is free to take generic callables of
>> any kind.
> 
> Am I doing something wrong?
> 
> I just get
> 
> +Traceback (most recent call last):
> +  File "093", line 26, in <module>
> +    class ThrottleTestCase(iotests.QMPTestCase):
> +  File "093", line 41, in ThrottleTestCase
> +    @iotests.skip_if_unsupported(self.required_drivers)
> +NameError: name 'self' is not defined
> 
> this way.
> 
> Max
> 
What was I even talking about? :\ Well.

I'd still like to define func_wrapper with a nod to the type constraint
it has:

def func_wrapper(instance: iotests.QMPTestCase, *args, **kwargs):
    [...]


Then, you'd write:

if callable(required_formats):
    fmts = required_formats(instance)
else:
    fmts = required_formats


And:

> +    def required_drivers(self):
> +        return [self.test_driver]
> +
> +    @iotests.skip_if_unsupported(required_drivers)
>      def setUp(self):

The problem is that 'self' isn't defined at the class level, so I was
mistaken about being able to use it :( Python does not have a notion of
a lexical constant to refer to the class being defined; and of course we
do not have an instance variable at definition time.

Sorry for the wild goose chase.

It's fine as-is.

(I wanted a way to define the required_formats callback without forcing
it to be a class method, but the decorator code runs at definition time
and we just don't HAVE the instance; so the way you wrote it is I think
the only way it CAN be written without some much nastier trickery.)

Reply via email to