1#!/usr/bin/env python 2# 3# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD 4# SPDX-License-Identifier: Apache-2.0 5# 6 7import os 8import sys 9import tempfile 10import unittest 11from io import StringIO 12 13from pyparsing import ParseException, ParseFatalException, Word, alphanums 14 15try: 16 from fragments import FRAGMENT_TYPES, Fragment, FragmentFile, Mapping 17 from sdkconfig import SDKConfig 18except ImportError: 19 sys.path.append('../') 20 from fragments import FRAGMENT_TYPES, Fragment, FragmentFile, Mapping 21 from sdkconfig import SDKConfig 22 23 24class SampleFragment(Fragment): 25 26 grammars = { 27 'key_1': Fragment.KeyValue(Word(alphanums + '_').setResultsName('value'), 0, None, True), 28 'key_2': Fragment.KeyValue(Word(alphanums + '_').setResultsName('value'), 0, None, False), 29 'key_3': Fragment.KeyValue(Word(alphanums + '_').setResultsName('value'), 3, 5, False) 30 } 31 32 def set_key_value(self, key, parse_results): 33 if key == 'key_1': 34 self.key_1 = list() 35 for result in parse_results: 36 self.key_1.append(result['value']) 37 elif key == 'key_2': 38 self.key_2 = list() 39 for result in parse_results: 40 self.key_2.append(result['value']) 41 42 def get_key_grammars(self): 43 return self.__class__.grammars 44 45 46FRAGMENT_TYPES['test'] = SampleFragment 47 48 49class FragmentTest(unittest.TestCase): 50 51 def setUp(self): 52 with tempfile.NamedTemporaryFile(delete=False) as f: 53 self.kconfigs_source_file = os.path.join(tempfile.gettempdir(), f.name) 54 with tempfile.NamedTemporaryFile(delete=False) as f: 55 self.kconfig_projbuilds_source_file = os.path.join(tempfile.gettempdir(), f.name) 56 57 os.environ['COMPONENT_KCONFIGS_SOURCE_FILE'] = self.kconfigs_source_file 58 os.environ['COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE'] = self.kconfig_projbuilds_source_file 59 os.environ['COMPONENT_KCONFIGS'] = '' 60 os.environ['COMPONENT_KCONFIGS_PROJBUILD'] = '' 61 62 # prepare_kconfig_files.py doesn't have to be called because COMPONENT_KCONFIGS and 63 # COMPONENT_KCONFIGS_PROJBUILD are empty 64 65 self.sdkconfig = SDKConfig('data/Kconfig', 'data/sdkconfig') 66 67 def tearDown(self): 68 try: 69 os.remove(self.kconfigs_source_file) 70 os.remove(self.kconfig_projbuilds_source_file) 71 except Exception: 72 pass 73 74 @staticmethod 75 def create_fragment_file(contents, name='test_fragment.lf'): 76 f = StringIO(contents) 77 f.name = name 78 return f 79 80 def test_basic(self): 81 test_fragment = self.create_fragment_file(u""" 82[test:test] 83key_1: 84 value_1 85 value_2 # comments should be ignored 86 value_3 87# this is a comment as well 88key_2: value_a 89 90# this is the last comment 91""") 92 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 93 94 self.assertEqual(len(fragment_file.fragments[0].key_1), 3) 95 self.assertEqual(fragment_file.fragments[0].key_1[0], 'value_1') 96 self.assertEqual(fragment_file.fragments[0].key_1[1], 'value_2') 97 self.assertEqual(fragment_file.fragments[0].key_1[2], 'value_3') 98 self.assertEqual(len(fragment_file.fragments[0].key_2), 1) 99 self.assertEqual(fragment_file.fragments[0].key_2[0], 'value_a') 100 101 def test_duplicate_keys(self): 102 test_fragment = self.create_fragment_file(u""" 103[test:test] 104key_1: value_1 105key_1: value_a 106""") 107 with self.assertRaises(ParseFatalException): 108 FragmentFile(test_fragment, self.sdkconfig) 109 110 def test_empty_key(self): 111 test_fragment = self.create_fragment_file(u""" 112[test:test] 113key_1: 114""") 115 with self.assertRaises(ParseException): 116 FragmentFile(test_fragment, self.sdkconfig) 117 118 def test_conditional(self): 119 test_fragment = self.create_fragment_file(u""" 120[test:test] 121key_1: 122 value_1 123 if A = y: 124 value_2 125 value_3 126 if A = n: 127 value_4 128 if B = n: 129 value_5 130""") 131 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 132 self.assertEqual(fragment_file.fragments[0].key_1[0], 'value_1') 133 self.assertEqual(fragment_file.fragments[0].key_1[1], 'value_2') 134 self.assertEqual(fragment_file.fragments[0].key_1[2], 'value_3') 135 self.assertEqual(fragment_file.fragments[0].key_1[3], 'value_5') 136 137 test_fragment = self.create_fragment_file(u""" 138[test:test] 139key_1: 140 value_1 141 if B = y: 142 value_2 143 elif C = y: 144 value_3 145 elif A = y: 146 value_4 147 else: 148 value_5 149 value_6 150""") 151 152 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 153 self.assertEqual(fragment_file.fragments[0].key_1[0], 'value_1') 154 self.assertEqual(fragment_file.fragments[0].key_1[1], 'value_3') 155 self.assertEqual(fragment_file.fragments[0].key_1[2], 'value_6') 156 157 test_fragment = self.create_fragment_file(u""" 158[test:test] 159key_1: 160 value_1 161 if A = y: 162 value_2 163 if B = y: 164 value_3 165 else: 166 value_4 167 if C = y: 168 value_5 169 value_6 170 value_7 171key_2: 172 value_a 173 if B != y: 174 value_b 175""") 176 177 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 178 self.assertEqual(fragment_file.fragments[0].key_1[0], 'value_1') 179 self.assertEqual(fragment_file.fragments[0].key_1[1], 'value_2') 180 self.assertEqual(fragment_file.fragments[0].key_1[2], 'value_4') 181 self.assertEqual(fragment_file.fragments[0].key_1[3], 'value_5') 182 self.assertEqual(fragment_file.fragments[0].key_1[4], 'value_6') 183 self.assertEqual(fragment_file.fragments[0].key_1[5], 'value_7') 184 self.assertEqual(fragment_file.fragments[0].key_2[0], 'value_a') 185 self.assertEqual(fragment_file.fragments[0].key_2[1], 'value_b') 186 187 test_fragment = self.create_fragment_file(u""" 188[test:test] 189key_1: 190 if A = n: 191 value_2 192""") 193 194 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 195 self.assertEqual(len(fragment_file.fragments[0].key_1), 0) 196 197 def test_empty_file(self): 198 test_fragment = self.create_fragment_file(u""" 199 200 201 202 203""") 204 205 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 206 self.assertEqual(len(fragment_file.fragments), 0) 207 208 def test_setting_indent(self): 209 test_fragment = self.create_fragment_file(u""" 210[test:test] 211key_1: 212 value_1 213 value_2 214 value_3 215""") 216 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 217 218 self.assertEqual(len(fragment_file.fragments[0].key_1), 3) 219 self.assertEqual(fragment_file.fragments[0].key_1[0], 'value_1') 220 self.assertEqual(fragment_file.fragments[0].key_1[1], 'value_2') 221 self.assertEqual(fragment_file.fragments[0].key_1[2], 'value_3') 222 223 test_fragment = self.create_fragment_file(u""" 224[test:test] 225key_1: 226 value_1 227 value_2 # first element dictates indent 228 value_3 229""") 230 with self.assertRaises(ParseFatalException): 231 FragmentFile(test_fragment, self.sdkconfig) 232 233 def test_values_num_limit(self): 234 test_fragment = self.create_fragment_file(u""" 235[test:test] 236key_1: 237 value_a 238key_3: 239 value_1 240 value_2 241 value_3 242""") 243 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 244 245 test_fragment = self.create_fragment_file(u""" 246[test:test] 247key_1: 248 value_a 249key_3: 250 value_1 251 value_2 252 value_3 253 value_4 254""") 255 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 256 self.assertEqual(len(fragment_file.fragments), 1) 257 258 test_fragment = self.create_fragment_file(u""" 259[test:test] 260key_1: 261 value_a 262key_3: 263 value_1 264 value_2 265 value_3 266 value_4 267 value_5 268""") 269 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 270 self.assertEqual(len(fragment_file.fragments), 1) 271 272 test_fragment = self.create_fragment_file(u""" 273[test:test] 274key_1: 275 value_a 276key_3: 277 value_1 278 value_2 279""") 280 281 with self.assertRaises(ParseFatalException): 282 FragmentFile(test_fragment, self.sdkconfig) 283 284 test_fragment = self.create_fragment_file(u""" 285[test:test] 286key_1: 287 value_a 288key_3: 289 value_1 290 value_2 291 value_3 292 value_4 293 value_5 294 value_6 295""") 296 297 with self.assertRaises(ParseFatalException): 298 FragmentFile(test_fragment, self.sdkconfig) 299 300 def test_unsupported_key(self): 301 test_fragment = self.create_fragment_file(u""" 302[test:test] 303key_1: 304 value_a 305key_4: 306 value_1 307""") 308 309 with self.assertRaises(ParseFatalException): 310 FragmentFile(test_fragment, self.sdkconfig) 311 312 def test_empty_fragment(self): 313 test_fragment = self.create_fragment_file(u""" 314[test:test] 315""") 316 317 with self.assertRaises(ParseException): 318 FragmentFile(test_fragment, self.sdkconfig) 319 320 def test_empty_conditional(self): 321 test_fragment = self.create_fragment_file(u""" 322[test:test] 323key_1: 324 if B = y: 325 else: 326 value_1 327""") 328 329 with self.assertRaises(ParseFatalException): 330 FragmentFile(test_fragment, self.sdkconfig) 331 332 test_fragment = self.create_fragment_file(u""" 333[test:test] 334key_1: 335 if B = y: 336 value_1 337 else B = y: 338""") 339 340 with self.assertRaises(ParseFatalException): 341 FragmentFile(test_fragment, self.sdkconfig) 342 343 test_fragment = self.create_fragment_file(u""" 344[test:test] 345key_1: 346 if B = y: 347 value_1 348 elif B = y: 349 else: 350 value_2 351""") 352 353 with self.assertRaises(ParseFatalException): 354 FragmentFile(test_fragment, self.sdkconfig) 355 356 def test_out_of_order_conditional(self): 357 test_fragment = self.create_fragment_file(u""" 358[test:test] 359key_1: 360 elif B = y: 361 value_1 362 else: 363 value_2 364""") 365 366 with self.assertRaises(ParseFatalException): 367 FragmentFile(test_fragment, self.sdkconfig) 368 369 test_fragment = self.create_fragment_file(u""" 370[test:test] 371key_1: 372 else: 373 value_2 374""") 375 376 with self.assertRaises(ParseFatalException): 377 FragmentFile(test_fragment, self.sdkconfig) 378 379 def test_required_keys(self): 380 test_fragment = self.create_fragment_file(u""" 381[test:test] 382key_2: 383 value_1 384""") 385 386 with self.assertRaises(ParseFatalException): 387 FragmentFile(test_fragment, self.sdkconfig) 388 389 def test_multiple_fragments(self): 390 test_fragment = self.create_fragment_file(u""" 391[test:test1] 392key_1: 393 value_1 394 395[test:test2] 396key_1: 397 value_2 398""") 399 400 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 401 402 self.assertEqual(len(fragment_file.fragments), 2) 403 self.assertEqual(fragment_file.fragments[0].key_1[0], 'value_1') 404 self.assertEqual(fragment_file.fragments[1].key_1[0], 'value_2') 405 406 def test_whole_conditional_fragment(self): 407 test_fragment = self.create_fragment_file(u""" 408if B = y: 409 [test:test1] 410 key_1: 411 value_1 412else: 413 [test:test2] 414 key_1: 415 value_2 416 417 if A = y: 418 [test:test3] 419 key_1: 420 value_3 421 if C = y: 422 value_6 423 424 [test:test4] 425 key_1: 426 value_4 427 428[test:test5] 429key_1: 430 value_5 431""") 432 433 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 434 self.assertEqual(len(fragment_file.fragments), 4) 435 self.assertEqual(fragment_file.fragments[0].name, 'test2') 436 self.assertEqual(fragment_file.fragments[1].name, 'test3') 437 self.assertEqual(fragment_file.fragments[1].key_1[1], 'value_6') 438 self.assertEqual(fragment_file.fragments[2].name, 'test4') 439 self.assertEqual(fragment_file.fragments[3].name, 'test5') 440 441 def test_equivalent_conditional_fragment(self): 442 test_fragment1 = self.create_fragment_file(u""" 443if A = y: 444 [test:test1] 445 key_1: 446 value_1 447else: 448 [test:test2] 449 key_1: 450 value_2 451""") 452 453 fragment_file1 = FragmentFile(test_fragment1, self.sdkconfig) 454 self.assertEqual(len(fragment_file1.fragments), 1) 455 self.assertEqual(fragment_file1.fragments[0].key_1[0], 'value_1') 456 457 test_fragment2 = self.create_fragment_file(u""" 458[test:test1] 459key_1: 460 if A = y: 461 value_1 462 else: 463 value_2 464""") 465 466 fragment_file2 = FragmentFile(test_fragment2, self.sdkconfig) 467 self.assertEqual(len(fragment_file2.fragments), 1) 468 self.assertEqual(fragment_file2.fragments[0].key_1[0], 'value_1') 469 470 471class SectionsTest(FragmentTest): 472 473 def test_basic(self): 474 test_fragment = self.create_fragment_file(u""" 475[sections:test] 476entries: 477 .section1 478 .section2 479""") 480 481 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 482 self.assertEqual(fragment_file.fragments[0].entries, {'.section1', '.section2'}) 483 484 def test_duplicate_entries(self): 485 test_fragment = self.create_fragment_file(u""" 486[sections:test] 487entries: 488 .section1 489 .section2 490 .section3 491 .section2 492""") 493 494 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 495 self.assertEqual(fragment_file.fragments[0].entries, {'.section1', '.section2', '.section3'}) 496 497 def test_empty_entries(self): 498 test_fragment = self.create_fragment_file(u""" 499[sections:test] 500entries: 501""") 502 503 with self.assertRaises(ParseException): 504 FragmentFile(test_fragment, self.sdkconfig) 505 506 test_fragment = self.create_fragment_file(u""" 507[sections:test] 508entries: 509 if B = y: 510 .section1 511""") 512 513 with self.assertRaises(ParseFatalException): 514 FragmentFile(test_fragment, self.sdkconfig) 515 516 def test_entries_grammar(self): 517 518 test_fragment = self.create_fragment_file(u""" 519[sections:test] 520entries: 521 _valid1 522 valid2. 523 .valid3_- 524""") 525 526 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 527 self.assertEqual(fragment_file.fragments[0].entries, 528 {'_valid1', 'valid2.', '.valid3_-'}) 529 530 # invalid starting char 531 test_fragment = self.create_fragment_file(u""" 532[sections:test] 533entries: 534 1invalid 535""") 536 537 with self.assertRaises(ParseException): 538 FragmentFile(test_fragment, self.sdkconfig) 539 540 test_fragment = self.create_fragment_file(u""" 541[sections:test] 542entries: 543 -invalid 544""") 545 546 with self.assertRaises(ParseException): 547 FragmentFile(test_fragment, self.sdkconfig) 548 549 # + notation 550 test_fragment = self.create_fragment_file(u""" 551[sections:test] 552entries: 553 valid+ 554""") 555 556 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 557 self.assertEqual(fragment_file.fragments[0].entries, 558 {'valid+'}) 559 560 test_fragment = self.create_fragment_file(u""" 561[sections:test] 562entries: 563 inva+lid+ 564""") 565 566 with self.assertRaises(ParseFatalException): 567 FragmentFile(test_fragment, self.sdkconfig) 568 569 570class SchemeTest(FragmentTest): 571 572 def test_basic(self): 573 test_fragment = self.create_fragment_file(u""" 574[scheme:test] 575entries: 576 sections1 -> target1 577 sections2 -> target2 578""") 579 580 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 581 self.assertEqual(fragment_file.fragments[0].entries, 582 {('sections1', 'target1'), 583 ('sections2', 'target2')}) 584 585 def test_duplicate_entries(self): 586 test_fragment = self.create_fragment_file(u""" 587[scheme:test] 588entries: 589 sections1 -> target1 590 sections2 -> target2 591 sections2 -> target2 592""") 593 594 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 595 self.assertEqual(fragment_file.fragments[0].entries, 596 {('sections1', 'target1'), 597 ('sections2', 'target2')}) 598 599 def test_empty_entries(self): 600 test_fragment = self.create_fragment_file(u""" 601[scheme:test] 602entries: 603""") 604 605 with self.assertRaises(ParseException): 606 FragmentFile(test_fragment, self.sdkconfig) 607 608 test_fragment = self.create_fragment_file(u""" 609[scheme:test] 610entries: 611 if B = y: 612 sections1 -> target1 613""") 614 615 with self.assertRaises(ParseFatalException): 616 FragmentFile(test_fragment, self.sdkconfig) 617 618 def test_improper_grammar(self): 619 test_fragment = self.create_fragment_file(u""" 620[scheme:test] 621entries: 622 sections1, target1 # improper separator 623""") 624 625 with self.assertRaises(ParseException): 626 FragmentFile(test_fragment, self.sdkconfig) 627 628 629class MappingTest(FragmentTest): 630 631 def test_basic(self): 632 test_fragment = self.create_fragment_file(u""" 633[mapping:test] 634archive: lib.a 635entries: 636 obj:symbol (noflash) 637 obj (noflash) 638 obj:symbol_2 (noflash) 639 obj_2 (noflash) 640 * (noflash) 641""") 642 643 expected = {('obj', 'symbol', 'noflash'), 644 ('obj', None, 'noflash'), 645 ('obj', 'symbol_2', 'noflash'), 646 ('obj_2', None, 'noflash'), 647 ('*', None, 'noflash')} 648 649 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 650 self.assertEqual(expected, fragment_file.fragments[0].entries) 651 652 def test_archive(self): 653 test_fragment = self.create_fragment_file(u""" 654[mapping:test] 655archive: 656entries: 657 * (default) 658""") 659 660 with self.assertRaises(ParseException): 661 FragmentFile(test_fragment, self.sdkconfig) 662 663 test_fragment = self.create_fragment_file(u""" 664[mapping:test] 665archive: 666 lib1.a 667 lib2.a 668entries: 669 * (default) 670""") 671 672 with self.assertRaises(ParseFatalException): 673 FragmentFile(test_fragment, self.sdkconfig) 674 675 def test_archive_allowed_names(self): 676 test_fragment = self.create_fragment_file(u""" 677[mapping:test] 678archive: 679 libstdc++.a 680entries: 681 * (default) 682""") 683 684 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 685 self.assertEqual('libstdc++.a', fragment_file.fragments[0].archive) 686 687 def test_empty_entries(self): 688 test_fragment = self.create_fragment_file(u""" 689[mapping:test] 690archive: 691 lib.a 692entries: 693 if B = y: 694 * (noflash) # if condition is false, then no 'entries' key value 695""") 696 697 expected = set() 698 699 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 700 self.assertEqual(expected, fragment_file.fragments[0].entries) 701 702 test_fragment = self.create_fragment_file(u""" 703[mapping:test] 704archive: 705 lib.a 706entries: 707""") 708 709 with self.assertRaises(ParseException): 710 FragmentFile(test_fragment, self.sdkconfig) 711 712 def test_duplicate_entries(self): 713 test_fragment = self.create_fragment_file(u""" 714[mapping:test] 715archive: 716 lib.a 717entries: 718 obj:symbol (noflash) 719 obj:symbol (noflash) 720""") 721 722 expected = {('obj', 'symbol', 'noflash')} 723 724 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 725 self.assertEqual(expected, fragment_file.fragments[0].entries) 726 727 def test_invalid_grammar(self): 728 test_fragment = self.create_fragment_file(u""" 729[mapping:test] 730archive: 731 lib.a 732""") 733 734 with self.assertRaises(ParseFatalException): 735 FragmentFile(test_fragment, self.sdkconfig) 736 737 test_fragment = self.create_fragment_file(u""" 738[mapping:test] 739entries: 740 * (default) 741""") 742 743 with self.assertRaises(ParseFatalException): 744 FragmentFile(test_fragment, self.sdkconfig) 745 746 test_fragment = self.create_fragment_file(u""" 747[mapping:test] 748archive: lib.a 749entries: 750 obj: (noflash) 751""") 752 753 with self.assertRaises(ParseException): 754 FragmentFile(test_fragment, self.sdkconfig) 755 756 test_fragment = self.create_fragment_file(u""" 757[mapping:test] 758archive: lib.a 759entries: 760 obj: () 761""") 762 763 with self.assertRaises(ParseException): 764 FragmentFile(test_fragment, self.sdkconfig) 765 766 test_fragment = self.create_fragment_file(u""" 767[mapping:test] 768archive: lib.a 769entries: 770 obj:symbol 771""") 772 773 with self.assertRaises(ParseException): 774 FragmentFile(test_fragment, self.sdkconfig) 775 776 test_fragment = self.create_fragment_file(u""" 777[mapping:test] 778archive: lib.a 779entries: 780 (noflash) 781""") 782 783 with self.assertRaises(ParseException): 784 FragmentFile(test_fragment, self.sdkconfig) 785 786 test_fragment = self.create_fragment_file(u""" 787[mapping:test] 788archive: lib.a 789entries: 790 obj:* (noflash) 791""") 792 793 with self.assertRaises(ParseException): 794 FragmentFile(test_fragment, self.sdkconfig) 795 796 test_fragment = self.create_fragment_file(u""" 797[mapping:test] 798archive: lib.a 799entries: 800 :symbol (noflash) 801""") 802 803 with self.assertRaises(ParseException): 804 FragmentFile(test_fragment, self.sdkconfig) 805 806 test_fragment = self.create_fragment_file(u""" 807[mapping:test] 808archive: lib.a 809entries: 810 *:symbol (noflash) 811""") 812 813 with self.assertRaises(ParseException): 814 FragmentFile(test_fragment, self.sdkconfig) 815 816 def test_keep_flag(self): 817 # Test parsing combinations and orders of flags 818 test_fragment = self.create_fragment_file(u""" 819[mapping:map] 820archive: libmain.a 821entries: 822 obj1 (default); 823 text->flash_text KEEP(), 824 rodata->flash_rodata KEEP() KEEP() 825""") 826 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 827 828 fragment = fragment_file.fragments[0] 829 830 expected = [('text', 'flash_text', [Mapping.Keep()]), 831 ('rodata', 'flash_rodata', [Mapping.Keep(), Mapping.Keep()])] 832 actual = fragment.flags[('obj1', None, 'default')] 833 834 self.assertEqual(expected, actual) 835 836 def test_align_flag(self): 837 # Test parsing combinations and orders of flags 838 test_fragment = self.create_fragment_file(u""" 839[mapping:map] 840archive: libmain.a 841entries: 842 obj1 (default); 843 text->flash_text ALIGN(8), 844 rodata->flash_rodata ALIGN(8, pre), 845 data->dram0_data ALIGN(8, pre, post), 846 bss->dram0_bss ALIGN(8, post), 847 common->dram0_bss ALIGN(8, pre, post) ALIGN(8) 848""") 849 850 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 851 fragment = fragment_file.fragments[0] 852 853 expected = [('text', 'flash_text', [Mapping.Align(8, True, False)]), 854 ('rodata', 'flash_rodata', [Mapping.Align(8, True, False)]), 855 ('data', 'dram0_data', [Mapping.Align(8, True, True)]), 856 ('bss', 'dram0_bss', [Mapping.Align(8, False, True)]), 857 ('common', 'dram0_bss', [Mapping.Align(8, True, True), Mapping.Align(8, True, False)])] 858 actual = fragment.flags[('obj1', None, 'default')] 859 860 self.assertEqual(expected, actual) 861 862 # Wrong post, pre order 863 test_fragment = self.create_fragment_file(u""" 864[mapping:map] 865archive: libmain.a 866entries: 867 obj1 (noflash) 868 text->iram0_text ALIGN(8, post, pre) 869""") 870 871 with self.assertRaises(ParseFatalException): 872 FragmentFile(test_fragment, self.sdkconfig) 873 874 def test_sort_flag(self): 875 # Test parsing combinations and orders of flags 876 test_fragment = self.create_fragment_file(u""" 877[mapping:map] 878archive: libmain.a 879entries: 880 obj1 (default); 881 text->flash_text SORT(name), 882 rodata->flash_rodata SORT(alignment), 883 data->dram0_data SORT(init_priority), 884 bss->dram0_bss SORT(name, alignment), 885 common->dram0_bss SORT(alignment, name), 886 iram->iram0_text SORT(name, name), 887 dram->dram0_data SORT(alignment, alignment) 888""") 889 890 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 891 fragment = fragment_file.fragments[0] 892 893 expected = [('text', 'flash_text', [Mapping.Sort('name')]), 894 ('rodata', 'flash_rodata', [Mapping.Sort('alignment')]), 895 ('data', 'dram0_data', [Mapping.Sort('init_priority')]), 896 ('bss', 'dram0_bss', [Mapping.Sort('name', 'alignment')]), 897 ('common', 'dram0_bss', [Mapping.Sort('alignment', 'name')]), 898 ('iram', 'iram0_text', [Mapping.Sort('name', 'name')]), 899 ('dram', 'dram0_data', [Mapping.Sort('alignment', 'alignment')])] 900 actual = fragment.flags[('obj1', None, 'default')] 901 self.assertEqual(expected, actual) 902 903 test_fragment = self.create_fragment_file(u""" 904[mapping:map] 905archive: libmain.a 906entries: 907 obj1 (default) 908 text->iram0_text SORT(name) SORT(alignment) 909""") 910 911 def test_surround_flag(self): 912 # Test parsing combinations and orders of flags 913 test_fragment = self.create_fragment_file(u""" 914[mapping:map] 915archive: libmain.a 916entries: 917 obj1 (default); 918 text->flash_text SURROUND(sym1) 919""") 920 921 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 922 fragment = fragment_file.fragments[0] 923 924 expected = [('text', 'flash_text', [Mapping.Surround('sym1')])] 925 actual = fragment.flags[('obj1', None, 'default')] 926 self.assertEqual(expected, actual) 927 928 def test_flag_order(self): 929 # Test that the order in which the flags are specified is retained 930 test_fragment = self.create_fragment_file(u""" 931[mapping:map] 932archive: libmain.a 933entries: 934 obj1 (default); 935 text->flash_text ALIGN(4) KEEP() SURROUND(sym1) ALIGN(8) SORT(name), 936 rodata->flash_rodata KEEP() ALIGN(4) KEEP() SURROUND(sym1) ALIGN(8) ALIGN(4) SORT(name) 937""") 938 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 939 fragment = fragment_file.fragments[0] 940 941 expected = [('text', 'flash_text', [Mapping.Align(4, True, False), 942 Mapping.Keep(), 943 Mapping.Surround('sym1'), 944 Mapping.Align(8, True, False), 945 Mapping.Sort('name')]), 946 ('rodata', 'flash_rodata', [Mapping.Keep(), 947 Mapping.Align(4, True, False), 948 Mapping.Keep(), 949 Mapping.Surround('sym1'), 950 Mapping.Align(8, True, False), 951 Mapping.Align(4, True, False), 952 Mapping.Sort('name')])] 953 actual = fragment.flags[('obj1', None, 'default')] 954 self.assertEqual(expected, actual) 955 956 def test_flags_entries_multiple_flags(self): 957 # Not an error, generation step handles this, since 958 # it that step has a more complete information 959 # about all mappings. 960 test_fragment = self.create_fragment_file(u""" 961[mapping:map] 962archive: libmain.a 963entries: 964 obj1 (default); 965 text->flash_text ALIGN(4) KEEP() SURROUND(sym1) SORT(name), 966 text->flash_text ALIGN(4) KEEP() SURROUND(sym1) SORT(name) 967""") 968 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 969 fragment = fragment_file.fragments[0] 970 971 expected = [('text', 'flash_text', [Mapping.Align(4, True, False), 972 Mapping.Keep(), 973 Mapping.Surround('sym1'), 974 Mapping.Sort('name')]), 975 ('text', 'flash_text', [Mapping.Align(4, True, False), 976 Mapping.Keep(), 977 Mapping.Surround('sym1'), 978 Mapping.Sort('name')])] 979 actual = fragment.flags[('obj1', None, 'default')] 980 self.assertEqual(expected, actual) 981 982 def test_flags_entries_multiple_flags_and_entries(self): 983 # Not an error, generation step handles this, since 984 # it that step has a more complete information 985 # about all mappings. This can happen across multiple 986 # mapping fragments. 987 test_fragment = self.create_fragment_file(u""" 988[mapping:map] 989archive: libmain.a 990entries: 991 obj1 (default); 992 text->flash_text ALIGN(4) KEEP() SURROUND(sym1) SORT(name) 993 obj1 (default); 994 text->flash_text ALIGN(4) KEEP() SURROUND(sym1) SORT(name) 995""") 996 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 997 fragment = fragment_file.fragments[0] 998 999 expected = [('text', 'flash_text', [Mapping.Align(4, True, False), 1000 Mapping.Keep(), 1001 Mapping.Surround('sym1'), 1002 Mapping.Sort('name')]), 1003 ('text', 'flash_text', [Mapping.Align(4, True, False), 1004 Mapping.Keep(), 1005 Mapping.Surround('sym1'), 1006 Mapping.Sort('name')])] 1007 actual = fragment.flags[('obj1', None, 'default')] 1008 self.assertEqual(expected, actual) 1009 1010 1011class DeprecatedMappingTest(FragmentTest): 1012 1013 def test_valid_grammar(self): 1014 test_fragment = self.create_fragment_file(u""" 1015[mapping] 1016archive: lib.a 1017entries: 1018 obj:symbol (noflash) 1019 # Comments should not matter 1020 obj (noflash) 1021 # Nor should whitespace 1022 obj : symbol_2 ( noflash ) 1023 obj_2 ( noflash ) 1024 * (noflash) 1025""") 1026 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1027 self.assertEqual('lib.a', fragment_file.fragments[0].archive) 1028 self.assertEqual('lib_a', fragment_file.fragments[0].name) 1029 1030 expected = {('obj', 'symbol', 'noflash'), 1031 ('obj', None, 'noflash'), 1032 ('obj', 'symbol_2', 'noflash'), 1033 ('obj_2', None, 'noflash'), 1034 ('*', None, 'noflash') 1035 } 1036 1037 self.assertEqual(expected, fragment_file.fragments[0].entries) 1038 1039 def test_explicit_blank_default_w_others(self): 1040 test_fragment = self.create_fragment_file(u""" 1041[mapping] 1042archive: lib.a 1043entries: 1044 : A = n 1045 obj_a (noflash) 1046 : default 1047""") 1048 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1049 expected = {('*', None, 'default')} 1050 1051 self.assertEqual(expected, fragment_file.fragments[0].entries) 1052 1053 def test_implicit_blank_default_w_others(self): 1054 test_fragment = self.create_fragment_file(u""" 1055[mapping] 1056archive: lib.a 1057entries: 1058 : A = n 1059 obj_a (noflash) 1060""") 1061 1062 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1063 expected = {('*', None, 'default')} 1064 1065 self.assertEqual(expected, fragment_file.fragments[0].entries) 1066 1067 def test_explicit_blank_default(self): 1068 test_fragment = self.create_fragment_file(u""" 1069[mapping] 1070archive: lib.a 1071entries: 1072 : default 1073""") 1074 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1075 expected = {('*', None, 'default')} 1076 1077 self.assertEqual(expected, fragment_file.fragments[0].entries) 1078 1079 def test_implicit_blank_default(self): 1080 test_fragment = self.create_fragment_file(u""" 1081[mapping] 1082archive: lib.a 1083entries: 1084 : default 1085""") 1086 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1087 expected = {('*', None, 'default')} 1088 1089 self.assertEqual(expected, fragment_file.fragments[0].entries) 1090 1091 def test_multiple_entries(self): 1092 test_fragment = self.create_fragment_file(u""" 1093[mapping] 1094archive: lib.a 1095entries: 1096 : A = n 1097 obj_a1 (noflash) 1098 obj_a2 (noflash) 1099 : B = n 1100 obj_b1 (noflash) 1101 obj_b2 (noflash) 1102 obj_b3 (noflash) 1103 : C = n 1104 obj_c1 (noflash) 1105""") 1106 1107 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1108 expected = {('obj_b1', None, 'noflash'), 1109 ('obj_b2', None, 'noflash'), 1110 ('obj_b3', None, 'noflash')} 1111 self.assertEqual(expected, fragment_file.fragments[0].entries) 1112 1113 def test_blank_entries(self): 1114 test_fragment = self.create_fragment_file(u""" 1115[mapping] 1116archive: lib.a 1117entries: 1118 : A = n 1119 obj_a (noflash) 1120 : B = n 1121 : C = n 1122 obj_c (noflash) 1123 : default 1124 obj (noflash) 1125""") 1126 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1127 expected = {('*', None, 'default')} 1128 self.assertEqual(expected, fragment_file.fragments[0].entries) 1129 1130 def test_blank_first_condition(self): 1131 test_fragment = self.create_fragment_file(u""" 1132[mapping] 1133archive: lib.a 1134entries: 1135 obj_a (noflash) 1136 : CONFIG_B = y 1137 obj_b (noflash) 1138""") 1139 1140 with self.assertRaises(ParseException): 1141 FragmentFile(test_fragment, self.sdkconfig) 1142 1143 def test_nonlast_default_1(self): 1144 test_fragment = self.create_fragment_file(u""" 1145[mapping] 1146archive: lib.a 1147entries: 1148 : default 1149 obj_a (noflash) 1150 : CONFIG_A = y 1151 obj_A (noflash) 1152""") 1153 1154 with self.assertRaises(ParseException): 1155 FragmentFile(test_fragment, self.sdkconfig) 1156 1157 def test_nonlast_default_2(self): 1158 test_fragment = self.create_fragment_file(u""" 1159[mapping] 1160archive: lib.a 1161entries: 1162 : A = y 1163 obj_A (noflash) 1164 : default 1165 obj_a (noflash) 1166 : B = y 1167 obj_B (noflash 1168""") 1169 1170 with self.assertRaises(ParseException): 1171 FragmentFile(test_fragment, self.sdkconfig) 1172 1173 def test_nonlast_default_3(self): 1174 test_fragment = self.create_fragment_file(u""" 1175[mapping] 1176archive: lib.a 1177entries: 1178 : A = y 1179 obj_A (noflash) 1180 : 1181 obj_a (noflash) 1182 : B = y 1183 obj_B (noflash 1184""") 1185 1186 with self.assertRaises(ParseException): 1187 FragmentFile(test_fragment, self.sdkconfig) 1188 1189 def test_duplicate_default_1(self): 1190 test_fragment = self.create_fragment_file(u""" 1191[mapping] 1192archive: lib.a 1193entries: 1194 : CONFIG_A = y 1195 obj_A (noflash) 1196 : default 1197 obj_a (noflash) 1198 : CONFIG_B = y 1199 obj_B (noflash) 1200 : default 1201 obj_a (noflash) 1202""") 1203 1204 with self.assertRaises(ParseException): 1205 FragmentFile(test_fragment, self.sdkconfig) 1206 1207 def test_duplicate_default_2(self): 1208 test_fragment = self.create_fragment_file(u""" 1209[mapping] 1210archive: lib.a 1211entries: 1212 : CONFIG_A = y 1213 obj_A (noflash) 1214 : CONFIG_B = y 1215 obj_a (noflash) 1216 : default 1217 obj_B (noflash) 1218 : 1219 obj_a (noflash) 1220""") 1221 1222 with self.assertRaises(ParseException): 1223 FragmentFile(test_fragment, self.sdkconfig) 1224 1225 def test_mixed_deprecated_mapping(self): 1226 test_fragment = self.create_fragment_file(u""" 1227[mapping] 1228archive: lib.a 1229entries: 1230 : A = n 1231 obj_A (noflash) 1232 : default 1233 obj_B (noflash) 1234 1235 1236[mapping:test] 1237archive: lib.a 1238entries: 1239 if A = n: 1240 obj_A (noflash) 1241 else: 1242 obj_B (noflash) 1243""") 1244 1245 fragment_file = FragmentFile(test_fragment, self.sdkconfig) 1246 self.assertEqual(2, len(fragment_file.fragments)) 1247 1248 self.assertEqual(fragment_file.fragments[0].entries, 1249 fragment_file.fragments[1].entries) 1250 1251 1252if __name__ == '__main__': 1253 unittest.main() 1254