blob: 76cfd6219dd0fd9c306fd6f7191dd293156555ee [file] [log] [blame]
George Burgess IV757887f2021-09-22 15:58:35 -07001# Copyright 2021 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Unit tests for xz_auto.py."""
6
7import os
8from pathlib import Path
9import unittest
10from unittest import mock
11
12from chromite.lib import cros_build_lib
13from chromite.lib import cros_test_lib
14from chromite.lib import osutils
15from chromite.scripts import xz_auto
16
17
18DIR = Path(__file__).resolve().parent
19
20
21def FindXzAutoLocation():
22 """Figures out where the xz_auto binary is."""
23 return DIR / 'xz_auto'
24
25
26class XzAutoTests(cros_test_lib.MockTempDirTestCase):
27 """Various tests for xz_auto."""
28
George Burgess IVd67df462021-10-27 14:31:33 -070029 TEST_FILE_CONTENTS = (b'', b'some random file contents')
30
George Burgess IV757887f2021-09-22 15:58:35 -070031 def DisablePixzForCurrentTest(self):
32 """Disables the use of pixz for the current test."""
33 # This will be cleaned up by cros_test_lib, so no need to addCleanup.
34 os.environ[xz_auto.PIXZ_DISABLE_VAR] = '1'
35
36 def testPixzArgParsingSeemsToWork(self):
37 """Tests our detection of file names in pixz commandlines."""
38 self.assertEqual(
39 xz_auto.ParsePixzArgs(['to_compress.txt']),
40 ([], 'to_compress.txt', None),
41 )
42 self.assertEqual(
43 xz_auto.ParsePixzArgs(['to_compress.txt', 'compressed.txt']),
44 ([], 'to_compress.txt', 'compressed.txt'),
45 )
46 self.assertEqual(
47 xz_auto.ParsePixzArgs(['to_compress.txt', '-c', 'compressed.txt',
48 '-9']),
49 (['-c', '-9'], 'to_compress.txt', 'compressed.txt'),
50 )
51 self.assertEqual(
52 xz_auto.ParsePixzArgs(
53 ['-t', 'to_compress.txt', '-c', 'compressed.txt', '-p', '2']),
54 (['-t', '-c', '-p', '2'], 'to_compress.txt', 'compressed.txt'),
55 )
56 self.assertEqual(
57 xz_auto.ParsePixzArgs(['-tcp2', 'to_compress.txt', 'compressed.txt']),
58 (['-t', '-c', '-p', '2'], 'to_compress.txt', 'compressed.txt'),
59 )
60
61 @unittest.skipIf(not xz_auto.HasPixz(), 'need pixz for this test')
62 @mock.patch.object(xz_auto, 'Execvp')
63 def testPixzCommandCreationSelectsPixzIfAvailable(self, execvp_mock):
64 """Tests that we actually execute pixz when we intend to."""
65 class ExecvpStopError(Exception):
66 """Convenient way to halt execution."""
67
68 def execvp_side_effect(argv):
69 """Does testing of our execvp calls."""
70 self.assertEqual(argv[0], 'pixz')
71 raise ExecvpStopError()
72
73 execvp_mock.side_effect = execvp_side_effect
74 with self.assertRaises(ExecvpStopError):
75 xz_auto.ExecCompressCommand(stdout=False, argv=[])
76
77 with self.assertRaises(ExecvpStopError):
78 xz_auto.ExecDecompressCommand(stdout=False, argv=[])
79
George Burgess IVd67df462021-10-27 14:31:33 -070080 def _TestFileCompressionImpl(self, test_empty_file=True):
George Burgess IV757887f2021-09-22 15:58:35 -070081 """Tests that compressing a file with xz_auto WAI."""
George Burgess IV757887f2021-09-22 15:58:35 -070082 xz_auto_script = str(FindXzAutoLocation())
George Burgess IV757887f2021-09-22 15:58:35 -070083
George Burgess IVd67df462021-10-27 14:31:33 -070084 test_file_contents = self.TEST_FILE_CONTENTS
85 if not test_empty_file:
86 test_file_contents = (x for x in test_file_contents if x)
87
88 for file_contents in test_file_contents:
89 file_location = os.path.join(self.tempdir, 'file.txt')
90 osutils.WriteFile(file_location, file_contents, mode='wb')
91
92 cros_build_lib.run(
93 [
94 xz_auto_script,
95 file_location,
96 ],
97 )
98
99 xz_location = file_location + '.xz'
100 self.assertExists(xz_location)
101 self.assertNotExists(file_location)
102 cros_build_lib.run([
103 xz_auto_script,
104 '--decompress',
105 xz_location,
106 ])
107 self.assertNotExists(xz_location)
108 self.assertExists(file_location)
109 self.assertEqual(
110 osutils.ReadFile(file_location, mode='rb'),
111 file_contents,
112 )
George Burgess IV757887f2021-09-22 15:58:35 -0700113
114 def _TestStdoutCompressionImpl(self):
115 """Tests that compressing stdstreams with xz_auto WAI."""
George Burgess IV757887f2021-09-22 15:58:35 -0700116 xz_auto_script = str(FindXzAutoLocation())
George Burgess IVd67df462021-10-27 14:31:33 -0700117 for file_contents in self.TEST_FILE_CONTENTS:
118 run_result = cros_build_lib.run(
119 [
120 xz_auto_script,
121 '-c',
122 ],
123 capture_output=True,
124 input=file_contents,
125 )
George Burgess IV757887f2021-09-22 15:58:35 -0700126
George Burgess IVd67df462021-10-27 14:31:33 -0700127 compressed_file = run_result.stdout
128 self.assertNotEqual(compressed_file, file_contents)
George Burgess IV757887f2021-09-22 15:58:35 -0700129
George Burgess IVd67df462021-10-27 14:31:33 -0700130 run_result = cros_build_lib.run(
131 [
132 xz_auto_script,
133 '--decompress',
134 '-c',
135 ],
136 input=compressed_file,
137 capture_output=True,
138 )
139 uncompressed_file = run_result.stdout
140 self.assertEqual(file_contents, uncompressed_file)
George Burgess IV757887f2021-09-22 15:58:35 -0700141
142 def _TestStdoutCompressionFromFileImpl(self):
143 """Tests that compression of a file & outputting to stdout works.
144
145 Pixz has some semi-weird behavior here (b/202735786).
146 """
George Burgess IV757887f2021-09-22 15:58:35 -0700147 xz_auto_script = str(FindXzAutoLocation())
George Burgess IVd67df462021-10-27 14:31:33 -0700148 for file_contents in self.TEST_FILE_CONTENTS:
149 file_location = os.path.join(self.tempdir, 'file.txt')
150 osutils.WriteFile(file_location, file_contents, mode='wb')
George Burgess IV757887f2021-09-22 15:58:35 -0700151
George Burgess IVd67df462021-10-27 14:31:33 -0700152 run_result = cros_build_lib.run(
153 [
154 xz_auto_script,
155 '-c',
156 file_location,
157 ],
158 capture_output=True,
159 )
George Burgess IV757887f2021-09-22 15:58:35 -0700160
George Burgess IVd67df462021-10-27 14:31:33 -0700161 compressed_file = run_result.stdout
162 self.assertExists(file_location)
163 self.assertNotEqual(compressed_file, file_contents)
George Burgess IV757887f2021-09-22 15:58:35 -0700164
George Burgess IVd67df462021-10-27 14:31:33 -0700165 run_result = cros_build_lib.run(
166 [
167 xz_auto_script,
168 '--decompress',
169 '-c',
170 ],
171 capture_output=True,
172 input=compressed_file,
173 )
174 uncompressed_file = run_result.stdout
175 self.assertEqual(file_contents, uncompressed_file)
George Burgess IV757887f2021-09-22 15:58:35 -0700176
177 @unittest.skipIf(not xz_auto.HasPixz(), 'need pixz for this test')
178 def testFileCompressionWithPixzWorks(self):
179 """Tests that compressing a file with pixz WAI."""
180 self._TestFileCompressionImpl()
181
George Burgess IVd67df462021-10-27 14:31:33 -0700182 # We fall back to `xz` with small files. Make sure we actually cover the
183 # pixz case, too. We disable testing of empty inputs, since pixz breaks
184 # with those.
185 #
186 # cros_test_lib will clean this var up at the end of the test.
187 os.environ[xz_auto.XZ_DISABLE_VAR] = '1'
188 self._TestFileCompressionImpl(test_empty_file=False)
189
George Burgess IV757887f2021-09-22 15:58:35 -0700190 @unittest.skipIf(not xz_auto.HasPixz(), 'need pixz for this test')
191 def testStdoutCompressionWithPixzWorks(self):
192 """Tests that compressing `stdout` with pixz WAI."""
193 self._TestStdoutCompressionImpl()
194
195 @unittest.skipIf(not xz_auto.HasPixz(), 'need pixz for this test')
196 def testStdoutCompressionFromFileWithPixzWorks(self):
197 """Tests that compressing from a file to stdout with pixz WAI."""
198 self._TestStdoutCompressionFromFileImpl()
199
200 def testFileCompressionWithXzWorks(self):
201 """Tests that compressing a file with pixz WAI."""
202 self.DisablePixzForCurrentTest()
203 self._TestFileCompressionImpl()
204
205 def testStdoutCompressionWithXzWorks(self):
206 """Tests that compressing `stdout` with pixz WAI."""
207 self.DisablePixzForCurrentTest()
208 self._TestStdoutCompressionImpl()
209
210 def testStdoutCompressionFromFileWithXzWorks(self):
211 """Tests that compressing from a file to stdout WAI."""
212 self.DisablePixzForCurrentTest()
213 self._TestStdoutCompressionFromFileImpl()