def test_issue_6030_deprecated_never_download(self): mock = MagicMock(return_value={"retcode": 0, "stdout": ""}) with patch.dict(virtualenv_mod.__salt__, {"cmd.run_all": mock}): virtualenv_mod.create("/tmp/foo", never_download=True) mock.assert_called_once_with( ["virtualenv", "--never-download", "/tmp/foo"], runas=None, python_shell=False, ) with TstSuiteLoggingHandler() as handler: mock = MagicMock(return_value={"retcode": 0, "stdout": ""}) # Let's fake a higher virtualenv version virtualenv_mock = MagicMock() virtualenv_mock.__version__ = "1.10rc1" with patch.dict(virtualenv_mod.__salt__, {"cmd.run_all": mock}): with patch.dict("sys.modules", {"virtualenv": virtualenv_mock}): virtualenv_mod.create("/tmp/foo", never_download=True) mock.assert_called_once_with(["virtualenv", "/tmp/foo"], runas=None, python_shell=False) # Are we logging the deprecation information? self.assertIn( "INFO:--never-download was deprecated in 1.10.0, " "but reimplemented in 14.0.0. If this feature is needed, " "please install a supported virtualenv version.", handler.messages, )
def test_adduser_error(self): """ Test adding a user and encountering an error """ msg = "An unknown directory object was requested" error = pywintypes.com_error( -1234, "Exception occurred.", (0, None, msg, None, 0, -2147352567), None ) # Create mock group object with mocked Add function which raises the # exception we need in order to test the error case. class GroupObj(MockGroupObj): def Add(self, name): raise error obj_group_mock = MagicMock(return_value=GroupObj("foo", ["WinNT://HOST/steve"])) with patch.object( win_groupadd, "_get_group_object", obj_group_mock ), patch.object(salt.utils.win_functions, "get_sam_name", self.sam_mock): with TstSuiteLoggingHandler() as handler: self.assertFalse(win_groupadd.adduser("foo", "username")) expected = ( "ERROR:Failed to add HOST\\username to group foo. An unknown" " directory object was requested" ) self.assertIn(expected, handler.messages)
def test_get_tops_python(self): """ test get_tops_python """ patch_proc = patch( "salt.utils.thin.subprocess.Popen", self._popen( None, side_effect=[ (bts("distro.py"), bts("")), (bts("jinja2/__init__.py"), bts("")), (bts("yaml/__init__.py"), bts("")), (bts("tornado/__init__.py"), bts("")), (bts("msgpack/__init__.py"), bts("")), (bts("certifi/__init__.py"), bts("")), (bts("singledispatch.py"), bts("")), (bts(""), bts("")), (bts(""), bts("")), (bts(""), bts("")), (bts(""), bts("")), (bts(""), bts("")), ], ), ) patch_os = patch("os.path.exists", return_value=True) patch_which = patch("salt.utils.path.which", return_value=True) with patch_proc, patch_os, patch_which: with TstSuiteLoggingHandler() as log_handler: ret = thin.get_tops_python("python2.7") assert ret == self.exp_ret assert ( "ERROR:Could not auto detect file location for module concurrent for python version python2.7" in log_handler.messages )
def test_issue_6030_deprecated_never_download(self): mock = MagicMock(return_value={'retcode': 0, 'stdout': ''}) with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}): virtualenv_mod.create('/tmp/foo', never_download=True) mock.assert_called_once_with( ['virtualenv', '--never-download', '/tmp/foo'], runas=None, python_shell=False) with TstSuiteLoggingHandler() as handler: mock = MagicMock(return_value={'retcode': 0, 'stdout': ''}) # Let's fake a higher virtualenv version virtualenv_mock = MagicMock() virtualenv_mock.__version__ = '1.10rc1' with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}): with patch.dict('sys.modules', {'virtualenv': virtualenv_mock}): virtualenv_mod.create('/tmp/foo', never_download=True) mock.assert_called_once_with(['virtualenv', '/tmp/foo'], runas=None, python_shell=False) # Are we logging the deprecation information? self.assertIn( 'INFO:--never-download was deprecated in 1.10.0, ' 'but reimplemented in 14.0.0. If this feature is needed, ' 'please install a supported virtualenv version.', handler.messages)
def test_pack_alternatives_path_doesnot_exist(self): """ test thin._pack_alternatives when the path doesnt exist. Check error log message and expect that because the directory does not exist jinja2 does not get added to the tar """ bad_path = os.path.join(tempfile.gettempdir(), "doesnotexisthere") tops = copy.deepcopy(self.tops) tops["test"]["dependencies"] = [bad_path] with patch("salt.utils.thin.get_ext_tops", MagicMock(return_value=tops)): with TstSuiteLoggingHandler() as log_handler: thin._pack_alternative(self.ext_conf, self.digest, self.tar) msg = "ERROR:File path {} does not exist. Unable to add to salt-ssh thin".format( bad_path ) assert msg in log_handler.messages calls = self.tar.mock_calls for _file in self.exp_files: arg = [x for x in calls if "{}".format(_file) in x.args] kwargs = [ x for x in calls if os.path.join("test", "pyall", _file) in x.kwargs["arcname"] ] if "jinja2" in _file: assert not arg assert not kwargs else: assert arg assert kwargs
def test_regression_49572(self): with TstSuiteLoggingHandler() as handler: GATHER_JOB_TIMEOUT = 1 self.application.opts["gather_job_timeout"] = GATHER_JOB_TIMEOUT low = [{"client": "local", "tgt": "*", "fun": "test.ping"}] fetch_kwargs = { "method": "POST", "body": salt.utils.json.dumps(low), "headers": { "Content-Type": self.content_type_map["json"], saltnado.AUTH_TOKEN_HEADER: self.token["token"], }, "connect_timeout": 30, "request_timeout": 30, } self.fetch("/", **fetch_kwargs) time.sleep(GATHER_JOB_TIMEOUT + 0.1) # ick # While the traceback is in the logs after the sleep without this # follow up fetch, the logging handler doesn't see it in its list # of messages unless something else runs. self.fetch("/", **fetch_kwargs) for message in handler.messages: if "TypeError: 'NoneType' object is not iterable" in message: raise AssertionError( "#49572: regression: set_result on completed event")
def setUp(self): """ Set up """ log_format = "[%(levelname)-8s] %(jid)s %(message)s" self.handler = TstSuiteLoggingHandler(format=log_format, level=logging.DEBUG)
def setUp(self): ''' Set up ''' log_format = '[%(levelname)-8s] %(jid)s %(message)s' self.handler = TstSuiteLoggingHandler(format=log_format, level=logging.DEBUG)
def test_gen_thin_python_exist_or_not(self): """ Test thin.gen_thin function if the opposite python binary does not exist """ with TstSuiteLoggingHandler() as handler: thin.gen_thin("") salt.utils.thin.subprocess.Popen.assert_not_called() if salt.ext.six.PY2: self.assertIn( "DEBUG:python3 binary does not exist. Will not attempt to generate " "tops for Python 3", handler.messages, ) if salt.ext.six.PY3: self.assertIn( "DEBUG:python2 binary does not exist. Will not " "detect Python 2 version", handler.messages, ) self.assertIn( "DEBUG:python2 binary does not exist. Will not attempt to generate " "tops for Python 2", handler.messages, )
def test_noop_return(self): with TstSuiteLoggingHandler( format="%(message)s", level=logging.DEBUG ) as handler: self.run_function("test.ping") assert ( any("NOOP_RETURN" in s for s in handler.messages) is True ), "NOOP_RETURN not found in log messages"
def test_show_keypair_no_keyname(self): """ test salt.cloud.clouds.vultr.show_keypair when keyname is not in kwargs """ kwargs = {} with TstSuiteLoggingHandler() as handler: assert not vultr.show_keypair(kwargs) assert "ERROR:A keyname is required." in handler.messages
def test_issue_2853_regex_TypeError(self): # Now, python's logging logger class is ours. # Let's make sure we have at least one instance log = SaltLoggingClass(__name__) # Test for a format which includes digits in name formatting. log_format = "[%(name)-15s] %(message)s" handler = TstSuiteLoggingHandler(format=log_format) log.addHandler(handler) # Trigger TstSuiteLoggingHandler.__enter__ with handler: # Let's create another log instance to trigger salt's logging class # calculations. try: SaltLoggingClass("{0}.with_digits".format(__name__)) except Exception as err: # pylint: disable=broad-except raise AssertionError( "No exception should have been raised: {0}".format(err) ) # Remove the testing handler log.removeHandler(handler) # Test for a format which does not include digits in name formatting. log_format = "[%(name)s] %(message)s" handler = TstSuiteLoggingHandler(format=log_format) log.addHandler(handler) # Trigger TstSuiteLoggingHandler.__enter__ with handler: # Let's create another log instance to trigger salt's logging class # calculations. try: SaltLoggingClass("{0}.without_digits".format(__name__)) except Exception as err: # pylint: disable=broad-except raise AssertionError( "No exception should have been raised: {0}".format(err) ) # Remove the testing handler log.removeHandler(handler)
def test_verify_log_warning_logged(self): args = ["--log-level", "debug"] + self.args with TstSuiteLoggingHandler(level=logging.DEBUG) as handler: parser = self.parser() with patch(self.config_func, MagicMock(return_value=self.testing_config)): parser.parse_args(args) self.assertIn( "WARNING:Insecure logging configuration detected! Sensitive data may be logged.", handler.messages, )
def test_get_name_error(self): """ Test get_name with an un mapped SID, should throw a CommandExecutionError """ test_sid = "S-1-2-3-4" sid_obj = win32security.ConvertStringSidToSid(test_sid) with TstSuiteLoggingHandler() as handler: self.assertRaises(CommandExecutionError, win_dacl.get_name, sid_obj) expected_message = 'ERROR:Error resolving "PySID:S-1-2-3-4"' self.assertIn(expected_message, handler.messages[0])
def test_show_current(): mock = MagicMock(return_value="/etc/alternatives/salt") with patch("salt.utils.path.readlink", mock): ret = alternatives.show_current("better-world") assert "/etc/alternatives/salt" == ret mock.assert_called_once_with("/etc/alternatives/better-world") with TstSuiteLoggingHandler() as handler: mock.side_effect = OSError("Hell was not found!!!") assert not alternatives.show_current("hell") mock.assert_called_with("/etc/alternatives/hell") assert "ERROR:alternative: hell does not exist" in handler.messages
def test_show_current(self): mock = MagicMock(return_value='/etc/alternatives/salt') with patch('salt.utils.path.readlink', mock): ret = alternatives.show_current('better-world') self.assertEqual('/etc/alternatives/salt', ret) mock.assert_called_once_with('/etc/alternatives/better-world') with TstSuiteLoggingHandler() as handler: mock.side_effect = OSError('Hell was not found!!!') self.assertFalse(alternatives.show_current('hell')) mock.assert_called_with('/etc/alternatives/hell') self.assertIn('ERROR:alternative: hell does not exist', handler.messages)
def test_create_ssh_key_ids_doesnotexist(self): """ Test create when setting ssh_key_ids that do not exist """ kwargs = { "provider": "vultr", "enable_private_network": True, "startup_script_id": "test_id", "ssh_key_names": "doesnotexist", "image": 223, "size": 13, "location": 1, "name": "test-vm", } patch_scripts = patch( "salt.cloud.clouds.vultrpy.avail_scripts", MagicMock(return_value=["test_id"]), ) patch_firewall = patch( "salt.cloud.clouds.vultrpy.avail_firewall_groups", MagicMock(return_value=["f_id"]), ) patch_keys = patch( "salt.cloud.clouds.vultrpy.avail_keys", MagicMock(return_value=["key3", "key2", "key1"]), ) patch_vultrid = patch( "salt.cloud.clouds.vultrpy._lookup_vultrid", MagicMock(return_value="test_id"), ) mock_query = MagicMock(return_value={"status": 200}) patch_query = patch("salt.cloud.clouds.vultrpy._query", mock_query) patch_show = patch("salt.cloud.clouds.vultrpy.show_instance", MagicMock()) with patch_scripts, patch_firewall, patch_keys, patch_vultrid, patch_query, patch_show: with TstSuiteLoggingHandler() as handler: ret = vultr.create(kwargs) self.assertIn( "ERROR:Your Vultr account does not have a key with ID doesnotexist", handler.messages, ) self.assertFalse(ret)
def test_run_all_output_loglevel_debug(self): """ Test that specifying debug for loglevel does log the command. """ stdout = b"test" proc = MagicMock(return_value=MockTimedProc(stdout=stdout)) msg = "INFO:Executing command 'some command' in directory" with patch("salt.utils.timed_subprocess.TimedProc", proc): with TstSuiteLoggingHandler() as log_handler: ret = cmdmod.run_all("some command", output_loglevel="debug") assert [x for x in log_handler.messages if msg in x] self.assertEqual(ret["stdout"], salt.utils.stringutils.to_unicode(stdout))
def test_latest_config_get_regexp_retcode(self, target): """ git.latest """ log_format = "[%(levelname)-8s] %(jid)s %(message)s" self.handler = TstSuiteLoggingHandler(format=log_format, level=logging.DEBUG) ret_code_err = "failed with return code: 1" with self.handler: ret = self.run_state("git.latest", name=TEST_REPO, target=target) self.assertSaltTrueReturn(ret) self.assertTrue(os.path.isdir(os.path.join(target, ".git"))) assert any(ret_code_err in s for s in self.handler.messages) is False, False
def test_run_all_output_loglevel_quiet(self): ''' Test that specifying quiet for loglevel does not log the command. ''' stdout = b'test' proc = MagicMock(return_value=MockTimedProc(stdout=stdout)) msg = "INFO:Executing command 'some command' in directory" with patch('salt.utils.timed_subprocess.TimedProc', proc): with TstSuiteLoggingHandler() as log_handler: ret = cmdmod.run_all('some command', output_loglevel='quiet') assert not [x for x in log_handler.messages if msg in x] self.assertEqual(ret['stdout'], salt.utils.stringutils.to_unicode(stdout))
def test_no_pillarenv(self): 'confirm that file_tree yells when pillarenv is missing for a relative path' with patch('salt.utils.minions.CkMinions.check_minions', MagicMock(return_value=_CHECK_MINIONS_RETURN)): with patch.dict(file_tree.__opts__, {'pillarenv': None}): with TstSuiteLoggingHandler() as handler: mypillar = file_tree.ext_pillar(MINION_ID, None, '.') self.assertEqual({}, mypillar) for message in handler.messages: if message.startswith( 'ERROR:' ) and 'pillarenv is not set' in message: break else: raise AssertionError('Did not find error message')
def test_no_pillarenv(self): "confirm that file_tree yells when pillarenv is missing for a relative path" with patch( "salt.utils.minions.CkMinions.check_minions", MagicMock(return_value=_CHECK_MINIONS_RETURN), ): with patch.dict(file_tree.__opts__, {"pillarenv": None}): with TstSuiteLoggingHandler() as handler: mypillar = file_tree.ext_pillar(MINION_ID, None, ".") self.assertEqual({}, mypillar) for message in handler.messages: if (message.startswith("ERROR:") and "pillarenv is not set" in message): break else: raise AssertionError("Did not find error message")
def test_get_tops_python(self): """ test get_tops_python """ patch_proc = patch( "salt.utils.thin.subprocess.Popen", self._popen( None, side_effect=[ (bts("jinja2/__init__.py"), bts("")), (bts("yaml/__init__.py"), bts("")), (bts("tornado/__init__.py"), bts("")), (bts("msgpack/__init__.py"), bts("")), (bts("certifi/__init__.py"), bts("")), (bts("singledispatch.py"), bts("")), (bts(""), bts("")), (bts(""), bts("")), (bts(""), bts("")), (bts(""), bts("")), (bts(""), bts("")), (bts("distro.py"), bts("")), ], ), ) patch_os = patch("os.path.exists", return_value=True) patch_which = patch("salt.utils.path.which", return_value=True) with patch_proc, patch_os, patch_which: with TstSuiteLoggingHandler() as log_handler: exp_ret = copy.deepcopy(self.exp_ret) ret = thin.get_tops_python("python3.7", ext_py_ver=[3, 7]) if salt.utils.platform.is_windows(): for key, value in ret.items(): ret[key] = str( pathlib.Path(value).resolve(strict=False)) for key, value in exp_ret.items(): exp_ret[key] = str( pathlib.Path(value).resolve(strict=False)) assert ret == exp_ret assert ( "ERROR:Could not auto detect file location for module concurrent for python version python3.7" in log_handler.messages)
def test_issue_6029_deprecated_distribute(self): mock = MagicMock(return_value={"retcode": 0, "stdout": ""}) with patch.dict(virtualenv_mod.__salt__, {"cmd.run_all": mock}): virtualenv_mod.create("/tmp/foo", system_site_packages=True, distribute=True) mock.assert_called_once_with( [ "virtualenv", "--distribute", "--system-site-packages", "/tmp/foo" ], runas=None, python_shell=False, ) with TstSuiteLoggingHandler() as handler: # Let's fake a higher virtualenv version virtualenv_mock = MagicMock() virtualenv_mock.__version__ = "1.10rc1" mock = MagicMock(return_value={"retcode": 0, "stdout": ""}) with patch.dict(virtualenv_mod.__salt__, {"cmd.run_all": mock}): with patch.dict("sys.modules", {"virtualenv": virtualenv_mock}): virtualenv_mod.create("/tmp/foo", system_site_packages=True, distribute=True) mock.assert_called_once_with( ["virtualenv", "--system-site-packages", "/tmp/foo"], runas=None, python_shell=False, ) # Are we logging the deprecation information? self.assertIn( "INFO:The virtualenv '--distribute' option has been " "deprecated in virtualenv(>=1.10), as such, the " "'distribute' option to `virtualenv.create()` has " "also been deprecated and it's not necessary anymore.", handler.messages, )
def test_gen_thin_python_exist_or_not(self): ''' Test thin.gen_thin function if the opposite python binary does not exist ''' with TstSuiteLoggingHandler() as handler: thin.gen_thin('') salt.utils.thin.subprocess.Popen.assert_not_called() if salt.ext.six.PY2: self.assertIn('DEBUG:python3 binary does not exist. Will not attempt to generate ' 'tops for Python 3', handler.messages) if salt.ext.six.PY3: self.assertIn('DEBUG:python2 binary does not exist. Will not ' 'detect Python 2 version', handler.messages) self.assertIn('DEBUG:python2 binary does not exist. Will not attempt to generate ' 'tops for Python 2', handler.messages)
def test_issue_6029_deprecated_distribute(self): mock = MagicMock(return_value={'retcode': 0, 'stdout': ''}) with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}): virtualenv_mod.create('/tmp/foo', system_site_packages=True, distribute=True) mock.assert_called_once_with([ 'virtualenv', '--distribute', '--system-site-packages', '/tmp/foo' ], runas=None, python_shell=False) with TstSuiteLoggingHandler() as handler: # Let's fake a higher virtualenv version virtualenv_mock = MagicMock() virtualenv_mock.__version__ = '1.10rc1' mock = MagicMock(return_value={'retcode': 0, 'stdout': ''}) with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}): with patch.dict('sys.modules', {'virtualenv': virtualenv_mock}): virtualenv_mod.create('/tmp/foo', system_site_packages=True, distribute=True) mock.assert_called_once_with( ['virtualenv', '--system-site-packages', '/tmp/foo'], runas=None, python_shell=False) # Are we logging the deprecation information? self.assertIn( 'INFO:The virtualenv \'--distribute\' option has been ' 'deprecated in virtualenv(>=1.10), as such, the ' '\'distribute\' option to `virtualenv.create()` has ' 'also been deprecated and it\'s not necessary anymore.', handler.messages)
def test_noop_return(self): with TstSuiteLoggingHandler(format='%(message)s', level=logging.DEBUG) as handler: self.run_function('test.ping') assert any('NOOP_RETURN' in s for s in handler.messages ) is True, 'NOOP_RETURN not found in log messages'
def test_max_open_files(self): with TstSuiteLoggingHandler() as handler: logmsg_dbg = ( 'DEBUG:This salt-master instance has accepted {0} minion keys.' ) logmsg_chk = ( '{0}:The number of accepted minion keys({1}) should be lower ' 'than 1/4 of the max open files soft setting({2}). According ' 'to the system\'s hard limit, there\'s still a margin of {3} ' 'to raise the salt\'s max_open_files setting. Please consider ' 'raising this value.') logmsg_crash = ( '{0}:The number of accepted minion keys({1}) should be lower ' 'than 1/4 of the max open files soft setting({2}). ' 'salt-master will crash pretty soon! According to the ' 'system\'s hard limit, there\'s still a margin of {3} to ' 'raise the salt\'s max_open_files setting. Please consider ' 'raising this value.') if sys.platform.startswith('win'): logmsg_crash = ( '{0}:The number of accepted minion keys({1}) should be lower ' 'than 1/4 of the max open files soft setting({2}). ' 'salt-master will crash pretty soon! Please consider ' 'raising this value.') if sys.platform.startswith('win'): # Check the Windows API for more detail on this # http://msdn.microsoft.com/en-us/library/xt874334(v=vs.71).aspx # and the python binding http://timgolden.me.uk/pywin32-docs/win32file.html mof_s = mof_h = win32file._getmaxstdio() else: mof_s, mof_h = resource.getrlimit(resource.RLIMIT_NOFILE) tempdir = tempfile.mkdtemp(prefix='fake-keys') keys_dir = os.path.join(tempdir, 'minions') os.makedirs(keys_dir) mof_test = 256 if sys.platform.startswith('win'): win32file._setmaxstdio(mof_test) else: resource.setrlimit(resource.RLIMIT_NOFILE, (mof_test, mof_h)) try: prev = 0 for newmax, level in ((24, None), (66, 'INFO'), (127, 'WARNING'), (196, 'CRITICAL')): for n in range(prev, newmax): kpath = os.path.join(keys_dir, six.text_type(n)) with salt.utils.files.fopen(kpath, 'w') as fp_: fp_.write( str(n) ) # future lint: disable=blacklisted-function opts = {'max_open_files': newmax, 'pki_dir': tempdir} check_max_open_files(opts) if level is None: # No log message is triggered, only the DEBUG one which # tells us how many minion keys were accepted. self.assertEqual([logmsg_dbg.format(newmax)], handler.messages) else: self.assertIn(logmsg_dbg.format(newmax), handler.messages) self.assertIn( logmsg_chk.format( level, newmax, mof_test, mof_test - newmax if sys.platform.startswith('win') else mof_h - newmax, ), handler.messages) handler.clear() prev = newmax newmax = mof_test for n in range(prev, newmax): kpath = os.path.join(keys_dir, six.text_type(n)) with salt.utils.files.fopen(kpath, 'w') as fp_: fp_.write(str( n)) # future lint: disable=blacklisted-function opts = {'max_open_files': newmax, 'pki_dir': tempdir} check_max_open_files(opts) self.assertIn(logmsg_dbg.format(newmax), handler.messages) self.assertIn( logmsg_crash.format( 'CRITICAL', newmax, mof_test, mof_test - newmax if sys.platform.startswith('win') else mof_h - newmax, ), handler.messages) handler.clear() except IOError as err: if err.errno == 24: # Too many open files self.skipTest('We\'ve hit the max open files setting') raise finally: if sys.platform.startswith('win'): win32file._setmaxstdio(mof_h) else: resource.setrlimit(resource.RLIMIT_NOFILE, (mof_s, mof_h)) shutil.rmtree(tempdir)
def test_max_open_files(self): with TstSuiteLoggingHandler() as handler: logmsg_dbg = "DEBUG:This salt-master instance has accepted {0} minion keys." logmsg_chk = ( "{0}:The number of accepted minion keys({1}) should be lower " "than 1/4 of the max open files soft setting({2}). According " "to the system's hard limit, there's still a margin of {3} " "to raise the salt's max_open_files setting. Please consider " "raising this value." ) logmsg_crash = ( "{0}:The number of accepted minion keys({1}) should be lower " "than 1/4 of the max open files soft setting({2}). " "salt-master will crash pretty soon! According to the " "system's hard limit, there's still a margin of {3} to " "raise the salt's max_open_files setting. Please consider " "raising this value." ) if sys.platform.startswith("win"): logmsg_crash = ( "{0}:The number of accepted minion keys({1}) should be lower " "than 1/4 of the max open files soft setting({2}). " "salt-master will crash pretty soon! Please consider " "raising this value." ) if sys.platform.startswith("win"): # Check the Windows API for more detail on this # http://msdn.microsoft.com/en-us/library/xt874334(v=vs.71).aspx # and the python binding http://timgolden.me.uk/pywin32-docs/win32file.html mof_s = mof_h = win32file._getmaxstdio() else: mof_s, mof_h = resource.getrlimit(resource.RLIMIT_NOFILE) tempdir = tempfile.mkdtemp(prefix="fake-keys") keys_dir = os.path.join(tempdir, "minions") os.makedirs(keys_dir) mof_test = 256 if sys.platform.startswith("win"): win32file._setmaxstdio(mof_test) else: resource.setrlimit(resource.RLIMIT_NOFILE, (mof_test, mof_h)) try: prev = 0 for newmax, level in ( (24, None), (66, "INFO"), (127, "WARNING"), (196, "CRITICAL"), ): for n in range(prev, newmax): kpath = os.path.join(keys_dir, str(n)) with salt.utils.files.fopen(kpath, "w") as fp_: fp_.write(str(n)) opts = {"max_open_files": newmax, "pki_dir": tempdir} check_max_open_files(opts) if level is None: # No log message is triggered, only the DEBUG one which # tells us how many minion keys were accepted. self.assertEqual([logmsg_dbg.format(newmax)], handler.messages) else: self.assertIn(logmsg_dbg.format(newmax), handler.messages) self.assertIn( logmsg_chk.format( level, newmax, mof_test, mof_test - newmax if sys.platform.startswith("win") else mof_h - newmax, ), handler.messages, ) handler.clear() prev = newmax newmax = mof_test for n in range(prev, newmax): kpath = os.path.join(keys_dir, str(n)) with salt.utils.files.fopen(kpath, "w") as fp_: fp_.write(str(n)) opts = {"max_open_files": newmax, "pki_dir": tempdir} check_max_open_files(opts) self.assertIn(logmsg_dbg.format(newmax), handler.messages) self.assertIn( logmsg_crash.format( "CRITICAL", newmax, mof_test, mof_test - newmax if sys.platform.startswith("win") else mof_h - newmax, ), handler.messages, ) handler.clear() except OSError as err: if err.errno == 24: # Too many open files self.skipTest("We've hit the max open files setting") raise finally: if sys.platform.startswith("win"): win32file._setmaxstdio(mof_h) else: resource.setrlimit(resource.RLIMIT_NOFILE, (mof_s, mof_h)) shutil.rmtree(tempdir)