Skip to content

Commit ce10b69

Browse files
committed
Address pylint warnings on tests for the new code
Address or disable pylint warnings raised on all test files inside the "tests/" directory testing the code of the new implementation. Signed-off-by: Martin Vrachev <[email protected]>
1 parent 5d3b0d0 commit ce10b69

8 files changed

+119
-77
lines changed

tests/repository_simulator.py

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
Timestamp,
7474
)
7575
from tuf.api.serialization.json import JSONSerializer
76-
from tuf.exceptions import FetcherHTTPError, RepositoryError
76+
from tuf.exceptions import FetcherHTTPError
7777
from tuf.ngclient.fetcher import FetcherInterface
7878

7979
logger = logging.getLogger(__name__)
@@ -83,13 +83,16 @@
8383

8484
@dataclass
8585
class RepositoryTarget:
86-
"""Contains actual target data and the related target metadata"""
86+
"""Contains actual target data and the related target metadata."""
8787

8888
data: bytes
8989
target_file: TargetFile
9090

9191

9292
class RepositorySimulator(FetcherInterface):
93+
"""Simulates a repository that can be used for testing."""
94+
95+
# pylint: disable=too-many-instance-attributes
9396
def __init__(self):
9497
self.md_root: Metadata[Root] = None
9598
self.md_timestamp: Metadata[Timestamp] = None
@@ -136,6 +139,7 @@ def targets(self) -> Targets:
136139
return self.md_targets.signed
137140

138141
def all_targets(self) -> Iterator[Tuple[str, Targets]]:
142+
"""Yield role name and signed portion of targets one by one."""
139143
yield "targets", self.md_targets.signed
140144
for role, md in self.md_delegates.items():
141145
yield role, md.signed
@@ -151,7 +155,7 @@ def add_signer(self, role: str, signer: SSlibSigner):
151155
self.signers[role][signer.key_dict["keyid"]] = signer
152156

153157
def _initialize(self):
154-
"""Setup a minimal valid repository"""
158+
"""Setup a minimal valid repository."""
155159

156160
targets = Targets(1, SPEC_VER, self.safe_expiry, {}, None)
157161
self.md_targets = Metadata(targets, OrderedDict())
@@ -176,7 +180,7 @@ def _initialize(self):
176180
self.publish_root()
177181

178182
def publish_root(self):
179-
"""Sign and store a new serialized version of root"""
183+
"""Sign and store a new serialized version of root."""
180184
self.md_root.signatures.clear()
181185
for signer in self.signers["root"].values():
182186
self.md_root.sign(signer, append=True)
@@ -185,6 +189,9 @@ def publish_root(self):
185189
logger.debug("Published root v%d", self.root.version)
186190

187191
def fetch(self, url: str) -> Iterator[bytes]:
192+
"""Fetches data from the given url and returns an Iterator (or yields
193+
bytes).
194+
"""
188195
if not self.root.consistent_snapshot:
189196
raise NotImplementedError("non-consistent snapshot not supported")
190197
path = parse.urlparse(url).path
@@ -209,15 +216,20 @@ def fetch(self, url: str) -> Iterator[bytes]:
209216
else:
210217
raise FetcherHTTPError(f"Unknown path '{path}'", 404)
211218

