Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

# 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
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
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()