• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    def test_without_basepath(self):
26        test_manifest_xml = '''
27        <manifest>
28          <components>
29            <component id="test">
30            </component>
31          </components>
32        </manifest>
33        '''
34        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
35
36        (component, base_path) = components.get_component(root, 'test')
37
38        self.assertIsInstance(component, xml.etree.ElementTree.Element)
39        self.assertEqual(component.tag, 'component')
40        self.assertEqual(base_path, None)
41
42    def test_with_basepath(self):
43        test_manifest_xml = '''
44        <manifest>
45          <components>
46            <component id="test" package_base_path="test">
47            </component>
48          </components>
49        </manifest>
50        '''
51        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
52
53        (component, base_path) = components.get_component(root, 'test')
54
55        self.assertIsInstance(component, xml.etree.ElementTree.Element)
56        self.assertEqual(component.tag, 'component')
57        self.assertEqual(base_path, pathlib.Path('test'))
58
59    def test_component_not_found(self):
60        test_manifest_xml = '''
61        <manifest>
62          <components>
63            <component id="other">
64            </component>
65          </components>
66        </manifest>
67        '''
68        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
69
70        (component, base_path) = components.get_component(root, 'test')
71
72        self.assertEqual(component, None)
73        self.assertEqual(base_path, None)
74
75
76class ParseDefinesTest(unittest.TestCase):
77    """parse_defines tests."""
78    def test_parse_defines(self):
79        test_manifest_xml = '''
80        <manifest>
81          <components>
82            <component id="test">
83              <defines>
84                <define name="TEST_WITH_VALUE" value="1"/>
85                <define name="TEST_WITHOUT_VALUE"/>
86              </defines>
87            </component>
88          </components>
89        </manifest>
90        '''
91        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
92        defines = components.parse_defines(root, 'test')
93
94        self.assertEqual(defines, ['TEST_WITH_VALUE=1', 'TEST_WITHOUT_VALUE'])
95
96    def test_no_defines(self):
97        test_manifest_xml = '''
98        <manifest>
99          <components>
100            <component id="test">
101            </component>
102          </components>
103        </manifest>
104        '''
105        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
106        defines = components.parse_defines(root, 'test')
107
108        self.assertEqual(defines, [])
109
110
111class ParseIncludePathsTest(unittest.TestCase):
112    """parse_include_paths tests."""
113    def test_parse_include_paths(self):
114        test_manifest_xml = '''
115        <manifest>
116          <components>
117            <component id="test">
118              <include_paths>
119                <include_path relative_path="example" type="c_include"/>
120                <include_path relative_path="asm" type="asm_include"/>
121              </include_paths>
122            </component>
123          </components>
124        </manifest>
125        '''
126        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
127        include_paths = components.parse_include_paths(root, 'test')
128
129        self.assertEqual(include_paths,
130                         [pathlib.Path('example'),
131                          pathlib.Path('asm')])
132
133    def test_with_base_path(self):
134        test_manifest_xml = '''
135        <manifest>
136          <components>
137            <component id="test" package_base_path="src">
138              <include_paths>
139                <include_path relative_path="example" type="c_include"/>
140                <include_path relative_path="asm" type="asm_include"/>
141              </include_paths>
142            </component>
143          </components>
144        </manifest>
145        '''
146        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
147        include_paths = components.parse_include_paths(root, 'test')
148
149        self.assertEqual(
150            include_paths,
151            [pathlib.Path('src/example'),
152             pathlib.Path('src/asm')])
153
154    def test_unknown_type(self):
155        test_manifest_xml = '''
156        <manifest>
157          <components>
158            <component id="test" package_base_path="src">
159              <include_paths>
160                <include_path relative_path="rust" type="rust_include"/>
161              </include_paths>
162            </component>
163          </components>
164        </manifest>
165        '''
166        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
167        include_paths = components.parse_include_paths(root, 'test')
168
169        self.assertEqual(include_paths, [])
170
171    def test_no_include_paths(self):
172        test_manifest_xml = '''
173        <manifest>
174          <components>
175            <component id="test">
176            </component>
177          </components>
178        </manifest>
179        '''
180        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
181        include_paths = components.parse_include_paths(root, 'test')
182
183        self.assertEqual(include_paths, [])
184
185
186class ParseHeadersTest(unittest.TestCase):
187    """parse_headers tests."""
188    def test_parse_headers(self):
189        test_manifest_xml = '''
190        <manifest>
191          <components>
192            <component id="test">
193              <source relative_path="include" type="c_include">
194                <files mask="test.h"/>
195                <files mask="test_types.h"/>
196              </source>
197            </component>
198          </components>
199        </manifest>
200        '''
201        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
202        headers = components.parse_headers(root, 'test')
203
204        self.assertEqual(headers, [
205            pathlib.Path('include/test.h'),
206            pathlib.Path('include/test_types.h')
207        ])
208
209    def test_with_base_path(self):
210        test_manifest_xml = '''
211        <manifest>
212          <components>
213            <component id="test" package_base_path="src">
214              <source relative_path="include" type="c_include">
215                <files mask="test.h"/>
216                <files mask="test_types.h"/>
217              </source>
218            </component>
219          </components>
220        </manifest>
221        '''
222        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
223        headers = components.parse_headers(root, 'test')
224
225        self.assertEqual(headers, [
226            pathlib.Path('src/include/test.h'),
227            pathlib.Path('src/include/test_types.h')
228        ])
229
230    def test_multiple_sets(self):
231        test_manifest_xml = '''
232        <manifest>
233          <components>
234            <component id="test">
235              <source relative_path="include" type="c_include">
236                <files mask="test.h"/>
237              </source>
238              <source relative_path="internal" type="c_include">
239                <files mask="test_types.h"/>
240              </source>
241            </component>
242          </components>
243        </manifest>
244        '''
245        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
246        headers = components.parse_headers(root, 'test')
247
248        self.assertEqual(headers, [
249            pathlib.Path('include/test.h'),
250            pathlib.Path('internal/test_types.h')
251        ])
252
253    def test_no_headers(self):
254        test_manifest_xml = '''
255        <manifest>
256          <components>
257            <component id="test">
258            </component>
259          </components>
260        </manifest>
261        '''
262        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
263        headers = components.parse_headers(root, 'test')
264
265        self.assertEqual(headers, [])
266
267
268class ParseSourcesTest(unittest.TestCase):
269    """parse_sources tests."""
270    def test_parse_sources(self):
271        test_manifest_xml = '''
272        <manifest>
273          <components>
274            <component id="test">
275              <source relative_path="src" type="src">
276                <files mask="main.cc"/>
277                <files mask="test.cc"/>
278              </source>
279            </component>
280          </components>
281        </manifest>
282        '''
283        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
284        sources = components.parse_sources(root, 'test')
285
286        self.assertEqual(
287            sources,
288            [pathlib.Path('src/main.cc'),
289             pathlib.Path('src/test.cc')])
290
291    def test_with_base_path(self):
292        test_manifest_xml = '''
293        <manifest>
294          <components>
295            <component id="test" package_base_path="src">
296              <source relative_path="app" type="src">
297                <files mask="main.cc"/>
298                <files mask="test.cc"/>
299              </source>
300            </component>
301          </components>
302        </manifest>
303        '''
304        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
305        sources = components.parse_sources(root, 'test')
306
307        self.assertEqual(
308            sources,
309            [pathlib.Path('src/app/main.cc'),
310             pathlib.Path('src/app/test.cc')])
311
312    def test_multiple_sets(self):
313        test_manifest_xml = '''
314        <manifest>
315          <components>
316            <component id="test">
317              <source relative_path="shared" type="src">
318                <files mask="test.cc"/>
319              </source>
320              <source relative_path="lib" type="src_c">
321                <files mask="test.c"/>
322              </source>
323              <source relative_path="app" type="src_cpp">
324                <files mask="main.cc"/>
325              </source>
326              <source relative_path="startup" type="asm_include">
327                <files mask="boot.s"/>
328              </source>
329            </component>
330          </components>
331        </manifest>
332        '''
333        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
334        sources = components.parse_sources(root, 'test')
335
336        self.assertEqual(sources, [
337            pathlib.Path('shared/test.cc'),
338            pathlib.Path('lib/test.c'),
339            pathlib.Path('app/main.cc'),
340            pathlib.Path('startup/boot.s')
341        ])
342
343    def test_unknown_type(self):
344        test_manifest_xml = '''
345        <manifest>
346          <components>
347            <component id="test">
348            <source relative_path="src" type="rust">
349                <files mask="test.rs"/>
350              </source>
351            </component>
352          </components>
353        </manifest>
354        '''
355        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
356        sources = components.parse_sources(root, 'test')
357
358        self.assertEqual(sources, [])
359
360    def test_no_sources(self):
361        test_manifest_xml = '''
362        <manifest>
363          <components>
364            <component id="test">
365            </component>
366          </components>
367        </manifest>
368        '''
369        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
370        sources = components.parse_sources(root, 'test')
371
372        self.assertEqual(sources, [])
373
374
375class ParseLibsTest(unittest.TestCase):
376    """parse_libs tests."""
377    def test_parse_libs(self):
378        test_manifest_xml = '''
379        <manifest>
380          <components>
381            <component id="test">
382              <source relative_path="gcc" type="lib">
383                <files mask="libtest.a"/>
384                <files mask="libtest_arm.a"/>
385              </source>
386            </component>
387          </components>
388        </manifest>
389        '''
390        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
391        libs = components.parse_libs(root, 'test')
392
393        self.assertEqual(
394            libs,
395            [pathlib.Path('gcc/libtest.a'),
396             pathlib.Path('gcc/libtest_arm.a')])
397
398    def test_with_base_path(self):
399        test_manifest_xml = '''
400        <manifest>
401          <components>
402            <component id="test" package_base_path="src">
403              <source relative_path="gcc" type="lib">
404                <files mask="libtest.a"/>
405                <files mask="libtest_arm.a"/>
406              </source>
407            </component>
408          </components>
409        </manifest>
410        '''
411        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
412        libs = components.parse_libs(root, 'test')
413
414        self.assertEqual(libs, [
415            pathlib.Path('src/gcc/libtest.a'),
416            pathlib.Path('src/gcc/libtest_arm.a')
417        ])
418
419    def test_multiple_sets(self):
420        test_manifest_xml = '''
421        <manifest>
422          <components>
423            <component id="test">
424              <source relative_path="gcc" type="lib">
425                <files mask="libtest.a"/>
426              </source>
427              <source relative_path="arm" type="lib">
428                <files mask="libtest_arm.a"/>
429              </source>
430            </component>
431          </components>
432        </manifest>
433        '''
434        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
435        libs = components.parse_libs(root, 'test')
436
437        self.assertEqual(
438            libs,
439            [pathlib.Path('gcc/libtest.a'),
440             pathlib.Path('arm/libtest_arm.a')])
441
442    def test_no_libs(self):
443        test_manifest_xml = '''
444        <manifest>
445          <components>
446            <component id="test">
447            </component>
448          </components>
449        </manifest>
450        '''
451        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
452        libs = components.parse_libs(root, 'test')
453
454        self.assertEqual(libs, [])
455
456
457class ParseDependenciesTest(unittest.TestCase):
458    """parse_dependencies tests."""
459    def test_component_dependency(self):
460        test_manifest_xml = '''
461        <manifest>
462          <components>
463            <component id="test">
464              <dependencies>
465                <component_dependency value="foo"/>
466              </dependencies>
467            </component>
468          </components>
469        </manifest>
470        '''
471        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
472        dependencies = components.parse_dependencies(root, 'test')
473
474        self.assertEqual(dependencies, ['foo'])
475
476    def test_all(self):
477        test_manifest_xml = '''
478        <manifest>
479          <components>
480            <component id="test">
481              <dependencies>
482                <all>
483                  <component_dependency value="foo"/>
484                  <component_dependency value="bar"/>
485                  <component_dependency value="baz"/>
486                </all>
487              </dependencies>
488            </component>
489          </components>
490        </manifest>
491        '''
492        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
493        dependencies = components.parse_dependencies(root, 'test')
494
495        self.assertEqual(dependencies, ['foo', 'bar', 'baz'])
496
497    def test_any_of_ignored(self):
498        test_manifest_xml = '''
499        <manifest>
500          <components>
501            <component id="test">
502              <dependencies>
503                <any_of>
504                  <component_dependency value="foo"/>
505                  <component_dependency value="bar"/>
506                  <component_dependency value="baz"/>
507                </any_of>
508              </dependencies>
509            </component>
510          </components>
511        </manifest>
512        '''
513        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
514        dependencies = components.parse_dependencies(root, 'test')
515
516        self.assertEqual(dependencies, [])
517
518    def test_any_of_inside_all_ignored(self):
519        test_manifest_xml = '''
520        <manifest>
521          <components>
522            <component id="test">
523              <dependencies>
524                <all>
525                  <component_dependency value="foo"/>
526                  <component_dependency value="bar"/>
527                  <component_dependency value="baz"/>
528                  <any_of>
529                    <all>
530                      <component_dependency value="frodo"/>
531                      <component_dependency value="bilbo"/>
532                    </all>
533                    <component_dependency value="gandalf"/>
534                  </any_of>
535                </all>
536              </dependencies>
537            </component>
538          </components>
539        </manifest>
540        '''
541        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
542        dependencies = components.parse_dependencies(root, 'test')
543
544        self.assertEqual(dependencies, ['foo', 'bar', 'baz'])
545
546    def test_no_dependencies(self):
547        test_manifest_xml = '''
548        <manifest>
549          <components>
550            <component id="test">
551            </component>
552          </components>
553        </manifest>
554        '''
555        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
556        dependencies = components.parse_dependencies(root, 'test')
557
558        self.assertEqual(dependencies, [])
559
560
561class CheckDependenciesTest(unittest.TestCase):
562    """check_dependencies tests."""
563    def test_any_of_satisfied(self):
564        test_manifest_xml = '''
565        <manifest>
566          <components>
567            <component id="test">
568              <dependencies>
569                <any_of>
570                  <component_dependency value="foo"/>
571                  <component_dependency value="bar"/>
572                  <component_dependency value="baz"/>
573                </any_of>
574              </dependencies>
575            </component>
576          </components>
577        </manifest>
578        '''
579        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
580        satisfied = components.check_dependencies(root,
581                                                  'test', ['test', 'foo'],
582                                                  exclude=None)
583
584        self.assertEqual(satisfied, True)
585
586    def test_any_of_not_satisfied(self):
587        test_manifest_xml = '''
588        <manifest>
589          <components>
590            <component id="test">
591              <dependencies>
592                <any_of>
593                  <component_dependency value="foo"/>
594                  <component_dependency value="bar"/>
595                  <component_dependency value="baz"/>
596                </any_of>
597              </dependencies>
598            </component>
599          </components>
600        </manifest>
601        '''
602        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
603        satisfied = components.check_dependencies(root,
604                                                  'test', ['test'],
605                                                  exclude=None)
606
607        self.assertEqual(satisfied, False)
608
609    def test_any_of_satisfied_by_exclude(self):
610        test_manifest_xml = '''
611        <manifest>
612          <components>
613            <component id="test">
614              <dependencies>
615                <any_of>
616                  <component_dependency value="foo"/>
617                  <component_dependency value="bar"/>
618                  <component_dependency value="baz"/>
619                </any_of>
620              </dependencies>
621            </component>
622          </components>
623        </manifest>
624        '''
625        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
626        satisfied = components.check_dependencies(root,
627                                                  'test', ['test'],
628                                                  exclude=['foo'])
629
630        self.assertEqual(satisfied, True)
631
632    def test_any_of_all_satisfied(self):
633        test_manifest_xml = '''
634        <manifest>
635          <components>
636            <component id="test">
637              <dependencies>
638                <any_of>
639                  <all>
640                    <component_dependency value="foo"/>
641                    <component_dependency value="bar"/>
642                    <component_dependency value="baz"/>
643                  </all>
644                </any_of>
645              </dependencies>
646            </component>
647          </components>
648        </manifest>
649        '''
650        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
651        satisfied = components.check_dependencies(
652            root, 'test', ['test', 'foo', 'bar', 'baz'], exclude=None)
653
654        self.assertEqual(satisfied, True)
655
656    def test_any_of_all_not_satisfied(self):
657        test_manifest_xml = '''
658        <manifest>
659          <components>
660            <component id="test">
661              <dependencies>
662                <any_of>
663                  <all>
664                    <component_dependency value="foo"/>
665                    <component_dependency value="bar"/>
666                    <component_dependency value="baz"/>
667                  </all>
668                </any_of>
669              </dependencies>
670            </component>
671          </components>
672        </manifest>
673        '''
674        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
675        satisfied = components.check_dependencies(root,
676                                                  'test',
677                                                  ['test', 'foo', 'bar'],
678                                                  exclude=None)
679
680        self.assertEqual(satisfied, False)
681
682    def test_any_of_all_satisfied_by_exclude(self):
683        test_manifest_xml = '''
684        <manifest>
685          <components>
686            <component id="test">
687              <dependencies>
688                <any_of>
689                  <all>
690                    <component_dependency value="foo"/>
691                    <component_dependency value="bar"/>
692                    <component_dependency value="baz"/>
693                  </all>
694                </any_of>
695              </dependencies>
696            </component>
697          </components>
698        </manifest>
699        '''
700        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
701        satisfied = components.check_dependencies(root,
702                                                  'test',
703                                                  ['test', 'foo', 'bar'],
704                                                  exclude=['baz'])
705
706        self.assertEqual(satisfied, True)
707
708    def test_any_of_all_or_one_satisfied(self):
709        test_manifest_xml = '''
710        <manifest>
711          <components>
712            <component id="test">
713              <dependencies>
714                <any_of>
715                  <all>
716                    <component_dependency value="foo"/>
717                    <component_dependency value="bar"/>
718                    <component_dependency value="baz"/>
719                  </all>
720                  <component_dependency value="frodo"/>
721                </any_of>
722              </dependencies>
723            </component>
724          </components>
725        </manifest>
726        '''
727        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
728        satisfied = components.check_dependencies(root,
729                                                  'test', ['test', 'frodo'],
730                                                  exclude=None)
731
732        self.assertEqual(satisfied, True)
733
734    def test_any_of_all_or_one_not_satisfied(self):
735        test_manifest_xml = '''
736        <manifest>
737          <components>
738            <component id="test">
739              <dependencies>
740                <any_of>
741                  <all>
742                    <component_dependency value="foo"/>
743                    <component_dependency value="bar"/>
744                    <component_dependency value="baz"/>
745                  </all>
746                  <component_dependency value="frodo"/>
747                </any_of>
748              </dependencies>
749            </component>
750          </components>
751        </manifest>
752        '''
753        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
754        satisfied = components.check_dependencies(root,
755                                                  'test', ['test'],
756                                                  exclude=None)
757
758        self.assertEqual(satisfied, False)
759
760    def test_any_of_all_or_one_satisfied_by_exclude(self):
761        test_manifest_xml = '''
762        <manifest>
763          <components>
764            <component id="test">
765              <dependencies>
766                <any_of>
767                  <all>
768                    <component_dependency value="foo"/>
769                    <component_dependency value="bar"/>
770                    <component_dependency value="baz"/>
771                  </all>
772                  <component_dependency value="frodo"/>
773                </any_of>
774              </dependencies>
775            </component>
776          </components>
777        </manifest>
778        '''
779        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
780        satisfied = components.check_dependencies(root,
781                                                  'test', ['test'],
782                                                  exclude=['frodo'])
783
784        self.assertEqual(satisfied, True)
785
786
787class CreateProjectTest(unittest.TestCase):
788    """create_project tests."""
789    def test_create_project(self):
790        """test creating a project."""
791        test_manifest_xml = '''
792        <manifest>
793          <components>
794            <component id="test">
795              <dependencies>
796                <component_dependency value="foo"/>
797                <component_dependency value="bar"/>
798                <any_of>
799                  <component_dependency value="baz"/>
800                </any_of>
801              </dependencies>
802            </component>
803            <component id="foo" package_base_path="foo">
804              <defines>
805                <define name="FOO"/>
806              </defines>
807              <source relative_path="include" type="c_include">
808                <files mask="foo.h"/>
809              </source>
810              <source relative_path="src" type="src">
811                <files mask="foo.cc"/>
812              </source>
813              <include_paths>
814                <include_path relative_path="include" type="c_include"/>
815              </include_paths>
816            </component>
817            <component id="bar" package_base_path="bar">
818              <defines>
819                <define name="BAR"/>
820              </defines>
821              <source relative_path="include" type="c_include">
822                <files mask="bar.h"/>
823              </source>
824              <source relative_path="src" type="src">
825                <files mask="bar.cc"/>
826              </source>
827              <include_paths>
828                <include_path relative_path="include" type="c_include"/>
829              </include_paths>
830            </component>
831            <!-- baz should not be included in the output -->
832            <component id="baz" package_base_path="baz">
833              <defines>
834                <define name="BAZ"/>
835              </defines>
836              <source relative_path="include" type="c_include">
837                <files mask="baz.h"/>
838              </source>
839              <source relative_path="src" type="src">
840                <files mask="baz.cc"/>
841              </source>
842              <include_paths>
843                <include_path relative_path="include" type="c_include"/>
844              </include_paths>
845            </component>
846            <component id="frodo" package_base_path="frodo">
847              <dependencies>
848                <component_dependency value="bilbo"/>
849              </dependencies>
850              <defines>
851                <define name="FRODO"/>
852              </defines>
853              <source relative_path="include" type="c_include">
854                <files mask="frodo.h"/>
855              </source>
856              <source relative_path="src" type="src">
857                <files mask="frodo.cc"/>
858              </source>
859              <source relative_path="./" type="lib">
860                <files mask="libonering.a"/>
861              </source>
862              <include_paths>
863                <include_path relative_path="include" type="c_include"/>
864              </include_paths>
865            </component>
866            <!-- bilbo should be excluded from the project -->
867            <component id="bilbo" package_base_path="bilbo">
868              <defines>
869                <define name="BILBO"/>
870              </defines>
871              <source relative_path="include" type="c_include">
872                <files mask="bilbo.h"/>
873              </source>
874              <source relative_path="src" type="src">
875                <files mask="bilbo.cc"/>
876              </source>
877              <include_paths>
878                <include_path relative_path="include" type="c_include"/>
879              </include_paths>
880            </component>
881          </components>
882        </manifest>
883        '''
884        root = xml.etree.ElementTree.fromstring(test_manifest_xml)
885        (component_ids, defines, include_dirs, headers, sources, libs) = \
886            components.create_project(root, ['test', 'frodo'],
887                                      exclude=['bilbo'])
888
889        self.assertEqual(component_ids, ['test', 'frodo', 'foo', 'bar'])
890        self.assertEqual(defines, ['FRODO', 'FOO', 'BAR'])
891        self.assertEqual(include_dirs, [
892            pathlib.Path('frodo/include'),
893            pathlib.Path('foo/include'),
894            pathlib.Path('bar/include')
895        ])
896        self.assertEqual(headers, [
897            pathlib.Path('frodo/include/frodo.h'),
898            pathlib.Path('foo/include/foo.h'),
899            pathlib.Path('bar/include/bar.h')
900        ])
901        self.assertEqual(sources, [
902            pathlib.Path('frodo/src/frodo.cc'),
903            pathlib.Path('foo/src/foo.cc'),
904            pathlib.Path('bar/src/bar.cc')
905        ])
906        self.assertEqual(libs, [pathlib.Path('frodo/libonering.a')])
907
908
909if __name__ == '__main__':
910    unittest.main()
911