212-
def _fetch_target(self, target_path: str, hash: Optional[str]) -> bytes:
213-
"""Return data for 'target_path', checking 'hash' if it is given.
219+
def _fetch_target(
220+
self, target_path: str, target_hash: Optional[str]
221+
) -> bytes:
222+
"""Return data for 'target_path', checking 'target_hash' if it is given.
214223
215-
If hash is None, then consistent_snapshot is not used
224+
If hash is None, then consistent_snapshot is not used.
216225
"""
217226
repo_target = self.target_files.get(target_path)
218227
if repo_target is None:
219228
raise FetcherHTTPError(f"No target {target_path}", 404)
220-
if hash and hash not in repo_target.target_file.hashes.values():
229+
if (
230+
target_hash
231+
and target_hash not in repo_target.target_file.hashes.values()
232+
):
221233
raise FetcherHTTPError(f"hash mismatch for {target_path}", 404)
222234

223235
logger.debug("fetched target %s", target_path)
@@ -228,41 +240,41 @@ def _fetch_metadata(
228240
) -> bytes:
229241
"""Return signed metadata for 'role', using 'version' if it is given.
230242
231-
If version is None, non-versioned metadata is being requested
243+
If version is None, non-versioned metadata is being requested.
232244
"""
233245
if role == "root":
234246
# return a version previously serialized in publish_root()
235247
if version is None or version > len(self.signed_roots):
236248
raise FetcherHTTPError(f"Unknown root version {version}", 404)
237-
logger.debug("fetched root version %d", role, version)
249+
logger.debug("fetched root version %d", version)
238250
return self.signed_roots[version - 1]
251+
252+
# sign and serialize the requested metadata
253+
if role == "timestamp":
254+
md: Metadata = self.md_timestamp
255+
elif role == "snapshot":
256+
md = self.md_snapshot
257+
elif role == "targets":
258+
md = self.md_targets
239259
else:
240-
# sign and serialize the requested metadata
241-
if role == "timestamp":
242-
md: Metadata = self.md_timestamp
243-
elif role == "snapshot":
244-
md = self.md_snapshot
245-
elif role == "targets":
246-
md = self.md_targets
247-
else:
248-
md = self.md_delegates[role]
249-
250-
if md is None:
251-
raise FetcherHTTPError(f"Unknown role {role}", 404)
252-
if version is not None and version != md.signed.version:
253-
raise FetcherHTTPError(f"Unknown {role} version {version}", 404)
254-
255-
md.signatures.clear()
256-
for signer in self.signers[role].values():
257-
md.sign(signer, append=True)
258-
259-
logger.debug(
260-
"fetched %s v%d with %d sigs",
261-
role,
262-
md.signed.version,
263-
len(self.signers[role]),
264-
)
265-
return md.to_bytes(JSONSerializer())
260+
md = self.md_delegates[role]
261+
262+
if md is None:
263+
raise FetcherHTTPError(f"Unknown role {role}", 404)
264+
if version is not None and version != md.signed.version:
265+
raise FetcherHTTPError(f"Unknown {role} version {version}", 404)
266+
267+
md.signatures.clear()
268+
for signer in self.signers[role].values():
269+
md.sign(signer, append=True)
270+
271+
logger.debug(
272+
"fetched %s v%d with %d sigs",
273+
role,
274+
md.signed.version,
275+
len(self.signers[role]),
276+
)
277+
return md.to_bytes(JSONSerializer())
266278

267279
def _compute_hashes_and_length(
268280
self, role: str
@@ -274,6 +286,9 @@ def _compute_hashes_and_length(
274286
return hashes, len(data)
275287

276288
def update_timestamp(self):
289+
"""Update timestamp and assign snapshot version to snapshot_meta
290+
version.
291+
"""
277292
self.timestamp.snapshot_meta.version = self.snapshot.version
278293

279294
if self.compute_metafile_hashes_length:
@@ -284,6 +299,7 @@ def update_timestamp(self):
284299
self.timestamp.version += 1
285300

286301
def update_snapshot(self):
302+
"""Update snapshot, assign targets versions and update timestamp."""
287303
for role, delegate in self.all_targets():
288304
hashes = None
289305
length = None
@@ -298,6 +314,7 @@ def update_snapshot(self):
298314
self.update_timestamp()
299315

300316
def add_target(self, role: str, data: bytes, path: str):
317+
"""Create a target from data and add it to the target_files."""
301318
if role == "targets":
302319
targets = self.targets
303320
else:
@@ -316,6 +333,7 @@ def add_delegation(
316333
paths: Optional[List[str]],
317334
hash_prefixes: Optional[List[str]],
318335
):
336+
"""Add delegated target role to the repository."""
319337
if delegator_name == "targets":
320338
delegator = self.targets
321339
else:
@@ -347,17 +365,17 @@ def write(self):
347365
print(f"Repository Simulator dumps in {self.dump_dir}")
348366

349367
self.dump_version += 1
350-
dir = os.path.join(self.dump_dir, str(self.dump_version))
351-
os.makedirs(dir)
368+
dest_dir = os.path.join(self.dump_dir, str(self.dump_version))
369+
os.makedirs(dest_dir)
352370

353371
for ver in range(1, len(self.signed_roots) + 1):
354-
with open(os.path.join(dir, f"{ver}.root.json"), "wb") as f:
372+
with open(os.path.join(dest_dir, f"{ver}.root.json"), "wb") as f:
355373
f.write(self._fetch_metadata("root", ver))
356374

357375
for role in ["timestamp", "snapshot", "targets"]:
358-
with open(os.path.join(dir, f"{role}.json"), "wb") as f:
376+
with open(os.path.join(dest_dir, f"{role}.json"), "wb") as f:
359377
f.write(self._fetch_metadata(role))
360378

361-
for role in self.md_delegates.keys():
362-
with open(os.path.join(dir, f"{role}.json"), "wb") as f:
379+
for role in self.md_delegates:
380+
with open(os.path.join(dest_dir, f"{role}.json"), "wb") as f:
363381
f.write(self._fetch_metadata(role))

tests/test_api.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444

4545

4646
class TestMetadata(unittest.TestCase):
47+
"""Tests for public API of all classes in 'tuf/api/metadata.py'."""
48+
4749
@classmethod
4850
def setUpClass(cls):
4951
# Create a temporary directory to store the repository, metadata, and
@@ -155,8 +157,8 @@ def test_to_from_bytes(self):
155157
self.assertEqual(metadata_obj_2.to_bytes(), obj_bytes)
156158

157159
def test_sign_verify(self):
158-
root_path = os.path.join(self.repo_dir, "metadata", "root.json")
159-
root = Metadata[Root].from_file(root_path).signed
160+
path = os.path.join(self.repo_dir, "metadata", "root.json")
161+
root = Metadata[Root].from_file(path).signed
160162

161163
# Locate the public keys we need from root
162164
targets_keyid = next(iter(root.roles["targets"].keyids))
@@ -203,7 +205,8 @@ def test_sign_verify(self):
203205
with self.assertRaises(exceptions.UnsignedMetadataError):
204206
targets_key.verify_signature(md_obj)
205207

206-
# Test failure on unknown scheme (securesystemslib UnsupportedAlgorithmError)
208+
# Test failure on unknown scheme (securesystemslib
209+
# UnsupportedAlgorithmError)
207210
scheme = timestamp_key.scheme
208211
timestamp_key.scheme = "foo"
209212
with self.assertRaises(exceptions.UnsignedMetadataError):
@@ -231,8 +234,8 @@ def test_sign_verify(self):
231234
sig.signature = correct_sig
232235

233236
def test_metadata_base(self):
234-
# Use of Snapshot is arbitrary, we're just testing the base class features
235-
# with real data
237+
# Use of Snapshot is arbitrary, we're just testing the base class
238+
# features with real data
236239
snapshot_path = os.path.join(self.repo_dir, "metadata", "snapshot.json")
237240
md = Metadata.from_file(snapshot_path)
238241

@@ -458,6 +461,7 @@ def test_root_add_key_and_remove_key(self):
458461
root.signed.remove_key("nosuchrole", keyid)
459462

460463
def test_is_target_in_pathpattern(self):
464+
# pylint: disable=protected-access
461465
supported_use_cases = [
462466
("foo.tgz", "foo.tgz"),
463467
("foo.tgz", "*"),
@@ -492,7 +496,7 @@ def test_metadata_targets(self):
492496
targets_path = os.path.join(self.repo_dir, "metadata", "targets.json")
493497
targets = Metadata[Targets].from_file(targets_path)
494498

495-
# Create a fileinfo dict representing what we expect the updated data to be
499+
# Create a fileinfo dict representing the expected updated data.
496500
filename = "file2.txt"
497501
hashes = {
498502
"sha256": "141f740f53781d1ca54b8a50af22cbf74e44c21a998fa2a8a05aaac2c002886b",

tests/test_fetcher.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
import tuf
1818
import tuf.exceptions
1919
import tuf.requests_fetcher
20-
import tuf.unittest_toolbox as unittest_toolbox
2120
from tests import utils
21+
from tuf import unittest_toolbox
2222

2323
logger = logging.getLogger(__name__)
2424

2525

2626
class TestFetcher(unittest_toolbox.Modified_TestCase):
27+
"""Unit tests for RequestFetcher."""
28+
2729
def setUp(self):
2830
"""
2931
Create a temporary file and launch a simple server in the
@@ -35,9 +37,9 @@ def setUp(self):
3537
# Making a temporary file.
3638
current_dir = os.getcwd()
3739
target_filepath = self.make_temp_data_file(directory=current_dir)
38-
self.target_fileobj = open(target_filepath, "r")
39-
self.file_contents = self.target_fileobj.read()
40-
self.file_length = len(self.file_contents)
40+
with open(target_filepath, "r", encoding="utf8") as target_fileobj:
41+
self.file_contents = target_fileobj.read()
42+
self.file_length = len(self.file_contents)
4143

