#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 The Android Open Source Project
#
# 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.
"""Unittests for the parser module."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import shutil
import tempfile
import unittest

import arch
import bpf
import parser  # pylint: disable=wrong-import-order

ARCH_64 = arch.Arch.load_from_json(
    os.path.join(
        os.path.dirname(os.path.abspath(__file__)), 'testdata/arch_64.json'))


class TokenizerTests(unittest.TestCase):
    """Tests for ParserState.tokenize."""

    @staticmethod
    def _tokenize(line):
        parser_state = parser.ParserState('<memory>')
        return list(parser_state.tokenize([line]))[0]

    def test_tokenize(self):
        """Accept valid tokens."""
        self.assertEqual([
            (token.type, token.value)
            for token in TokenizerTests._tokenize('@include /minijail.policy')
        ], [
            ('INCLUDE', '@include'),
            ('PATH', '/minijail.policy'),
        ])
        self.assertEqual([
            (token.type, token.value)
            for token in TokenizerTests._tokenize('@include ./minijail.policy')
        ], [
            ('INCLUDE', '@include'),
            ('PATH', './minijail.policy'),
        ])
        self.assertEqual(
            [(token.type, token.value) for token in TokenizerTests._tokenize(
                'read: arg0 in ~0xffff || arg0 & (1|2) && arg0 == 0o755; '
                'return ENOSYS # ignored')], [
                    ('IDENTIFIER', 'read'),
                    ('COLON', ':'),
                    ('ARGUMENT', 'arg0'),
                    ('OP', 'in'),
                    ('BITWISE_COMPLEMENT', '~'),
                    ('NUMERIC_CONSTANT', '0xffff'),
                    ('OR', '||'),
                    ('ARGUMENT', 'arg0'),
                    ('OP', '&'),
                    ('LPAREN', '('),
                    ('NUMERIC_CONSTANT', '1'),
                    ('BITWISE_OR', '|'),
                    ('NUMERIC_CONSTANT', '2'),
                    ('RPAREN', ')'),
                    ('AND', '&&'),
                    ('ARGUMENT', 'arg0'),
                    ('OP', '=='),
                    ('NUMERIC_CONSTANT', '0o755'),
                    ('SEMICOLON', ';'),
                    ('RETURN', 'return'),
                    ('IDENTIFIER', 'ENOSYS'),
                ])
        # Ensure that tokens that have an otherwise valid token as prefix are
        # still matched correctly.
        self.assertEqual([
            (token.type, token.value)
            for token in TokenizerTests._tokenize(
                'inotify_wait return_sys killall trace_sys')
        ], [
            ('IDENTIFIER', 'inotify_wait'),
            ('IDENTIFIER', 'return_sys'),
            ('IDENTIFIER', 'killall'),
            ('IDENTIFIER', 'trace_sys'),
        ])

    def test_tokenize_invalid_token(self):
        """Reject tokenizer errors."""
        with self.assertRaisesRegex(parser.ParseException,
                                    (r'<memory>\(1:1\): invalid token\n'
                                     r'    %invalid-token%\n'
                                     r'    \^')):
            TokenizerTests._tokenize('%invalid-token%')


class ParseConstantTests(unittest.TestCase):
    """Tests for PolicyParser.parse_value."""

    def setUp(self):
        self.arch = ARCH_64
        self.parser = parser.PolicyParser(
            self.arch, kill_action=bpf.KillProcess())

    def _tokenize(self, line):
        # pylint: disable=protected-access
        return list(self.parser._parser_state.tokenize([line]))[0]

    def test_parse_constant_unsigned(self):
        """Accept reasonably-sized unsigned constants."""
        self.assertEqual(
            self.parser.parse_value(self._tokenize('0x80000000')), 0x80000000)
        if self.arch.bits == 64:
            self.assertEqual(
                self.parser.parse_value(self._tokenize('0x8000000000000000')),
                0x8000000000000000)

    def test_parse_constant_unsigned_too_big(self):
        """Reject unreasonably-sized unsigned constants."""
        if self.arch.bits == 32:
            with self.assertRaisesRegex(parser.ParseException,
                                        'unsigned overflow'):
                self.parser.parse_value(self._tokenize('0x100000000'))
        with self.assertRaisesRegex(parser.ParseException,
                                    'unsigned overflow'):
            self.parser.parse_value(self._tokenize('0x10000000000000000'))

    def test_parse_constant_signed(self):
        """Accept reasonably-sized signed constants."""
        self.assertEqual(
            self.parser.parse_value(self._tokenize('-1')),
            self.arch.max_unsigned)

    def test_parse_constant_signed_too_negative(self):
        """Reject unreasonably-sized signed constants."""
        if self.arch.bits == 32:
            with self.assertRaisesRegex(parser.ParseException,
                                        'signed underflow'):
                self.parser.parse_value(self._tokenize('-0x800000001'))
        with self.assertRaisesRegex(parser.ParseException, 'signed underflow'):
            self.parser.parse_value(self._tokenize('-0x8000000000000001'))

    def test_parse_mask(self):
        """Accept parsing a mask value."""
        self.assertEqual(
            self.parser.parse_value(self._tokenize('0x1|0x2|0x4|0x8')), 0xf)

    def test_parse_parenthesized_expressions(self):
        """Accept parsing parenthesized expressions."""
        bad_expressions = [
            '(1',
            '|(1)',
            '(1)|',
            '()',
            '(',
            '((',
            '(()',
            '(()1',
        ]
        for expression in bad_expressions:
            with self.assertRaises(parser.ParseException, msg=expression):
                self.parser.parse_value(self._tokenize(expression))

        bad_partial_expressions = [
            '1)',
            '(1)1',
            '1(0)',
        ]
        for expression in bad_partial_expressions:
            tokens = self._tokenize(expression)
            self.parser.parse_value(tokens)
            self.assertNotEqual(tokens, [])

        good_expressions = [
            '(3)',
            '(1)|2',
            '1|(2)',
            '(1)|(2)',
            '((3))',
            '0|(1|2)',
            '(0|1|2)',
        ]
        for expression in good_expressions:
            self.assertEqual(
                self.parser.parse_value(self._tokenize(expression)), 3)

    def test_parse_constant_complements(self):
        """Accept complementing constants."""
        self.assertEqual(
            self.parser.parse_value(self._tokenize('~0')),
            self.arch.max_unsigned)
        self.assertEqual(
            self.parser.parse_value(self._tokenize('~0|~0')),
            self.arch.max_unsigned)
        if self.arch.bits == 32:
            self.assertEqual(
                self.parser.parse_value(
                    self._tokenize('~0x005AF0FF|~0xFFA50FFF')), 0xFFFFFF00)
            self.assertEqual(
                self.parser.parse_value(
                    self._tokenize('0x0F|~(0x005AF000|0x00A50FFF)|0xF0')),
                0xFF0000FF)
        else:
            self.assertEqual(
                self.parser.parse_value(
                    self._tokenize('~0x00005A5AF0F0FFFF|~0xFFFFA5A50F0FFFFF')),
                0xFFFFFFFFFFFF0000)
            self.assertEqual(
                self.parser.parse_value(
                    self._tokenize(
                        '0x00FF|~(0x00005A5AF0F00000|0x0000A5A50F0FFFFF)|0xFF00'
                    )), 0xFFFF00000000FFFF)

    def test_parse_double_complement(self):
        """Reject double-complementing constants."""
        with self.assertRaisesRegex(parser.ParseException,
                                    'double complement'):
            self.parser.parse_value(self._tokenize('~~0'))

    def test_parse_empty_complement(self):
        """Reject complementing nothing."""
        with self.assertRaisesRegex(parser.ParseException, 'empty complement'):
            self.parser.parse_value(self._tokenize('0|~'))

    def test_parse_named_constant(self):
        """Accept parsing a named constant."""
        self.assertEqual(
            self.parser.parse_value(self._tokenize('O_RDONLY')), 0)

    def test_parse_empty_constant(self):
        """Reject parsing nothing."""
        with self.assertRaisesRegex(parser.ParseException, 'empty constant'):
            self.parser.parse_value([])
        with self.assertRaisesRegex(parser.ParseException, 'empty constant'):
            self.parser.parse_value(self._tokenize('0|'))

    def test_parse_invalid_constant(self):
        """Reject parsing invalid constants."""
        with self.assertRaisesRegex(parser.ParseException, 'invalid constant'):
            self.parser.parse_value(self._tokenize('foo'))


class ParseFilterExpressionTests(unittest.TestCase):
    """Tests for PolicyParser.parse_argument_expression."""

    def setUp(self):
        self.arch = ARCH_64
        self.parser = parser.PolicyParser(
            self.arch, kill_action=bpf.KillProcess())

    def _tokenize(self, line):
        # pylint: disable=protected-access
        return list(self.parser._parser_state.tokenize([line]))[0]

    def test_parse_argument_expression(self):
        """Accept valid argument expressions."""
        self.assertEqual(
            self.parser.parse_argument_expression(
                self._tokenize(
                    'arg0 in 0xffff || arg0 == PROT_EXEC && arg1 == PROT_WRITE'
                )), [
                    [parser.Atom(0, 'in', 0xffff)],
                    [parser.Atom(0, '==', 4),
                     parser.Atom(1, '==', 2)],
                ])

    def test_parse_empty_argument_expression(self):
        """Reject empty argument expressions."""
        with self.assertRaisesRegex(parser.ParseException,
                                    'empty argument expression'):
            self.parser.parse_argument_expression(
                self._tokenize('arg0 in 0xffff ||'))

    def test_parse_empty_clause(self):
        """Reject empty clause."""
        with self.assertRaisesRegex(parser.ParseException, 'empty clause'):
            self.parser.parse_argument_expression(
                self._tokenize('arg0 in 0xffff &&'))

    def test_parse_invalid_argument(self):
        """Reject invalid argument."""
        with self.assertRaisesRegex(parser.ParseException, 'invalid argument'):
            self.parser.parse_argument_expression(
                self._tokenize('argX in 0xffff'))

    def test_parse_invalid_operator(self):
        """Reject invalid operator."""
        with self.assertRaisesRegex(parser.ParseException, 'invalid operator'):
            self.parser.parse_argument_expression(
                self._tokenize('arg0 = 0xffff'))

    def test_parse_missing_operator(self):
        """Reject missing operator."""
        with self.assertRaisesRegex(parser.ParseException, 'missing operator'):
            self.parser.parse_argument_expression(self._tokenize('arg0'))

    def test_parse_missing_operand(self):
        """Reject missing operand."""
        with self.assertRaisesRegex(parser.ParseException, 'empty constant'):
            self.parser.parse_argument_expression(self._tokenize('arg0 =='))


class ParseFilterTests(unittest.TestCase):
    """Tests for PolicyParser.parse_filter."""

    def setUp(self):
        self.arch = ARCH_64
        self.parser = parser.PolicyParser(
            self.arch, kill_action=bpf.KillProcess())

    def _tokenize(self, line):
        # pylint: disable=protected-access
        return list(self.parser._parser_state.tokenize([line]))[0]

    def test_parse_filter(self):
        """Accept valid filters."""
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('arg0 == 0')), [
                parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('kill-process')), [
                parser.Filter(None, bpf.KillProcess()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('kill-thread')), [
                parser.Filter(None, bpf.KillThread()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('trap')), [
                parser.Filter(None, bpf.Trap()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('return ENOSYS')), [
                parser.Filter(None,
                              bpf.ReturnErrno(self.arch.constants['ENOSYS'])),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('trace')), [
                parser.Filter(None, bpf.Trace()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('user-notify')), [
                parser.Filter(None, bpf.UserNotify()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('log')), [
                parser.Filter(None, bpf.Log()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('allow')), [
                parser.Filter(None, bpf.Allow()),
            ])
        self.assertEqual(
            self.parser.parse_filter(self._tokenize('1')), [
                parser.Filter(None, bpf.Allow()),
            ])
        self.assertEqual(
            self.parser.parse_filter(
                self._tokenize(
                    '{ arg0 == 0, arg0 == 1; return ENOSYS, trap }')),
            [
                parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                parser.Filter([[parser.Atom(0, '==', 1)]],
                              bpf.ReturnErrno(self.arch.constants['ENOSYS'])),
                parser.Filter(None, bpf.Trap()),
            ])

    def test_parse_missing_return_value(self):
        """Reject missing return value."""
        with self.assertRaisesRegex(parser.ParseException,
                                    'missing return value'):
            self.parser.parse_filter(self._tokenize('return'))

    def test_parse_invalid_return_value(self):
        """Reject invalid return value."""
        with self.assertRaisesRegex(parser.ParseException, 'invalid constant'):
            self.parser.parse_filter(self._tokenize('return arg0'))

    def test_parse_unclosed_brace(self):
        """Reject unclosed brace."""
        with self.assertRaisesRegex(parser.ParseException, 'unclosed brace'):
            self.parser.parse_filter(self._tokenize('{ allow'))


class ParseFilterStatementTests(unittest.TestCase):
    """Tests for PolicyParser.parse_filter_statement."""

    def setUp(self):
        self.arch = ARCH_64
        self.parser = parser.PolicyParser(
            self.arch, kill_action=bpf.KillProcess())

    def _tokenize(self, line):
        # pylint: disable=protected-access
        return list(self.parser._parser_state.tokenize([line]))[0]

    def assertEqualIgnoringToken(self, actual, expected, msg=None):
        """Similar to assertEqual, but ignores the token field."""
        if (actual.syscalls != expected.syscalls or
            actual.filters != expected.filters):
            self.fail('%r != %r' % (actual, expected), msg)

    def test_parse_filter_statement(self):
        """Accept valid filter statements."""
        self.assertEqualIgnoringToken(
            self.parser.parse_filter_statement(
                self._tokenize('read: arg0 == 0')),
            parser.ParsedFilterStatement(
                syscalls=(parser.Syscall('read', 0), ),
                filters=[
                    parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                ],
                token=None))
        self.assertEqualIgnoringToken(
            self.parser.parse_filter_statement(
                self._tokenize('{read, write}: arg0 == 0')),
            parser.ParsedFilterStatement(
                syscalls=(
                    parser.Syscall('read', 0),
                    parser.Syscall('write', 1),
                ),
                filters=[
                    parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                ],
                token=None))
        self.assertEqualIgnoringToken(
            self.parser.parse_filter_statement(
                self._tokenize('io@libc: arg0 == 0')),
            parser.ParsedFilterStatement(
                syscalls=(
                    parser.Syscall('read', 0),
                    parser.Syscall('write', 1),
                ),
                filters=[
                    parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                ],
                token=None))
        self.assertEqualIgnoringToken(
            self.parser.parse_filter_statement(
                self._tokenize('file-io@systemd: arg0 == 0')),
            parser.ParsedFilterStatement(
                syscalls=(
                    parser.Syscall('read', 0),
                    parser.Syscall('write', 1),
                ),
                filters=[
                    parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                ],
                token=None))
        self.assertEqualIgnoringToken(
            self.parser.parse_filter_statement(
                self._tokenize('kill: arg0 == 0')),
            parser.ParsedFilterStatement(
                syscalls=(
                    parser.Syscall('kill', 62),
                ),
                filters=[
                    parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                ],
                token=None))

    def test_parse_metadata(self):
        """Accept valid filter statements with metadata."""
        self.assertEqualIgnoringToken(
            self.parser.parse_filter_statement(
                self._tokenize('read[arch=test]: arg0 == 0')),
            parser.ParsedFilterStatement(
                syscalls=(
                    parser.Syscall('read', 0),
                ),
                filters=[
                    parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                ],
                token=None))
        self.assertEqualIgnoringToken(
            self.parser.parse_filter_statement(
                self._tokenize(
                    '{read, nonexistent[arch=nonexistent]}: arg0 == 0')),
            parser.ParsedFilterStatement(
                syscalls=(
                    parser.Syscall('read', 0),
                ),
                filters=[
                    parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
                ],
                token=None))

    def test_parse_unclosed_brace(self):
        """Reject unclosed brace."""
        with self.assertRaisesRegex(parser.ParseException, 'unclosed brace'):
            self.parser.parse_filter(self._tokenize('{ allow'))

    def test_parse_invalid_syscall_group(self):
        """Reject invalid syscall groups."""
        with self.assertRaisesRegex(parser.ParseException, 'unclosed brace'):
            self.parser.parse_filter_statement(
                self._tokenize('{ read, write: arg0 == 0'))

    def test_parse_missing_colon(self):
        """Reject missing colon."""
        with self.assertRaisesRegex(parser.ParseException, 'missing colon'):
            self.parser.parse_filter_statement(self._tokenize('read'))

    def test_parse_invalid_colon(self):
        """Reject invalid colon."""
        with self.assertRaisesRegex(parser.ParseException, 'invalid colon'):
            self.parser.parse_filter_statement(self._tokenize('read arg0'))

    def test_parse_missing_filter(self):
        """Reject missing filter."""
        with self.assertRaisesRegex(parser.ParseException, 'missing filter'):
            self.parser.parse_filter_statement(self._tokenize('read:'))


class ParseFileTests(unittest.TestCase):
    """Tests for PolicyParser.parse_file."""

    def setUp(self):
        self.arch = ARCH_64
        self.parser = parser.PolicyParser(
            self.arch, kill_action=bpf.KillProcess())
        self.tempdir = tempfile.mkdtemp()

    def tearDown(self):
        shutil.rmtree(self.tempdir)

    def _write_file(self, filename, contents):
        """Helper to write out a file for testing."""
        path = os.path.join(self.tempdir, filename)
        with open(path, 'w') as outf:
            outf.write(contents)
        return path

    def test_parse_simple(self):
        """Allow simple policy files."""
        path = self._write_file(
            'test.policy', """
            # Comment.
            read: allow
            write: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                    parser.FilterStatement(
                        syscall=parser.Syscall('write', 1),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))

    def test_parse_multiline(self):
        """Allow simple multi-line policy files."""
        path = self._write_file(
            'test.policy', """
            # Comment.
            read: \
                allow
            write: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                    parser.FilterStatement(
                        syscall=parser.Syscall('write', 1),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))

    def test_parse_default(self):
        """Allow defining a default action."""
        path = self._write_file(
            'test.policy', """
            @default kill-thread
            read: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillThread(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))

    def test_parse_default_permissive(self):
        """Reject defining a permissive default action."""
        path = self._write_file(
            'test.policy', """
            @default log
            read: allow
        """)

        with self.assertRaisesRegex(parser.ParseException,
                                    r'invalid permissive default action'):
            self.parser.parse_file(path)

    def test_parse_simple_grouped(self):
        """Allow simple policy files."""
        path = self._write_file(
            'test.policy', """
            # Comment.
            {read, write}: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                    parser.FilterStatement(
                        syscall=parser.Syscall('write', 1),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))

    def test_parse_other_arch(self):
        """Allow entries that only target another architecture."""
        path = self._write_file(
            'test.policy', """
            # Comment.
            read[arch=nonexistent]: allow
            write: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('write', 1),
                        frequency=1,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))

    def test_parse_include(self):
        """Allow including policy files."""
        path = self._write_file(
            'test.include.policy', """
            {read, write}: arg0 == 0; allow
        """)
        path = self._write_file(
            'test.policy', """
            @include ./test.include.policy
            read: return ENOSYS
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=1,
                        filters=[
                            parser.Filter([[parser.Atom(0, '==', 0)]],
                                          bpf.Allow()),
                            parser.Filter(
                                None,
                                bpf.ReturnErrno(
                                    self.arch.constants['ENOSYS'])),
                        ]),
                    parser.FilterStatement(
                        syscall=parser.Syscall('write', 1),
                        frequency=1,
                        filters=[
                            parser.Filter([[parser.Atom(0, '==', 0)]],
                                          bpf.Allow()),
                            parser.Filter(None, bpf.KillProcess()),
                        ]),
                ]))

    def test_parse_invalid_include(self):
        """Reject including invalid policy files."""
        with self.assertRaisesRegex(parser.ParseException,
                                    r'empty include path'):
            path = self._write_file(
                'test.policy', """
                @include
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException,
                                    r'invalid include path'):
            path = self._write_file(
                'test.policy', """
                @include arg0
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException,
                                    r'@include statement nested too deep'):
            path = self._write_file(
                'test.policy', """
                @include ./test.policy
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException,
                                    r'Could not @include .*'):
            path = self._write_file(
                'test.policy', """
                @include ./nonexistent.policy
            """)
            self.parser.parse_file(path)

    def test_parse_frequency(self):
        """Allow including frequency files."""
        self._write_file(
            'test.frequency', """
            read: 2
            write: 3
        """)
        path = self._write_file(
            'test.policy', """
            @frequency ./test.frequency
            read: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=2,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))

    def test_parse_invalid_frequency(self):
        """Reject including invalid frequency files."""
        path = self._write_file('test.policy',
                                """@frequency ./test.frequency""")

        with self.assertRaisesRegex(parser.ParseException, r'missing colon'):
            self._write_file('test.frequency', """
                read
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException, r'invalid colon'):
            self._write_file('test.frequency', """
                read foo
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException, r'missing number'):
            self._write_file('test.frequency', """
                read:
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException, r'invalid number'):
            self._write_file('test.frequency', """
                read: foo
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException, r'invalid number'):
            self._write_file('test.frequency', """
                read: -1
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException,
                                    r'empty frequency path'):
            path = self._write_file(
                'test.policy', """
                @frequency
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException,
                                    r'invalid frequency path'):
            path = self._write_file(
                'test.policy', """
                @frequency arg0
            """)
            self.parser.parse_file(path)

        with self.assertRaisesRegex(parser.ParseException,
                                    r'Could not open frequency file.*'):
            path = self._write_file(
                'test.policy', """
                @frequency ./nonexistent.frequency
            """)
            self.parser.parse_file(path)

    def test_parse_multiple_unconditional(self):
        """Reject actions after an unconditional action."""
        path = self._write_file(
            'test.policy', """
            read: allow
            read: allow
        """)

        with self.assertRaisesRegex(
                parser.ParseException,
                (r'test.policy\(3:17\): '
                 r'Syscall read.*already had an unconditional action '
                 r'applied')):
            self.parser.parse_file(path)

        path = self._write_file(
            'test.policy', """
            read: log
            read: arg0 == 0; log
        """)

        with self.assertRaisesRegex(
                parser.ParseException,
                (r'test.policy\(3:17\): '
                 r'Syscall read.*already had an unconditional action '
                 r'applied')):
            self.parser.parse_file(path)


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