1*4882a593Smuzhiyun# 2*4882a593Smuzhiyun# Copyright BitBake Contributors 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only 5*4882a593Smuzhiyun# 6*4882a593Smuzhiyun 7*4882a593Smuzhiyunfrom pathlib import Path 8*4882a593Smuzhiyunimport bb.compress.lz4 9*4882a593Smuzhiyunimport bb.compress.zstd 10*4882a593Smuzhiyunimport contextlib 11*4882a593Smuzhiyunimport os 12*4882a593Smuzhiyunimport shutil 13*4882a593Smuzhiyunimport tempfile 14*4882a593Smuzhiyunimport unittest 15*4882a593Smuzhiyunimport subprocess 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun 18*4882a593Smuzhiyunclass CompressionTests(object): 19*4882a593Smuzhiyun def setUp(self): 20*4882a593Smuzhiyun self._t = tempfile.TemporaryDirectory() 21*4882a593Smuzhiyun self.tmpdir = Path(self._t.name) 22*4882a593Smuzhiyun self.addCleanup(self._t.cleanup) 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun def _file_helper(self, mode_suffix, data): 25*4882a593Smuzhiyun tmp_file = self.tmpdir / "compressed" 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun with self.do_open(tmp_file, mode="w" + mode_suffix) as f: 28*4882a593Smuzhiyun f.write(data) 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun with self.do_open(tmp_file, mode="r" + mode_suffix) as f: 31*4882a593Smuzhiyun read_data = f.read() 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun self.assertEqual(read_data, data) 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun def test_text_file(self): 36*4882a593Smuzhiyun self._file_helper("t", "Hello") 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun def test_binary_file(self): 39*4882a593Smuzhiyun self._file_helper("b", "Hello".encode("utf-8")) 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun def _pipe_helper(self, mode_suffix, data): 42*4882a593Smuzhiyun rfd, wfd = os.pipe() 43*4882a593Smuzhiyun with open(rfd, "rb") as r, open(wfd, "wb") as w: 44*4882a593Smuzhiyun with self.do_open(r, mode="r" + mode_suffix) as decompress: 45*4882a593Smuzhiyun with self.do_open(w, mode="w" + mode_suffix) as compress: 46*4882a593Smuzhiyun compress.write(data) 47*4882a593Smuzhiyun read_data = decompress.read() 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun self.assertEqual(read_data, data) 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun def test_text_pipe(self): 52*4882a593Smuzhiyun self._pipe_helper("t", "Hello") 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun def test_binary_pipe(self): 55*4882a593Smuzhiyun self._pipe_helper("b", "Hello".encode("utf-8")) 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun def test_bad_decompress(self): 58*4882a593Smuzhiyun tmp_file = self.tmpdir / "compressed" 59*4882a593Smuzhiyun with tmp_file.open("wb") as f: 60*4882a593Smuzhiyun f.write(b"\x00") 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun with self.assertRaises(OSError): 63*4882a593Smuzhiyun with self.do_open(tmp_file, mode="rb", stderr=subprocess.DEVNULL) as f: 64*4882a593Smuzhiyun data = f.read() 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun 67*4882a593Smuzhiyunclass LZ4Tests(CompressionTests, unittest.TestCase): 68*4882a593Smuzhiyun def setUp(self): 69*4882a593Smuzhiyun if shutil.which("lz4c") is None: 70*4882a593Smuzhiyun self.skipTest("'lz4c' not found") 71*4882a593Smuzhiyun super().setUp() 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun @contextlib.contextmanager 74*4882a593Smuzhiyun def do_open(self, *args, **kwargs): 75*4882a593Smuzhiyun with bb.compress.lz4.open(*args, **kwargs) as f: 76*4882a593Smuzhiyun yield f 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun 79*4882a593Smuzhiyunclass ZStdTests(CompressionTests, unittest.TestCase): 80*4882a593Smuzhiyun def setUp(self): 81*4882a593Smuzhiyun if shutil.which("zstd") is None: 82*4882a593Smuzhiyun self.skipTest("'zstd' not found") 83*4882a593Smuzhiyun super().setUp() 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun @contextlib.contextmanager 86*4882a593Smuzhiyun def do_open(self, *args, **kwargs): 87*4882a593Smuzhiyun with bb.compress.zstd.open(*args, **kwargs) as f: 88*4882a593Smuzhiyun yield f 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun 91*4882a593Smuzhiyunclass PZStdTests(CompressionTests, unittest.TestCase): 92*4882a593Smuzhiyun def setUp(self): 93*4882a593Smuzhiyun if shutil.which("pzstd") is None: 94*4882a593Smuzhiyun self.skipTest("'pzstd' not found") 95*4882a593Smuzhiyun super().setUp() 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun @contextlib.contextmanager 98*4882a593Smuzhiyun def do_open(self, *args, **kwargs): 99*4882a593Smuzhiyun with bb.compress.zstd.open(*args, num_threads=2, **kwargs) as f: 100*4882a593Smuzhiyun yield f 101