4244
# Launch a SimpleHTTPServer (serves files in the current dir).
4345
self.server_process_handler = utils.TestServerProcess(log=logger)
@@ -54,6 +56,7 @@ def setUp(self):
5456

5557
# Create a temporary file where the target file chunks are written
5658
# during fetching
59+
# pylint: disable-next=consider-using-with
5760
self.temp_file = tempfile.TemporaryFile()
5861
self.fetcher = tuf.requests_fetcher.RequestsFetcher()
5962

@@ -62,7 +65,6 @@ def tearDown(self):
6265
# Cleans the resources and flush the logged lines (if any).
6366
self.server_process_handler.clean()
6467

65-
self.target_fileobj.close()
6668
self.temp_file.close()
6769

6870
# Remove temporary directory

tests/test_fetcher_ng.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727

2828
class TestFetcher(unittest_toolbox.Modified_TestCase):
29+
"""Test RequestsFetcher class."""
30+
2931
@classmethod
3032
def setUpClass(cls):
3133
# Launch a SimpleHTTPServer (serves files in the current dir).
@@ -48,17 +50,21 @@ def setUp(self):
4850
current_dir = os.getcwd()
4951
target_filepath = self.make_temp_data_file(directory=current_dir)
5052

51-
self.target_fileobj = open(target_filepath, "r")
52-
self.file_contents = self.target_fileobj.read()
53-
self.file_length = len(self.file_contents)
53+
with open(target_filepath, "r", encoding="utf8") as target_fileobj:
54+
self.file_contents = target_fileobj.read()
55+
self.file_length = len(self.file_contents)
56+
5457
self.rel_target_filepath = os.path.basename(target_filepath)
55-
self.url = f"http://{utils.TEST_HOST_ADDRESS}:{str(self.server_process_handler.port)}/{self.rel_target_filepath}"
58+
self.url_prefix = (
59+
f"http://{utils.TEST_HOST_ADDRESS}:"
60+
f"{str(self.server_process_handler.port)}"
61+
)
62+
self.url = f"{self.url_prefix}/{self.rel_target_filepath}"
5663

