]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use context managers as suggested by PyLint 2.8.2
authorMichał Kępień <michal@isc.org>
Tue, 18 May 2021 08:53:17 +0000 (10:53 +0200)
committerMichał Kępień <michal@isc.org>
Tue, 18 May 2021 08:53:17 +0000 (10:53 +0200)
PyLint 2.8.2 reports the following suggestions for two Python scripts
used in the system test suite:

    ************* Module tests_rndc_deadlock
    bin/tests/system/addzone/tests_rndc_deadlock.py:71:4: R1732: Consider using 'with' for resource-allocating operations (consider-using-with)
    ************* Module tests-shutdown
    bin/tests/system/shutdown/tests-shutdown.py:68:4: R1732: Consider using 'with' for resource-allocating operations (consider-using-with)
    bin/tests/system/shutdown/tests-shutdown.py:154:8: R1732: Consider using 'with' for resource-allocating operations (consider-using-with)

Implement the above suggestions by using
concurrent.futures.ThreadPoolExecutor() and subprocess.Popen() as
context managers.

bin/tests/system/addzone/tests_rndc_deadlock.py
bin/tests/system/shutdown/tests-shutdown.py

index 852c551a0d727eac3aafc92cff706f66617ba21b..4e1e1090ba9784a2a1e3329f507335647a9d9f9f 100755 (executable)
@@ -68,23 +68,22 @@ def test_rndc_deadlock():
     test_state = {'finished': False}
 
     # Create 4 worker threads running "rndc" commands in a loop.
-    executor = concurrent.futures.ThreadPoolExecutor()
-    for i in range(1, 5):
-        domain = 'example%d' % i
-        executor.submit(rndc_loop, test_state, domain)
-
-    # Run "rndc status" in 1-second intervals for a maximum of 10 seconds.  If
-    # any "rndc status" command fails, the loop will be interrupted.
-    server_is_responsive = True
-    attempts = 10
-    while server_is_responsive and attempts > 0:
-        server_is_responsive = check_if_server_is_responsive()
-        attempts -= 1
-        time.sleep(1)
-
-    # Signal worker threads that the test is finished.
-    test_state['finished'] = True
-    executor.shutdown()
+    with concurrent.futures.ThreadPoolExecutor() as executor:
+        for i in range(1, 5):
+            domain = 'example%d' % i
+            executor.submit(rndc_loop, test_state, domain)
+
+        # Run "rndc status" in 1-second intervals for a maximum of 10 seconds.
+        # If any "rndc status" command fails, the loop will be interrupted.
+        server_is_responsive = True
+        attempts = 10
+        while server_is_responsive and attempts > 0:
+            server_is_responsive = check_if_server_is_responsive()
+            attempts -= 1
+            time.sleep(1)
+
+        # Signal worker threads that the test is finished.
+        test_state['finished'] = True
 
     # Check whether all "rndc status" commands succeeded.
     assert server_is_responsive
index e1ed83f242ad5c8e17ffd978b1bb14dd936447ca..1556f9f5fbda1bd49110af872ead2fec14ca187d 100755 (executable)
@@ -65,65 +65,63 @@ def do_work(named_proc, resolver, rndc_cmd, kill_method, n_workers, n_queries):
 
     # We're going to execute queries in parallel by means of a thread pool.
     # dnspython functions block, so we need to circunvent that.
