# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Unittest for Aruba acl rendering module."""

import datetime
import logging
import textwrap
from absl.testing import absltest
from unittest import mock

from capirca.lib import aruba
from capirca.lib import nacaddr
from capirca.lib import naming
from capirca.lib import policy

GOOD_HEADER_V4 = """
header {
  target:: aruba test-filter
}
"""

GOOD_HEADER_V6 = """
header {
  target:: aruba test-filter inet6
}
"""

GOOD_HEADER_NOVERBOSE = """
header {
  target:: aruba test-filter noverbose
}
"""

EXPIRED_TERM = """
term is-expired {
  expiration:: 2010-01-01
  action:: accept
}
"""

EXPIRING_TERM = """
term is-expiring {
  expiration:: %s
  action:: accept
}
"""

GOOD_TERM_SIMPLE = """
term good-term-simple {
  action:: accept
}
"""

GOOD_TERM_SHORT_COMMENT = """
term good-term-short-comment {
  comment:: "Some short comment."
  owner:: someowner
  action:: deny
}
"""

GOOD_TERM_LONG_COMMENT = """
term good-term-long-comment {
  comment:: "Two households, both alike in dignity,"
  comment:: "In fair Verona, where we lay our scene,"
  comment:: "From ancient grudge break to new mutiny, Where civil blood makes civil hands unclean."
  owner:: wshakespeare
  action:: accept
}
"""

GOOD_TERM_VERBATIM = """
term much-verbatim {
  verbatim:: aruba "aruba uses some odd ACL format"
  verbatim:: aruba "which is kinda like, weird"
  verbatim:: aruba ""
  verbatim:: cisco "But Cisco's format is Ok, tho."
  verbatim:: juniper "And Juniper's is the best!"
}
"""

GOOD_TERM_ALLOW_ANY_ANY = """
term good-term-allow-any-any {
  action:: accept
}
"""

GOOD_TERM_DENY_ANY_ANY = """
term good-term-deny-any-any {
  action:: deny
}
"""

GOOD_TERM_SINGLE_NETDESTINATION = """
term gt-one-netd {
  source-address:: SINGLE_HOST
  protocol:: icmp
  action:: accept
}
"""

GOOD_TERM_TWO_NETDESTINATIONS = """
term gt-two-netd {
  source-address:: SINGLE_HOST
  destination-address:: SINGLE_HOST
  protocol:: icmp
  action:: accept
}
"""

GOOD_TERM_TWO_NETWORK_NETDESTINATIONS = """
term gt-mix-netd {
  source-address:: SOME_NETWORK
  destination-address:: SOME_NETWORK
  protocol:: icmp
  action:: accept
}
"""

GOOD_TERM_COMBINED_NETDESTINATIONS = """
term good-term-combined-netdestinations {
  source-address:: MIXED_HOSTS
  protocol:: tcp
  destination-port:: HTTP
  action:: deny
}
"""

GOOD_TERMS_COMBINED_SINGLE_CASE = """
term good-terms-combined-1 {
  source-address:: SOME_HOST
  destination-address:: SOME_HOST
  protocol:: udp
  destination-port:: TFTP
  action:: accept
}

term good-terms-combined-2 {
  action:: deny
}
"""

GOOD_TERM_SOURCE_IS_USER = """
term good-term-source-is-user {
  destination-address:: SOME_NETWORK
  protocol:: tcp
  destination-port:: DNS
  action:: accept
  option:: source-is-user
}
"""

GOOD_TERM_DESTINATION_IS_USER = """
term good-term-destination-is-user {
  source-address:: SOME_NETWORK
  protocol:: tcp
  destination-port:: DNS
  action:: accept
  option:: destination-is-user
}
"""

GOOD_TERM_NEGATE_1 = """
term good-term-negate {
  source-address:: SOME_NETWORK
  action:: deny
  option:: negate
}
"""

GOOD_TERM_NEGATE_2 = """
term good-term-negate {
  action:: accept
  option:: negate
}
"""

GOOD_TERM_PROTOCOL_MAP = """
term allow-icmp {
  protocol:: icmp
  action:: accept
}

term allow-gre {
  protocol:: gre
  action:: accept
}

term allow-esp {
  protocol:: esp
  action:: accept
}
"""

SUPPORTED_TOKENS = {
    'action',
    'comment',
    'destination_address',
    'destination_port',
    'expiration',
    'stateless_reply',
    'name',
    'option',
    'protocol',
    'source_address',
    'translated',
    'verbatim',
}

SUPPORTED_SUB_TOKENS = {
    'action': {
        'accept',
        'deny',
    },
    'option': {
        'source-is-user',
        'destination-is-user',
        'negate',
    },
}

# Print a info message when a term is set to expire in that many weeks.
# This is normally passed from command line.
EXP_INFO = 2


