Merge ~jslarraz/review-tools:work-on-test-cases into review-tools:master

Proposed by Jorge Sancho Larraz
Status: Merged
Merged at revision: 2979f040fdce69a935de810afca9430afae3a89c
Proposed branch: ~jslarraz/review-tools:work-on-test-cases
Merge into: review-tools:master
Diff against target: 491 lines (+128/-167)
4 files modified
reviewtools/containers/base_container.py (+12/-3)
reviewtools/containers/squashfs_container.py (+0/-11)
reviewtools/tests/containers/test_base_container.py (+97/-120)
reviewtools/tests/containers/test_squashfs_container.py (+19/-33)
Reviewer Review Type Date Requested Status
Alex Murray Needs Fixing
Review via email: mp+466819@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jorge Sancho Larraz (jslarraz) wrote (last edit ):

Move check for container format to BaseContainer initialization and properly mock required functions: https://git.launchpad.net/~jslarraz/review-tools/commit/?id=9477ee6500544e63ed46ea19ab1486c8f4cf268c

Remove unneeded exception handling on error cases from tests classes (makes code cleaner and improves coverage): https://git.launchpad.net/~jslarraz/review-tools/commit/?id=acb74aab8dab0c2d0eedb354adda7bb0ea10e295

Add missing tests case for missing extension on container file name and mock _unpack_dir: https://git.launchpad.net/~jslarraz/review-tools/commit/?id=037aefd2f9dadec3b3734b1b2f368df8cba569b2

Revision history for this message
Alex Murray (alexmurray) wrote :

