python-tuf/tests/test_fetcher.py
Jussi Kukkonen 1902975d0e tests: Kill processes before deleting temp files
These tests seem to try to remove temp files before the processes
using those files had stopped. This likely lead to an error (and
dangling temp files) on Windows, but Modified_Testcase hides the error

Make sure temp directories are removed as the last thing in teardown.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-04-12 11:55:37 +03:00

131 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.
"""
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):
# Cleans the resources and flush the logged lines (if any).
self.server_process_handler.clean()
self.target_fileobj.close()
self.temp_file.close()
# Remove temporary directory
unittest_toolbox.Modified_TestCase.tearDown(self)
# 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()