[Avocado-devel] miniRFC: Call `tearDown` after `setUp` failure

Lukáš Doktor ldoktor at redhat.com
Wed Mar 22 18:05:48 UTC 2017


Hello guys,

I remember early in development we decided to abort the execution when 
`setUp` fails without executing `tearDown`, but over the time I keep 
thinking about it and I don't think it's optimal. My main reason is to 
simplify `setUp` code, let me demonstrate it on an example.

Currently when you (safely) want to get a few remote servers, nfs share 
and local service, you have to:

     class MyTest(test):
         def setUp(self):
             self.nfs_share = None
             self.remote_servers = []
             self.service = None
             try:
                 for addr in self.params.get("remote_servers"):
                     self.remote_servers.append(login(addr))
                 self.nfs_share = get_nfs_share()
                 self.service = get_service()
             except:
                 for server in self.remote_servers:
                     server.close()
                 if self.nfs_share:
                     self.nfs_share.close()
                 if self.service:
                     self.service.stop()
                 raise

         def tearDown(self):
             if self.nfs_share:
                 self.nfs_share.close()
             for server in self.remote_servers:
                 server.close()
             if self.service:
                 self.service.stop()


But if the tearDown was also executed, you'd simply write:

     class MyTest(test):
         def setUp(self):
             self.nfs_share = None
             self.remote_servers = []
             self.service = None

             for addr in self.params.get("remote_servers"):
                 self.remote_servers.append(login(addr))
             self.nfs_share = get_nfs_share()
             self.service = get_service()

         def tearDown(self):
             if self.nfs_share:
                 self.nfs_share.close()
             for server in self.remote_servers:
                 server.close()
             if self.service:
                 self.service.stop()

As you can see the current solution requires catching exceptions and 
basically writing the tearDown twice. Yes, properly written tearDown 
could be manually executed from the `setUp`, but that looks a bit odd 
and my experience is that people usually just write:

     class MyTest(test):
         def setUp(self):
             self.remote_servers = []
             for addr in self.params.get("remote_servers"):
                 self.remote_servers.append(login(addr))
             self.nfs_share = get_nfs_share()
             self.service = get_service()

         def tearDown(self):
             self.nfs_share.close()
             for server in self.remote_servers:
                 server.close()
             self.service.stop()

which usually works but when the `get_nfs_share` fails, the 
remote_servers are not cleaned, which might spoil the following tests 
(as they might be persistent, eg. via aexpect).

Kind regards,
Lukáš

PS: Yes, the tearDown is unsafe as when `nfs_share.close()` fails the 
rest is not cleaned up. This is just a demonstration and the proper 
tearDown and a proper setUp for the current behavior would be way more 
complex.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 502 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/avocado-devel/attachments/20170322/fa1a9af7/attachment.sig>


More information about the Avocado-devel mailing list