From 4d08ec67aad1925f08b33f30afaddd87abcd850c Mon Sep 17 00:00:00 2001 From: Lars Butler Date: Tue, 29 Oct 2013 13:28:08 +0100 Subject: [PATCH] Fix to make ConfigOpts no longer obscure IOErrors This changes ConfigParser._parse_file such that it no longer interprets all IOErrors as 'No such file or directory', and instead allows these errors to propagate normally. The current behavior with respect to ConfigOpts does not change for IOErrors indicating 'No such file' or 'Permission denied'. Also added a test to exercise the case where IOErrors are reraised. The 'No such file' case is already covered by existing tests. Change-Id: I10e4e5965212737a19f4f17153143f62b5c0c83e Closes-Bug: #1244674 --- oslo/config/cfg.py | 9 ++++++--- test-requirements.txt | 3 +++ tests/test_cfg.py | 13 +++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/oslo/config/cfg.py b/oslo/config/cfg.py index 301784f..1025f19 100644 --- a/oslo/config/cfg.py +++ b/oslo/config/cfg.py @@ -263,6 +263,7 @@ command line arguments using the SubCommandOpt class: import argparse import collections import copy +import errno import functools import glob import itertools @@ -1275,9 +1276,11 @@ class ConfigParser(iniparser.BaseParser): parser.parse() except iniparser.ParseError as pe: raise ConfigFileParseError(pe.filename, str(pe)) - except IOError: - namespace._file_not_found(config_file) - return + except IOError as err: + if err.errno in (errno.ENOENT, errno.EACCES): + namespace._file_not_found(config_file) + return + raise namespace.add_parsed_config_file(sections, normalized) diff --git a/test-requirements.txt b/test-requirements.txt index 48d64b1..856f9d1 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -15,3 +15,6 @@ coverage>=3.6 # this is required for the docs build jobs sphinx>=1.1.2 oslo.sphinx + +# mocking framework +mock>=1.0 diff --git a/tests/test_cfg.py b/tests/test_cfg.py index 0fe7b56..e4af7c0 100644 --- a/tests/test_cfg.py +++ b/tests/test_cfg.py @@ -15,12 +15,14 @@ # under the License. import argparse +import errno import os import shutil import sys import tempfile import fixtures +import mock import six from six import moves import testscenarios @@ -2517,6 +2519,17 @@ class ConfigParserTestCase(BaseTestCase): parser = cfg.ConfigParser(tmpfile.name, {}) self.assertRaises(cfg.ParseError, parser.parse) + def test__parse_file_ioerror(self): + # Test that IOErrors (other than 'No such file or directory') + # are propagated. + filename = 'fake' + namespace = mock.Mock() + with mock.patch('oslo.config.cfg.ConfigParser.parse') as parse: + parse.side_effect = IOError(errno.EMFILE, filename, + 'Too many open files') + self.assertRaises(IOError, cfg.ConfigParser._parse_file, filename, + namespace) + class MultiConfigParserTestCase(BaseTestCase):