• 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"""Unit tests for generate_cc_blob_library.py"""
15
16from pathlib import Path
17import tempfile
18import textwrap
19import unittest
20
21from pw_build import generate_cc_blob_library
22
23
24class TestSplitIntoChunks(unittest.TestCase):
25    """Unit tests for the split_into_chunks() function."""
26    def test_perfect_split(self):
27        """Tests basic splitting where the iterable divides perfectly."""
28        data = (1, 7, 0, 1)
29        self.assertEqual(
30            ((1, 7), (0, 1)),
31            tuple(generate_cc_blob_library.split_into_chunks(data, 2)))
32
33    def test_split_with_remainder(self):
34        """Tests basic splitting where there is a remainder."""
35        data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
36        self.assertEqual(
37            ((1, 2, 3), (4, 5, 6), (7, 8, 9), (10, )),
38            tuple(generate_cc_blob_library.split_into_chunks(data, 3)))
39
40
41class TestHeaderFromBlobs(unittest.TestCase):
42    """Unit tests for the header_from_blobs() function."""
43    def test_single_blob_header(self):
44        """Tests the generation of a header for a single blob."""
45        foo_blob = Path(tempfile.NamedTemporaryFile().name)
46        foo_blob.write_bytes(bytes((1, 2, 3, 4, 5, 6)))
47        blobs = [generate_cc_blob_library.Blob('fooBlob', foo_blob, None)]
48
49        header = generate_cc_blob_library.header_from_blobs(blobs)
50        expected_header = textwrap.dedent("""\
51            // This file is auto-generated; Do not hand-modify!
52            // See https://pigweed.dev/pw_build/#pw-cc-blob-library for details.
53
54            #pragma once
55
56            #include <array>
57            #include <cstddef>
58
59            extern const std::array<std::byte, 6> fooBlob;
60            """)
61
62        self.assertEqual(expected_header, header)
63
64    def test_multi_blob_header(self):
65        """Tests the generation of a header for multiple blobs."""
66        foo_blob = Path(tempfile.NamedTemporaryFile().name)
67        foo_blob.write_bytes(bytes((1, 2, 3, 4, 5, 6)))
68        bar_blob = Path(tempfile.NamedTemporaryFile().name)
69        bar_blob.write_bytes(bytes((10, 9, 8, 7, 6)))
70        blobs = [
71            generate_cc_blob_library.Blob('fooBlob', foo_blob, None),
72            generate_cc_blob_library.Blob('barBlob', bar_blob, None),
73        ]
74
75        header = generate_cc_blob_library.header_from_blobs(blobs)
76        expected_header = textwrap.dedent("""\
77            // This file is auto-generated; Do not hand-modify!
78            // See https://pigweed.dev/pw_build/#pw-cc-blob-library for details.
79
80            #pragma once
81
82            #include <array>
83            #include <cstddef>
84
85            extern const std::array<std::byte, 6> fooBlob;
86
87            extern const std::array<std::byte, 5> barBlob;
88            """)
89
90        self.assertEqual(expected_header, header)
91
92    def test_header_with_namespace(self):
93        """Tests the header generation of namespace definitions."""
94        foo_blob = Path(tempfile.NamedTemporaryFile().name)
95        foo_blob.write_bytes(bytes((1, 2, 3, 4, 5, 6)))
96        blobs = [generate_cc_blob_library.Blob('fooBlob', foo_blob, None)]
97
98        header = generate_cc_blob_library.header_from_blobs(blobs, 'pw::foo')
99        expected_header = textwrap.dedent("""\
100            // This file is auto-generated; Do not hand-modify!
101            // See https://pigweed.dev/pw_build/#pw-cc-blob-library for details.
102
103            #pragma once
104
105            #include <array>
106            #include <cstddef>
107
108            namespace pw::foo {
109
110            extern const std::array<std::byte, 6> fooBlob;
111
112            }  // namespace pw::foo
113            """)
114
115        self.assertEqual(expected_header, header)
116
117
118class TestArrayDefFromBlobData(unittest.TestCase):
119    """Unit tests for the array_def_from_blob_data() function."""
120    def test_single_line(self):
121        """Tests the generation of single-line array definitions."""
122        foo_data = bytes((1, 2))
123
124        foo_definition = generate_cc_blob_library.array_def_from_blob_data(
125            'fooBlob', foo_data)
126        expected_definition = ('const std::array<std::byte, 2> fooBlob'
127                               ' = { std::byte{0x01}, std::byte{0x02} };')
128
129        self.assertEqual(expected_definition, foo_definition)
130
131    def test_multi_line(self):
132        """Tests the generation of multi-line array definitions."""
133        foo_data = bytes((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
134
135        foo_definition = generate_cc_blob_library.array_def_from_blob_data(
136            'fooBlob', foo_data)
137        expected_definition = ('const std::array<std::byte, 10> fooBlob = {\n'
138                               '  std::byte{0x01}, std::byte{0x02}, '
139                               'std::byte{0x03}, std::byte{0x04},\n'
140                               '  std::byte{0x05}, std::byte{0x06}, '
141                               'std::byte{0x07}, std::byte{0x08},\n'
142                               '  std::byte{0x09}, std::byte{0x0A}\n'
143                               '};')
144
145        self.assertEqual(expected_definition, foo_definition)
146
147
148class TestSourceFromBlobs(unittest.TestCase):
149    """Unit tests for the source_from_blobs() function."""
150    def test_source_with_mixed_blobs(self):
151        """Tests generation of a source file with single- and multi-liners."""
152        foo_blob = Path(tempfile.NamedTemporaryFile().name)
153        foo_blob.write_bytes(bytes((1, 2)))
154        bar_blob = Path(tempfile.NamedTemporaryFile().name)
155        bar_blob.write_bytes(bytes((1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
156        blobs = [
157            generate_cc_blob_library.Blob('fooBlob', foo_blob, None),
158            generate_cc_blob_library.Blob('barBlob', bar_blob, None),
159        ]
160
161        source = generate_cc_blob_library.source_from_blobs(
162            blobs, 'path/to/header.h')
163        expected_source = textwrap.dedent("""\
164            // This file is auto-generated; Do not hand-modify!
165            // See https://pigweed.dev/pw_build/#pw-cc-blob-library for details.
166
167            #include "path/to/header.h"
168
169            #include <array>
170            #include <cstddef>
171
172            #include "pw_preprocessor/compiler.h"
173
174            """)
175        expected_source += ('const std::array<std::byte, 2> fooBlob'
176                            ' = { std::byte{0x01}, std::byte{0x02} };\n\n')
177        expected_source += ('const std::array<std::byte, 10> barBlob = {\n'
178                            '  std::byte{0x01}, std::byte{0x02}, '
179                            'std::byte{0x03}, std::byte{0x04},\n'
180                            '  std::byte{0x05}, std::byte{0x06}, '
181                            'std::byte{0x07}, std::byte{0x08},\n'
182                            '  std::byte{0x09}, std::byte{0x0A}\n'
183                            '};\n')
184
185        self.assertEqual(expected_source, source)
186
187    def test_source_with_namespace(self):
188        """Tests the source generation of namespace definitions."""
189        foo_blob = Path(tempfile.NamedTemporaryFile().name)
190        foo_blob.write_bytes(bytes((1, 2)))
191        blobs = [generate_cc_blob_library.Blob('fooBlob', foo_blob, None)]
192
193        source = generate_cc_blob_library.source_from_blobs(
194            blobs, 'path/to/header.h', 'pw::foo')
195        expected_source = textwrap.dedent("""\
196            // This file is auto-generated; Do not hand-modify!
197            // See https://pigweed.dev/pw_build/#pw-cc-blob-library for details.
198
199            #include "path/to/header.h"
200
201            #include <array>
202            #include <cstddef>
203
204            #include "pw_preprocessor/compiler.h"
205
206            namespace pw::foo {
207
208            const std::array<std::byte, 2> fooBlob = { std::byte{0x01}, std::byte{0x02} };
209
210            }  // namespace pw::foo
211            """)
212
213        self.assertEqual(expected_source, source)
214
215    def test_source_with_linker_sections(self):
216        """Tests generation of a source file with defined linker sections"""
217        foo_blob = Path(tempfile.NamedTemporaryFile().name)
218        foo_blob.write_bytes(bytes((1, 2)))
219        bar_blob = Path(tempfile.NamedTemporaryFile().name)
220        bar_blob.write_bytes(bytes((1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
221        blobs = [
222            generate_cc_blob_library.Blob('fooBlob', foo_blob, ".foo_section"),
223            generate_cc_blob_library.Blob('barBlob', bar_blob, ".bar_section"),
224        ]
225
226        source = generate_cc_blob_library.source_from_blobs(
227            blobs, 'path/to/header.h')
228        expected_source = textwrap.dedent("""\
229            // This file is auto-generated; Do not hand-modify!
230            // See https://pigweed.dev/pw_build/#pw-cc-blob-library for details.
231
232            #include "path/to/header.h"
233
234            #include <array>
235            #include <cstddef>
236
237            #include "pw_preprocessor/compiler.h"
238
239            """)
240        expected_source += ('PW_PLACE_IN_SECTION(".foo_section")\n'
241                            'const std::array<std::byte, 2> fooBlob'
242                            ' = { std::byte{0x01}, std::byte{0x02} };\n\n')
243        expected_source += ('PW_PLACE_IN_SECTION(".bar_section")\n'
244                            'const std::array<std::byte, 10> barBlob = {\n'
245                            '  std::byte{0x01}, std::byte{0x02}, '
246                            'std::byte{0x03}, std::byte{0x04},\n'
247                            '  std::byte{0x05}, std::byte{0x06}, '
248                            'std::byte{0x07}, std::byte{0x08},\n'
249                            '  std::byte{0x09}, std::byte{0x0A}\n'
250                            '};\n')
251
252        self.assertEqual(expected_source, source)
253
254
255if __name__ == '__main__':
256    unittest.main()
257