98-tests/test_deterministic_zip.py
import hashlib, importlib.util, tempfile, unittest, zipfile
from pathlib import Path
MODULE=Path(__file__).parents[1]/'60-packaging'/'deterministic_zip.py'
spec=importlib.util.spec_from_file_location('deterministic_zip', MODULE)
zipmod=importlib.util.module_from_spec(spec); spec.loader.exec_module(zipmod)
class DeterministicZipTest(unittest.TestCase):
def fixture(self, root: Path):
repo=root/'demo'; (repo/'sub').mkdir(parents=True); (repo/'.git').mkdir()
(repo/'README.md').write_text('demo\n'); (repo/'sub'/'b.txt').write_text('b')
(repo/'a.txt').write_text('a'); (repo/'.env').write_text('secret')
(repo/'.env.example').write_text('example')
return repo
def test_deterministic_order_root_and_excludes(self):
with tempfile.TemporaryDirectory() as d:
root=Path(d); envelope=root/'envelope'; envelope.mkdir(); repo=self.fixture(envelope); a=root/'a.zip'; b=root/'b.zip'
zipmod.create_repository_zip(repo,a); zipmod.create_repository_zip(envelope,b)
self.assertEqual(hashlib.sha256(a.read_bytes()).digest(), hashlib.sha256(b.read_bytes()).digest())
with zipfile.ZipFile(a) as z:
self.assertEqual(z.namelist(), ['demo/.env.example','demo/README.md','demo/a.txt','demo/sub/b.txt'])
self.assertEqual({i.date_time for i in z.infolist()}, {zipmod.FIXED_TIMESTAMP})
def test_explicit_temporary_exclusion(self):
with tempfile.TemporaryDirectory() as d:
root=Path(d); repo=self.fixture(root); (repo/'out').mkdir(); (repo/'out'/'generated.zip').write_text('x')
out=root/'result.zip'; zipmod.create_repository_zip(repo,out,zipmod.DEFAULT_EXCLUDES+('out/**',))
with zipfile.ZipFile(out) as z: self.assertNotIn('demo/out/generated.zip',z.namelist())
def test_default_excludes_generated_and_local_tool_paths(self):
with tempfile.TemporaryDirectory() as d:
root=Path(d); repo=self.fixture(root)
for relative in ('out/generated.zip','archive/roundtrip-imports/before-import.zip','logs/run.log','node_modules/pkg/index.js','.github/workflows/test.yml'):
path=repo/relative; path.parent.mkdir(parents=True,exist_ok=True); path.write_text('generated')
out=root/'result.zip'; zipmod.create_repository_zip(repo,out)
with zipfile.ZipFile(out) as z:
names=z.namelist()
self.assertFalse(any('/out/' in name for name in names))
self.assertFalse(any('/archive/' in name for name in names))
self.assertFalse(any('/logs/' in name for name in names))
self.assertFalse(any('/node_modules/' in name for name in names))
self.assertFalse(any('/.github/' in name for name in names))
if __name__=='__main__': unittest.main()