tls-canary/tests/firefox_downloader_test.py

95 строки
3.8 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import pytest
from time import sleep
import unittest.mock as mock
import tlscanary.tools.firefox_downloader as fd
def test_firefox_downloader_instance(tmpdir):
"""FirefoxDownloader instances sanity check"""
fdl = fd.FirefoxDownloader(tmpdir)
build_list, platform_list, test_default, base_default = fdl.list()
assert "nightly" in build_list and "release" in build_list, "build list looks sane"
assert "linux" in platform_list and "osx" in platform_list, "platform list looks sane"
assert test_default in build_list and base_default in build_list, "defaults are valid builds"
def test_firefox_downloader_exceptions(tmpdir):
"""Test handling of invalid parameters"""
fdl = fd.FirefoxDownloader(tmpdir)
build_list, platform_list, test_default, base_default = fdl.list()
assert "foobar" not in build_list and "foobar" not in platform_list
with pytest.raises(Exception):
fdl.download("foobar", platform_list[0])
with pytest.raises(Exception):
fdl.download(test_default, "foobar")
@mock.patch('urllib.request.urlopen')
@mock.patch('sys.stdout') # to silence progress bar
def test_firefox_downloader_downloading(mock_stdout, mock_urlopen, tmpdir):
"""Test the download function"""
del mock_stdout
# This test is checking caching behavior, hence:
# Using a test-specific test directory to not wipe regular cache.
test_tmp_dir = str(tmpdir.join("download_test"))
fdl = fd.FirefoxDownloader(test_tmp_dir, cache_timeout=1)
mock_req = mock.Mock()
mock_read = mock.Mock(side_effect=(b"foo", b"bar", None))
mock_info = mock.Mock()
mock_get = mock.Mock(return_value="6")
mock_info.return_value = mock.Mock(get=mock_get)
mock_req.info = mock_info
mock_req.read = mock_read
mock_urlopen.return_value = mock_req
output_file_name = fdl.download("nightly", "linux", use_cache=True)
assert mock_get.call_args_list == [(("Content-Length",),)],\
"only checks content length (assumed by test mock)"
expected_url = """https://download.mozilla.org/?product=firefox-nightly-latest&os=linux64&lang=en-US"""
assert mock_urlopen.call_args_list == [((expected_url,),)], "downloads the expected URL"
assert len(mock_read.call_args_list) == 3, "properly calls read()"
assert output_file_name.endswith("firefox-nightly_linux.tar.bz2"), "uses expected file name"
assert output_file_name.startswith(test_tmp_dir), "writes file to expected directory"
assert os.path.isfile(output_file_name), "creates proper file"
with open(output_file_name, "rb") as f:
content = f.read()
assert content == b"foobar", "downloads expected content"
# Test caching by re-downloading
mock_read.reset_mock()
mock_read.side_effect = (b"foo", b"bar", None)
second_output_file_name = fdl.download("nightly", "linux", use_cache=True)
assert not mock_read.called, "does not re-download"
assert output_file_name == second_output_file_name, "uses cached file"
# Test purging on obsolete cache. Cache is purged on fdl init.
sleep(1.1)
mock_read.reset_mock()
mock_read.side_effect = (b"foo", b"bar", None)
fdl = fd.FirefoxDownloader(test_tmp_dir, cache_timeout=1)
fdl.download("nightly", "linux", use_cache=True)
assert mock_read.called, "re-downloads when cache is stale"
# Test caching when file changes upstream (checks file size).
mock_get.reset_mock()
mock_get.return_value = "7"
mock_read.reset_mock()
mock_read.side_effect = (b"foo", b"barr", None)
fdl.download("nightly", "linux", use_cache=True)
assert mock_read.called, "re-downloads when upstream changes"