-    executor = ThreadPoolExecutor(n_workers + 1)
-
-    # Helper dict, where keys=Future objects and values are tags used
-    # to process results later.
-    futures = {}
-
-    # 50% of work will be A queries.
-    # 1 work will be rndc stop.
-    # Remaining work will be rndc status (so we test parallel control
-    #  connections that were crashing named).
-    shutdown = True
-    for i in range(n_queries):
-        if i < (n_queries // 2):
-            # Half work will be standard A queries.
-            # Among those we split 50% queries relname='www',
-            # 50% queries relname=random characters
-            if random.randrange(2) == 1:
-                tag = "good"
-                relname = "www"
-            else:
-                tag = "bad"
-                length = random.randint(4, 10)
-                relname = "".join(letters[
-                    random.randrange(len(letters))] for i in range(length))
-
-            qname = relname + ".test"
-            futures[executor.submit(resolver.query, qname, 'A')] = tag
-        elif shutdown:  # We attempt to stop named in the middle
-            shutdown = False
-            if kill_method == "rndc":
-                futures[executor.submit(launch_rndc, ['stop'])] = 'stop'
-            else:
-                futures[executor.submit(named_proc.terminate)] = 'kill'
+    with ThreadPoolExecutor(n_workers + 1) as executor:
+
+        # Helper dict, where keys=Future objects and values are tags used
+        # to process results later.
+        futures = {}
+
+        # 50% of work will be A queries.
+        # 1 work will be rndc stop.
+        # Remaining work will be rndc status (so we test parallel control
+        #  connections that were crashing named).
+        shutdown = True
+        for i in range(n_queries):
+            if i < (n_queries // 2):
+                # Half work will be standard A queries.
+                # Among those we split 50% queries relname='www',
+                # 50% queries relname=random characters
+                if random.randrange(2) == 1:
+                    tag = "good"
+                    relname = "www"
+                else:
+                    tag = "bad"
+                    length = random.randint(4, 10)
+                    relname = "".join(letters[
+                        random.randrange(len(letters))] for i in range(length))
+
+                qname = relname + ".test"
+                futures[executor.submit(resolver.query, qname, 'A')] = tag
+            elif shutdown:  # We attempt to stop named in the middle
+                shutdown = False
+                if kill_method == "rndc":
+                    futures[executor.submit(launch_rndc, ['stop'])] = 'stop'
+                else:
+                    futures[executor.submit(named_proc.terminate)] = 'kill'
 
-        else:
-            # We attempt to send couple rndc commands while named is
-            # being shutdown
-            futures[executor.submit(launch_rndc, ['status'])] = 'status'
-
-    ret_code = -1
-    for future in as_completed(futures):
-        try:
-            result = future.result()
-            # If tag is "stop", result is an instance of
-            # subprocess.CompletedProcess, then we check returncode
-            # attribute to know if rncd stop command finished successfully.
-            #
-            # if tag is "kill" then the main function will check if
-            # named process exited gracefully after SIGTERM signal.
-            if futures[future] == "stop":
-                ret_code = result
+            else:
+                # We attempt to send couple rndc commands while named is
+                # being shutdown
+                futures[executor.submit(launch_rndc, ['status'])] = 'status'
 
-        except (dns.resolver.NXDOMAIN, dns.exception.Timeout):
-            pass
+        ret_code = -1
+        for future in as_completed(futures):
+            try:
+                result = future.result()
+                # If tag is "stop", result is an instance of
+                # subprocess.CompletedProcess, then we check returncode
+                # attribute to know if rncd stop command finished successfully.
+                #
+                # if tag is "kill" then the main function will check if
+                # named process exited gracefully after SIGTERM signal.
+                if futures[future] == "stop":
+                    ret_code = result
 
-    if kill_method == "rndc":
-        assert ret_code == 0
+            except (dns.resolver.NXDOMAIN, dns.exception.Timeout):
+                pass
 
-    executor.shutdown()
+        if kill_method == "rndc":
+            assert ret_code == 0
 
 
 @pytest.mark.dnspython
@@ -149,14 +147,6 @@ def test_named_shutdown(named_port, control_port):
     rndc_cmd = [rndc, "-c", rndc_cfg, "-p", str(control_port),
                 "-s", "10.53.0.3"]
 
-    # Helper function, launch named without blocking.
-    def launch_named():
-        proc = subprocess.Popen([named, "-c", cfg_file, "-f"], cwd=cfg_dir)
-        # Ensure named is running
-        assert proc.poll() is None
-
-        return proc
-
     # We create a resolver instance that will be used to send queries.
     resolver = dns.resolver.Resolver()
     resolver.nameservers = ['10.53.0.3']
@@ -167,38 +157,41 @@ def test_named_shutdown(named_port, control_port):
     # Method 2: killing with SIGTERM
     # In both methods named should exit gracefully.
     for kill_method in ("rndc", "sigterm"):
-        named_proc = launch_named()
-        # wait for named to finish loading
-        for _ in range(10):
-            try:
-                resolver.query('version.bind', 'TXT', 'CH')
-                break
-            except (dns.resolver.NoNameservers, dns.exception.Timeout):
-                time.sleep(1)
-
-        do_work(named_proc, resolver, rndc_cmd,
-                kill_method, n_workers=12, n_queries=16)
+        named_cmdline = [named, "-c", cfg_file, "-f"]
+        with subprocess.Popen(named_cmdline, cwd=cfg_dir) as named_proc:
+            # Ensure named is running
+            assert named_proc.poll() is None
+            # wait for named to finish loading
+            for _ in range(10):
+                try:
+                    resolver.query('version.bind', 'TXT', 'CH')
+                    break
+                except (dns.resolver.NoNameservers, dns.exception.Timeout):
+                    time.sleep(1)
 
-        # Wait named to exit for a maximum of MAX_TIMEOUT seconds.
-        MAX_TIMEOUT = 10
-        is_dead = False
-        for _ in range(MAX_TIMEOUT):
-            if named_proc.poll() is not None:
-                is_dead = True
-                break
-            time.sleep(1)
+            do_work(named_proc, resolver, rndc_cmd,
+                    kill_method, n_workers=12, n_queries=16)
 
-        if not is_dead:
-            named_proc.send_signal(signal.SIGABRT)
+            # Wait named to exit for a maximum of MAX_TIMEOUT seconds.
+            MAX_TIMEOUT = 10
+            is_dead = False
             for _ in range(MAX_TIMEOUT):
                 if named_proc.poll() is not None:
                     is_dead = True
                     break
                 time.sleep(1)
-            if not is_dead:
-                named_proc.kill()
 
-        assert is_dead
-        # Ensures that named exited gracefully.
-        # If it crashed (abort()) exitcode will be non zero.
-        assert named_proc.returncode == 0
+            if not is_dead:
+                named_proc.send_signal(signal.SIGABRT)
+                for _ in range(MAX_TIMEOUT):
+                    if named_proc.poll() is not None:
+                        is_dead = True
+                        break
+                    time.sleep(1)
+                if not is_dead:
+                    named_proc.kill()
+
+            assert is_dead
+            # Ensures that named exited gracefully.
+            # If it crashed (abort()) exitcode will be non zero.
+            assert named_proc.returncode == 0