Compare commits
1 Commits
test-upgra
...
dual_inter
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49ae6d4921 |
138
certbot-apache/certbot_apache/assertions.py
Normal file
138
certbot-apache/certbot_apache/assertions.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from certbot_apache import interfaces
|
||||
|
||||
|
||||
PASS = "CERTBOT_PASS_ASSERT"
|
||||
|
||||
|
||||
def assertEqual(first, second):
|
||||
""" Equality assertion """
|
||||
|
||||
if isinstance(first, interfaces.CommentNode):
|
||||
assertEqualComment(first, second)
|
||||
elif isinstance(first, interfaces.DirectiveNode):
|
||||
assertEqualDirective(first, second)
|
||||
elif isinstance(first, interfaces.BlockNode):
|
||||
assertEqualBlock(first, second)
|
||||
|
||||
# Skip tests if filepath includes the pass value. This is done
|
||||
# because filepath is variable of the base ParserNode interface, and
|
||||
# unless the implementation is actually done, we cannot assume getting
|
||||
# correct results from boolean assertion for dirty
|
||||
if not isPass(first.filepath, second.filepath):
|
||||
assert first.dirty == second.dirty
|
||||
# We might want to disable this later if testing with two separate
|
||||
# (but identical) directory structures.
|
||||
assert first.filepath == second.filepath
|
||||
|
||||
def assertEqualComment(first, second):
|
||||
""" Equality assertion for CommentNode """
|
||||
|
||||
assert isinstance(first, interfaces.CommentNode)
|
||||
assert isinstance(second, interfaces.CommentNode)
|
||||
|
||||
if not isPass(first.comment, second.comment):
|
||||
assert first.comment == second.comment
|
||||
|
||||
if not isPass(first.filepath, second.filepath):
|
||||
assert first.filepath == second.filepath
|
||||
|
||||
def _assertEqualDirectiveComponents(first, second):
|
||||
""" Handles assertion for instance variables for DirectiveNode and BlockNode"""
|
||||
|
||||
# Enabled value cannot be asserted, because Augeas implementation
|
||||
# is unable to figure that out.
|
||||
# assert first.enabled == second.enabled
|
||||
if not isPass(first.name, second.name):
|
||||
assert first.name == second.name
|
||||
|
||||
if not isPass(first.filepath, second.filepath):
|
||||
assert first.filepath == second.filepath
|
||||
|
||||
if not isPass(first.parameters, second.parameters):
|
||||
assert first.parameters == second.parameters
|
||||
|
||||
def assertEqualDirective(first, second):
|
||||
""" Equality assertion for DirectiveNode """
|
||||
|
||||
assert isinstance(first, interfaces.DirectiveNode)
|
||||
assert isinstance(second, interfaces.DirectiveNode)
|
||||
_assertEqualDirectiveComponents(first, second)
|
||||
|
||||
def assertEqualBlock(first, second):
|
||||
""" Equality assertion for BlockNode """
|
||||
|
||||
# first was checked in the assertEqual method
|
||||
assert isinstance(first, interfaces.BlockNode)
|
||||
assert isinstance(second, interfaces.BlockNode)
|
||||
_assertEqualDirectiveComponents(first, second)
|
||||
# Children cannot be asserted, because Augeas implementation will not
|
||||
# prepopulate the sequence of children.
|
||||
# assert len(first.children) == len(second.children)
|
||||
|
||||
def isPass(first, second):
|
||||
""" Checks if either first or second holds the assertion pass value """
|
||||
|
||||
if isinstance(first, tuple) or isinstance(first, list):
|
||||
if PASS in first:
|
||||
return True
|
||||
if isinstance(second, tuple) or isinstance(second, list):
|
||||
if PASS in second:
|
||||
return True
|
||||
if PASS in [first, second]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def isPassNodeList(nodelist):
|
||||
""" Checks if a ParserNode in the nodelist should pass the assertion,
|
||||
this function is used for results of find_* methods. Unimplemented find_*
|
||||
methods should return a sequence containing a single ParserNode instance
|
||||
with assertion pass string."""
|
||||
|
||||
try:
|
||||
node = nodelist[0]
|
||||
except IndexError:
|
||||
node = None
|
||||
|
||||
if not node:
|
||||
# Empty result means that the method is implemented
|
||||
return False
|
||||
|
||||
if isinstance(node, interfaces.BlockNode):
|
||||
return _isPassDirective(node)
|
||||
if isinstance(node, interfaces.DirectiveNode):
|
||||
return _isPassDirective(node)
|
||||
return _isPassComment(node)
|
||||
|
||||
def _isPassDirective(block):
|
||||
""" Checks if BlockNode or DirectiveNode should pass the assertion """
|
||||
|
||||
if block.name == PASS:
|
||||
return True
|
||||
if PASS in block.parameters:
|
||||
return True
|
||||
if block.filepath == PASS:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _isPassComment(comment):
|
||||
""" Checks if CommentNode should pass the assertion """
|
||||
|
||||
if comment.comment == PASS:
|
||||
return True
|
||||
if comment.filepath == PASS:
|
||||
return True
|
||||
return False
|
||||
|
||||
def assertSimple(first, second):
|
||||
""" Simple assertion """
|
||||
if not isPass(first, second):
|
||||
assert first == second
|
||||
|
||||
def assertSimpleList(first, second):
|
||||
""" Simple assertion that lists contain the same objects. This needs to
|
||||
be used when there's uncertainty about the ordering of the list. """
|
||||
|
||||
if not isPass(first, second):
|
||||
if first:
|
||||
for f in first:
|
||||
assert f in second
|
||||
127
certbot-apache/certbot_apache/augeasparser.py
Normal file
127
certbot-apache/certbot_apache/augeasparser.py
Normal file
@@ -0,0 +1,127 @@
|
||||
""" Augeas implementation of the ParserNode interface """
|
||||
from certbot_apache import assertions
|
||||
from certbot_apache import interfaces
|
||||
from certbot_apache import parsernode_util as util
|
||||
|
||||
|
||||
class AugeasParserNode(interfaces.ParserNode):
|
||||
""" Augeas implementation of ParserNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
ancestor, dirty, filepath, metadata = util.parsernode_kwargs(kwargs)
|
||||
self.ancestor = ancestor
|
||||
# self.filepath = filepath
|
||||
self.filepath = assertions.PASS
|
||||
self.dirty = dirty
|
||||
self.metadata = metadata
|
||||
|
||||
def save(self, msg): # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class AugeasCommentNode(AugeasParserNode):
|
||||
""" Augeas implementation of CommentNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
comment, kwargs = util.commentnode_kwargs(kwargs)
|
||||
super(AugeasCommentNode, self).__init__(**kwargs)
|
||||
self.comment = comment
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return (self.comment == other.comment and
|
||||
self.filepath == other.filepath and
|
||||
self.dirty == other.dirty and
|
||||
self.ancestor == other.ancestor and
|
||||
self.metadata == other.metadata)
|
||||
|
||||
|
||||
class AugeasDirectiveNode(AugeasParserNode):
|
||||
""" Augeas implementation of DirectiveNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
name, parameters, enabled, kwargs = util.directivenode_kwargs(kwargs)
|
||||
super(AugeasDirectiveNode, self).__init__(**kwargs)
|
||||
self.name = name
|
||||
self.parameters = parameters
|
||||
self.enabled = enabled
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return (self.name == other.name and
|
||||
self.filepath == other.filepath and
|
||||
self.parameters == other.parameters and
|
||||
self.enabled == other.enabled and
|
||||
self.dirty == other.dirty and
|
||||
self.ancestor == other.ancestor and
|
||||
self.metadata == other.metadata)
|
||||
|
||||
def set_parameters(self, parameters):
|
||||
self.parameters = parameters
|
||||
|
||||
|
||||
class AugeasBlockNode(AugeasDirectiveNode):
|
||||
""" Augeas implementation of BlockNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(AugeasBlockNode, self).__init__(**kwargs)
|
||||
self.children = ()
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return (self.name == other.name and
|
||||
self.filepath == other.filepath and
|
||||
self.parameters == other.parameters and
|
||||
self.children == other.children and
|
||||
self.enabled == other.enabled and
|
||||
self.dirty == other.dirty and
|
||||
self.ancestor == other.ancestor and
|
||||
self.metadata == other.metadata)
|
||||
|
||||
|
||||
def add_child_block(self, name, parameters=None, position=None):
|
||||
new_block = AugeasBlockNode(name=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS)
|
||||
self.children += (new_block,)
|
||||
return new_block
|
||||
|
||||
def add_child_directive(self, name, parameters=None, position=None):
|
||||
new_dir = AugeasDirectiveNode(name=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS)
|
||||
self.children += (new_dir,)
|
||||
return new_dir
|
||||
|
||||
def add_child_comment(self, comment="", position=None):
|
||||
new_comment = AugeasCommentNode(comment=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS)
|
||||
self.children += (new_comment,)
|
||||
return new_comment
|
||||
|
||||
def find_blocks(self, name, exclude=True):
|
||||
return [AugeasBlockNode(name=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS)]
|
||||
|
||||
def find_directives(self, name, exclude=True):
|
||||
return [AugeasDirectiveNode(name=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS)]
|
||||
|
||||
def find_comments(self, comment, exact=False):
|
||||
return [AugeasCommentNode(comment=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS)]
|
||||
|
||||
def delete_child(self, child): # pragma: no cover
|
||||
pass
|
||||
|
||||
def unsaved_files(self): # pragma: no cover
|
||||
return [assertions.PASS]
|
||||
|
||||
|
||||
interfaces.CommentNode.register(AugeasCommentNode)
|
||||
interfaces.DirectiveNode.register(AugeasDirectiveNode)
|
||||
interfaces.BlockNode.register(AugeasBlockNode)
|
||||
318
certbot-apache/certbot_apache/dualparser.py
Normal file
318
certbot-apache/certbot_apache/dualparser.py
Normal file
@@ -0,0 +1,318 @@
|
||||
""" Tests for ParserNode interface """
|
||||
from certbot_apache import assertions
|
||||
from certbot_apache import augeasparser
|
||||
|
||||
|
||||
class DualNodeBase(object):
|
||||
""" Dual parser interface for in development testing. This is used as the
|
||||
base class for dual parser interface classes. This class handles runtime
|
||||
attribute value assertions."""
|
||||
|
||||
def save(self, msg): # pragma: no cover
|
||||
""" Call save for both parsers """
|
||||
self.primary.save(msg)
|
||||
self.secondary.save(msg)
|
||||
|
||||
def __getattr__(self, aname):
|
||||
""" Attribute value assertion """
|
||||
firstval = getattr(self.primary, aname)
|
||||
secondval = getattr(self.secondary, aname)
|
||||
if not assertions.isPass(firstval, secondval):
|
||||
assertions.assertSimple(firstval, secondval)
|
||||
return firstval
|
||||
|
||||
|
||||
class DualCommentNode(DualNodeBase):
|
||||
""" Dual parser implementation of CommentNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
""" This initialization implementation allows ordinary initialization
|
||||
of CommentNode objects as well as creating a DualCommentNode object
|
||||
using precreated or fetched CommentNode objects if provided as optional
|
||||
arguments primary and secondary.
|
||||
|
||||
Parameters other than the following are from interfaces.CommentNode:
|
||||
|
||||
:param CommentNode primary: Primary pre-created CommentNode, mainly
|
||||
used when creating new DualParser nodes using add_* methods.
|
||||
:param CommentNode secondary: Secondary pre-created CommentNode
|
||||
"""
|
||||
|
||||
kwargs.setdefault("primary", None)
|
||||
kwargs.setdefault("secondary", None)
|
||||
primary = kwargs.pop("primary")
|
||||
secondary = kwargs.pop("secondary")
|
||||
|
||||
if not primary:
|
||||
self.primary = augeasparser.AugeasCommentNode(**kwargs)
|
||||
else:
|
||||
self.primary = primary
|
||||
if not secondary:
|
||||
self.secondary = augeasparser.AugeasCommentNode(**kwargs)
|
||||
else:
|
||||
self.secondary = secondary
|
||||
|
||||
assertions.assertEqual(self.primary, self.secondary)
|
||||
|
||||
|
||||
class DualDirectiveNode(DualNodeBase):
|
||||
""" Dual parser implementation of DirectiveNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
""" This initialization implementation allows ordinary initialization
|
||||
of DirectiveNode objects as well as creating a DualDirectiveNode object
|
||||
using precreated or fetched DirectiveNode objects if provided as optional
|
||||
arguments primary and secondary.
|
||||
|
||||
Parameters other than the following are from interfaces.DirectiveNode:
|
||||
|
||||
:param DirectiveNode primary: Primary pre-created DirectiveNode, mainly
|
||||
used when creating new DualParser nodes using add_* methods.
|
||||
:param DirectiveNode secondary: Secondary pre-created DirectiveNode
|
||||
|
||||
|
||||
"""
|
||||
|
||||
kwargs.setdefault("primary", None)
|
||||
kwargs.setdefault("secondary", None)
|
||||
primary = kwargs.pop("primary")
|
||||
secondary = kwargs.pop("secondary")
|
||||
|
||||
if not primary:
|
||||
self.primary = augeasparser.AugeasDirectiveNode(**kwargs)
|
||||
else:
|
||||
self.primary = primary
|
||||
|
||||
if not secondary:
|
||||
self.secondary = augeasparser.AugeasDirectiveNode(**kwargs)
|
||||
else:
|
||||
self.secondary = secondary
|
||||
|
||||
assertions.assertEqual(self.primary, self.secondary)
|
||||
|
||||
def set_parameters(self, parameters):
|
||||
""" Sets parameters and asserts that both implementation successfully
|
||||
set the parameter sequence """
|
||||
|
||||
self.primary.set_parameters(parameters)
|
||||
self.secondary.set_parameters(parameters)
|
||||
assertions.assertEqual(self.primary, self.secondary)
|
||||
|
||||
|
||||
class DualBlockNode(DualDirectiveNode):
|
||||
""" Dual parser implementation of BlockNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
""" This initialization implementation allows ordinary initialization
|
||||
of BlockNode objects as well as creating a DualBlockNode object
|
||||
using precreated or fetched BlockNode objects if provided as optional
|
||||
arguments primary and secondary.
|
||||
|
||||
Parameters other than the following are from interfaces.BlockNode:
|
||||
|
||||
:param BlockNode primary: Primary pre-created BlockNode, mainly
|
||||
used when creating new DualParser nodes using add_* methods.
|
||||
:param BlockNode secondary: Secondary pre-created BlockNode
|
||||
"""
|
||||
|
||||
kwargs.setdefault("primary", None)
|
||||
kwargs.setdefault("secondary", None)
|
||||
primary = kwargs.pop("primary")
|
||||
secondary = kwargs.pop("secondary")
|
||||
|
||||
if not primary:
|
||||
self.primary = augeasparser.AugeasBlockNode(**kwargs)
|
||||
else:
|
||||
self.primary = primary
|
||||
|
||||
if not secondary:
|
||||
self.secondary = augeasparser.AugeasBlockNode(**kwargs)
|
||||
else:
|
||||
self.secondary = secondary
|
||||
|
||||
assertions.assertEqual(self.primary, self.secondary)
|
||||
|
||||
def add_child_block(self, name, parameters=None, position=None):
|
||||
""" Creates a new child BlockNode, asserts that both implementations
|
||||
did it in a similar way, and returns a newly created DualBlockNode object
|
||||
encapsulating both of the newly created objects """
|
||||
|
||||
primary_new = self.primary.add_child_block(name, parameters, position)
|
||||
secondary_new = self.secondary.add_child_block(name, parameters, position)
|
||||
assertions.assertEqual(primary_new, secondary_new)
|
||||
new_block = DualBlockNode(primary=primary_new, secondary=secondary_new)
|
||||
return new_block
|
||||
|
||||
def add_child_directive(self, name, parameters=None, position=None):
|
||||
""" Creates a new child DirectiveNode, asserts that both implementations
|
||||
did it in a similar way, and returns a newly created DualDirectiveNode
|
||||
object encapsulating both of the newly created objects """
|
||||
|
||||
primary_new = self.primary.add_child_directive(name, parameters, position)
|
||||
secondary_new = self.secondary.add_child_directive(name, parameters, position)
|
||||
assertions.assertEqual(primary_new, secondary_new)
|
||||
new_dir = DualDirectiveNode(primary=primary_new, secondary=secondary_new)
|
||||
return new_dir
|
||||
|
||||
def add_child_comment(self, comment="", position=None):
|
||||
""" Creates a new child CommentNode, asserts that both implementations
|
||||
did it in a similar way, and returns a newly created DualCommentNode
|
||||
object encapsulating both of the newly created objects """
|
||||
|
||||
primary_new = self.primary.add_child_comment(comment, position)
|
||||
secondary_new = self.secondary.add_child_comment(comment, position)
|
||||
assertions.assertEqual(primary_new, secondary_new)
|
||||
new_comment = DualCommentNode(primary=primary_new, secondary=secondary_new)
|
||||
return new_comment
|
||||
|
||||
def _create_matching_list(self, primary_list, secondary_list): # pragma: no cover
|
||||
""" Matches the list of primary_list to a list of secondary_list and
|
||||
returns a list of tuples. This is used to create results for find_
|
||||
methods. """
|
||||
|
||||
matched = list()
|
||||
for p in primary_list:
|
||||
match = None
|
||||
for s in secondary_list:
|
||||
try:
|
||||
assertions.assertEqual(p, s)
|
||||
match = s
|
||||
except AssertionError:
|
||||
continue
|
||||
if match:
|
||||
matched.append((p,s))
|
||||
else:
|
||||
raise AssertionError("Could not find a matching node.")
|
||||
return matched
|
||||
|
||||
def find_blocks(self, name, exclude=True): # pragma: no cover
|
||||
"""
|
||||
Performs a search for BlockNodes using both implementations and does simple
|
||||
checks for results. This is built upon the assumption that unimplemented
|
||||
find_* methods return a list with a single assertion passing object.
|
||||
After the assertion, it creates a list of newly created DualBlockNode
|
||||
instances that encapsulate the pairs of returned BlockNode objects.
|
||||
"""
|
||||
|
||||
primary_blocks = self.primary.find_blocks(name, exclude)
|
||||
secondary_blocks = self.secondary.find_blocks(name, exclude)
|
||||
|
||||
# The order of search results for Augeas implementation cannot be
|
||||
# assured.
|
||||
|
||||
pass_primary = assertions.isPassNodeList(primary_blocks)
|
||||
pass_secondary = assertions.isPassNodeList(secondary_blocks)
|
||||
new_blocks = list()
|
||||
|
||||
if pass_primary and pass_secondary:
|
||||
# Both unimplemented
|
||||
new_blocks.append(DualBlockNode(primary=primary_blocks[0],
|
||||
secondary=secondary_blocks[0]))
|
||||
elif pass_primary:
|
||||
for c in secondary_blocks:
|
||||
new_blocks.append(DualBlockNode(primary=primary_blocks[0],
|
||||
secondary=c))
|
||||
elif pass_secondary:
|
||||
for c in primary_blocks:
|
||||
new_blocks.append(DualBlockNode(primary=c,
|
||||
secondary=secondary_blocks[0]))
|
||||
else:
|
||||
assert len(primary_blocks) == len(secondary_blocks)
|
||||
matches = self._create_matching_list(primary_blocks, secondary_blocks)
|
||||
for p,s in matches:
|
||||
new_blocks.append(DualBlockNode(primary=p, secondary=s))
|
||||
|
||||
return new_blocks
|
||||
|
||||
def find_directives(self, name, exclude=True): # pragma: no cover
|
||||
"""
|
||||
Performs a search for DirectiveNodes using both implementations and
|
||||
checks the results. This is built upon the assumption that unimplemented
|
||||
find_* methods return a list with a single assertion passing object.
|
||||
After the assertion, it creates a list of newly created DualDirectiveNode
|
||||
instances that encapsulate the pairs of returned DirectiveNode objects.
|
||||
"""
|
||||
primary_dirs = self.primary.find_directives(name, exclude)
|
||||
secondary_dirs = self.secondary.find_directives(name, exclude)
|
||||
|
||||
# The order of search results for Augeas implementation cannot be
|
||||
# assured.
|
||||
|
||||
pass_primary = assertions.isPassNodeList(primary_dirs)
|
||||
pass_secondary = assertions.isPassNodeList(secondary_dirs)
|
||||
new_dirs = list()
|
||||
|
||||
if pass_primary and pass_secondary:
|
||||
# Both unimplemented
|
||||
new_dirs.append(DualDirectiveNode(primary=primary_dirs[0],
|
||||
secondary=secondary_dirs[0]))
|
||||
elif pass_primary:
|
||||
for c in secondary_dirs:
|
||||
new_dirs.append(DualDirectiveNode(primary=primary_dirs[0],
|
||||
secondary=c))
|
||||
elif pass_secondary:
|
||||
for c in primary_dirs:
|
||||
new_dirs.append(DualDirectiveNode(primary=c,
|
||||
secondary=secondary_dirs[0]))
|
||||
else:
|
||||
assert len(primary_dirs) == len(secondary_dirs)
|
||||
matches = self._create_matching_list(primary_dirs, secondary_dirs)
|
||||
for p,s in matches:
|
||||
new_dirs.append(DualDirectiveNode(primary=p, secondary=s))
|
||||
|
||||
return new_dirs
|
||||
|
||||
def find_comments(self, comment, exact=False): # pragma: no cover
|
||||
"""
|
||||
Performs a search for CommentNodes using both implementations and
|
||||
checks the results. This is built upon the assumption that unimplemented
|
||||
find_* methods return a list with a single assertion passing object.
|
||||
After the assertion, it creates a list of newly created DualCommentNode
|
||||
instances that encapsulate the pairs of returned CommentNode objects.
|
||||
"""
|
||||
primary_com = self.primary.find_comments(comment, exact)
|
||||
secondary_com = self.secondary.find_comments(comment, exact)
|
||||
|
||||
# The order of search results for Augeas implementation cannot be
|
||||
# assured.
|
||||
|
||||
pass_primary = assertions.isPassNodeList(primary_com)
|
||||
pass_secondary = assertions.isPassNodeList(secondary_com)
|
||||
new_com = list()
|
||||
|
||||
if pass_primary and pass_secondary:
|
||||
# Both unimplemented
|
||||
new_com.append(DualCommentNode(primary=primary_com[0],
|
||||
secondary=secondary_com[0]))
|
||||
elif pass_primary:
|
||||
for c in secondary_com:
|
||||
new_com.append(DualCommentNode(primary=primary_com[0],
|
||||
secondary=c))
|
||||
elif pass_secondary:
|
||||
for c in primary_com:
|
||||
new_com.append(DualCommentNode(primary=c,
|
||||
secondary=secondary_com[0]))
|
||||
else:
|
||||
assert len(primary_com) == len(secondary_com)
|
||||
matches = self._create_matching_list(primary_com, secondary_com)
|
||||
for p,s in matches:
|
||||
new_com.append(DualCommentNode(primary=p, secondary=s))
|
||||
|
||||
return new_com
|
||||
|
||||
def delete_child(self, child): # pragma: no cover
|
||||
"""Deletes a child from the ParserNode implementations. The actual
|
||||
ParserNode implementations are used here directly in order to be able
|
||||
to match a child to the list of children."""
|
||||
|
||||
self.primary.delete_child(child.primary)
|
||||
self.secondary.delete_child(child.secondary)
|
||||
|
||||
def unsaved_files(self):
|
||||
""" Fetches the list of unsaved file paths and asserts that the lists
|
||||
match """
|
||||
primary_files = self.primary.unsaved_files()
|
||||
secondary_files = self.secondary.unsaved_files()
|
||||
assertions.assertSimple(primary_files, secondary_files)
|
||||
|
||||
return primary_files
|
||||
167
certbot-apache/certbot_apache/tests/dualnode_test.py
Normal file
167
certbot-apache/certbot_apache/tests/dualnode_test.py
Normal file
@@ -0,0 +1,167 @@
|
||||
"""Tests for DualParserNode implementation"""
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
||||
from certbot_apache import assertions
|
||||
from certbot_apache import dualparser
|
||||
|
||||
|
||||
class DualParserNodeTest(unittest.TestCase):
|
||||
"""DualParserNode tests"""
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
self.block = dualparser.DualBlockNode(name="block",
|
||||
ancestor=None,
|
||||
filepath="/tmp/something")
|
||||
self.block_two = dualparser.DualBlockNode(name="block",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something")
|
||||
self.directive = dualparser.DualDirectiveNode(name="directive",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something")
|
||||
self.comment = dualparser.DualCommentNode(comment="comment",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something")
|
||||
|
||||
def test_create_with_primary(self):
|
||||
cnode = dualparser.DualCommentNode(comment="comment",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something",
|
||||
primary=self.comment.secondary)
|
||||
dnode = dualparser.DualDirectiveNode(name="directive",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something",
|
||||
primary=self.directive.secondary)
|
||||
bnode = dualparser.DualBlockNode(name="block",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something",
|
||||
primary=self.block.secondary)
|
||||
self.assertTrue(cnode.primary is self.comment.secondary)
|
||||
self.assertTrue(dnode.primary is self.directive.secondary)
|
||||
self.assertTrue(bnode.primary is self.block.secondary)
|
||||
|
||||
def test_create_with_secondary(self):
|
||||
cnode = dualparser.DualCommentNode(comment="comment",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something",
|
||||
secondary=self.comment.primary)
|
||||
dnode = dualparser.DualDirectiveNode(name="directive",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something",
|
||||
secondary=self.directive.primary)
|
||||
bnode = dualparser.DualBlockNode(name="block",
|
||||
ancestor=self.block,
|
||||
filepath="/tmp/something",
|
||||
secondary=self.block.primary)
|
||||
self.assertTrue(cnode.secondary is self.comment.primary)
|
||||
self.assertTrue(dnode.secondary is self.directive.primary)
|
||||
self.assertTrue(bnode.secondary is self.block.primary)
|
||||
|
||||
def test_set_params(self):
|
||||
params = ("first", "second")
|
||||
self.directive.set_parameters(params)
|
||||
self.assertEqual(self.directive.primary.parameters, params)
|
||||
self.assertEqual(self.directive.secondary.parameters, params)
|
||||
|
||||
def test_set_parameters(self):
|
||||
pparams = mock.MagicMock()
|
||||
sparams = mock.MagicMock()
|
||||
pparams.parameters = ("a", "b")
|
||||
sparams.parameters = ("a", "b")
|
||||
self.directive.primary.set_parameters = pparams
|
||||
self.directive.secondary.set_parameters = sparams
|
||||
self.directive.set_parameters(("param","seq"))
|
||||
self.assertTrue(pparams.called)
|
||||
self.assertTrue(sparams.called)
|
||||
|
||||
def test_delete_child(self):
|
||||
pdel = mock.MagicMock()
|
||||
sdel = mock.MagicMock()
|
||||
self.block.primary.delete_child = pdel
|
||||
self.block.secondary.delete_child = sdel
|
||||
self.block.delete_child(self.comment)
|
||||
self.assertTrue(pdel.called)
|
||||
self.assertTrue(sdel.called)
|
||||
|
||||
def test_unsaved_files(self):
|
||||
puns = mock.MagicMock()
|
||||
suns = mock.MagicMock()
|
||||
puns.return_value = assertions.PASS
|
||||
suns.return_value = assertions.PASS
|
||||
self.block.primary.unsaved_files = puns
|
||||
self.block.secondary.unsaved_files = suns
|
||||
self.block.unsaved_files()
|
||||
self.assertTrue(puns.called)
|
||||
self.assertTrue(suns.called)
|
||||
|
||||
def test_add_child_block(self):
|
||||
p = mock.MagicMock()
|
||||
p.return_value = self.block
|
||||
s = mock.MagicMock()
|
||||
s.return_value = self.block
|
||||
self.block.primary.add_child_block = p
|
||||
self.block.secondary.add_child_block = s
|
||||
self.block.add_child_block("name")
|
||||
self.assertTrue(p.called)
|
||||
self.assertTrue(s.called)
|
||||
|
||||
def test_add_child_directive(self):
|
||||
p = mock.MagicMock()
|
||||
p.return_value = self.directive
|
||||
s = mock.MagicMock()
|
||||
s.return_value = self.directive
|
||||
self.block.primary.add_child_directive = p
|
||||
self.block.secondary.add_child_directive = s
|
||||
self.block.add_child_directive("name")
|
||||
self.assertTrue(p.called)
|
||||
self.assertTrue(s.called)
|
||||
|
||||
def test_add_child_comment(self):
|
||||
p = mock.MagicMock()
|
||||
p.return_value = self.comment
|
||||
s = mock.MagicMock()
|
||||
s.return_value = self.comment
|
||||
self.block.primary.add_child_comment = p
|
||||
self.block.secondary.add_child_comment = s
|
||||
self.block.add_child_comment("comment")
|
||||
self.assertTrue(p.called)
|
||||
self.assertTrue(s.called)
|
||||
|
||||
def test_find_blocks(self):
|
||||
dblks = self.block.find_blocks("block")
|
||||
p_dblks = [d.primary for d in dblks]
|
||||
s_dblks = [d.secondary for d in dblks]
|
||||
p_blks = self.block.primary.find_blocks("block")
|
||||
s_blks = self.block.secondary.find_blocks("block")
|
||||
# Check that every block response is represented in the list of
|
||||
# DualParserNode instances.
|
||||
for p in p_dblks:
|
||||
self.assertTrue(p in p_blks)
|
||||
for s in s_dblks:
|
||||
self.assertTrue(s in s_blks)
|
||||
|
||||
def test_find_directives(self):
|
||||
ddirs = self.block.find_directives("directive")
|
||||
p_ddirs = [d.primary for d in ddirs]
|
||||
s_ddirs = [d.secondary for d in ddirs]
|
||||
p_dirs = self.block.primary.find_directives("directive")
|
||||
s_dirs = self.block.secondary.find_directives("directive")
|
||||
# Check that every directive response is represented in the list of
|
||||
# DualParserNode instances.
|
||||
for p in p_ddirs:
|
||||
self.assertTrue(p in p_dirs)
|
||||
for s in s_ddirs:
|
||||
self.assertTrue(s in s_dirs)
|
||||
|
||||
def test_find_comments(self):
|
||||
dcoms = self.block.find_comments("comment")
|
||||
p_dcoms = [d.primary for d in dcoms]
|
||||
s_dcoms = [d.secondary for d in dcoms]
|
||||
p_coms = self.block.primary.find_comments("comment")
|
||||
s_coms = self.block.secondary.find_comments("comment")
|
||||
# Check that every comment response is represented in the list of
|
||||
# DualParserNode instances.
|
||||
for p in p_dcoms:
|
||||
self.assertTrue(p in p_coms)
|
||||
for s in s_dcoms:
|
||||
self.assertTrue(s in s_coms)
|
||||
Reference in New Issue
Block a user