python-tuf/tests/test_fetcher.py
Teodora Sechkova 93c6573008
Apply the new code style to fetcher docstrings
Ensure that the newly added files' docstrings adhere to the
recently adopted code style guideline (#1232).

Small code style improvements in comments and imports.

Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
2021-02-24 11:41:35 +02:00

133 lines
3.9 KiB
Python

#!/usr/bin/env python
# Copyright 2021, New York University and the TUF contributors
# SPDX-License-Identifier: MIT OR Apache-2.0
"""Unit test for RequestsFetcher.
"""
# Help with Python 2 compatibility, where the '/' operator performs
# integer division.
from __future__ import division
import logging
import os
import io
import sys
import unittest
import tempfile
import math
import tuf
import tuf.exceptions
import tuf.requests_fetcher
import tuf.unittest_toolbox as unittest_toolbox
from tests import utils
logger = logging.getLogger(__name__)
class TestFetcher(unittest_toolbox.Modified_TestCase):
def setUp(self):
"""
Create a temporary file and launch a simple server in the
current working directory.
"""
unittest_toolbox.Modified_TestCase.setUp(self)
# Making a temporary file.
current_dir = os.getcwd()
target_filepath = self.make_temp_data_file(directory=current_dir)
self.target_fileobj = open(target_filepath, 'r')
self.file_contents = self.target_fileobj.read()
self.file_length = len(self.file_contents)
# Launch a SimpleHTTPServer (serves files in the current dir).
self.server_process_handler = utils.TestServerProcess(log=logger)
rel_target_filepath = os.path.basename(target_filepath)
self.url = 'http://' + utils.TEST_HOST_ADDRESS + ':' \
+ str(self.server_process_handler.port) + '/' + rel_target_filepath
# Create a temporary file where the target file chunks are written
# during fetching
self.temp_file = tempfile.TemporaryFile()
self.fetcher = tuf.requests_fetcher.RequestsFetcher()
# Stop server process and perform clean up.
def tearDown(self):
unittest_toolbox.Modified_TestCase.tearDown(self)
# Cleans the resources and flush the logged lines (if any).
self.server_process_handler.clean()
self.target_fileobj.close()
self.temp_file.close()
# Test: Normal case.
def test_fetch(self):
for chunk in self.fetcher.fetch(self.url, self.file_length):
self.temp_file.write(chunk)
self.temp_file.seek(0)
temp_file_data = self.temp_file.read().decode('utf-8')
self.assertEqual(self.file_contents, temp_file_data)
# Test if fetcher downloads file up to a required length
def test_fetch_restricted_length(self):
for chunk in self.fetcher.fetch(self.url, self.file_length-4):
self.temp_file.write(chunk)
self.temp_file.seek(0, io.SEEK_END)
self.assertEqual(self.temp_file.tell(), self.file_length-4)
# Test that fetcher does not download more than actual file length
def test_fetch_upper_length(self):
for chunk in self.fetcher.fetch(self.url, self.file_length+4):
self.temp_file.write(chunk)
self.temp_file.seek(0, io.SEEK_END)
self.assertEqual(self.temp_file.tell(), self.file_length)
# Test incorrect URL parsing
def test_url_parsing(self):
with self.assertRaises(tuf.exceptions.URLParsingError):
self.fetcher.fetch(self.random_string(), self.file_length)
# Test: Normal case with url data downloaded in more than one chunk
def test_fetch_in_chunks(self):
# Set smaller chunk size to ensure that the file will be downloaded
# in more than one chunk
default_chunk_size = tuf.settings.CHUNK_SIZE
tuf.settings.CHUNK_SIZE = 4
# expected_chunks_count: 3
expected_chunks_count = math.ceil(self.file_length/tuf.settings.CHUNK_SIZE)
self.assertEqual(expected_chunks_count, 3)
chunks_count = 0
for chunk in self.fetcher.fetch(self.url, self.file_length):
self.temp_file.write(chunk)
chunks_count+=1
self.temp_file.seek(0)
temp_file_data = self.temp_file.read().decode('utf-8')
self.assertEqual(self.file_contents, temp_file_data)
# Check that we calculate chunks as expected
self.assertEqual(chunks_count, expected_chunks_count)
# Restore default settings
tuf.settings.CHUNK_SIZE = default_chunk_size
# Run unit test.
if __name__ == '__main__':
utils.configure_test_logging(sys.argv)
unittest.main()