python/mozbuild/mozpack/test/test_mozjar.py

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 # This Source Code Form is subject to the terms of the Mozilla Public
     2 # License, v. 2.0. If a copy of the MPL was not distributed with this
     3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     5 from mozpack.mozjar import (
     6     JarReaderError,
     7     JarWriterError,
     8     JarStruct,
     9     JarReader,
    10     JarWriter,
    11     Deflater,
    12     JarLog,
    13 )
    14 from collections import OrderedDict
    15 from mozpack.test.test_files import MockDest
    16 import unittest
    17 import mozunit
    18 from cStringIO import StringIO
    19 from urllib import pathname2url
    20 import mozpack.path
    21 import os
    24 class TestJarStruct(unittest.TestCase):
    25     class Foo(JarStruct):
    26         MAGIC = 0x01020304
    27         STRUCT = OrderedDict([
    28             ('foo', 'uint32'),
    29             ('bar', 'uint16'),
    30             ('qux', 'uint16'),
    31             ('length', 'uint16'),
    32             ('length2', 'uint16'),
    33             ('string', 'length'),
    34             ('string2', 'length2'),
    35         ])
    37     def test_jar_struct(self):
    38         foo = TestJarStruct.Foo()
    39         self.assertEqual(foo.signature, TestJarStruct.Foo.MAGIC)
    40         self.assertEqual(foo['foo'], 0)
    41         self.assertEqual(foo['bar'], 0)
    42         self.assertEqual(foo['qux'], 0)
    43         self.assertFalse('length' in foo)
    44         self.assertFalse('length2' in foo)
    45         self.assertEqual(foo['string'], '')
    46         self.assertEqual(foo['string2'], '')
    48         self.assertEqual(foo.size, 16)
    50         foo['foo'] = 0x42434445
    51         foo['bar'] = 0xabcd
    52         foo['qux'] = 0xef01
    53         foo['string'] = 'abcde'
    54         foo['string2'] = 'Arbitrarily long string'
    56         serialized = b'\x04\x03\x02\x01\x45\x44\x43\x42\xcd\xab\x01\xef' + \
    57                      b'\x05\x00\x17\x00abcdeArbitrarily long string'
    58         self.assertEqual(foo.size, len(serialized))
    59         foo_serialized = foo.serialize()
    60         self.assertEqual(foo_serialized, serialized)
    62     def do_test_read_jar_struct(self, data):
    63         self.assertRaises(JarReaderError, TestJarStruct.Foo, data)
    64         self.assertRaises(JarReaderError, TestJarStruct.Foo, data[2:])
    66         foo = TestJarStruct.Foo(data[1:])
    67         self.assertEqual(foo['foo'], 0x45444342)
    68         self.assertEqual(foo['bar'], 0xcdab)
    69         self.assertEqual(foo['qux'], 0x01ef)
    70         self.assertFalse('length' in foo)
    71         self.assertFalse('length2' in foo)
    72         self.assertEqual(foo['string'], '012345')
    73         self.assertEqual(foo['string2'], '67')
    75     def test_read_jar_struct(self):
    76         data = b'\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
    77                b'\x01\x06\x00\x02\x0001234567890'
    78         self.do_test_read_jar_struct(data)
    80     def test_read_jar_struct_memoryview(self):
    81         data = b'\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
    82                b'\x01\x06\x00\x02\x0001234567890'
    83         self.do_test_read_jar_struct(memoryview(data))
    86 class TestDeflater(unittest.TestCase):
    87     def wrap(self, data):
    88         return data
    90     def test_deflater_no_compress(self):
    91         deflater = Deflater(False)
    92         deflater.write(self.wrap('abc'))
    93         self.assertFalse(deflater.compressed)
    94         self.assertEqual(deflater.uncompressed_size, 3)
    95         self.assertEqual(deflater.compressed_size, deflater.uncompressed_size)
    96         self.assertEqual(deflater.compressed_data, 'abc')
    97         self.assertEqual(deflater.crc32, 0x352441c2)
    99     def test_deflater_compress_no_gain(self):
   100         deflater = Deflater(True)
   101         deflater.write(self.wrap('abc'))
   102         self.assertFalse(deflater.compressed)
   103         self.assertEqual(deflater.uncompressed_size, 3)
   104         self.assertEqual(deflater.compressed_size, deflater.uncompressed_size)
   105         self.assertEqual(deflater.compressed_data, 'abc')
   106         self.assertEqual(deflater.crc32, 0x352441c2)
   108     def test_deflater_compress(self):
   109         deflater = Deflater(True)
   110         deflater.write(self.wrap('aaaaaaaaaaaaanopqrstuvwxyz'))
   111         self.assertTrue(deflater.compressed)
   112         self.assertEqual(deflater.uncompressed_size, 26)
   113         self.assertNotEqual(deflater.compressed_size,
   114                             deflater.uncompressed_size)
   115         self.assertEqual(deflater.crc32, 0xd46b97ed)
   116         # The CRC is the same as when not compressed
   117         deflater = Deflater(False)
   118         self.assertFalse(deflater.compressed)
   119         deflater.write(self.wrap('aaaaaaaaaaaaanopqrstuvwxyz'))
   120         self.assertEqual(deflater.crc32, 0xd46b97ed)
   123 class TestDeflaterMemoryView(TestDeflater):
   124     def wrap(self, data):
   125         return memoryview(data)
   128 class TestJar(unittest.TestCase):
   129     optimize = False
   131     def test_jar(self):
   132         s = MockDest()
   133         with JarWriter(fileobj=s, optimize=self.optimize) as jar:
   134             jar.add('foo', 'foo')
   135             self.assertRaises(JarWriterError, jar.add, 'foo', 'bar')
   136             jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
   137             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', False)
   139         files = [j for j in JarReader(fileobj=s)]
   141         self.assertEqual(files[0].filename, 'foo')
   142         self.assertFalse(files[0].compressed)
   143         self.assertEqual(files[0].read(), 'foo')
   145         self.assertEqual(files[1].filename, 'bar')
   146         self.assertTrue(files[1].compressed)
   147         self.assertEqual(files[1].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
   149         self.assertEqual(files[2].filename, 'baz/qux')
   150         self.assertFalse(files[2].compressed)
   151         self.assertEqual(files[2].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
   153         s = MockDest()
   154         with JarWriter(fileobj=s, compress=False,
   155                        optimize=self.optimize) as jar:
   156             jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
   157             jar.add('foo', 'foo')
   158             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', True)
   160         jar = JarReader(fileobj=s)
   161         files = [j for j in jar]
   163         self.assertEqual(files[0].filename, 'bar')
   164         self.assertFalse(files[0].compressed)
   165         self.assertEqual(files[0].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
   167         self.assertEqual(files[1].filename, 'foo')
   168         self.assertFalse(files[1].compressed)
   169         self.assertEqual(files[1].read(), 'foo')
   171         self.assertEqual(files[2].filename, 'baz/qux')
   172         self.assertTrue(files[2].compressed)
   173         self.assertEqual(files[2].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
   175         self.assertTrue('bar' in jar)
   176         self.assertTrue('foo' in jar)
   177         self.assertFalse('baz' in jar)
   178         self.assertTrue('baz/qux' in jar)
   179         self.assertTrue(jar['bar'], files[1])
   180         self.assertTrue(jar['foo'], files[0])
   181         self.assertTrue(jar['baz/qux'], files[2])
   183         s.seek(0)
   184         jar = JarReader(fileobj=s)
   185         self.assertTrue('bar' in jar)
   186         self.assertTrue('foo' in jar)
   187         self.assertFalse('baz' in jar)
   188         self.assertTrue('baz/qux' in jar)
   190         files[0].seek(0)
   191         self.assertEqual(jar['bar'].filename, files[0].filename)
   192         self.assertEqual(jar['bar'].compressed, files[0].compressed)
   193         self.assertEqual(jar['bar'].read(), files[0].read())
   195         files[1].seek(0)
   196         self.assertEqual(jar['foo'].filename, files[1].filename)
   197         self.assertEqual(jar['foo'].compressed, files[1].compressed)
   198         self.assertEqual(jar['foo'].read(), files[1].read())
   200         files[2].seek(0)
   201         self.assertEqual(jar['baz/qux'].filename, files[2].filename)
   202         self.assertEqual(jar['baz/qux'].compressed, files[2].compressed)
   203         self.assertEqual(jar['baz/qux'].read(), files[2].read())
   205     def test_rejar(self):
   206         s = MockDest()
   207         with JarWriter(fileobj=s, optimize=self.optimize) as jar:
   208             jar.add('foo', 'foo')
   209             jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
   210             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', False)
   212         new = MockDest()
   213         with JarWriter(fileobj=new, optimize=self.optimize) as jar:
   214             for j in JarReader(fileobj=s):
   215                 jar.add(j.filename, j)
   217         jar = JarReader(fileobj=new)
   218         files = [j for j in jar]
   220         self.assertEqual(files[0].filename, 'foo')
   221         self.assertFalse(files[0].compressed)
   222         self.assertEqual(files[0].read(), 'foo')
   224         self.assertEqual(files[1].filename, 'bar')
   225         self.assertTrue(files[1].compressed)
   226         self.assertEqual(files[1].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
   228         self.assertEqual(files[2].filename, 'baz/qux')
   229         self.assertTrue(files[2].compressed)
   230         self.assertEqual(files[2].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
   233 class TestOptimizeJar(TestJar):
   234     optimize = True
   237 class TestPreload(unittest.TestCase):
   238     def test_preload(self):
   239         s = MockDest()
   240         with JarWriter(fileobj=s) as jar:
   241             jar.add('foo', 'foo')
   242             jar.add('bar', 'abcdefghijklmnopqrstuvwxyz')
   243             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz')
   245         jar = JarReader(fileobj=s)
   246         self.assertEqual(jar.last_preloaded, None)
   248         with JarWriter(fileobj=s) as jar:
   249             jar.add('foo', 'foo')
   250             jar.add('bar', 'abcdefghijklmnopqrstuvwxyz')
   251             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz')
   252             jar.preload(['baz/qux', 'bar'])
   254         jar = JarReader(fileobj=s)
   255         self.assertEqual(jar.last_preloaded, 'bar')
   256         files = [j for j in jar]
   258         self.assertEqual(files[0].filename, 'baz/qux')
   259         self.assertEqual(files[1].filename, 'bar')
   260         self.assertEqual(files[2].filename, 'foo')
   263 class TestJarLog(unittest.TestCase):
   264     def test_jarlog(self):
   265         base = 'file:' + pathname2url(os.path.abspath(os.curdir))
   266         s = StringIO('\n'.join([
   267             base + '/bar/baz.jar first',
   268             base + '/bar/baz.jar second',
   269             base + '/bar/baz.jar third',
   270             base + '/bar/baz.jar second',
   271             base + '/bar/baz.jar second',
   272             'jar:' + base + '/qux.zip!/omni.ja stuff',
   273             base + '/bar/baz.jar first',
   274             'jar:' + base + '/qux.zip!/omni.ja other/stuff',
   275             'jar:' + base + '/qux.zip!/omni.ja stuff',
   276             base + '/bar/baz.jar third',
   277             'jar:jar:' + base + '/qux.zip!/baz/baz.jar!/omni.ja nested/stuff',
   278             'jar:jar:jar:' + base + '/qux.zip!/baz/baz.jar!/foo.zip!/omni.ja' +
   279             ' deeply/nested/stuff',
   280         ]))
   281         log = JarLog(fileobj=s)
   282         canonicalize = lambda p: \
   283             mozpack.path.normsep(os.path.normcase(os.path.realpath(p)))
   284         baz_jar = canonicalize('bar/baz.jar')
   285         qux_zip = canonicalize('qux.zip')
   286         self.assertEqual(set(log.keys()), set([
   287             baz_jar,
   288             (qux_zip, 'omni.ja'),
   289             (qux_zip, 'baz/baz.jar', 'omni.ja'),
   290             (qux_zip, 'baz/baz.jar', 'foo.zip', 'omni.ja'),
   291         ]))
   292         self.assertEqual(log[baz_jar], [
   293             'first',
   294             'second',
   295             'third',
   296         ])
   297         self.assertEqual(log[(qux_zip, 'omni.ja')], [
   298             'stuff',
   299             'other/stuff',
   300         ])
   301         self.assertEqual(log[(qux_zip, 'baz/baz.jar', 'omni.ja')],
   302                          ['nested/stuff'])
   303         self.assertEqual(log[(qux_zip, 'baz/baz.jar', 'foo.zip',
   304                               'omni.ja')], ['deeply/nested/stuff'])
   306         # The above tests also indirectly check the value returned by
   307         # JarLog.canonicalize for various jar: and file: urls, but
   308         # JarLog.canonicalize also supports plain paths.
   309         self.assertEqual(JarLog.canonicalize(os.path.abspath('bar/baz.jar')),
   310                          baz_jar)
   311         self.assertEqual(JarLog.canonicalize('bar/baz.jar'), baz_jar)
   314 if __name__ == '__main__':
   315     mozunit.main()

mercurial