Add test for recursive file parsing

This commit is contained in:
yan 2015-04-07 14:57:37 -07:00
parent eaef4065e3
commit 4f3bf3d720
5 changed files with 161 additions and 8 deletions

View file

@ -37,7 +37,10 @@ class NginxParser(object):
.. todo:: Can Nginx 'virtual hosts' be defined somewhere other than in
the server context?
:param str filepath: The path to the files to parse, as a glob
"""
filepath = self.abs_path(filepath)
trees = self._parse_files(filepath)
for tree in trees:
for entry in tree:
@ -56,6 +59,20 @@ class NginxParser(object):
if self._is_include_directive(server_entry):
self._parse_recursively(server_entry[1])
def abs_path(self, path):
"""Converts a relative path to an absolute path relative to the root.
Does nothing for paths that are already absolute.
:param str path: The path
:returns: The absolute path
:rtype str
"""
if not os.path.isabs(path):
return os.path.join(self.root, path)
else:
return path
def _is_include_directive(self, entry):
"""Checks if an nginx parsed entry is an 'include' directive.
@ -339,7 +356,7 @@ class NginxParser(object):
return regex
def _parse_files(self, filepath):
"""Parse file
"""Parse files from a glob
:param str filepath: Nginx config file path
:returns: list of parsed tree structures
@ -356,7 +373,7 @@ class NginxParser(object):
self.parsed[f] = parsed
trees.append(parsed)
except IOError:
logging.warn("Could not parse file: %s" % f)
logging.warn("Could not open file: %s" % f)
except pyparsing.ParseException:
logging.warn("Could not parse file: %s" % f)
return trees
@ -390,7 +407,7 @@ class NginxParser(object):
"""
root = self._find_config_root()
default = os.path.join(self.root, 'nginx.conf')
default = root
temp = os.path.join(self.root, "ports.conf")
if os.path.isfile(temp):

View file

@ -0,0 +1,123 @@
"""Tests for letsencrypt.client.plugins.nginx.parser."""
import os
import shutil
import sys
import unittest
import mock
import zope.component
from letsencrypt.client import errors
from letsencrypt.client.display import util as display_util
from letsencrypt.client.plugins.nginx.parser import NginxParser
from letsencrypt.client.plugins.nginx.tests import util
class NginxParserTest(util.NginxTest):
"""Nginx Parser Test."""
def setUp(self):
super(NginxParserTest, self).setUp()
self.maxDiff = None
zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
def test_root_normalized(self):
path = os.path.join(self.temp_dir, "debian_nginx_2_4/////"
"two_vhost_80/../../testdata")
parser = NginxParser(path, None)
self.assertEqual(parser.root, self.config_path)
def test_root_absolute(self):
parser = NginxParser(os.path.relpath(self.config_path), None)
self.assertEqual(parser.root, self.config_path)
def test_root_no_trailing_slash(self):
parser = NginxParser(self.config_path + os.path.sep, None)
self.assertEqual(parser.root, self.config_path)
def test_parse(self):
"""Test recursive conf file parsing.
"""
self.parser = NginxParser(self.config_path, self.ssl_options)
self.assertEqual(set(map(self.parser.abs_path,
['foo.conf', 'nginx.conf', 'server.conf',
'sites-enabled/default',
'sites-enabled/example.com'])),
set(self.parser.parsed.keys()))
self.assertEqual([['server_name', 'somename alias another.alias']],
self.parser.parsed[self.parser.abs_path(
'server.conf')])
self.assertEqual([[['server'], [['listen', '9000'],
['server_name', 'example.com']]]],
self.parser.parsed[self.parser.abs_path(
'sites-enabled/example.com')])
# def test_find_dir(self):
# from letsencrypt.client.plugins.nginx.parser import case_i
# test = self.parser.find_dir(case_i("Listen"), "443")
# # This will only look in enabled hosts
# test2 = self.parser.find_dir(case_i("documentroot"))
# self.assertEqual(len(test), 2)
# self.assertEqual(len(test2), 3)
#
# def test_add_dir(self):
# aug_default = "/files" + self.parser.loc["default"]
# self.parser.add_dir(aug_default, "AddDirective", "test")
#
# self.assertTrue(
# self.parser.find_dir("AddDirective", "test", aug_default))
#
# self.parser.add_dir(aug_default, "AddList", ["1", "2", "3", "4"])
# matches = self.parser.find_dir("AddList", None, aug_default)
# for i, match in enumerate(matches):
# self.assertEqual(self.parser.aug.get(match), str(i + 1))
#
# def test_add_dir_to_ifmodssl(self):
# """test add_dir_to_ifmodssl.
#
# Path must be valid before attempting to add to augeas
#
# """
# from letsencrypt.client.plugins.nginx.parser import get_aug_path
# self.parser.add_dir_to_ifmodssl(
# get_aug_path(self.parser.loc["default"]),
# "FakeDirective", "123")
#
# matches = self.parser.find_dir("FakeDirective", "123")
#
# self.assertEqual(len(matches), 1)
# self.assertTrue("IfModule" in matches[0])
#
# def test_get_aug_path(self):
# from letsencrypt.client.plugins.nginx.parser import get_aug_path
# self.assertEqual("/files/etc/nginx", get_aug_path("/etc/nginx"))
#
# def test_set_locations(self):
# with mock.patch("letsencrypt.client.plugins.nginx.parser."
# "os.path") as mock_path:
#
# mock_path.isfile.return_value = False
#
# # pylint: disable=protected-access
# self.assertRaises(errors.LetsEncryptConfiguratorError,
# self.parser._set_locations, self.ssl_options)
#
# mock_path.isfile.side_effect = [True, False, False]
#
# # pylint: disable=protected-access
# results = self.parser._set_locations(self.ssl_options)
#
# self.assertEqual(results["default"], results["listen"])
# self.assertEqual(results["default"], results["name"])
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,9 @@
server {
listen 1234;
server_name example.org;
location / {
root html;
index index.html index.htm;
}
}

