ldgen: additional tests for generation support classes

This commit is contained in:
Renz Bagaporo 2021-01-27 16:02:44 +08:00
parent a41a56b5b0
commit 0142676cbf
10 changed files with 623 additions and 5 deletions

View File

@ -72,8 +72,10 @@ test_ldgen_on_host:
extends: .host_test_template
script:
- cd tools/ldgen/test
- ./test_fragments.py
- ./test_generation.py
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_fragments.py
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_generation.py
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_entity.py
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_output_commands.py
variables:
LC_ALL: C.UTF-8

View File

@ -88,8 +88,10 @@ tools/kconfig_new/test/confserver/test_confserver.py
tools/kconfig_new/test/gen_kconfig_doc/test_kconfig_out.py
tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py
tools/ldgen/ldgen.py
tools/ldgen/test/test_entity.py
tools/ldgen/test/test_fragments.py
tools/ldgen/test/test_generation.py
tools/ldgen/test/test_output_commands.py
tools/mass_mfg/mfg_gen.py
tools/mkdfu.py
tools/mkuf2.py

View File

@ -0,0 +1,78 @@
#
# 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.
#
from entity import Entity
class InputSectionDesc():
def __init__(self, entity, sections, exclusions=None):
assert(entity.specificity != Entity.Specificity.SYMBOL)
self.entity = entity
self.sections = set(sections)
self.exclusions = set()
if exclusions:
assert(not [e for e in exclusions if e.specificity == Entity.Specificity.SYMBOL or
e.specificity == Entity.Specificity.NONE])
self.exclusions = set(exclusions)
else:
self.exclusions = set()
def __str__(self):
if self.sections:
exclusion_strings = []
for exc in sorted(self.exclusions):
if exc.specificity == Entity.Specificity.ARCHIVE:
exc_string = '*%s' % (exc.archive)
else:
exc_string = '*%s:%s.*' % (exc.archive, exc.obj)
exclusion_strings.append(exc_string)
section_strings = []
if exclusion_strings:
exclusion_string = 'EXCLUDE_FILE(%s)' % ' '.join(exclusion_strings)
for section in sorted(self.sections):
section_strings.append('%s %s' % (exclusion_string, section))
else:
for section in sorted(self.sections):
section_strings.append(section)
sections_string = '(%s)' % ' '.join(section_strings)
else:
sections_string = '( )'
command = None
if self.entity.specificity == Entity.Specificity.NONE:
command = '*%s' % (sections_string)
elif self.entity.specificity == Entity.Specificity.ARCHIVE:
command = '*%s:%s' % (self.entity.archive, sections_string)
else:
command = '*%s:%s.*%s' % (self.entity.archive, self.entity.obj, sections_string)
return command
def __eq__(self, other):
return (self.entity == other.entity and
self.sections == other.sections and
self.exclusions == other.exclusions)

View File

