From a4aebd73e291ab0be9fc95b81bad2a156aa74a19 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 17 Apr 2023 14:28:11 -0700 Subject: [PATCH] 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 --- tests/smbserver.py | 55 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/tests/smbserver.py b/tests/smbserver.py index 5a73d0b12e..3de8d69c0a 100755 --- a/tests/smbserver.py +++ b/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 = ""