View file

@ -0,0 +1,4 @@
server {
listen 9000;
server_name example.com;
}

View file

@ -18,12 +18,12 @@ class NginxTest(unittest.TestCase): # pylint: disable=too-few-public-methods
super(NginxTest, self).setUp()
self.temp_dir, self.config_dir, self.work_dir = dir_setup(
"debian_nginx_2_4/two_vhost_80")
"testdata")
self.ssl_options = setup_nginx_ssl_options(self.config_dir)
self.config_path = os.path.join(
self.temp_dir, "debian_nginx_2_4/two_vhost_80/nginx2")
self.temp_dir, "testdata")
self.rsa256_file = pkg_resources.resource_filename(
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
@ -36,14 +36,14 @@ def get_data_filename(filename):
"letsencrypt.client.plugins.nginx.tests", "testdata/%s" % filename)
def dir_setup(test_dir="debian_nginx_2_4/two_vhost_80"):
def dir_setup(test_dir="debian_nginx/two_vhost_80"):
"""Setup the directories necessary for the configurator."""
temp_dir = tempfile.mkdtemp("temp")
config_dir = tempfile.mkdtemp("config")
work_dir = tempfile.mkdtemp("work")
test_configs = pkg_resources.resource_filename(
"letsencrypt.client.plugins.nginx.tests", "testdata/%s" % test_dir)
"letsencrypt.client.plugins.nginx.tests", test_dir)
shutil.copytree(
test_configs, os.path.join(temp_dir, test_dir), symlinks=True)
@ -54,7 +54,7 @@ def dir_setup(test_dir="debian_nginx_2_4/two_vhost_80"):
def setup_nginx_ssl_options(config_dir):
"""Move the ssl_options into position and return the path."""
option_path = os.path.join(config_dir, "options-ssl.conf")
shutil.copyfile(constants.APACHE_MOD_SSL_CONF, option_path)
shutil.copyfile(constants.NGINX_MOD_SSL_CONF, option_path)
return option_path