esp-idf/tools/ldgen/test/test_fragments.py
2018-12-19 11:56:24 +01:00

640 lines
15 KiB
Python
Executable File

#!/usr/bin/env python
#
# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
#
# 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.
#
import unittest
import sys
from pyparsing import ParseException
from pyparsing import restOfLine
try:
import fragments
except ImportError:
sys.path.append('../')
import fragments
from sdkconfig import SDKConfig
class FragmentTest(unittest.TestCase):
def parse(self, text):
self.parser.ignore("#" + restOfLine)
fragment = self.parser.parseString(text, parseAll=True)
return fragment[0]
class SectionsTest(FragmentTest):
def setUp(self):
self.parser = fragments.Sections.get_fragment_grammar()
def test_valid_entries(self):
valid_entries = """
[sections:test]
entries:
.section1
.section2
# Section 3 should not exist
# section3
.section4
# This is a comment
.section5
"""
sections = self.parse(valid_entries)
self.assertEqual("test", sections.name)
entries = sections.entries
expected = {
".section1",
".section2",
".section4",
".section5"
}
self.assertEqual(set(entries), expected)
def test_blank_entries(self):
blank_entries = """
[sections:test]
entries:
"""
with self.assertRaises(ParseException):
self.parse(blank_entries)
def test_invalid_names(self):
with_spaces = """
[sections:invalid name 1]
entries:
"""
begins_with_number = """
[sections:2invalid_name]
entries:
"""
with_special_character = """
[sections:invalid_name~]
entries:
"""
with self.assertRaises(ParseException):
self.parse(with_spaces)
with self.assertRaises(ParseException):
self.parse(begins_with_number)
with self.assertRaises(ParseException):
self.parse(with_special_character)
def test_non_existent_entries(self):
misspelled_entries_field = """
[sections:test]
entrie:
.section1
"""
missing_entries_field = """
[sections:test]
"""
with self.assertRaises(ParseException):
self.parse(misspelled_entries_field)
with self.assertRaises(ParseException):
self.parse(missing_entries_field)
def test_duplicate_entries(self):
duplicate_entries = """
[sections:test]
entries:
.section1
.section3
.section1
.section1
.section2
.section3
.section1
"""
sections = self.parse(duplicate_entries)
entries = sections.entries
expected = {
".section1",
".section2",
".section3",
}
self.assertEqual(set(entries), expected)
class SchemeTest(FragmentTest):
def setUp(self):
self.parser = fragments.Scheme.get_fragment_grammar()
def test_valid_entries(self):
valid_entries = """
[scheme:test]
entries:
sections1 -> target1
sections2 -> target2
"""
scheme = self.parse(valid_entries)
entries = scheme.entries
expected = {
("sections1", "target1"),
("sections2", "target2")
}
self.assertEqual(entries, expected)
def test_duplicate_same_mapping(self):
duplicate_entries = """
[scheme:duplicate_same_mapping]
entries:
sections1 -> target1
sections2 -> target2
sections1 -> target1
"""
scheme = self.parse(duplicate_entries)
entries = scheme.entries
expected = {
("sections1", "target1"),
("sections2", "target2")
}
self.assertEqual(len(entries), 2)
self.assertEqual(entries, expected)
def test_invalid_separator(self):
wrong_character = """
[scheme:test]
entries:
sections1, target1
"""
single_word = """
[scheme:test]
entries:
sections1
"""
with self.assertRaises(ParseException):
self.parse(wrong_character)
with self.assertRaises(ParseException):
self.parse(single_word)
def test_blank_entries(self):
blank_entries = """
[scheme:test]
entries:
"""
with self.assertRaises(ParseException):
self.parse(blank_entries)
def test_non_existent_entries(self):
misspelled_entries_field = """
[scheme:test]
entrie:
section -> target
"""
missing_entries_field = """
[scheme:test]
"""
with self.assertRaises(ParseException):
self.parse(misspelled_entries_field)
with self.assertRaises(ParseException):
self.parse(missing_entries_field)
class MappingTest(FragmentTest):
def setUp(self):
self.parser = fragments.Mapping.get_fragment_grammar()
def parse_expression(self, expression):
parser = SDKConfig.get_expression_grammar()
return parser.parseString(expression, parseAll=True)
def test_valid_grammar(self):
valid_entries = """
[mapping]
archive: lib.a
entries:
obj:symbol (noflash)
# Comments should not matter
obj (noflash)
# Nor should whitespace
obj : symbol_2 ( noflash )
obj_2 ( noflash )
* (noflash)
"""
mapping = self.parse(valid_entries)
self.assertEqual("lib.a", mapping.archive)
self.assertEqual("lib_a", mapping.name)
entries = mapping.entries
expected = [("default", {
("obj", "symbol", "noflash"),
("obj", None, "noflash"),
("obj", "symbol_2", "noflash"),
("obj_2", None, "noflash"),
("*", None, "noflash")
})]
self.assertEqual(entries, expected)
def test_invalid_grammar(self):
with_fragment_name = """
[mapping:name]
archive: lib.a
entries:
obj:symbol (noflash)
"""
missing_archive = """
[mapping:name]
entries:
obj:symbol (noflash)
"""
misspelled_archive = """
[mapping:name]
archi: lib.a
entries:
obj:symbol (noflash)
"""
missing_entries = """
[mapping]
archive: lib.a
"""
misspelled_entries = """
[mapping]
archive: lib.a
entrie:
obj:symbol (noflash)
"""
missing_symbols = """
[mapping]
archive: lib.a
entries:
obj: (noflash)
"""
missing_scheme_1 = """
[mapping]
archive: lib.a
entries:
obj: ()
"""
missing_scheme_2 = """
[mapping]
archive: lib.a
entries:
obj:symbol
"""
missing_entity = """
[mapping]
archive: lib.a
entries:
(noflash)
"""
wilcard_symbol = """
[mapping]
archive: lib.a
entries:
obj:* (noflash)
"""
empty_object_with_symbol = """
[mapping]
archive: lib.a
entries:
:symbol (noflash)
"""
wildcard_object_with_symbol = """
[mapping]
archive: lib.a
entries:
*:symbol (noflash)
"""
empty_definition = """
[mapping]
"""
with self.assertRaises(ParseException):
self.parse(with_fragment_name)
with self.assertRaises(ParseException):
self.parse(missing_archive)
with self.assertRaises(ParseException):
self.parse(misspelled_archive)
with self.assertRaises(ParseException):
self.parse(missing_entries)
with self.assertRaises(ParseException):
self.parse(misspelled_entries)
with self.assertRaises(ParseException):
self.parse(missing_symbols)
with self.assertRaises(ParseException):
self.parse(missing_scheme_1)
with self.assertRaises(ParseException):
self.parse(missing_scheme_2)
with self.assertRaises(ParseException):
self.parse(missing_entity)
with self.assertRaises(ParseException):
self.parse(wilcard_symbol)
with self.assertRaises(ParseException):
self.parse(empty_object_with_symbol)
with self.assertRaises(ParseException):
self.parse(wildcard_object_with_symbol)
with self.assertRaises(ParseException):
self.parse(empty_definition)
def test_explicit_blank_default_w_others(self):
expl_blnk_w_oth = """
[mapping]
archive: lib.a
entries:
: CONFIG_A = y
obj_a (noflash)
: default
"""
mapping = self.parse(expl_blnk_w_oth)
entries = mapping.entries
expected = [(entries[0][0], {
("obj_a", None, "noflash"),
}),
("default", set())]
self.assertEqual(entries, expected)
def test_implicit_blank_default_w_others(self):
impl_blnk_w_oth = """
[mapping]
archive: lib.a
entries:
: CONFIG_A = y
obj_a (noflash)
"""
mapping = self.parse(impl_blnk_w_oth)
entries = mapping.entries
expected = [(entries[0][0], {
("obj_a", None, "noflash"),
}),
("default", set())]
self.assertEqual(entries, expected)
def test_explicit_blank_default(self):
expl_blnk_def = """
[mapping]
archive: lib.a
entries:
: default
"""
mapping = self.parse(expl_blnk_def)
entries = mapping.entries
expected = [("default", set())]
self.assertEqual(entries, expected)
def test_implicit_blank_default(self):
impl_blnk_def = """
[mapping]
archive: lib.a
entries:
: default
"""
mapping = self.parse(impl_blnk_def)
entries = mapping.entries
expected = [("default", set())]
self.assertEqual(entries, expected)
def test_multiple_entries(self):
multiple_entries = """
[mapping]
archive: lib.a
entries:
: CONFIG_A = y
obj_a1 (noflash)
obj_a2 (noflash)
: CONFIG_B = y
obj_b1 (noflash)
obj_b2 (noflash)
obj_b3 (noflash)
: CONFIG_C = y
obj_c1 (noflash)
"""
mapping = self.parse(multiple_entries)
entries = mapping.entries
expected = [(entries[0][0], {
("obj_a1", None, "noflash"),
("obj_a2", None, "noflash"),
}),
(entries[1][0], {
("obj_b1", None, "noflash"),
("obj_b2", None, "noflash"),
("obj_b3", None, "noflash"),
}),
(entries[2][0], {
("obj_c1", None, "noflash"),
}),
("default", set())]
self.assertEqual(entries, expected)
def test_blank_entries(self):
blank_entries = """
[mapping]
archive: lib.a
entries:
: CONFIG_A = y
obj_a (noflash)
: CONFIG_B = y
: CONFIG_C = y
obj_c (noflash)
: CONFIG_D = y
: CONFIG_E = y
: default
obj (noflash)
"""
mapping = self.parse(blank_entries)
entries = mapping.entries
expected = [(entries[0][0], {
("obj_a", None, "noflash")
}),
(entries[1][0], set()),
(entries[2][0], {
("obj_c", None, "noflash")
}),
(entries[3][0], set()),
(entries[4][0], set()),
("default", {
("obj", None, "noflash")
})]
self.assertEqual(entries, expected)
def test_blank_first_condition(self):
blank_first_condition = """
[mapping]
archive: lib.a
entries:
obj_a (noflash)
: CONFIG_B = y
obj_b (noflash)
"""
with self.assertRaises(ParseException):
self.parse(blank_first_condition)
def test_nonlast_default(self):
nonlast_default_1 = """
[mapping]
archive: lib.a
entries:
: default
obj_a (noflash)
: CONFIG_A = y
obj_A (noflash)
"""
nonlast_default_2 = """
[mapping]
archive: lib.a
entries:
: CONFIG_A = y
obj_A (noflash)
: default
obj_a (noflash)
: CONFIG_B = y
obj_B (noflash)
"""
nonlast_default_3 = """
[mapping]
archive: lib.a
entries:
: CONFIG_A = y
obj_A (noflash)
:
obj_a (noflash)
: CONFIG_B = y
obj_B (noflash)
"""
with self.assertRaises(ParseException):
self.parse(nonlast_default_1)
with self.assertRaises(ParseException):
self.parse(nonlast_default_2)
with self.assertRaises(ParseException):
self.parse(nonlast_default_3)
def test_duplicate_default(self):
duplicate_default_1 = """
archive: lib.a
entries:
: CONFIG_A = y
obj_A (noflash)
: default
obj_a (noflash)
: CONFIG_B = y
obj_B (noflash)
: default
obj_a (noflash)
"""
duplicate_default_2 = """
archive: lib.a
entries:
: CONFIG_A = y
obj_A (noflash)
: CONFIG_B = y
obj_a (noflash)
: default
obj_B (noflash)
:
obj_a (noflash)
"""
with self.assertRaises(ParseException):
self.parse(duplicate_default_1)
with self.assertRaises(ParseException):
self.parse(duplicate_default_2)
if __name__ == "__main__":
unittest.main()