# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys import tempfile import unittest # Allow us to run even if not at the `tools` directory. root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) sys.path.insert(0, root_dir) from pbpack import ResourcePack import stm32_crc SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) class TestResourcePack(unittest.TestCase): def test_deserialize_serialize_v2(self): filename = os.path.join(SCRIPT_DIR, 'app_resources_v2.pbpack') self._test_deserialize_serialize_file(filename, is_system=False) def test_deserialize_serialize_duplicate_resources(self): is_system = False pack = ResourcePack(is_system) pack.add_resource('asdf') pack.add_resource('xyz') pack.add_resource('asdf') after_pack = self._test_deserialize_serialize_pack(pack, is_system) # Only one because we deduped it self.assertEquals(len(after_pack.contents), 2) # But we have three entries self.assertEquals(len(after_pack.table_entries), 3) def test_deserialize_serialize_all_duplicate_resources(self): is_system = False pack = ResourcePack(is_system) pack.add_resource('asdf') pack.add_resource('asdf') pack.add_resource('asdf') after_pack = self._test_deserialize_serialize_pack(pack, is_system) # Only one because we deduped it self.assertEquals(len(after_pack.contents), 1) # But we have three entries self.assertEquals(len(after_pack.table_entries), 3) def test_deserialize_serialize_last_resource_is_a_dupe(self): is_system = False pack = ResourcePack(is_system) pack.add_resource('1') pack.add_resource('22') pack.add_resource('333') pack.add_resource('22') after_pack = self._test_deserialize_serialize_pack(pack, is_system) # Verify the content of the table self.assertEquals(len(after_pack.contents), 3) self.assertEquals(after_pack.contents[after_pack.table_entries[0].content_index], '1') self.assertEquals(after_pack.contents[after_pack.table_entries[1].content_index], '22') self.assertEquals(after_pack.contents[after_pack.table_entries[2].content_index], '333') self.assertEquals(after_pack.contents[after_pack.table_entries[3].content_index], '22') self.assertEquals(len(after_pack.table_entries), 4) def test_add_empty_resources(self): is_system = False pack = ResourcePack(is_system) pack.add_resource('') pack.add_resource('asdf') pack.add_resource('') after_pack = self._test_deserialize_serialize_pack(pack, is_system) # Make sure we deduped an empty resource self.assertEquals(len(after_pack.contents), 2) self.assertEquals(after_pack.contents[after_pack.table_entries[0].content_index], '') self.assertEquals(after_pack.contents[after_pack.table_entries[1].content_index], 'asdf') self.assertEquals(after_pack.contents[after_pack.table_entries[2].content_index], '') self.assertEquals(len(after_pack.table_entries), 3) def _test_deserialize_serialize_pack(self, pack, is_system): """ Serialize a given pack object to a file and then assert that if we deserialize and serialize it again the contents remain equal. Returns a pack object after the first deserialization round. """ try: with tempfile.NamedTemporaryFile(delete=False) as f: filename = f.name pack.serialize(f) # Don't call this before the file is closed, you'll confuse # _test_deserialize_serialize_file which will try to open it again and will expect # the contents to be available and flushed. return self._test_deserialize_serialize_file(f.name, is_system) finally: os.remove(filename) def _test_deserialize_serialize_file(self, f_in_name, is_system): """ Deserialize a given pack file and assert that if we serialize it again the contents remain equal. Returns a pack object from deserializing the given file. """ # Read in our test file and deserialize it with open(f_in_name, 'rb') as f_in: resource_pack = ResourcePack.deserialize(f_in, is_system) try: # Write out a serialized version with tempfile.NamedTemporaryFile(delete=False) as f_out: f_out_name = f_out.name resource_pack.serialize(f_out) # Read the input and output files into buffers and make sure they're equal def read_all(filename): with open(filename, 'rb') as f: f.seek(0) return f.read() contents_pair = map(read_all, (f_out_name, f_in_name)) self.assertEquals(*contents_pair) finally: os.remove(f_out_name) return resource_pack if __name__ == '__main__': unittest.main()