xref: /aosp_15_r20/external/pigweed/pw_build_mcuxpresso/py/tests/components_test.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2021 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Components Tests."""
15
16import pathlib
17import unittest
18import xml.etree.ElementTree
19
20from pw_build_mcuxpresso import components
21
22
23class GetComponentTest(unittest.TestCase):
24    """get_component tests."""
25
26    def test_without_basepath(self):
27        test_manifest_xml = '''
28        <manifest>
29          <components>
30            <component id="test">
31            </component>
32          </components>
33        </manifest>
34        '''
35        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
36
37        (component, base_path) = components.get_component(root, 'test')
38
39        self.assertIsInstance(component, xml.etree.ElementTree.Element)
40        self.assertEqual(component.tag, 'component')
41        self.assertEqual(base_path, None)
42
43    def test_with_basepath(self):
44        test_manifest_xml = '''
45        <manifest>
46          <components>
47            <component id="test" package_base_path="test">
48            </component>
49          </components>
50        </manifest>
51        '''
52        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
53
54        (component, base_path) = components.get_component(root, 'test')
55
56        self.assertIsInstance(component, xml.etree.ElementTree.Element)
57        self.assertEqual(component.tag, 'component')
58        self.assertEqual(base_path, pathlib.Path('test'))
59
60    def test_component_not_found(self):
61        test_manifest_xml = '''
62        <manifest>
63          <components>
64            <component id="other">
65            </component>
66          </components>
67        </manifest>
68        '''
69        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
70
71        (component, base_path) = components.get_component(root, 'test')
72
73        self.assertEqual(component, None)
74        self.assertEqual(base_path, None)
75
76    def test_with_device_cores(self):
77        test_manifest_xml = '''
78        <manifest>
79          <components>
80            <component id="test" package_base_path="test" device_cores="CORE0">
81            </component>
82          </components>
83        </manifest>
84        '''
85        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
86
87        (component, base_path) = components.get_component(
88            root, 'test', device_core='CORE0'
89        )
90
91        self.assertIsInstance(component, xml.etree.ElementTree.Element)
92        self.assertEqual(component.tag, 'component')
93        self.assertEqual(base_path, pathlib.Path('test'))
94
95    def test_device_core_not_found(self):
96        test_manifest_xml = '''
97        <manifest>
98          <components>
99            <component id="test" package_base_path="test" device_cores="CORE0">
100            </component>
101          </components>
102        </manifest>
103        '''
104        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
105
106        (component, base_path) = components.get_component(
107            root, 'test', device_core='CORE1'
108        )
109
110        self.assertEqual(component, None)
111        self.assertEqual(base_path, None)
112
113
114class ParseDefinesTest(unittest.TestCase):
115    """parse_defines tests."""
116
117    def test_parse_defines(self):
118        test_manifest_xml = '''
119        <manifest>
120          <components>
121            <component id="test">
122              <defines>
123                <define name="TEST_WITH_VALUE" value="1"/>
124                <define name="TEST_WITHOUT_VALUE"/>
125              </defines>
126            </component>
127          </components>
128        </manifest>
129        '''
130        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
131        defines = components.parse_defines(root, 'test')
132
133        self.assertEqual(defines, ['TEST_WITH_VALUE=1', 'TEST_WITHOUT_VALUE'])
134
135    def test_no_defines(self):
136        test_manifest_xml = '''
137        <manifest>
138          <components>
139            <component id="test">
140            </component>
141          </components>
142        </manifest>
143        '''
144        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
145        defines = components.parse_defines(root, 'test')
146
147        self.assertEqual(defines, [])
148
149    def test_device_cores(self):
150        test_manifest_xml = '''
151        <manifest>
152          <components>
153            <component id="test">
154              <defines>
155                <define name="TEST_WITH_CORE" device_cores="CORE0"/>
156                <define name="TEST_WITHOUT_CORE" device_cores="CORE1"/>
157                <define name="TEST_WITHOUT_CORES"/>
158              </defines>
159            </component>
160          </components>
161        </manifest>
162        '''
163        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
164        defines = components.parse_defines(root, 'test', device_core='CORE0')
165
166        self.assertEqual(defines, ['TEST_WITH_CORE', 'TEST_WITHOUT_CORES'])
167
168
169class ParseIncludePathsTest(unittest.TestCase):
170    """parse_include_paths tests."""
171
172    def test_parse_include_paths(self):
173        test_manifest_xml = '''
174        <manifest>
175          <components>
176            <component id="test">
177              <include_paths>
178                <include_path relative_path="example" type="c_include"/>
179                <include_path relative_path="asm" type="asm_include"/>
180              </include_paths>
181            </component>
182          </components>
183        </manifest>
184        '''
185        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
186        include_paths = components.parse_include_paths(root, 'test')
187
188        self.assertEqual(
189            include_paths, [pathlib.Path('example'), pathlib.Path('asm')]
190        )
191
192    def test_with_base_path(self):
193        test_manifest_xml = '''
194        <manifest>
195          <components>
196            <component id="test" package_base_path="src">
197              <include_paths>
198                <include_path relative_path="example" type="c_include"/>
199                <include_path relative_path="asm" type="asm_include"/>
200              </include_paths>
201            </component>
202          </components>
203        </manifest>
204        '''
205        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
206        include_paths = components.parse_include_paths(root, 'test')
207
208        self.assertEqual(
209            include_paths,
210            [pathlib.Path('src/example'), pathlib.Path('src/asm')],
211        )
212
213    def test_unknown_type(self):
214        test_manifest_xml = '''
215        <manifest>
216          <components>
217            <component id="test" package_base_path="src">
218              <include_paths>
219                <include_path relative_path="rust" type="rust_include"/>
220              </include_paths>
221            </component>
222          </components>
223        </manifest>
224        '''
225        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
226        include_paths = components.parse_include_paths(root, 'test')
227
228        self.assertEqual(include_paths, [])
229
230    def test_no_include_paths(self):
231        test_manifest_xml = '''
232        <manifest>
233          <components>
234            <component id="test">
235            </component>
236          </components>
237        </manifest>
238        '''
239        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
240        include_paths = components.parse_include_paths(root, 'test')
241
242        self.assertEqual(include_paths, [])
243
244    def test_device_cores(self):
245        test_manifest_xml = '''
246        <manifest>
247          <components>
248            <component id="test">
249              <include_paths>
250                <include_path relative_path="with_core" type="c_include"
251                              device_cores="CORE0"/>
252                <include_path relative_path="without_core" type="c_include"
253                              device_cores="CORE1"/>
254                <include_path relative_path="without_cores" type="c_include"/>
255              </include_paths>
256            </component>
257          </components>
258        </manifest>
259        '''
260        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
261        include_paths = components.parse_include_paths(
262            root, 'test', device_core='CORE0'
263        )
264
265        self.assertEqual(
266            include_paths,
267            [pathlib.Path('with_core'), pathlib.Path('without_cores')],
268        )
269
270
271class ParseHeadersTest(unittest.TestCase):
272    """parse_headers tests."""
273
274    def test_parse_headers(self):
275        test_manifest_xml = '''
276        <manifest>
277          <components>
278            <component id="test">
279              <source relative_path="include" type="c_include">
280                <files mask="test.h"/>
281                <files mask="test_types.h"/>
282              </source>
283            </component>
284          </components>
285        </manifest>
286        '''
287        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
288        headers = components.parse_headers(root, 'test')
289
290        self.assertEqual(
291            headers,
292            [
293                pathlib.Path('include/test.h'),
294                pathlib.Path('include/test_types.h'),
295            ],
296        )
297
298    def test_with_base_path(self):
299        test_manifest_xml = '''
300        <manifest>
301          <components>
302            <component id="test" package_base_path="src">
303              <source relative_path="include" type="c_include">
304                <files mask="test.h"/>
305                <files mask="test_types.h"/>
306              </source>
307            </component>
308          </components>
309        </manifest>
310        '''
311        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
312        headers = components.parse_headers(root, 'test')
313
314        self.assertEqual(
315            headers,
316            [
317                pathlib.Path('src/include/test.h'),
318                pathlib.Path('src/include/test_types.h'),
319            ],
320        )
321
322    def test_multiple_sets(self):
323        test_manifest_xml = '''
324        <manifest>
325          <components>
326            <component id="test">
327              <source relative_path="include" type="c_include">
328                <files mask="test.h"/>
329              </source>
330              <source relative_path="internal" type="c_include">
331                <files mask="test_types.h"/>
332              </source>
333            </component>
334          </components>
335        </manifest>
336        '''
337        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
338        headers = components.parse_headers(root, 'test')
339
340        self.assertEqual(
341            headers,
342            [
343                pathlib.Path('include/test.h'),
344                pathlib.Path('internal/test_types.h'),
345            ],
346        )
347
348    def test_no_headers(self):
349        test_manifest_xml = '''
350        <manifest>
351          <components>
352            <component id="test">
353            </component>
354          </components>
355        </manifest>
356        '''
357        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
358        headers = components.parse_headers(root, 'test')
359
360        self.assertEqual(headers, [])
361
362    def test_device_cores(self):
363        test_manifest_xml = '''
364        <manifest>
365          <components>
366            <component id="test">
367              <source relative_path="with_core" type="c_include"
368                      device_cores="CORE0">
369                <files mask="test.h"/>
370              </source>
371              <source relative_path="without_core" type="c_include"
372                      device_cores="CORE1">
373                <files mask="test.h"/>
374              </source>
375              <source relative_path="without_cores" type="c_include">
376                <files mask="test.h"/>
377              </source>
378            </component>
379          </components>
380        </manifest>
381        '''
382        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
383        headers = components.parse_headers(root, 'test', device_core='CORE0')
384
385        self.assertEqual(
386            headers,
387            [
388                pathlib.Path('with_core/test.h'),
389                pathlib.Path('without_cores/test.h'),
390            ],
391        )
392
393
394class ParseSourcesTest(unittest.TestCase):
395    """parse_sources tests."""
396
397    def test_parse_sources(self):
398        test_manifest_xml = '''
399        <manifest>
400          <components>
401            <component id="test">
402              <source relative_path="src" type="src">
403                <files mask="main.cc"/>
404                <files mask="test.cc"/>
405              </source>
406            </component>
407          </components>
408        </manifest>
409        '''
410        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
411        sources = components.parse_sources(root, 'test')
412
413        self.assertEqual(
414            sources, [pathlib.Path('src/main.cc'), pathlib.Path('src/test.cc')]
415        )
416
417    def test_with_base_path(self):
418        test_manifest_xml = '''
419        <manifest>
420          <components>
421            <component id="test" package_base_path="src">
422              <source relative_path="app" type="src">
423                <files mask="main.cc"/>
424                <files mask="test.cc"/>
425              </source>
426            </component>
427          </components>
428        </manifest>
429        '''
430        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
431        sources = components.parse_sources(root, 'test')
432
433        self.assertEqual(
434            sources,
435            [pathlib.Path('src/app/main.cc'), pathlib.Path('src/app/test.cc')],
436        )
437
438    def test_multiple_sets(self):
439        test_manifest_xml = '''
440        <manifest>
441          <components>
442            <component id="test">
443              <source relative_path="shared" type="src">
444                <files mask="test.cc"/>
445              </source>
446              <source relative_path="lib" type="src_c">
447                <files mask="test.c"/>
448              </source>
449              <source relative_path="app" type="src_cpp">
450                <files mask="main.cc"/>
451              </source>
452              <source relative_path="startup" type="asm_include">
453                <files mask="boot.s"/>
454              </source>
455            </component>
456          </components>
457        </manifest>
458        '''
459        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
460        sources = components.parse_sources(root, 'test')
461
462        self.assertEqual(
463            sources,
464            [
465                pathlib.Path('shared/test.cc'),
466                pathlib.Path('lib/test.c'),
467                pathlib.Path('app/main.cc'),
468                pathlib.Path('startup/boot.s'),
469            ],
470        )
471
472    def test_unknown_type(self):
473        test_manifest_xml = '''
474        <manifest>
475          <components>
476            <component id="test">
477            <source relative_path="src" type="rust">
478                <files mask="test.rs"/>
479              </source>
480            </component>
481          </components>
482        </manifest>
483        '''
484        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
485        sources = components.parse_sources(root, 'test')
486
487        self.assertEqual(sources, [])
488
489    def test_no_sources(self):
490        test_manifest_xml = '''
491        <manifest>
492          <components>
493            <component id="test">
494            </component>
495          </components>
496        </manifest>
497        '''
498        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
499        sources = components.parse_sources(root, 'test')
500
501        self.assertEqual(sources, [])
502
503    def test_device_cores(self):
504        test_manifest_xml = '''
505        <manifest>
506          <components>
507            <component id="test">
508              <source relative_path="with_core" type="src" device_cores="CORE0">
509                <files mask="main.cc"/>
510              </source>
511              <source relative_path="without_core" type="src"
512                      device_cores="CORE1">
513                <files mask="main.cc"/>
514              </source>
515              <source relative_path="without_cores" type="src">
516                <files mask="main.cc"/>
517              </source>
518            </component>
519          </components>
520        </manifest>
521        '''
522        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
523        sources = components.parse_sources(root, 'test', device_core='CORE0')
524
525        self.assertEqual(
526            sources,
527            [
528                pathlib.Path('with_core/main.cc'),
529                pathlib.Path('without_cores/main.cc'),
530            ],
531        )
532
533
534class ParseLibsTest(unittest.TestCase):
535    """parse_libs tests."""
536
537    def test_parse_libs(self):
538        test_manifest_xml = '''
539        <manifest>
540          <components>
541            <component id="test">
542              <source relative_path="gcc" type="lib">
543                <files mask="libtest.a"/>
544                <files mask="libtest_arm.a"/>
545              </source>
546            </component>
547          </components>
548        </manifest>
549        '''
550        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
551        libs = components.parse_libs(root, 'test')
552
553        self.assertEqual(
554            libs,
555            [pathlib.Path('gcc/libtest.a'), pathlib.Path('gcc/libtest_arm.a')],
556        )
557
558    def test_with_base_path(self):
559        test_manifest_xml = '''
560        <manifest>
561          <components>
562            <component id="test" package_base_path="src">
563              <source relative_path="gcc" type="lib">
564                <files mask="libtest.a"/>
565                <files mask="libtest_arm.a"/>
566              </source>
567            </component>
568          </components>
569        </manifest>
570        '''
571        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
572        libs = components.parse_libs(root, 'test')
573
574        self.assertEqual(
575            libs,
576            [
577                pathlib.Path('src/gcc/libtest.a'),
578                pathlib.Path('src/gcc/libtest_arm.a'),
579            ],
580        )
581
582    def test_multiple_sets(self):
583        test_manifest_xml = '''
584        <manifest>
585          <components>
586            <component id="test">
587              <source relative_path="gcc" type="lib">
588                <files mask="libtest.a"/>
589              </source>
590              <source relative_path="arm" type="lib">
591                <files mask="libtest_arm.a"/>
592              </source>
593            </component>
594          </components>
595        </manifest>
596        '''
597        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
598        libs = components.parse_libs(root, 'test')
599
600        self.assertEqual(
601            libs,
602            [pathlib.Path('gcc/libtest.a'), pathlib.Path('arm/libtest_arm.a')],
603        )
604
605    def test_no_libs(self):
606        test_manifest_xml = '''
607        <manifest>
608          <components>
609            <component id="test">
610            </component>
611          </components>
612        </manifest>
613        '''
614        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
615        libs = components.parse_libs(root, 'test')
616
617        self.assertEqual(libs, [])
618
619    def test_device_cores(self):
620        test_manifest_xml = '''
621        <manifest>
622          <components>
623            <component id="test">
624              <source relative_path="with_core" type="lib" device_cores="CORE0">
625                <files mask="libtest.a"/>
626              </source>
627              <source relative_path="without_core" type="lib"
628                      device_cores="CORE1">
629                <files mask="libtest.a"/>
630              </source>
631              <source relative_path="without_cores" type="lib">
632                <files mask="libtest.a"/>
633              </source>
634            </component>
635          </components>
636        </manifest>
637        '''
638        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
639        libs = components.parse_libs(root, 'test', device_core='CORE0')
640
641        self.assertEqual(
642            libs,
643            [
644                pathlib.Path('with_core/libtest.a'),
645                pathlib.Path('without_cores/libtest.a'),
646            ],
647        )
648
649
650class ParseDependenciesTest(unittest.TestCase):
651    """parse_dependencies tests."""
652
653    def test_component_dependency(self):
654        test_manifest_xml = '''
655        <manifest>
656          <components>
657            <component id="test">
658              <dependencies>
659                <component_dependency value="foo"/>
660              </dependencies>
661            </component>
662          </components>
663        </manifest>
664        '''
665        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
666        dependencies = components.parse_dependencies(root, 'test')
667
668        self.assertEqual(dependencies, ['foo'])
669
670    def test_all(self):
671        test_manifest_xml = '''
672        <manifest>
673          <components>
674            <component id="test">
675              <dependencies>
676                <all>
677                  <component_dependency value="foo"/>
678                  <component_dependency value="bar"/>
679                  <component_dependency value="baz"/>
680                </all>
681              </dependencies>
682            </component>
683          </components>
684        </manifest>
685        '''
686        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
687        dependencies = components.parse_dependencies(root, 'test')
688
689        self.assertEqual(dependencies, ['foo', 'bar', 'baz'])
690
691    def test_any_of_ignored(self):
692        test_manifest_xml = '''
693        <manifest>
694          <components>
695            <component id="test">
696              <dependencies>
697                <any_of>
698                  <component_dependency value="foo"/>
699                  <component_dependency value="bar"/>
700                  <component_dependency value="baz"/>
701                </any_of>
702              </dependencies>
703            </component>
704          </components>
705        </manifest>
706        '''
707        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
708        dependencies = components.parse_dependencies(root, 'test')
709
710        self.assertEqual(dependencies, [])
711
712    def test_any_of_inside_all_ignored(self):
713        test_manifest_xml = '''
714        <manifest>
715          <components>
716            <component id="test">
717              <dependencies>
718                <all>
719                  <component_dependency value="foo"/>
720                  <component_dependency value="bar"/>
721                  <component_dependency value="baz"/>
722                  <any_of>
723                    <all>
724                      <component_dependency value="frodo"/>
725                      <component_dependency value="bilbo"/>
726                    </all>
727                    <component_dependency value="gandalf"/>
728                  </any_of>
729                </all>
730              </dependencies>
731            </component>
732          </components>
733        </manifest>
734        '''
735        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
736        dependencies = components.parse_dependencies(root, 'test')
737
738        self.assertEqual(dependencies, ['foo', 'bar', 'baz'])
739
740    def test_no_dependencies(self):
741        test_manifest_xml = '''
742        <manifest>
743          <components>
744            <component id="test">
745            </component>
746          </components>
747        </manifest>
748        '''
749        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
750        dependencies = components.parse_dependencies(root, 'test')
751
752        self.assertEqual(dependencies, [])
753
754
755class CheckDependenciesTest(unittest.TestCase):
756    """check_dependencies tests."""
757
758    def test_any_of_satisfied(self):
759        test_manifest_xml = '''
760        <manifest>
761          <components>
762            <component id="test">
763              <dependencies>
764                <any_of>
765                  <component_dependency value="foo"/>
766                  <component_dependency value="bar"/>
767                  <component_dependency value="baz"/>
768                </any_of>
769              </dependencies>
770            </component>
771          </components>
772        </manifest>
773        '''
774        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
775        satisfied = components.check_dependencies(
776            root, 'test', ['test', 'foo'], exclude=None
777        )
778
779        self.assertEqual(satisfied, True)
780
781    def test_any_of_not_satisfied(self):
782        test_manifest_xml = '''
783        <manifest>
784          <components>
785            <component id="test">
786              <dependencies>
787                <any_of>
788                  <component_dependency value="foo"/>
789                  <component_dependency value="bar"/>
790                  <component_dependency value="baz"/>
791                </any_of>
792              </dependencies>
793            </component>
794          </components>
795        </manifest>
796        '''
797        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
798        satisfied = components.check_dependencies(
799            root, 'test', ['test'], exclude=None
800        )
801
802        self.assertEqual(satisfied, False)
803
804    def test_any_of_satisfied_by_exclude(self):
805        test_manifest_xml = '''
806        <manifest>
807          <components>
808            <component id="test">
809              <dependencies>
810                <any_of>
811                  <component_dependency value="foo"/>
812                  <component_dependency value="bar"/>
813                  <component_dependency value="baz"/>
814                </any_of>
815              </dependencies>
816            </component>
817          </components>
818        </manifest>
819        '''
820        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
821        satisfied = components.check_dependencies(
822            root, 'test', ['test'], exclude=['foo']
823        )
824
825        self.assertEqual(satisfied, True)
826
827    def test_any_of_all_satisfied(self):
828        test_manifest_xml = '''
829        <manifest>
830          <components>
831            <component id="test">
832              <dependencies>
833                <any_of>
834                  <all>
835                    <component_dependency value="foo"/>
836                    <component_dependency value="bar"/>
837                    <component_dependency value="baz"/>
838                  </all>
839                </any_of>
840              </dependencies>
841            </component>
842          </components>
843        </manifest>
844        '''
845        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
846        satisfied = components.check_dependencies(
847            root, 'test', ['test', 'foo', 'bar', 'baz'], exclude=None
848        )
849
850        self.assertEqual(satisfied, True)
851
852    def test_any_of_all_not_satisfied(self):
853        test_manifest_xml = '''
854        <manifest>
855          <components>
856            <component id="test">
857              <dependencies>
858                <any_of>
859                  <all>
860                    <component_dependency value="foo"/>
861                    <component_dependency value="bar"/>
862                    <component_dependency value="baz"/>
863                  </all>
864                </any_of>
865              </dependencies>
866            </component>
867          </components>
868        </manifest>
869        '''
870        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
871        satisfied = components.check_dependencies(
872            root, 'test', ['test', 'foo', 'bar'], exclude=None
873        )
874
875        self.assertEqual(satisfied, False)
876
877    def test_any_of_all_satisfied_by_exclude(self):
878        test_manifest_xml = '''
879        <manifest>
880          <components>
881            <component id="test">
882              <dependencies>
883                <any_of>
884                  <all>
885                    <component_dependency value="foo"/>
886                    <component_dependency value="bar"/>
887                    <component_dependency value="baz"/>
888                  </all>
889                </any_of>
890              </dependencies>
891            </component>
892          </components>
893        </manifest>
894        '''
895        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
896        satisfied = components.check_dependencies(
897            root, 'test', ['test', 'foo', 'bar'], exclude=['baz']
898        )
899
900        self.assertEqual(satisfied, True)
901
902    def test_any_of_all_or_one_satisfied(self):
903        test_manifest_xml = '''
904        <manifest>
905          <components>
906            <component id="test">
907              <dependencies>
908                <any_of>
909                  <all>
910                    <component_dependency value="foo"/>
911                    <component_dependency value="bar"/>
912                    <component_dependency value="baz"/>
913                  </all>
914                  <component_dependency value="frodo"/>
915                </any_of>
916              </dependencies>
917            </component>
918          </components>
919        </manifest>
920        '''
921        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
922        satisfied = components.check_dependencies(
923            root, 'test', ['test', 'frodo'], exclude=None
924        )
925
926        self.assertEqual(satisfied, True)
927
928    def test_any_of_all_or_one_not_satisfied(self):
929        test_manifest_xml = '''
930        <manifest>
931          <components>
932            <component id="test">
933              <dependencies>
934                <any_of>
935                  <all>
936                    <component_dependency value="foo"/>
937                    <component_dependency value="bar"/>
938                    <component_dependency value="baz"/>
939                  </all>
940                  <component_dependency value="frodo"/>
941                </any_of>
942              </dependencies>
943            </component>
944          </components>
945        </manifest>
946        '''
947        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
948        satisfied = components.check_dependencies(
949            root, 'test', ['test'], exclude=None
950        )
951
952        self.assertEqual(satisfied, False)
953
954    def test_any_of_all_or_one_satisfied_by_exclude(self):
955        test_manifest_xml = '''
956        <manifest>
957          <components>
958            <component id="test">
959              <dependencies>
960                <any_of>
961                  <all>
962                    <component_dependency value="foo"/>
963                    <component_dependency value="bar"/>
964                    <component_dependency value="baz"/>
965                  </all>
966                  <component_dependency value="frodo"/>
967                </any_of>
968              </dependencies>
969            </component>
970          </components>
971        </manifest>
972        '''
973        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
974        satisfied = components.check_dependencies(
975            root, 'test', ['test'], exclude=['frodo']
976        )
977
978        self.assertEqual(satisfied, True)
979
980
981class ProjectTest(unittest.TestCase):
982    """Project tests."""
983
984    def test_create_project(self):
985        """test creating a project."""
986        test_manifest_xml = '''
987        <manifest>
988          <components>
989            <component id="test">
990              <dependencies>
991                <component_dependency value="foo"/>
992                <component_dependency value="bar"/>
993                <any_of>
994                  <component_dependency value="baz"/>
995                </any_of>
996              </dependencies>
997            </component>
998            <component id="foo" package_base_path="foo">
999              <defines>
1000                <define name="FOO"/>
1001              </defines>
1002              <source relative_path="include" type="c_include">
1003                <files mask="foo.h"/>
1004              </source>
1005              <source relative_path="src" type="src">
1006                <files mask="foo.cc"/>
1007              </source>
1008              <include_paths>
1009                <include_path relative_path="include" type="c_include"/>
1010              </include_paths>
1011              <!-- core0 should be included in the project -->
1012              <source relative_path="include" type="c_include"
1013                      device_cores="CORE0">
1014                <files mask="core0.h"/>
1015              </source>
1016              <source relative_path="src" type="src" device_cores="CORE0">
1017                <files mask="core0.cc"/>
1018              </source>
1019              <!-- core1 should not be included in the project -->
1020              <source relative_path="include" type="c_include"
1021                      device_cores="CORE1">
1022                <files mask="core1.h"/>
1023              </source>
1024              <source relative_path="src" type="src" device_cores="CORE1">
1025                <files mask="core0.cc"/>
1026              </source>
1027              <!-- common should be -->
1028              <source relative_path="include" type="c_include"
1029                      device_cores="CORE0 CORE1">
1030                <files mask="common.h"/>
1031              </source>
1032              <source relative_path="src" type="src" device_cores="CORE0 CORE1">
1033                <files mask="common.cc"/>
1034              </source>
1035            </component>
1036            <component id="bar" package_base_path="bar">
1037              <defines>
1038                <define name="BAR"/>
1039              </defines>
1040              <source relative_path="include" type="c_include">
1041                <files mask="bar.h"/>
1042              </source>
1043              <source relative_path="src" type="src">
1044                <files mask="bar.cc"/>
1045              </source>
1046              <include_paths>
1047                <include_path relative_path="include" type="c_include"/>
1048              </include_paths>
1049            </component>
1050            <!-- baz should not be included in the output -->
1051            <component id="baz" package_base_path="baz">
1052              <defines>
1053                <define name="BAZ"/>
1054              </defines>
1055              <source relative_path="include" type="c_include">
1056                <files mask="baz.h"/>
1057              </source>
1058              <source relative_path="src" type="src">
1059                <files mask="baz.cc"/>
1060              </source>
1061              <include_paths>
1062                <include_path relative_path="include" type="c_include"/>
1063              </include_paths>
1064            </component>
1065            <component id="frodo" package_base_path="frodo">
1066              <dependencies>
1067                <component_dependency value="bilbo"/>
1068              </dependencies>
1069              <defines>
1070                <define name="FRODO"/>
1071              </defines>
1072              <source relative_path="include" type="c_include">
1073                <files mask="frodo.h"/>
1074              </source>
1075              <source relative_path="src" type="src">
1076                <files mask="frodo.cc"/>
1077              </source>
1078              <source relative_path="./" type="lib">
1079                <files mask="libonering.a"/>
1080              </source>
1081              <include_paths>
1082                <include_path relative_path="include" type="c_include"/>
1083              </include_paths>
1084            </component>
1085            <!-- bilbo should be excluded from the project -->
1086            <component id="bilbo" package_base_path="bilbo">
1087              <defines>
1088                <define name="BILBO"/>
1089              </defines>
1090              <source relative_path="include" type="c_include">
1091                <files mask="bilbo.h"/>
1092              </source>
1093              <source relative_path="src" type="src">
1094                <files mask="bilbo.cc"/>
1095              </source>
1096              <include_paths>
1097                <include_path relative_path="include" type="c_include"/>
1098              </include_paths>
1099            </component>
1100          </components>
1101        </manifest>
1102        '''
1103        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
1104        project = components.Project(
1105            root,
1106            ['test', 'frodo'],
1107            exclude=['baz', 'bilbo'],
1108            device_core='CORE0',
1109        )
1110
1111        self.assertEqual(project.component_ids, ['test', 'frodo', 'foo', 'bar'])
1112        self.assertEqual(project.defines, ['FRODO', 'FOO', 'BAR'])
1113        self.assertEqual(
1114            project.include_dirs,
1115            [
1116                pathlib.Path('frodo/include'),
1117                pathlib.Path('foo/include'),
1118                pathlib.Path('bar/include'),
1119            ],
1120        )
1121        self.assertEqual(
1122            project.headers,
1123            [
1124                pathlib.Path('frodo/include/frodo.h'),
1125                pathlib.Path('foo/include/foo.h'),
1126                pathlib.Path('foo/include/core0.h'),
1127                pathlib.Path('foo/include/common.h'),
1128                pathlib.Path('bar/include/bar.h'),
1129            ],
1130        )
1131        self.assertEqual(
1132            project.sources,
1133            [
1134                pathlib.Path('frodo/src/frodo.cc'),
1135                pathlib.Path('foo/src/foo.cc'),
1136                pathlib.Path('foo/src/core0.cc'),
1137                pathlib.Path('foo/src/common.cc'),
1138                pathlib.Path('bar/src/bar.cc'),
1139            ],
1140        )
1141        self.assertEqual(project.libs, [pathlib.Path('frodo/libonering.a')])
1142        self.assertTrue(project.dependencies_satisfied)
1143
1144
1145if __name__ == '__main__':
1146    unittest.main()
1147