LGTM except one minor change needed to the comment in base_container.py

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/reviewtools/containers/base_container.py b/reviewtools/containers/base_container.py
index 3c4555f..0759469 100644
--- a/reviewtools/containers/base_container.py
+++ b/reviewtools/containers/base_container.py
@@ -90,6 +90,9 @@ class BaseContainer:
90 # Check max/min size if defined90 # Check max/min size if defined
91 self.check_container_size()91 self.check_container_size()
9292
93 # Check container has the expected format
94 self.check_container_format()
95
93 @property96 @property
94 def unpack_dir(self) -> str:97 def unpack_dir(self) -> str:
95 """98 """
@@ -143,7 +146,9 @@ class BaseContainer:
143 format is specific to the container type. This method needs to be146 format is specific to the container type. This method needs to be
144 implemented by the specific subclasses.147 implemented by the specific subclasses.
145 """148 """
146 raise NotImplementedError("Must be implemented by subclasses")149 raise NotImplementedError(
150 "Must be implemented by subclasses"
151 ) # pragma: no cover
147152
148 def get_container_size(self) -> int:153 def get_container_size(self) -> int:
149 """154 """
@@ -188,7 +193,9 @@ class BaseContainer:
188 estimation method is specific to the container type. This method193 estimation method is specific to the container type. This method
189 needs to be implemented by the specific subclasses.194 needs to be implemented by the specific subclasses.
190 """195 """
191 raise NotImplementedError("Must be implemented by subclasses")196 raise NotImplementedError(
197 "Must be implemented by subclasses"
198 ) # pragma: no cover
192199
193 def check_unpacked_size(self):200 def check_unpacked_size(self):
194 """201 """
@@ -243,7 +250,9 @@ class BaseContainer:
243 estimation method is specific to the container type. This method250 estimation method is specific to the container type. This method
244 needs to be implemented by the specific subclasses.251 needs to be implemented by the specific subclasses.
245 """252 """
246 raise NotImplementedError("Must be implemented by subclasses")253 raise NotImplementedError(
254 "Must be implemented by subclasses"
255 ) # pragma: no cover
247256
248 def get_file(self, fn: str) -> bytes:257 def get_file(self, fn: str) -> bytes:
249 """258 """
diff --git a/reviewtools/containers/squashfs_container.py b/reviewtools/containers/squashfs_container.py
index 631fe76..4896bbb 100644
--- a/reviewtools/containers/squashfs_container.py
+++ b/reviewtools/containers/squashfs_container.py
@@ -10,17 +10,6 @@ class SquashfsContainer(BaseContainer):
10 BaseContainer to handle functionality that is specific to Squashfs containers.10 BaseContainer to handle functionality that is specific to Squashfs containers.
11 """11 """
1212
13 def __init__(self, fn):
14 """
15 If SquashfsContainer is initialized with a container file, it will also
16 verify that the provided file is actually a squashfs, in addition to the
17 checks performed by the BaseContainer.
18 """
19 super().__init__(fn)
20
21 # Check is squash file
22 self.check_container_format()
23
24 def check_container_format(self):13 def check_container_format(self):
25 """14 """
26 Checks that the container file has the expected format.15 Checks that the container file has the expected format.
diff --git a/reviewtools/tests/containers/test_base_container.py b/reviewtools/tests/containers/test_base_container.py
index 277be8f..d4e0726 100644
--- a/reviewtools/tests/containers/test_base_container.py
+++ b/reviewtools/tests/containers/test_base_container.py
@@ -1,10 +1,19 @@
1import os1import os
2import shutil2import shutil
3import unittest3import unittest
4from tempfile import mkdtemp4from unittest.mock import patch
5from tempfile import mkdtemp, mkstemp
5from reviewtools.containers.base_container import BaseContainer, ContainerException6from reviewtools.containers.base_container import BaseContainer, ContainerException
67
78
9def _mock_check_container_format(self):
10 return True
11
12
13def _mock_calculate_unpacked_size(self):
14 return 10**3
15
16
8class TestBaseContainer(unittest.TestCase):17class TestBaseContainer(unittest.TestCase):
9 """Tests for reviewtools.containers.base_container.BaseContainer"""18 """Tests for reviewtools.containers.base_container.BaseContainer"""
1019
@@ -17,11 +26,33 @@ class TestBaseContainer(unittest.TestCase):
17 cls.fn = cls._create_container(cls)26 cls.fn = cls._create_container(cls)
18 cls.unpack_dir = cls._create_unpackdir(cls)27 cls.unpack_dir = cls._create_unpackdir(cls)
1928
29 # Mock required classes
30 cls.patches = [
31 unittest.mock.patch(
32 "reviewtools.tests.containers.test_base_container.BaseContainer.check_container_format",
33 _mock_check_container_format,
34 ),
35 unittest.mock.patch(
36 "reviewtools.tests.containers.test_base_container.BaseContainer.calculate_unpacked_size",
37 _mock_calculate_unpacked_size,
38 ),
39 unittest.mock.patch(
40 "reviewtools.tests.containers.test_base_container.BaseContainer._unpack_dir",
41 cls.unpack_dir,
42 ),
43 ]
44 for patch in cls.patches:
45 patch.start()
46
20 @classmethod47 @classmethod
21 def tearDownClass(cls):48 def tearDownClass(cls):
22 if os.path.exists(cls.tmp_dir):49 if os.path.exists(cls.tmp_dir):
23 shutil.rmtree(cls.tmp_dir)50 shutil.rmtree(cls.tmp_dir)
2451
52 # Stop mocking
53 for patch in cls.patches:
54 patch.stop()
55
25 def _create_container(self, container_size: int = 10000):56 def _create_container(self, container_size: int = 10000):
26 fn = os.path.join(self.tmp_dir, "container.test")57 fn = os.path.join(self.tmp_dir, "container.test")
27 with open(fn, "w") as f:58 with open(fn, "w") as f:
@@ -49,112 +80,89 @@ map:
49 return unpack_dir80 return unpack_dir
5081
51 # Test class initialization82 # Test class initialization
52 def test_initialization_container__happy(self):83 def test_initialization__happy(self):
53 try:84 BaseContainer(self.fn)
54 BaseContainer(self.fn)85
55 except ContainerException:86 def test_initialization__missing_extension(self):
56 self.fail(87 fd, plain_file = mkstemp()
57 "An unexpected error occurred during BaseContainer initialization with container file"88 with self.assertRaises(ContainerException) as context:
58 )89 BaseContainer(plain_file)
90 self.assertEqual(
91 "container filename must include an extension", context.exception.value
92 )
93 os.unlink(plain_file)
5994
60 def test_initialization__missing_file(self):95 def test_initialization__missing_file(self):
61 with self.assertRaises(ContainerException) as context:96 with self.assertRaises(ContainerException) as context:
62 BaseContainer("/non/existing/path")97 BaseContainer("/non/existing/path")
63 self.assertTrue(98 self.assertTrue("Could not find " in context.exception.value)
64 "does not exists or has incorrect permissions"
65 in context.exception.value
66 )
6799
68 # Test deletion100 # Test deletion
69 def test_check_cleanup(self):101 def test_check_cleanup(self):
70 try:102 container = BaseContainer(self.fn)
71 container = BaseContainer(self.fn)103 tmp_dir = container.tmp_dir
72 tmp_dir = container.tmp_dir104 del container
73 del container105 self.assertFalse(os.path.exists(tmp_dir))
74 self.assertFalse(os.path.exists(tmp_dir))
75 except Exception:
76 self.fail("An unexpected error occurred during deletion test")
77106
78 # Test check container size107 # Test check container size
79 def test_check_container_size__happy(self):108 def test_check_container_size__happy(self):
80 container = BaseContainer(self.fn)109 container = BaseContainer(self.fn)
81 container._min_packed_size = 0110 container._min_packed_size = 0
82 container._max_packed_size = 10**6111 container._max_packed_size = 10**6
83 try:112 container.check_container_size()
84 container.check_container_size()
85 except ContainerException:
86 self.fail("An unexpected error occurred while checking file size")
87113
88 def test_check_container_size__too_big(self):114 def test_check_container_size__too_big(self):
89 container = BaseContainer(self.fn)115 container = BaseContainer(self.fn)
90 container._max_packed_size = 1116 container._max_packed_size = 1
91 with self.assertRaises(ContainerException) as context:117 with self.assertRaises(ContainerException) as context:
92 container.check_container_size()118 container.check_container_size()
93 self.assertTrue("container file is too large " in context.exception.value)119 self.assertTrue("container file is too large " in context.exception.value)
94120
95 def test_check_container_size__too_small(self):121 def test_check_container_size__too_small(self):
96 container = BaseContainer(self.fn)122 container = BaseContainer(self.fn)
97 container._min_packed_size = 10**6123 container._min_packed_size = 10**6
98 with self.assertRaises(ContainerException) as context:124 with self.assertRaises(ContainerException) as context:
99 container.check_container_size()125 container.check_container_size()
100 self.assertTrue("container file is too small " in context.exception.value)126 self.assertTrue("container file is too small " in context.exception.value)
101127
102 # Test check unpacked size128 # Test check unpacked size
103 def _mock_calculate_unpacked_size(self):
104 return 10**3
105
106 def test_check_unpacked_size__happy(self):129 def test_check_unpacked_size__happy(self):
107 container = BaseContainer(self.fn)130 container = BaseContainer(self.fn)
108 container.calculate_unpacked_size = self._mock_calculate_unpacked_size
109 container._min_unpacked_size = 0131 container._min_unpacked_size = 0
110 container._max_unpacked_size = 10**6132 container._max_unpacked_size = 10**6
111 try:133 container.check_unpacked_size()
112 container.check_unpacked_size()
113 except ContainerException:
114 self.fail("An unexpected error occurred while checking file size")
115134
116 def test_check_unpacked_size__too_big(self):135 def test_check_unpacked_size__too_big(self):
117 container = BaseContainer(self.fn)136 container = BaseContainer(self.fn)
118 container.calculate_unpacked_size = self._mock_calculate_unpacked_size
119 container._max_unpacked_size = 1137 container._max_unpacked_size = 1
120 with self.assertRaises(ContainerException) as context:138 with self.assertRaises(ContainerException) as context:
121 container.check_unpacked_size()139 container.check_unpacked_size()
122 self.assertTrue("container file is too large " in context.exception.value)140 self.assertTrue("unpacked directory is too large " in context.exception.value)
123141
124 def test_check_unpacked_size__too_small(self):142 def test_check_unpacked_size__too_small(self):
125 container = BaseContainer(self.fn)143 container = BaseContainer(self.fn)
126 container.calculate_unpacked_size = self._mock_calculate_unpacked_size
127 container._min_unpacked_size = 10**6144 container._min_unpacked_size = 10**6
128 with self.assertRaises(ContainerException) as context:145 with self.assertRaises(ContainerException) as context:
129 container.check_unpacked_size()146 container.check_unpacked_size()
130 self.assertTrue("container file is too small " in context.exception.value)147 self.assertTrue("unpacked directory is too small " in context.exception.value)
131148
132 # Test get file149 # Test get file
133 def test_get_file__happy(self):150 def test_get_file__happy(self):
134 try:151 container = BaseContainer(self.fn)
135 container = BaseContainer(self.fn)152 snap_yaml = container.get_file("meta/icon.png")
136 container._unpack_dir = self.unpack_dir153 self.assertEqual(snap_yaml.decode(), "Test")
137 snap_yaml = container.get_file("meta/icon.png")
138 self.assertEqual(snap_yaml.decode(), "Test")
139 except ContainerException:
140 self.fail("An unexpected error occurred while getting meta/icon.png")
141154
142 def test_get_file__missing_file(self):155 def test_get_file__missing_file(self):
156 container = BaseContainer(self.fn)
143 with self.assertRaises(ContainerException) as context:157 with self.assertRaises(ContainerException) as context:
144 container = BaseContainer(self.fn)
145 container._unpack_dir = self.unpack_dir
146 container.get_file("non/existent/file")158 container.get_file("non/existent/file")
147 self.assertTrue("Could not find" in context.exception.value)159 self.assertTrue("Could not find" in context.exception.value)
148160
149 # Test get yaml161 # Test get yaml
150 def test_get_file_as_yaml__happy(self):162 def test_get_file_as_yaml__happy(self):
151 try:163 container = BaseContainer(self.fn)
152 container = BaseContainer(self.fn)164 snap_yaml = container.get_file_as_yaml("meta/snap.yaml")
153 container._unpack_dir = self.unpack_dir165 self.assertEqual(snap_yaml, {"map": {"key": "value"}})
154 snap_yaml = container.get_file_as_yaml("meta/snap.yaml")
155 self.assertEqual(snap_yaml, {"map": {"key": "value"}})
156 except ContainerException:
157 self.fail("An unexpected error occurred while getting meta/snap.yaml")
158166
159 def test_get_file_as_yaml__dup_keys(self):167 def test_get_file_as_yaml__dup_keys(self):
160 # Write the file to test168 # Write the file to test
@@ -169,7 +177,6 @@ map:
169177
170 with self.assertRaises(ContainerException) as context:178 with self.assertRaises(ContainerException) as context:
171 container = BaseContainer(self.fn)179 container = BaseContainer(self.fn)
172 container._unpack_dir = self.unpack_dir
173 container.get_file_as_yaml("test.yaml")180 container.get_file_as_yaml("test.yaml")
174 self.assertTrue('found duplicate key "key"' in context.exception.value)181 self.assertTrue('found duplicate key "key"' in context.exception.value)
175182
@@ -188,7 +195,6 @@ map:
188 )195 )
189196
190 container = BaseContainer(self.fn)197 container = BaseContainer(self.fn)
191 container._unpack_dir = self.unpack_dir
192 container.get_file_as_yaml("test.yaml", allow_duplicate_keys=True)198 container.get_file_as_yaml("test.yaml", allow_duplicate_keys=True)
193199
194 # Clean the tested file200 # Clean the tested file
@@ -204,7 +210,6 @@ mode: 0777
204 )210 )
205211
206 container = BaseContainer(self.fn)212 container = BaseContainer(self.fn)
207 container._unpack_dir = self.unpack_dir
208 test_yaml = container.get_file_as_yaml("test.yaml", yaml_version="1.1")213 test_yaml = container.get_file_as_yaml("test.yaml", yaml_version="1.1")
209 self.assertEqual(test_yaml["mode"], 511)214 self.assertEqual(test_yaml["mode"], 511)
210215
@@ -221,7 +226,6 @@ mode: 0777
221 )226 )
222227
223 container = BaseContainer(self.fn)228 container = BaseContainer(self.fn)
224 container._unpack_dir = self.unpack_dir
225 test_yaml = container.get_file_as_yaml("test.yaml")229 test_yaml = container.get_file_as_yaml("test.yaml")
226 self.assertEqual(test_yaml["mode"], 777)230 self.assertEqual(test_yaml["mode"], 777)
227231
@@ -230,76 +234,49 @@ mode: 0777
230234
231 # Test get files list235 # Test get files list
232 def test_get_files_list__happy(self):236 def test_get_files_list__happy(self):
233 try:237 container = BaseContainer(self.fn)
234 container = BaseContainer(self.fn)238 self.assertCountEqual(
235 container._unpack_dir = self.unpack_dir239 container.get_files_list(),
236 self.assertCountEqual(240 self.expected_files,
237 container.get_files_list(),241 )
238 self.expected_files,
239 )
240 except ContainerException:
241 self.fail("An unexpected error occurred while getting files list")
242242
243 def test_get_files_list_abs__happy(self):243 def test_get_files_list_abs__happy(self):
244 try:244 container = BaseContainer(self.fn)
245 container = BaseContainer(self.fn)245 self.assertCountEqual(
246 container._unpack_dir = self.unpack_dir246 container.get_files_list(abs=True),
247 self.assertCountEqual(247 [os.path.join(container.unpack_dir, file) for file in self.expected_files],
248 container.get_files_list(abs=True),248 )
249 [
250 os.path.join(container.unpack_dir, file)
251 for file in self.expected_files
252 ],
253 )
254 except ContainerException:
255 self.fail("An unexpected error occurred while getting files list")
256249
257 def test_files__happy(self):250 def test_files__happy(self):
258 try:251 container = BaseContainer(self.fn)
259 container = BaseContainer(self.fn)252 self.assertCountEqual(
260 container._unpack_dir = self.unpack_dir253 container.files,
261 self.assertCountEqual(254 self.expected_files,
262 container.files,255 )
263 self.expected_files,
264 )
265 except ContainerException:
266 self.fail("An unexpected error occurred while getting files list")
267256
268 # Test get binaries list257 # Test get binaries list
269 def test_get_compiled_binaries_list__happy(self):258 def test_get_compiled_binaries_list__happy(self):
270 try:259 container = BaseContainer(self.fn)
271 container = BaseContainer(self.fn)260 self.assertCountEqual(
272 container._unpack_dir = self.unpack_dir261 container.get_compiled_binaries_list(), self.expected_binaries
273 self.assertCountEqual(262 )
274 container.get_compiled_binaries_list(), self.expected_binaries
275 )
276 except ContainerException:
277 self.fail(
278 "An unexpected error occurred while getting compiled binaries list"
279 )
280263
281 def test_get_compiled_binaries_list_abs__happy(self):264 def test_get_compiled_binaries_list_abs__happy(self):
282 try:265 container = BaseContainer(self.fn)
283 container = BaseContainer(self.fn)266 self.assertCountEqual(
284 container._unpack_dir = self.unpack_dir267 container.get_compiled_binaries_list(abs=True),
285 self.assertCountEqual(268 [
286 container.get_compiled_binaries_list(abs=True),269 os.path.join(container.unpack_dir, file)
287 [270 for file in self.expected_binaries
288 os.path.join(container.unpack_dir, file)271 ],
289 for file in self.expected_binaries272 )
290 ],
291 )
292 except ContainerException:
293 self.fail(
294 "An unexpected error occurred while getting compiled binaries list"
295 )
296273
297 def test_bin_files__happy(self):274 def test_bin_files__happy(self):
298 try:275 container = BaseContainer(self.fn)
299 container = BaseContainer(self.fn)276 self.assertCountEqual(container.bin_files, self.expected_binaries)
300 container._unpack_dir = self.unpack_dir277
301 self.assertCountEqual(container.bin_files, self.expected_binaries)278
302 except ContainerException:279class TestContainerException(unittest.TestCase):
303 self.fail(280 def test_exception__happy(self):
304 "An unexpected error occurred while getting compiled binaries list"281 e = ContainerException("Test exception")
305 )282 self.assertEqual(str(e), "Test exception")
diff --git a/reviewtools/tests/containers/test_squashfs_container.py b/reviewtools/tests/containers/test_squashfs_container.py
index 7d19a77..3241f23 100644
--- a/reviewtools/tests/containers/test_squashfs_container.py
+++ b/reviewtools/tests/containers/test_squashfs_container.py
@@ -22,52 +22,38 @@ class TestSquashfsContainer(unittest.TestCase):
2222
23 # Test initialization23 # Test initialization
24 def test_check_initialization__happy(self):24 def test_check_initialization__happy(self):
25 try:25 SquashfsContainer(self.fn)
26 SquashfsContainer(self.fn)
27 except Exception:
28 self.fail(
29 "An unexpected error occurred during SquashfsContainer initialization with container file"
30 )
3126
32 def test_check_initialization__invalid_format(self):27 def test_check_initialization__invalid_format(self):
28 fd, plain_file = mkstemp(suffix=".snap")
33 with self.assertRaises(ContainerException) as context:29 with self.assertRaises(ContainerException) as context:
34 fd, plain_file = mkstemp()
35 SquashfsContainer(plain_file)30 SquashfsContainer(plain_file)
36 self.assertEqual(31 self.assertEqual(
37 "unsupported package format (not squashfs)", context.exception.value32 "Unsupported package format (not squashfs)", context.exception.value
38 )33 )
39 os.unlink(plain_file)34 os.unlink(plain_file)
4035
41 # Test check format36 # Test check format
42 def test_calculate_unpacked_size__happy(self):37 def test_calculate_unpacked_size__happy(self):
43 try:38 # unpacked size calculated is a bit smaller than actual size as it does not consider that
44 # unpacked size calculated is a bit smaller than actual size as it does not consider that39 # folders require at least one complete block
45 # folders require at least one complete block40 container = SquashfsContainer(self.fn)
46 container = SquashfsContainer(self.fn)41 size = container.calculate_unpacked_size()
47 size = container.calculate_unpacked_size()42 self.assertTrue(isinstance(size, int))
48 self.assertTrue(isinstance(size, int))
49 except Exception:
50 self.fail("An unexpected error occurred during unpacked size calculation")
5143
52 # Test unpack44 # Test unpack
53 def test_unpack__happy(self):45 def test_unpack__happy(self):
54 try:46 container = SquashfsContainer(self.fn)
55 container = SquashfsContainer(self.fn)47 container.unpack()
56 container.unpack()
57 except Exception:
58 self.fail("An unexpected error occurred during unpack")
5948
60 def test_unpack__force(self):49 def test_unpack__force(self):
61 try:50 container = SquashfsContainer(self.fn)
62 container = SquashfsContainer(self.fn)51 container.unpack()
63 container.unpack()52 container.unpack(force=True)
64 container.unpack(force=True)
65 except Exception:
66 self.fail("An unexpected error occurred during unpack")
6753
68 def test_unpack__no_force(self):54 def test_unpack__no_force(self):
55 container = SquashfsContainer(self.fn)
56 container.unpack()
69 with self.assertRaises(ContainerException) as context:57 with self.assertRaises(ContainerException) as context:
70 container = SquashfsContainer(self.fn)
71 container.unpack()
72 container.unpack()58 container.unpack()
73 self.assertTrue(" exists. Aborting." in context.exception.value)59 self.assertTrue(" exists. Aborting." in context.exception.value)

Subscribers

People subscribed via source and target branches