<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Mar 22, 2017 at 7:05 PM Lukáš Doktor <<a href="mailto:ldoktor@redhat.com">ldoktor@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello guys,<br class="gmail_msg">
<br class="gmail_msg">
I remember early in development we decided to abort the execution when<br class="gmail_msg">
`setUp` fails without executing `tearDown`, but over the time I keep<br class="gmail_msg">
thinking about it and I don't think it's optimal. My main reason is to<br class="gmail_msg">
simplify `setUp` code, let me demonstrate it on an example.<br class="gmail_msg">
<br class="gmail_msg">
Currently when you (safely) want to get a few remote servers, nfs share<br class="gmail_msg">
and local service, you have to:<br class="gmail_msg">
<br class="gmail_msg">
     class MyTest(test):<br class="gmail_msg">
         def setUp(self):<br class="gmail_msg">
             self.nfs_share = None<br class="gmail_msg">
             self.remote_servers = []<br class="gmail_msg">
             self.service = None<br class="gmail_msg">
             try:<br class="gmail_msg">
                 for addr in self.params.get("remote_servers"):<br class="gmail_msg">
                     self.remote_servers.append(login(addr))<br class="gmail_msg">
                 self.nfs_share = get_nfs_share()<br class="gmail_msg">
                 self.service = get_service()<br class="gmail_msg">
             except:<br class="gmail_msg">
                 for server in self.remote_servers:<br class="gmail_msg">
                     server.close()<br class="gmail_msg">
                 if self.nfs_share:<br class="gmail_msg">
                     self.nfs_share.close()<br class="gmail_msg">
                 if self.service:<br class="gmail_msg">
                     self.service.stop()<br class="gmail_msg">
                 raise<br class="gmail_msg">
<br class="gmail_msg">
         def tearDown(self):<br class="gmail_msg">
             if self.nfs_share:<br class="gmail_msg">
                 self.nfs_share.close()<br class="gmail_msg">
             for server in self.remote_servers:<br class="gmail_msg">
                 server.close()<br class="gmail_msg">
             if self.service:<br class="gmail_msg">
                 self.service.stop()<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
But if the tearDown was also executed, you'd simply write:<br class="gmail_msg">
<br class="gmail_msg">
     class MyTest(test):<br class="gmail_msg">
         def setUp(self):<br class="gmail_msg">
             self.nfs_share = None<br class="gmail_msg">
             self.remote_servers = []<br class="gmail_msg">
             self.service = None<br class="gmail_msg">
<br class="gmail_msg">
             for addr in self.params.get("remote_servers"):<br class="gmail_msg">
                 self.remote_servers.append(login(addr))<br class="gmail_msg">
             self.nfs_share = get_nfs_share()<br class="gmail_msg">
             self.service = get_service()<br class="gmail_msg">
<br class="gmail_msg">
         def tearDown(self):<br class="gmail_msg">
             if self.nfs_share:<br class="gmail_msg">
                 self.nfs_share.close()<br class="gmail_msg">
             for server in self.remote_servers:<br class="gmail_msg">
                 server.close()<br class="gmail_msg">
             if self.service:<br class="gmail_msg">
                 self.service.stop()<br class="gmail_msg">
<br class="gmail_msg">
As you can see the current solution requires catching exceptions and<br class="gmail_msg">
basically writing the tearDown twice. Yes, properly written tearDown<br class="gmail_msg">
could be manually executed from the `setUp`, but that looks a bit odd<br class="gmail_msg">
and my experience is that people usually just write:<br class="gmail_msg">
<br class="gmail_msg">
     class MyTest(test):<br class="gmail_msg">
         def setUp(self):<br class="gmail_msg">
             self.remote_servers = []<br class="gmail_msg">
             for addr in self.params.get("remote_servers"):<br class="gmail_msg">
                 self.remote_servers.append(login(addr))<br class="gmail_msg">
             self.nfs_share = get_nfs_share()<br class="gmail_msg">
             self.service = get_service()<br class="gmail_msg">
<br class="gmail_msg">
         def tearDown(self):<br class="gmail_msg">
             self.nfs_share.close()<br class="gmail_msg">
             for server in self.remote_servers:<br class="gmail_msg">
                 server.close()<br class="gmail_msg">
             self.service.stop()<br class="gmail_msg">
<br class="gmail_msg">
which usually works but when the `get_nfs_share` fails, the<br class="gmail_msg">
remote_servers are not cleaned, which might spoil the following tests<br class="gmail_msg">
(as they might be persistent, eg. via aexpect).<br class="gmail_msg"></blockquote><div><br></div><div>That's a better solution than what we currently have, and I personally had to resort to the workarounds described above. +1.</div><div><br></div><div>So in summary, anything that lets you clean up resources created/used during the test without manual intervention is a great thing to have. Having to manually clean up resources is a fairly unpleasant experience, and we should help the user with that to a reasonable extent.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Kind regards,<br class="gmail_msg">
Lukáš<br class="gmail_msg">
<br class="gmail_msg">
PS: Yes, the tearDown is unsafe as when `nfs_share.close()` fails the<br class="gmail_msg">
rest is not cleaned up. This is just a demonstration and the proper<br class="gmail_msg">
tearDown and a proper setUp for the current behavior would be way more<br class="gmail_msg">
complex.<br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div></div>