Merge branch 'master' of https://github.com/mozilla/build-mar
This commit is contained in:
Коммит
e37ab88585
|
@ -1,4 +1,5 @@
|
|||
language: python
|
||||
sudo: false
|
||||
python:
|
||||
- "3.5"
|
||||
|
||||
|
|
|
@ -154,16 +154,20 @@ class MarFile:
|
|||
|
||||
# TODO: Handle writing the product information block
|
||||
|
||||
def __init__(self, name, mode="r", signature_versions=[]):
|
||||
def __init__(self, name, mode="r", fileobj=None, signature_versions=[]):
|
||||
if mode not in "rw":
|
||||
raise ValueError("Mode must be either 'r' or 'w'")
|
||||
|
||||
self.name = name
|
||||
self.mode = mode
|
||||
if mode == 'w':
|
||||
self.fileobj = open(name, 'wb')
|
||||
if fileobj:
|
||||
self.fileobj = fileobj
|
||||
if hasattr(self.fileobj, "mode"):
|
||||
# take the first letter of "rb"/"wb"
|
||||
self.mode = fileobj.mode[0]
|
||||
else:
|
||||
self.fileobj = open(name, 'rb')
|
||||
if self.mode == 'w':
|
||||
self.fileobj = open(name, 'wb')
|
||||
else:
|
||||
self.fileobj = open(name, 'rb')
|
||||
|
||||
self.members = []
|
||||
self.additional_info = []
|
||||
|
@ -180,10 +184,10 @@ class MarFile:
|
|||
self.signatures = []
|
||||
self.signature_versions = signature_versions
|
||||
|
||||
if mode == "r":
|
||||
if self.mode == "r":
|
||||
# Read the file's index
|
||||
self._read()
|
||||
elif mode == "w":
|
||||
elif self.mode == "w":
|
||||
self._prepare_index()
|
||||
|
||||
def _prepare_index(self):
|
||||
|
@ -396,8 +400,9 @@ class MarFile:
|
|||
self.fileobj.flush()
|
||||
|
||||
if self.signatures:
|
||||
fileobj = open(self.name, 'rb')
|
||||
generate_signature(fileobj, self._update_signatures)
|
||||
curr_pos = self.fileobj.tell()
|
||||
generate_signature(self.fileobj, self._update_signatures)
|
||||
self.fileobj.seek(curr_pos)
|
||||
for sig in self.signatures:
|
||||
# print sig._offset
|
||||
sig.write_signature(self.fileobj)
|
||||
|
|
|
@ -16,33 +16,39 @@ def sha1sum(b):
|
|||
return h.hexdigest()
|
||||
|
||||
|
||||
def test_list():
|
||||
with MarFile(TEST_MAR) as m:
|
||||
assert repr(m.members[0]) == "<update.manifest 664 141 bytes starting at 392>", m.members[0]
|
||||
assert repr(m.members[1]) == "<defaults/pref/channel-prefs.js 664 76 bytes starting at 533>", m.members[1]
|
||||
assert len(m.additional_info) == 1
|
||||
assert m.additional_info[0].name == "PRODUCT INFORMATION"
|
||||
assert m.additional_info[0].info == {'MARChannelName': 'thunderbird-comm-esr', 'ProductVersion': '100.0'}
|
||||
class TestList(TestCase):
|
||||
@staticmethod
|
||||
def check_list(marfile):
|
||||
with marfile as m:
|
||||
assert repr(m.members[0]) == "<update.manifest 664 141 bytes starting at 392>", m.members[0]
|
||||
assert repr(m.members[1]) == "<defaults/pref/channel-prefs.js 664 76 bytes starting at 533>", m.members[1]
|
||||
assert len(m.additional_info) == 1
|
||||
assert m.additional_info[0].name == "PRODUCT INFORMATION"
|
||||
assert m.additional_info[0].info == {'MARChannelName': 'thunderbird-comm-esr', 'ProductVersion': '100.0'}
|
||||
|
||||
with BZ2MarFile(TEST_MAR) as m:
|
||||
assert repr(m.members[0]) == "<update.manifest 664 141 bytes starting at 392>", m.members[0]
|
||||
assert repr(m.members[1]) == "<defaults/pref/channel-prefs.js 664 76 bytes starting at 533>", m.members[1]
|
||||
assert len(m.additional_info) == 1
|
||||
assert m.additional_info[0].name == "PRODUCT INFORMATION"
|
||||
assert m.additional_info[0].info == {'MARChannelName': 'thunderbird-comm-esr', 'ProductVersion': '100.0'}
|
||||
def test_list_name(self):
|
||||
self.check_list(MarFile(TEST_MAR))
|
||||
|
||||
def test_list_name_bz(self):
|
||||
self.check_list(BZ2MarFile(TEST_MAR))
|
||||
|
||||
def test_list_fo(self):
|
||||
self.check_list(MarFile(None, fileobj=open(TEST_MAR, 'rb')))
|
||||
|
||||
def test_list_fo_bz(self):
|
||||
self.check_list(BZ2MarFile(None, fileobj=open(TEST_MAR, 'rb')))
|
||||
|
||||
|
||||
class TestReadingMar(TestCase):
|
||||
def setUp(self):
|
||||
self.tmpdir = tempfile.mkdtemp()
|
||||
self.marfile = MarFile(TEST_MAR)
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
def test_extract(self):
|
||||
m = self.marfile.members[0]
|
||||
self.marfile.extract(m, self.tmpdir)
|
||||
def check_extract(self, marfile):
|
||||
m = marfile.members[0]
|
||||
marfile.extract(m, self.tmpdir)
|
||||
fn = os.path.join(self.tmpdir, m.name)
|
||||
|
||||
# Check that the size matches what's in the manifest
|
||||
|
@ -53,29 +59,40 @@ class TestReadingMar(TestCase):
|
|||
h = sha1sum(data)
|
||||
self.assertEquals("6a7890e740f1e18a425b51fefbde2f6b86f91a12", h)
|
||||
|
||||
def test_extractall(self):
|
||||
self.marfile.extractall(self.tmpdir)
|
||||
def check_extractall(self, marfile):
|
||||
marfile.extractall(self.tmpdir)
|
||||
|
||||
all_files = []
|
||||
for root, dirs, files in os.walk(self.tmpdir):
|
||||
for f in files:
|
||||
all_files.append(os.path.join(root, f))
|
||||
|
||||
for member in self.marfile.members:
|
||||
for member in marfile.members:
|
||||
self.assertTrue(os.path.join(self.tmpdir, member.name) in all_files)
|
||||
|
||||
def test_extract_name(self):
|
||||
self.check_extract(MarFile(TEST_MAR))
|
||||
|
||||
def test_extractall_name(self):
|
||||
self.check_extractall(MarFile(TEST_MAR))
|
||||
|
||||
def test_extract_fileobj(self):
|
||||
self.check_extract(MarFile(None, fileobj=open(TEST_MAR, "rb")))
|
||||
|
||||
def test_extractall_fileobj(self):
|
||||
self.check_extractall(MarFile(None, fileobj=open(TEST_MAR, "rb")))
|
||||
|
||||
|
||||
class TestReadingBZ2Mar(TestCase):
|
||||
def setUp(self):
|
||||
self.tmpdir = tempfile.mkdtemp()
|
||||
self.marfile = BZ2MarFile(TEST_MAR)
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
def test_extract_bz2(self):
|
||||
m = self.marfile.members[0]
|
||||
self.marfile.extract(m, self.tmpdir)
|
||||
def check_extract_bz2(self, marfile):
|
||||
m = marfile.members[0]
|
||||
marfile.extract(m, self.tmpdir)
|
||||
fn = os.path.join(self.tmpdir, m.name)
|
||||
|
||||
# The size in the manifest is of the compressed data, so we need to
|
||||
|
@ -88,6 +105,12 @@ class TestReadingBZ2Mar(TestCase):
|
|||
h = sha1sum(data)
|
||||
self.assertEquals("5177f5938923e94820d8565a1a0f25d19b4821d1", h)
|
||||
|
||||
def test_extract_bz2(self):
|
||||
self.check_extract_bz2(BZ2MarFile(TEST_MAR))
|
||||
|
||||
def test_extract_bz2_fo(self):
|
||||
self.check_extract_bz2(BZ2MarFile(None, fileobj=open(TEST_MAR, "rb")))
|
||||
|
||||
|
||||
class TestWritingMar(TestCase):
|
||||
def setUp(self):
|
||||
|
@ -98,7 +121,7 @@ class TestWritingMar(TestCase):
|
|||
|
||||
def test_add(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
with MarFile(marfile, 'w') as m:
|
||||
with MarFile(marfile, mode='w') as m:
|
||||
m.add(__file__)
|
||||
|
||||
with MarFile(marfile) as m:
|
||||
|
@ -111,9 +134,24 @@ class TestWritingMar(TestCase):
|
|||
open(__file__, 'rb').read()
|
||||
)
|
||||
|
||||
def test_add_fo(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
with MarFile(None, fileobj=open(marfile, "wb")) as m:
|
||||
m.add(__file__)
|
||||
|
||||
with MarFile(None, fileobj=open(marfile, "rb")) as m:
|
||||
self.assertEquals(len(m.members), 1)
|
||||
self.assertEquals(m.members[0].size, os.path.getsize(__file__))
|
||||
self.assertEquals(m.members[0].flags, os.stat(__file__).st_mode & 0o777)
|
||||
extracted = m.extract(m.members[0], self.tmpdir)
|
||||
self.assertEquals(
|
||||
open(extracted, 'rb').read(),
|
||||
open(__file__, 'rb').read()
|
||||
)
|
||||
|
||||
def test_additional_info(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
with MarFile(marfile, 'w') as m:
|
||||
with MarFile(marfile, mode='w') as m:
|
||||
info = AdditionalInfo.from_info({'MARChannelName': 'test1', 'ProductVersion': '123'})
|
||||
m.additional_info.append(info)
|
||||
m.add(__file__)
|
||||
|
@ -123,10 +161,22 @@ class TestWritingMar(TestCase):
|
|||
self.assertEquals(m.additional_info[0].name, 'PRODUCT INFORMATION')
|
||||
self.assertEquals(m.additional_info[0].info, {'MARChannelName': 'test1', 'ProductVersion': '123'})
|
||||
|
||||
def test_additional_info_fo(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
with MarFile(None, fileobj=open(marfile, "wb")) as m:
|
||||
info = AdditionalInfo.from_info({'MARChannelName': 'test1', 'ProductVersion': '123'})
|
||||
m.additional_info.append(info)
|
||||
m.add(__file__)
|
||||
|
||||
with MarFile(None, fileobj=open(marfile, "rb")) as m:
|
||||
self.assertEquals(len(m.additional_info), 1)
|
||||
self.assertEquals(m.additional_info[0].name, 'PRODUCT INFORMATION')
|
||||
self.assertEquals(m.additional_info[0].info, {'MARChannelName': 'test1', 'ProductVersion': '123'})
|
||||
|
||||
def test_add_dir(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
dirname = os.path.dirname(__file__)
|
||||
with MarFile(marfile, 'w') as m:
|
||||
with MarFile(marfile, mode='w') as m:
|
||||
m.add(dirname)
|
||||
|
||||
# List out the files in dirname so we can compare
|
||||
|
@ -149,9 +199,35 @@ class TestWritingMar(TestCase):
|
|||
open(member.name, 'rb').read()
|
||||
)
|
||||
|
||||
def test_add_dir_fo(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
dirname = os.path.dirname(__file__)
|
||||
with MarFile(None, fileobj=open(marfile, "wb")) as m:
|
||||
m.add(dirname)
|
||||
|
||||
# List out the files in dirname so we can compare
|
||||
my_files = []
|
||||
for root, dirs, files in os.walk(dirname):
|
||||
for f in files:
|
||||
my_files.append(os.path.join(root, f))
|
||||
|
||||
with MarFile(None, fileobj=open(marfile, "rb")) as m:
|
||||
self.assertEquals(len(m.members), len(my_files))
|
||||
for member in m.members:
|
||||
self.assertTrue(member.name in my_files)
|
||||
self.assertEquals(member.size, os.path.getsize(member.name))
|
||||
self.assertEquals(member.flags, os.stat(member.name).st_mode & 0o777)
|
||||
|
||||
extracted = m.extract(member, self.tmpdir)
|
||||
self.assertNotEquals(extracted, member.name)
|
||||
self.assertEquals(
|
||||
open(extracted, 'rb').read(),
|
||||
open(member.name, 'rb').read()
|
||||
)
|
||||
|
||||
def test_bz2_add(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
with BZ2MarFile(marfile, 'w') as m:
|
||||
with BZ2MarFile(marfile, mode='w') as m:
|
||||
m.add(__file__)
|
||||
|
||||
with BZ2MarFile(marfile) as m:
|
||||
|
@ -162,10 +238,23 @@ class TestWritingMar(TestCase):
|
|||
open(__file__, 'rb').read()
|
||||
)
|
||||
|
||||
def test_bz2_add_fo(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
with BZ2MarFile(None, fileobj=open(marfile, "wb")) as m:
|
||||
m.add(__file__)
|
||||
|
||||
with BZ2MarFile(None, fileobj=open(marfile, "rb")) as m:
|
||||
self.assertEquals(len(m.members), 1)
|
||||
extracted = m.extract(m.members[0], self.tmpdir)
|
||||
self.assertEquals(
|
||||
open(extracted, 'rb').read(),
|
||||
open(__file__, 'rb').read()
|
||||
)
|
||||
|
||||
def test_bz2_add_dir(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
dirname = os.path.dirname(__file__)
|
||||
with BZ2MarFile(marfile, 'w') as m:
|
||||
with BZ2MarFile(marfile, mode='w') as m:
|
||||
m.add(dirname)
|
||||
|
||||
# List out the files in dirname so we can compare
|
||||
|
@ -187,11 +276,40 @@ class TestWritingMar(TestCase):
|
|||
open(member.name, 'rb').read()
|
||||
)
|
||||
|
||||
def test_bz2_add_dir_fo(self):
|
||||
marfile = os.path.join(self.tmpdir, 'test.mar')
|
||||
dirname = os.path.dirname(__file__)
|
||||
with BZ2MarFile(None, fileobj=open(marfile, "wb")) as m:
|
||||
m.add(dirname)
|
||||
|
||||
# List out the files in dirname so we can compare
|
||||
my_files = []
|
||||
for root, dirs, files in os.walk(dirname):
|
||||
for f in files:
|
||||
my_files.append(os.path.join(root, f))
|
||||
|
||||
with BZ2MarFile(None, fileobj=open(marfile, "rb")) as m:
|
||||
self.assertEquals(len(m.members), len(my_files))
|
||||
for member in m.members:
|
||||
self.assertTrue(member.name in my_files)
|
||||
self.assertEquals(member.flags, os.stat(member.name).st_mode & 0o777)
|
||||
|
||||
extracted = m.extract(member, self.tmpdir)
|
||||
self.assertNotEquals(extracted, member.name)
|
||||
self.assertEquals(
|
||||
open(extracted, 'rb').read(),
|
||||
open(member.name, 'rb').read()
|
||||
)
|
||||
|
||||
|
||||
class TestExceptions(TestCase):
|
||||
def test_badmar(self):
|
||||
self.assertRaises(ValueError, MarFile, __file__)
|
||||
|
||||
def test_badmar_fo(self):
|
||||
self.assertRaises(ValueError, MarFile, name=None,
|
||||
fileobj=open(__file__, "rb"))
|
||||
|
||||
|
||||
from hypothesis import given, example
|
||||
from hypothesis import strategies as st
|
||||
|
|
|
@ -17,3 +17,9 @@ class TestMarSignatures(TestCase):
|
|||
"""Check that our test mar is signed correctly"""
|
||||
marfile = MarFile(TEST_MAR, signature_versions=[(1, TEST_KEY)])
|
||||
marfile.verify_signatures()
|
||||
|
||||
def test_verify_fo(self):
|
||||
"""Check that our test mar fileobject is signed correctly"""
|
||||
marfile = MarFile(name=TEST_MAR, fileobj=open(TEST_MAR, "rb"),
|
||||
signature_versions=[(1, TEST_KEY)])
|
||||
marfile.verify_signatures()
|
||||
|
|
Загрузка…
Ссылка в новой задаче