@ -343,6 +343,111 @@ Idx Name Size VMA LMA File off Algn
49 .xt.prop 00000408 00000000 00000000 00002f3e 2**0
CONTENTS, RELOC, READONLY
port.cpp.obj: file format elf32-xtensa-le
Sections:
Idx Name Size VMA LMA File off Algn
0 .literal.pxPortInitialiseStack 00000018 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .literal.xPortStartScheduler 00000014 00000000 00000000 0000004c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
2 .literal.xPortSysTickHandler 00000008 00000000 00000000 00000060 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
3 .literal.vPortYieldOtherCore 00000004 00000000 00000000 00000068 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
4 .literal.vPortReleaseTaskMPUSettings 00000004 00000000 00000000 0000006c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .literal.xPortInIsrContext 00000008 00000000 00000000 00000070 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
6 .iram1.literal 00000004 00000000 00000000 00000078 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .literal.vPortAssertIfInISR 00000018 00000000 00000000 0000007c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .literal.vPortCPUInitializeMutex 00000004 00000000 00000000 00000094 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
9 .literal.vPortCPUAcquireMutex 00000030 00000000 00000000 00000098 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .literal.vPortCPUAcquireMutexTimeout 00000030 00000000 00000000 000000c8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .literal.vPortCPUReleaseMutex 00000028 00000000 00000000 000000f8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
12 .literal.vPortSetStackWatchpoint 00000008 00000000 00000000 00000120 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
13 .text 00000000 00000000 00000000 00000128 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .data 00000000 00000000 00000000 00000128 2**0
CONTENTS, ALLOC, LOAD, DATA
15 .bss 00000000 00000000 00000000 00000128 2**0
ALLOC
16 .text.pxPortInitialiseStack 00000086 00000000 00000000 00000128 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
17 .text.vPortEndScheduler 00000005 00000000 00000000 000001b0 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
18 .text.xPortStartScheduler 0000002e 00000000 00000000 000001b8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
19 .text.xPortSysTickHandler 00000016 00000000 00000000 000001e8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
20 .text.vPortYieldOtherCore 0000000e 00000000 00000000 00000200 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
21 .text.vPortStoreTaskMPUSettings 00000013 00000000 00000000 00000210 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
22 .text.vPortReleaseTaskMPUSettings 0000000e 00000000 00000000 00000224 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
23 .text.xPortInIsrContext 00000026 00000000 00000000 00000234 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
24 .iram1 0000001a 00000000 00000000 0000025c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
25 .rodata.str1.4 0000013b 00000000 00000000 00000278 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
26 .text.vPortAssertIfInISR 00000025 00000000 00000000 000003b4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
27 .text.vPortCPUInitializeMutex 0000000e 00000000 00000000 000003dc 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
28 .text.vPortCPUAcquireMutex 00000088 00000000 00000000 000003ec 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
29 .text.vPortCPUAcquireMutexTimeout 000000ab 00000000 00000000 00000474 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
30 .text.vPortCPUReleaseMutex 00000061 00000000 00000000 00000520 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
31 .text.vPortSetStackWatchpoint 0000001a 00000000 00000000 00000584 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
32 .text.xPortGetTickRateHz 00000008 00000000 00000000 000005a0 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
33 .rodata.__func__$5264 00000029 00000000 00000000 000005a8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
34 .rodata.__func__$5259 00000029 00000000 00000000 000005d4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
35 .rodata.__FUNCTION__$5243 00000013 00000000 00000000 00000600 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
36 .bss.port_interruptNesting 00000008 00000000 00000000 00000614 2**2
ALLOC
37 .bss.port_xSchedulerRunning 00000008 00000000 00000000 00000614 2**2
ALLOC
38 .debug_frame 00000190 00000000 00000000 00000614 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
39 .debug_info 00000e78 00000000 00000000 000007a4 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
40 .debug_abbrev 00000404 00000000 00000000 0000161c 2**0
CONTENTS, READONLY, DEBUGGING
41 .debug_loc 000005f1 00000000 00000000 00001a20 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
42 .debug_aranges 00000098 00000000 00000000 00002011 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
43 .debug_ranges 000000a0 00000000 00000000 000020a9 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
44 .debug_line 000005fb 00000000 00000000 00002149 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
45 .debug_str 0000071f 00000000 00000000 00002744 2**0
CONTENTS, READONLY, DEBUGGING
46 .comment 0000003b 00000000 00000000 00002e63 2**0
CONTENTS, READONLY
47 .xtensa.info 00000038 00000000 00000000 00002e9e 2**0
CONTENTS, READONLY
48 .xt.lit 00000068 00000000 00000000 00002ed6 2**0
CONTENTS, RELOC, READONLY
49 .xt.prop 00000408 00000000 00000000 00002f3e 2**0
CONTENTS, RELOC, READONLY
portasm.S.obj: file format elf32-xtensa-le
Sections:

View File

@ -0,0 +1,39 @@
In archive /home/user/build/esp-idf/freertos/libfreertos.a:
croutine.c.obj: file format elf32-xtensa-le
Sections:
Idx Name Size VMA LMA File off Algn
0 .literal.prvCheckPendingReadyList 00000018 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .literal.prvCheckDelayedList 0000002c 00000000 00000000 0000004c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
croutine.cpp.obj: file format elf32-xtensa-le
Sections:
Idx Name Size VMA LMA File off Algn
9 .text.prvCheckPendingReadyList 00000056 00000000 00000000 000000d8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .text.prvCheckDelayedList 000000ac 00000000 00000000 00000130 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
croutine.S.obj: file format elf32-xtensa-le
Sections:
Idx Name Size VMA LMA File off Algn
26 .debug_frame 000000a0 00000000 00000000 00000394 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
27 .debug_info 000006b8 00000000 00000000 00000434 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
28 .debug_abbrev 00000233 00000000 00000000 00000aec 2**0
CONTENTS, READONLY, DEBUGGING
timers.o: file format elf32-xtensa-le
Sections:
Idx Name Size VMA LMA File off Algn
0 .literal.prvGetNextExpireTime 00000004 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .literal.prvInsertTimerInActiveList 00000010 00000000 00000000 00000038 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