class ArubaTest(absltest.TestCase):

  def setUp(self):
    super().setUp()
    self.naming = mock.create_autospec(naming.Naming)

  def testBuildTokens(self):
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_SIMPLE,
                                         self.naming), EXP_INFO)
    st, sst = aru._BuildTokens()
    self.assertEqual(SUPPORTED_TOKENS, st)
    self.assertEqual(SUPPORTED_SUB_TOKENS, sst)

  @mock.patch.object(logging, 'warning')
  def testExpiredTerm(self, mock_warn):
    aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 + EXPIRED_TERM,
                                   self.naming), EXP_INFO)
    mock_warn.assert_called_once_with(
        'WARNING: Term %s in policy %s is expired and will not '
        'be rendered.', 'is-expired', 'test-filter')

  @mock.patch.object(logging, 'info')
  def testExpiringTerm(self, mock_info):
    exp_date = datetime.date.today() + datetime.timedelta(weeks=EXP_INFO)
    aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 + EXPIRING_TERM %
                                   exp_date.strftime('%Y-%m-%d'),
                                   self.naming), EXP_INFO)
    mock_info.assert_called_once_with(
        'INFO: Term %s in policy %s expires in '
        'less than two weeks.', 'is-expiring', 'test-filter')

  def testSimpleTerm(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      any any any permit
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_SIMPLE,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testShortComment(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      # Some short comment.
      # Owner: someowner
      any any any deny
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_SHORT_COMMENT,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testNoVerbose(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      any any any deny
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_NOVERBOSE +
                                         GOOD_TERM_SHORT_COMMENT,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testLongWrappedComment(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      # Two households, both alike in dignity,
      # In fair Verona, where we lay our scene,
      # From ancient grudge break to new mutiny, Where civil blood makes civil
      # hands unclean.
      # Owner: wshakespeare
      any any any permit
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_LONG_COMMENT,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testVerbatim(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      aruba uses some odd ACL format
      which is kinda like, weird
      any any any permit
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_VERBATIM +
                                         GOOD_TERM_ALLOW_ANY_ANY,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testMultipleCallsSingleOwnerLine(self):
    expected_result = textwrap.dedent("""\
        # $Id:$
        # $Date:$
        # $Revision:$
        ip access-list session test-filter
          # Two households, both alike in dignity,
          # In fair Verona, where we lay our scene,
          # From ancient grudge break to new mutiny, Where civil blood makes civil
          # hands unclean.
          # Owner: wshakespeare
          any any any permit
        !
        """)
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_LONG_COMMENT,
                                         self.naming), EXP_INFO)
    self.assertEqual(expected_result, str(aru))
    self.assertEqual(expected_result, str(aru))

  def testTermAllowAnyAnyIPv4(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      any any any permit
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_ALLOW_ANY_ANY,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testTermAllowAnyAnyIPv6(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      ipv6 any any any permit
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 +
                                         GOOD_TERM_ALLOW_ANY_ANY,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testTermDenyAnyAnyIPv4(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      any any any deny
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_DENY_ANY_ANY,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testTermDenyAnyAnyIPv6(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      ipv6 any any any deny
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 +
                                         GOOD_TERM_DENY_ANY_ANY,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testMultipleCallsSingleNetdestinationsBlock(self):
    expected_result = textwrap.dedent("""\
        # $Id:$
        # $Date:$
        # $Revision:$
        netdestination gt-one-netd_src
          host 10.1.1.1
        !

        ip access-list session test-filter
          alias gt-one-netd_src any 1 permit
        !
        """)
    self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.1/32')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_SINGLE_NETDESTINATION,
                                         self.naming), EXP_INFO)
    self.assertEqual(expected_result, str(aru))
    self.assertEqual(expected_result, str(aru))

  def testSingleNetdestinationIPv4(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination gt-one-netd_src
      host 10.1.1.1
    !

    ip access-list session test-filter
      alias gt-one-netd_src any 1 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.1/32')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_SINGLE_NETDESTINATION,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testSingleNetdestinationIPv6(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination6 gt-one-netd_src
      host 2001::
    !

    ip access-list session test-filter
      ipv6 alias gt-one-netd_src any 1 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('2001::/128')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 +
                                         GOOD_TERM_SINGLE_NETDESTINATION,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testTwoNetdestinationsIPv4(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination gt-two-netd_src
      host 10.1.1.1
    !

    netdestination gt-two-netd_dst
      host 10.1.1.1
    !

    ip access-list session test-filter
      alias gt-two-netd_src alias gt-two-netd_dst 1 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.1/32')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_TWO_NETDESTINATIONS,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testTwoNetdestinationsIPv6(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination6 gt-two-netd_src
      host 2001::
    !

    netdestination6 gt-two-netd_dst
      host 2001::
    !

    ip access-list session test-filter
      ipv6 alias gt-two-netd_src alias gt-two-netd_dst 1 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('2001::/128')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 +
                                         GOOD_TERM_TWO_NETDESTINATIONS,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testTwoNetworkNetdestinationsIPv4(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination gt-mix-netd_src
      network 10.0.0.0 255.0.0.0
    !

    netdestination gt-mix-netd_dst
      network 10.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      alias gt-mix-netd_src alias gt-mix-netd_dst 1 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('10.0.0.0/8')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_TWO_NETWORK_NETDESTINATIONS,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testTwoNetworkNetdestinationsIPv6(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination6 gt-mix-netd_src
      network 2001::/64
    !

    netdestination6 gt-mix-netd_dst
      network 2001::/64
    !

    ip access-list session test-filter
      ipv6 alias gt-mix-netd_src alias gt-mix-netd_dst 1 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('2001::/64')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 +
                                         GOOD_TERM_TWO_NETWORK_NETDESTINATIONS,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testCombinedNetdestinationsIPv4(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination good-term-combined-netdestinations_src
      host 10.0.0.1
      network 100.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      alias good-term-combined-netdestinations_src any tcp 80 deny
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8'),
                                           nacaddr.IP('10.0.0.1/32')]
    self.naming.GetServiceByProto.return_value = ['80']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_COMBINED_NETDESTINATIONS,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testCombinedNetdestinationsIPv6(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination6 good-term-combined-netdestinations_src
      host 2001::
      network 2002::/64
    !

    ip access-list session test-filter
      ipv6 alias good-term-combined-netdestinations_src any tcp 80 deny
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('2002::/64'),
                                           nacaddr.IP('2001::/128')]
    self.naming.GetServiceByProto.return_value = ['80']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 +
                                         GOOD_TERM_COMBINED_NETDESTINATIONS,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testMultipleTermsIPv4(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination good-terms-combined-1_src
      host 10.0.0.1
      network 100.0.0.0 255.0.0.0
    !

    netdestination good-terms-combined-1_dst
      host 10.0.0.1
      network 100.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      alias good-terms-combined-1_src alias good-terms-combined-1_dst udp 69 permit
      any any any deny
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8'),
                                           nacaddr.IP('10.0.0.1/32')]
    self.naming.GetServiceByProto.return_value = ['69']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERMS_COMBINED_SINGLE_CASE,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testMultipleTermsIPv6(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination6 good-terms-combined-1_src
      host 2001::
      network 2002::/64
    !

    netdestination6 good-terms-combined-1_dst
      host 2001::
      network 2002::/64
    !

    ip access-list session test-filter
      ipv6 alias good-terms-combined-1_src alias good-terms-combined-1_dst udp 69 permit
      ipv6 any any any deny
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('2002::/64'),
                                           nacaddr.IP('2001::/128')]
    self.naming.GetServiceByProto.return_value = ['69']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 +
                                         GOOD_TERMS_COMBINED_SINGLE_CASE,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testSourceIsUser(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination good-term-source-is-user_dst
      network 100.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      user alias good-term-source-is-user_dst tcp 53 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')]
    self.naming.GetServiceByProto.return_value = ['53']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_SOURCE_IS_USER,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testDestinationIsUser(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination good-term-destination-is-user_src
      network 100.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      alias good-term-destination-is-user_src user tcp 53 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')]
    self.naming.GetServiceByProto.return_value = ['53']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_DESTINATION_IS_USER,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testProtocolIsContiguousRange(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination good-term-destination-is-user_src
      network 100.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      alias good-term-destination-is-user_src user tcp 53 55 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')]
    self.naming.GetServiceByProto.return_value = ['53-55', '54']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_DESTINATION_IS_USER,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testProtocolIsDiscontiguousRange(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination good-term-destination-is-user_src
      network 100.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      alias good-term-destination-is-user_src user tcp 1 permit
      alias good-term-destination-is-user_src user tcp 10 20 permit
      alias good-term-destination-is-user_src user tcp 53 55 permit
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')]
    self.naming.GetServiceByProto.return_value = ['53-55', '54', '10-20', '1']
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_DESTINATION_IS_USER,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testNegateWithNetwork(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    netdestination good-term-negate_src
      network 100.0.0.0 255.0.0.0
    !

    ip access-list session test-filter
      no alias good-term-negate_src any any deny
    !
    """
    self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')]
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_NEGATE_1,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testNegateAny(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      no any any any permit
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_NEGATE_2,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))

  def testProtocolMap(self):
    expected_result = """\
    # $Id:$
    # $Date:$
    # $Revision:$
    ip access-list session test-filter
      any any 1 permit
      any any 47 permit
      any any 50 permit
    !
    """
    aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 +
                                         GOOD_TERM_PROTOCOL_MAP,
                                         self.naming), EXP_INFO)
    self.assertEqual(textwrap.dedent(expected_result), str(aru))


if __name__ == '__main__':
  absltest.main()