5764
# Instantiate a concrete instance of FetcherInterface
5865
self.fetcher = RequestsFetcher()
5966

6067
def tearDown(self):
61-
self.target_fileobj.close()
6268
# Remove temporary directory
6369
unittest_toolbox.Modified_TestCase.tearDown(self)
6470

@@ -106,7 +112,7 @@ def test_url_parsing(self):
106112
# File not found error
107113
def test_http_error(self):
108114
with self.assertRaises(exceptions.FetcherHTTPError) as cm:
109-
self.url = f"http://{utils.TEST_HOST_ADDRESS}:{str(self.server_process_handler.port)}/non-existing-path"
115+
self.url = f"{self.url_prefix}/non-existing-path"
110116
self.fetcher.fetch(self.url)
111117
self.assertEqual(cm.exception.status_code, 404)
112118

tests/test_metadata_serialization.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232

3333
class TestSerialization(unittest.TestCase):
34+
"""Test serialization for all classes in 'tuf/api/metadata.py'."""
3435

3536
# Snapshot instances with meta = {} are valid, but for a full valid
3637
# repository it's required that meta has at least one element inside it.

tests/test_trusted_metadata_set.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Unit tests for 'tuf/ngclient/_internal/trusted_metadata_set.py'."""
12
import logging
23
import os
34
import sys
@@ -26,16 +27,18 @@
2627

2728
logger = logging.getLogger(__name__)
2829

29-
30+
# pylint: disable=too-many-public-methods
3031
class TestTrustedMetadataSet(unittest.TestCase):
32+
"""Tests for all public API of the TrustedMetadataSet class."""
33+
3134
def modify_metadata(
32-
self, rolename: str, modification_func: Callable[["Signed"], None]
35+
self, rolename: str, modification_func: Callable[[Signed], None]
3336
) -> bytes:
3437
"""Instantiate metadata from rolename type, call modification_func and
3538
sign it again with self.keystore[rolename] signer.
3639
3740
Attributes:
38-
rolename: A denoting the name of the metadata which will be modified.
41+
rolename: Denoting the name of the metadata which will be modified.
3942
modification_func: Function that will be called to modify the signed
4043
portion of metadata bytes.
4144
"""

0 commit comments

Comments
 (0)