Browse Source

smbserver: remove temporary files before exit

Each execution of test 1451 would leave a file in /tmp before. Since
Windows can't delete a file while it's open, all the temporary file
names are stored and deleted on exit.

Closes #10990
Dan Fandrich 1 year ago
parent
commit
a4aebd73e2
1 changed files with 54 additions and 1 deletions
  1. 54 1
      tests/smbserver.py

+ 54 - 1
tests/smbserver.py

@@ -29,8 +29,10 @@ from __future__ import (absolute_import, division, print_function,
 import argparse
 import logging
 import os
+import signal
 import sys
 import tempfile
+import threading
 
 # Import our curl test data helper
 from util import ClosingFileHandler, TestData
@@ -59,6 +61,49 @@ VERIFIED_REQ = "verifiedserver"
 VERIFIED_RSP = "WE ROOLZ: {pid}\n"
 
 
+class ShutdownHandler(threading.Thread):
+    """Cleanly shut down the SMB server
+
+    This can only be done from another thread while the server is in
+    serve_forever(), so a thread is spawned here that waits for a shutdown
+    signal before doing its thing. Use in a with statement around the
+    serve_forever() call.
+    """
+
+    def __init__(self, server):
+        super(ShutdownHandler, self).__init__()
+        self.server = server
+        self.shutdown_event = threading.Event()
+
+    def __enter__(self):
+        self.start()
+        signal.signal(signal.SIGINT, self._sighandler)
+        signal.signal(signal.SIGTERM, self._sighandler)
+
+    def __exit__(self, *_):
+        # Call for shutdown just in case it wasn't done already
+        self.shutdown_event.set()
+        # Wait for thread, and therefore also the server, to finish
+        self.join()
+        # Uninstall our signal handlers
+        signal.signal(signal.SIGINT, signal.SIG_DFL)
+        signal.signal(signal.SIGTERM, signal.SIG_DFL)
+        # Delete any temporary files created by the server during its run
+        log.info("Deleting %d temporary files", len(self.server.tmpfiles))
+        for f in self.server.tmpfiles:
+            os.unlink(f)
+
+    def _sighandler(self, _signum, _frame):
+        # Wake up the cleanup task
+        self.shutdown_event.set()
+
+    def run(self):
+        # Wait for shutdown signal
+        self.shutdown_event.wait()
+        # Notify the server to shut down
+        self.server.shutdown()
+
+
 def smbserver(options):
     """Start up a TCP SMB server that serves forever
 
@@ -105,7 +150,12 @@ def smbserver(options):
                                test_data_directory=test_data_dir)
     log.info("[SMB] setting up SMB server on port %s", options.port)
     smb_server.processConfigFile()
-    smb_server.serve_forever()
+
+    # Start a thread that cleanly shuts down the server on a signal
+    with ShutdownHandler(smb_server):
+        # This will block until smb_server.shutdown() is called
+        smb_server.serve_forever()
+
     return 0
 
 
@@ -122,6 +172,7 @@ class TestSmbServer(imp_smbserver.SMBSERVER):
         imp_smbserver.SMBSERVER.__init__(self,
                                          address,
                                          config_parser=config_parser)
+        self.tmpfiles = []
 
         # Set up a test data object so we can get test data later.
         self.ctd = TestData(test_data_directory)
@@ -182,6 +233,8 @@ class TestSmbServer(imp_smbserver.SMBSERVER):
                 assert (path == TESTS_MAGIC)
                 fid, full_path = self.get_test_path(requested_file)
 
+            self.tmpfiles.append(full_path)
+
             resp_parms = imp_smb.SMBNtCreateAndXResponse_Parameters()
             resp_data = ""