View File

@ -1,4 +1,4 @@
In archive /home/user/ãóç+ěščřžýáíé/build/esp-idf/freertos/libsections_parse.a:
In archive /home/user/ãóç+ěščřžýáíé/build/esp-idf/freertos/ěščřžýáíé.a:
croutine.c.obj: file format elf32-littleriscv
@ -11,9 +11,9 @@ Idx Name Size VMA LMA File off Algn
2 .bss 00000000 00000000 00000000 00000034 2**0
ALLOC
FreeRTOS-openocd.c.obj: file format elf32-xtensa-le // 'F' should not get included in match for 'CONTENTS, ALLOC, LOAD ...' prior
FreeRTOS-ěščřžýáíé.c.obj: file format elf32-xtensa-le // 'F' should not get included in match for 'CONTENTS, ALLOC, LOAD ...' prior
Sections:
Idx Name Size VMA LMA File off Algn
0 .literal.prvCheckPendingReadyList 00000018 00000000 00000000 00000034 2**2
0 .literal.ěščřžýáíé 00000018 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

251
tools/ldgen/test/test_entity.py Executable file
View File

@ -0,0 +1,251 @@
#!/usr/bin/env python
# coding=utf-8
#
# Copyright 2018-2020 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 sys
import unittest
try:
from entity import Entity, EntityDB
except ImportError:
sys.path.append('../')
from entity import Entity, EntityDB
class EntityTest(unittest.TestCase):
def test_create_none(self):
entity = Entity(Entity.ALL)
self.assertEqual(Entity.Specificity.NONE, entity.specificity)
entity = Entity(None)
self.assertEqual(Entity.Specificity.NONE, entity.specificity)
entity = Entity()
self.assertEqual(Entity.Specificity.NONE, entity.specificity)
def test_create_archive(self):
entity = Entity('libfreertos.a')
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
entity = Entity('libfreertos.a', Entity.ALL, Entity.ALL)
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
entity = Entity('libfreertos.a', None, None)
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
entity = Entity('libfreertos.a', Entity.ALL, None)
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
entity = Entity('libfreertos.a', None, Entity.ALL)
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
def test_create_obj(self):
entity = Entity('libfreertos.a', 'croutine')
self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
entity = Entity('libfreertos.a', 'croutine', Entity.ALL)
self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
entity = Entity('libfreertos.a', 'croutine', None)
self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
def test_create_symbol(self):
entity = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
self.assertEqual(Entity.Specificity.SYMBOL, entity.specificity)
def test_create_invalid(self):
with self.assertRaises(ValueError):
Entity(None, 'croutine')
with self.assertRaises(ValueError):
Entity(Entity.ALL, 'croutine')
with self.assertRaises(ValueError):
Entity(None, None, 'prvCheckPendingReadyList')
with self.assertRaises(ValueError):
Entity(Entity.ALL, Entity.ALL, 'prvCheckPendingReadyList')
with self.assertRaises(ValueError):
Entity(None, Entity.ALL, 'prvCheckPendingReadyList')
with self.assertRaises(ValueError):
Entity(Entity.ALL, None, 'prvCheckPendingReadyList')
with self.assertRaises(ValueError):
Entity('libfreertos.a', None, 'prvCheckPendingReadyList')
with self.assertRaises(ValueError):
Entity('libfreertos.a', Entity.ALL, 'prvCheckPendingReadyList')
def test_compare_different_specificity(self):
# Different specificity: NONE < ARCHIVE < OBJ < SYMBOL
entity_a = Entity()
entity_b = Entity('libfreertos.a')
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a')
entity_b = Entity('libfreertos.a', 'croutine')
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a', 'croutine')
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
self.assertLess(entity_a, entity_b)
entity_a = Entity(Entity.ALL)
entity_b = Entity('libfreertos.a')
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a', Entity.ALL)
entity_b = Entity('libfreertos.a', 'croutine')
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a', 'croutine', Entity.ALL)
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
self.assertLess(entity_a, entity_b)
def test_compare_equal(self):
# Compare equal specificities and members
entity_a = Entity()
entity_b = Entity()
self.assertEqual(entity_a, entity_b)
entity_a = Entity('libfreertos.a')
entity_b = Entity('libfreertos.a')
self.assertEqual(entity_a, entity_b)
entity_a = Entity('libfreertos.a', 'croutine')
entity_b = Entity('libfreertos.a', 'croutine')
self.assertEqual(entity_a, entity_b)
entity_a = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
self.assertEqual(entity_a, entity_b)
def test_compare_none_vs_all(self):
# Two entities might have the same specifity whether
# Entity.ALL is used or not specified; the latter is
# considered less than the former.
entity_a = Entity()
entity_b = Entity(Entity.ALL)
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a')
entity_b = Entity('libfreertos.a', Entity.ALL, Entity.ALL)
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a', 'croutine')
entity_b = Entity('libfreertos.a', 'croutine', Entity.ALL)
self.assertLess(entity_a, entity_b)
def test_compare_same_specificity(self):
# Test that entities will be compared alphabetically
# when the specificities are the same.
entity_a = Entity('libfreertos_a.a')
entity_b = Entity('libfreertos_b.a')
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos_b.a', 'croutine_a')
entity_b = Entity('libfreertos_a.a', 'croutine_b')
self.assertLess(entity_b, entity_a)
entity_a = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList_a')
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList_b')
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a', 'croutine_b', 'prvCheckPendingReadyList_a')
entity_b = Entity('libfreertos.a', 'croutine_a', 'prvCheckPendingReadyList_b')
self.assertLess(entity_b, entity_a)
entity_a = Entity('libfreertos_a.a', 'croutine_b', 'prvCheckPendingReadyList_a')
entity_b = Entity('libfreertos_b.a', 'croutine_a', 'prvCheckPendingReadyList_b')
self.assertLess(entity_a, entity_b)
def test_compare_all_non_character(self):
# Test that Entity.ALL is not treated as an
# ordinary character in comparisons.
entity_a = Entity(Entity.ALL)
entity_b = Entity(chr(ord(Entity.ALL[0]) - 1))
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a', Entity.ALL)
entity_b = Entity('libfreertos.a', chr(ord(Entity.ALL[0]) - 1))
self.assertLess(entity_a, entity_b)
entity_a = Entity('libfreertos.a', 'croutine', '*')
entity_b = Entity('libfreertos.a', 'croutine', chr(ord(Entity.ALL[0]) - 1))
self.assertLess(entity_a, entity_b)
class EntityDBTest(unittest.TestCase):
def setUp(self):
self.entities = EntityDB()
with open('data/test_entity/libfreertos.a.txt') as objdump:
self.entities.add_sections_info(objdump)
def test_get_archives(self):
archives = self.entities.get_archives()
self.assertEqual(set(archives), set(['libfreertos.a']))
def test_get_objs(self):
objs = self.entities.get_objects('libfreertos.a')
self.assertEqual(set(objs), set(['croutine.S.obj', 'croutine.c.obj', 'croutine.cpp.obj', 'timers.o']))
def test_get_sections(self):
# Needs disambugation between possible matches: croutine.S, croutine.c, croutine.cpp
with self.assertRaises(ValueError):
self.entities.get_sections('libfreertos.a', 'croutine')
# Test disambugation works
sections = self.entities.get_sections('libfreertos.a', 'croutine.c')
expected = set(['.literal.prvCheckPendingReadyList', '.literal.prvCheckDelayedList'])
self.assertEqual(set(sections), expected)
sections = self.entities.get_sections('libfreertos.a', 'croutine.S')
expected = set(['.debug_frame', '.debug_info', '.debug_abbrev'])
self.assertEqual(set(sections), expected)
# Test .o extension works
sections = self.entities.get_sections('libfreertos.a', 'timers')
expected = set(['.literal.prvGetNextExpireTime', '.literal.prvInsertTimerInActiveList'])
self.assertEqual(set(sections), expected)
def test_parsing(self):
# Tests parsing objdump with the following:
#
# - non-ascii characters
# - different architecture string
# - different column entries for each sections
# - unexpected 'comments'
with open('data/test_entity/parse_test.txt') as objdump:
self.entities.add_sections_info(objdump)
sections = self.entities.get_sections('ěščřžýáíé.a', 'croutine')
self.assertEqual(set(sections), set(['.text', '.data', '.bss']))
sections = self.entities.get_sections('ěščřžýáíé.a', 'FreeRTOS-ěščřžýáíé')
self.assertEqual(set(sections), set(['.literal.ěščřžýáíé']))
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,141 @@
#!/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 sys
import unittest
try:
from output_commands import InputSectionDesc
except ImportError:
sys.path.append('../')
from output_commands import InputSectionDesc
from entity import Entity
SECTIONS = ['.text', '.text.*', '.literal', '.literal.*']
FREERTOS = Entity('libfreertos.a')
CROUTINE = Entity('libfreertos.a', 'croutine')
class InputSectionDescTest(unittest.TestCase):
def test_output_00(self):
# Test default (catch-all) command
expected = '*(.literal .literal.* .text .text.*)'
desc = InputSectionDesc(Entity(), SECTIONS)
self.assertEqual(expected, str(desc))
desc = InputSectionDesc(Entity(Entity.ALL), SECTIONS)
self.assertEqual(expected, str(desc))
def test_output_01(self):
# Test library placement command
expected = '*libfreertos.a:(.literal .literal.* .text .text.*)'
desc = InputSectionDesc(Entity('libfreertos.a'), SECTIONS)
self.assertEqual(expected, str(desc))
desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL), SECTIONS)
self.assertEqual(expected, str(desc))
desc = InputSectionDesc(Entity('libfreertos.a', None, Entity.ALL), SECTIONS)
self.assertEqual(expected, str(desc))
desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL, Entity.ALL), SECTIONS)
self.assertEqual(expected, str(desc))
def test_output_02(self):
# Test object placement command
expected = '*libfreertos.a:croutine.*(.literal .literal.* .text .text.*)'
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS)
self.assertEqual(expected, str(desc))
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS)
self.assertEqual(expected, str(desc))
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine', Entity.ALL), SECTIONS)
self.assertEqual(expected, str(desc))
# Disambugated placement
expected = '*libfreertos.a:croutine.c.*(.literal .literal.* .text .text.*)'
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine.c'), SECTIONS)
self.assertEqual(expected, str(desc))
def test_output_03(self):
# Invalid entity specification
with self.assertRaises(AssertionError):
InputSectionDesc(Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList'), SECTIONS)
with self.assertRaises(AssertionError):
InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity()])
with self.assertRaises(AssertionError):
InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')])
def test_output_04(self):
# Test exclusions
# Library
expected = ('*libfreertos.a:croutine.*'
'(EXCLUDE_FILE(*libfreertos.a) '
'.literal EXCLUDE_FILE(*libfreertos.a) '
'.literal.* EXCLUDE_FILE(*libfreertos.a) '
'.text EXCLUDE_FILE(*libfreertos.a) .text.*)')
desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS])
self.assertEqual(expected, str(desc))
# Object
expected = ('*libfreertos.a:croutine.*'
'(EXCLUDE_FILE(*libfreertos.a:croutine.*) '
'.literal EXCLUDE_FILE(*libfreertos.a:croutine.*) '
'.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.*) '
'.text EXCLUDE_FILE(*libfreertos.a:croutine.*) .text.*)')
desc = InputSectionDesc(CROUTINE, SECTIONS, [CROUTINE])
self.assertEqual(expected, str(desc))
# Multiple exclusions
expected = ('*libfreertos.a:croutine.*'
'(EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
'.literal EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
'.literal.* EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
'.text EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) .text.*)')
desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS, CROUTINE])
self.assertEqual(expected, str(desc))
# Disambugated exclusion
expected = ('*libfreertos.a:croutine.*'
'(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
'.literal EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
'.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
'.text EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)')
desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')])
self.assertEqual(expected, str(desc))
def test_output_05(self):
# Test empty sections
expected = '*libfreertos.a:croutine.*( )'
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), [])
self.assertEqual(expected, str(desc))
if __name__ == '__main__':
unittest.main()