Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- Manifest: python/mozbuild/mozpack/test/python.toml
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
import os
import unittest
from collections import OrderedDict
import mozunit
import six
import mozpack.path as mozpath
from mozpack.files import FileFinder
from mozpack.mozjar import (
Deflater,
JarLog,
JarReader,
JarReaderError,
JarStruct,
JarWriter,
JarWriterError,
)
from mozpack.test.test_files import MockDest
test_data_path = mozpath.abspath(mozpath.dirname(__file__))
test_data_path = mozpath.join(test_data_path, "data")
class TestJarStruct(unittest.TestCase):
class Foo(JarStruct):
MAGIC = 0x01020304
STRUCT = OrderedDict(
[
("foo", "uint32"),
("bar", "uint16"),
("qux", "uint16"),
("length", "uint16"),
("length2", "uint16"),
("string", "length"),
("string2", "length2"),
]
)
def test_jar_struct(self):
foo = TestJarStruct.Foo()
self.assertEqual(foo.signature, TestJarStruct.Foo.MAGIC)
self.assertEqual(foo["foo"], 0)
self.assertEqual(foo["bar"], 0)
self.assertEqual(foo["qux"], 0)
self.assertFalse("length" in foo)
self.assertFalse("length2" in foo)
self.assertEqual(foo["string"], "")
self.assertEqual(foo["string2"], "")
self.assertEqual(foo.size, 16)
foo["foo"] = 0x42434445
foo["bar"] = 0xABCD
foo["qux"] = 0xEF01
foo["string"] = "abcde"
foo["string2"] = "Arbitrarily long string"
serialized = (
b"\x04\x03\x02\x01\x45\x44\x43\x42\xcd\xab\x01\xef"
+ b"\x05\x00\x17\x00abcdeArbitrarily long string"
)
self.assertEqual(foo.size, len(serialized))
foo_serialized = foo.serialize()
self.assertEqual(foo_serialized, serialized)
def do_test_read_jar_struct(self, data):
self.assertRaises(JarReaderError, TestJarStruct.Foo, data)
self.assertRaises(JarReaderError, TestJarStruct.Foo, data[2:])
foo = TestJarStruct.Foo(data[1:])
self.assertEqual(foo["foo"], 0x45444342)
self.assertEqual(foo["bar"], 0xCDAB)
self.assertEqual(foo["qux"], 0x01EF)
self.assertFalse("length" in foo)
self.assertFalse("length2" in foo)
self.assertEqual(foo["string"], b"012345")
self.assertEqual(foo["string2"], b"67")
def test_read_jar_struct(self):
data = (
b"\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef"
+ b"\x01\x06\x00\x02\x0001234567890"
)
self.do_test_read_jar_struct(data)
def test_read_jar_struct_memoryview(self):
data = (
b"\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef"
+ b"\x01\x06\x00\x02\x0001234567890"
)
self.do_test_read_jar_struct(memoryview(data))
class TestDeflater(unittest.TestCase):
def wrap(self, data):
return data
def test_deflater_no_compress(self):
deflater = Deflater(False)
deflater.write(self.wrap(b"abc"))
self.assertFalse(deflater.compressed)
self.assertEqual(deflater.uncompressed_size, 3)
self.assertEqual(deflater.compressed_size, deflater.uncompressed_size)
self.assertEqual(deflater.compressed_data, b"abc")
self.assertEqual(deflater.crc32, 0x352441C2)
def test_deflater_compress_no_gain(self):
deflater = Deflater(True)
deflater.write(self.wrap(b"abc"))
self.assertFalse(deflater.compressed)
self.assertEqual(deflater.uncompressed_size, 3)
self.assertEqual(deflater.compressed_size, deflater.uncompressed_size)
self.assertEqual(deflater.compressed_data, b"abc")
self.assertEqual(deflater.crc32, 0x352441C2)
def test_deflater_compress(self):
deflater = Deflater(True)
deflater.write(self.wrap(b"aaaaaaaaaaaaanopqrstuvwxyz"))
self.assertTrue(deflater.compressed)
self.assertEqual(deflater.uncompressed_size, 26)
self.assertNotEqual(deflater.compressed_size, deflater.uncompressed_size)
self.assertEqual(deflater.crc32, 0xD46B97ED)
# The CRC is the same as when not compressed
deflater = Deflater(False)
self.assertFalse(deflater.compressed)
deflater.write(self.wrap(b"aaaaaaaaaaaaanopqrstuvwxyz"))
self.assertEqual(deflater.crc32, 0xD46B97ED)
def test_deflater_empty(self):
deflater = Deflater(False)
self.assertFalse(deflater.compressed)
self.assertEqual(deflater.uncompressed_size, 0)
self.assertEqual(deflater.compressed_size, deflater.uncompressed_size)
self.assertEqual(deflater.compressed_data, b"")
self.assertEqual(deflater.crc32, 0)
class TestDeflaterMemoryView(TestDeflater):
def wrap(self, data):
return memoryview(data)
class TestJar(unittest.TestCase):
def test_jar(self):
s = MockDest()
with JarWriter(fileobj=s) as jar:
jar.add("foo", b"foo")
self.assertRaises(JarWriterError, jar.add, "foo", b"bar")
jar.add("bar", b"aaaaaaaaaaaaanopqrstuvwxyz")
jar.add("baz/qux", b"aaaaaaaaaaaaanopqrstuvwxyz", False)
jar.add("baz\\backslash", b"aaaaaaaaaaaaaaa")
files = [j for j in JarReader(fileobj=s)]
self.assertEqual(files[0].filename, "foo")
self.assertFalse(files[0].compressed)
self.assertEqual(files[0].read(), b"foo")
self.assertEqual(files[1].filename, "bar")
self.assertTrue(files[1].compressed)
self.assertEqual(files[1].read(), b"aaaaaaaaaaaaanopqrstuvwxyz")
self.assertEqual(files[2].filename, "baz/qux")
self.assertFalse(files[2].compressed)
self.assertEqual(files[2].read(), b"aaaaaaaaaaaaanopqrstuvwxyz")
if os.sep == "\\":
self.assertEqual(
files[3].filename,
"baz/backslash",
"backslashes in filenames on Windows should get normalized",
)
else:
self.assertEqual(
files[3].filename,
"baz\\backslash",
"backslashes in filenames on POSIX platform are untouched",
)
s = MockDest()
with JarWriter(fileobj=s, compress=False) as jar:
jar.add("bar", b"aaaaaaaaaaaaanopqrstuvwxyz")
jar.add("foo", b"foo")
jar.add("baz/qux", b"aaaaaaaaaaaaanopqrstuvwxyz", True)
jar = JarReader(fileobj=s)
files = [j for j in jar]
self.assertEqual(files[0].filename, "bar")
self.assertFalse(files[0].compressed)
self.assertEqual(files[0].read(), b"aaaaaaaaaaaaanopqrstuvwxyz")
self.assertEqual(files[1].filename, "foo")
self.assertFalse(files[1].compressed)
self.assertEqual(files[1].read(), b"foo")
self.assertEqual(files[2].filename, "baz/qux")
self.assertTrue(files[2].compressed)
self.assertEqual(files[2].read(), b"aaaaaaaaaaaaanopqrstuvwxyz")
self.assertTrue("bar" in jar)
self.assertTrue("foo" in jar)
self.assertFalse("baz" in jar)
self.assertTrue("baz/qux" in jar)
self.assertTrue(jar["bar"], files[1])
self.assertTrue(jar["foo"], files[0])
self.assertTrue(jar["baz/qux"], files[2])
s.seek(0)
jar = JarReader(fileobj=s)
self.assertTrue("bar" in jar)
self.assertTrue("foo" in jar)
self.assertFalse("baz" in jar)
self.assertTrue("baz/qux" in jar)
files[0].seek(0)
self.assertEqual(jar["bar"].filename, files[0].filename)
self.assertEqual(jar["bar"].compressed, files[0].compressed)
self.assertEqual(jar["bar"].read(), files[0].read())
files[1].seek(0)
self.assertEqual(jar["foo"].filename, files[1].filename)
self.assertEqual(jar["foo"].compressed, files[1].compressed)
self.assertEqual(jar["foo"].read(), files[1].read())
files[2].seek(0)
self.assertEqual(jar["baz/qux"].filename, files[2].filename)
self.assertEqual(jar["baz/qux"].compressed, files[2].compressed)
self.assertEqual(jar["baz/qux"].read(), files[2].read())
def test_rejar(self):
s = MockDest()
with JarWriter(fileobj=s) as jar:
jar.add("foo", b"foo")
jar.add("bar", b"aaaaaaaaaaaaanopqrstuvwxyz")
jar.add("baz/qux", b"aaaaaaaaaaaaanopqrstuvwxyz", False)
new = MockDest()
with JarWriter(fileobj=new) as jar:
for j in JarReader(fileobj=s):
jar.add(j.filename, j)
jar = JarReader(fileobj=new)
files = [j for j in jar]
self.assertEqual(files[0].filename, "foo")
self.assertFalse(files[0].compressed)
self.assertEqual(files[0].read(), b"foo")
self.assertEqual(files[1].filename, "bar")
self.assertTrue(files[1].compressed)
self.assertEqual(files[1].read(), b"aaaaaaaaaaaaanopqrstuvwxyz")
self.assertEqual(files[2].filename, "baz/qux")
self.assertTrue(files[2].compressed)
self.assertEqual(files[2].read(), b"aaaaaaaaaaaaanopqrstuvwxyz")
def test_add_from_finder(self):
s = MockDest()
with JarWriter(fileobj=s) as jar:
finder = FileFinder(test_data_path)
for p, f in finder.find("test_data"):
jar.add("test_data", f)
jar = JarReader(fileobj=s)
files = [j for j in jar]
self.assertEqual(files[0].filename, "test_data")
self.assertFalse(files[0].compressed)
self.assertEqual(files[0].read(), b"test_data")
class TestPreload(unittest.TestCase):
def test_preload(self):
s = MockDest()
with JarWriter(fileobj=s) as jar:
jar.add("foo", b"foo")
jar.add("bar", b"abcdefghijklmnopqrstuvwxyz")
jar.add("baz/qux", b"aaaaaaaaaaaaanopqrstuvwxyz")
jar = JarReader(fileobj=s)
self.assertEqual(jar.last_preloaded, None)
with JarWriter(fileobj=s) as jar:
jar.add("foo", b"foo")
jar.add("bar", b"abcdefghijklmnopqrstuvwxyz")
jar.add("baz/qux", b"aaaaaaaaaaaaanopqrstuvwxyz")
jar.preload(["baz/qux", "bar"])
jar = JarReader(fileobj=s)
self.assertEqual(jar.last_preloaded, "bar")
files = [j for j in jar]
self.assertEqual(files[0].filename, "baz/qux")
self.assertEqual(files[1].filename, "bar")
self.assertEqual(files[2].filename, "foo")
class TestJarLog(unittest.TestCase):
def test_jarlog(self):
s = six.moves.cStringIO(
"\n".join(
[
"bar/baz.jar first",
"bar/baz.jar second",
"bar/baz.jar third",
"bar/baz.jar second",
"bar/baz.jar second",
"omni.ja stuff",
"bar/baz.jar first",
"omni.ja other/stuff",
"omni.ja stuff",
"bar/baz.jar third",
]
)
)
log = JarLog(fileobj=s)
self.assertEqual(
set(log.keys()),
set(
[
"bar/baz.jar",
"omni.ja",
]
),
)
self.assertEqual(
log["bar/baz.jar"],
[
"first",
"second",
"third",
],
)
self.assertEqual(
log["omni.ja"],
[
"stuff",
"other/stuff",
],
)
if __name__ == "__main__":
mozunit.main()