forked from mirrors/gecko-dev
Backed out changeset e8fcfc7f8108 (bug 1811850) Backed out changeset f8950d716c9e (bug 1811850) Backed out changeset f650123cc188 (bug 1811850) Backed out changeset d96f90c2c58b (bug 1811850) Backed out changeset c3b0f9666183 (bug 1811850)
349 lines
12 KiB
Python
349 lines
12 KiB
Python
# 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 mozpack.path as mozpath
|
|
import mozunit
|
|
import six
|
|
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()
|