Skip to content

Commit

Permalink
Unit tests Recipe download feature
Browse files Browse the repository at this point in the history
Currently unit tests the following:

- `Recipe.download_if_necessary()`
- `Recipe.download()`

Next up is `Recipe.download_file()`. This is more difficult and will be
addressed in subsequent pull request.
  • Loading branch information
AndreMiras committed Jul 31, 2019
1 parent e21cd8b commit 721e7c5
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
4 changes: 2 additions & 2 deletions pythonforandroid/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ def report_hook(index, blksize, size):
while True:
try:
urlretrieve(url, target, report_hook)
except OSError as e:
except OSError:
attempts += 1
if attempts >= 5:
raise e
raise
stdout.write('Download failed retrying in a second...')
time.sleep(1)
continue
Expand Down
64 changes: 64 additions & 0 deletions tests/test_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,28 @@
import types
import unittest
import warnings
import mock
from backports import tempfile
from pythonforandroid.build import Context
from pythonforandroid.recipe import Recipe, import_recipe


def patch_logger(level):
return mock.patch('pythonforandroid.recipe.{}'.format(level))


def patch_logger_info():
return patch_logger('info')


def patch_logger_debug():
return patch_logger('debug')


class DummyRecipe(Recipe):
pass


class TestRecipe(unittest.TestCase):

def test_recipe_dirs(self):
Expand Down Expand Up @@ -58,3 +76,49 @@ def test_import_recipe(self):
module = import_recipe(name, pathname)
assert module is not None
assert recorded_warnings == []

def test_download_if_necessary(self):
"""
Download should happen via `Recipe.download()` only if the recipe
specific environment variable is not set.
"""
# download should happen as the environment variable is not set
recipe = DummyRecipe()
with mock.patch.object(Recipe, 'download') as m_download:
recipe.download_if_necessary()
assert m_download.call_args_list == [mock.call()]
# after setting it the download should be skipped
env_var = 'P4A_test_recipe_DIR'
env_dict = {env_var: '1'}
with mock.patch.object(Recipe, 'download') as m_download, mock.patch.dict(os.environ, env_dict):
recipe.download_if_necessary()
assert m_download.call_args_list == []

def test_download(self):
"""
Verifies the actual download gets triggered when the URL is set.
"""
# test with no URL set
recipe = DummyRecipe()
with patch_logger_info() as m_info:
recipe.download()
assert m_info.call_args_list == [
mock.call('Skipping test_recipe download as no URL is set')]
# when the URL is set `Recipe.download_file()` should be called
filename = 'Python-3.7.4.tgz'
url = 'https://www.python.org/ftp/python/3.7.4/{}'.format(filename)
recipe._url = url
recipe.ctx = Context()
with (
patch_logger_debug()) as m_debug, (
mock.patch.object(Recipe, 'download_file')) as m_download_file, (
mock.patch('pythonforandroid.recipe.sh.touch')) as m_touch, (
tempfile.TemporaryDirectory()) as temp_dir:
recipe.ctx.setup_dirs(temp_dir)
recipe.download()
assert m_download_file.call_args_list == [mock.call(url, filename)]
assert m_debug.call_args_list == [
mock.call(
'Downloading test_recipe from '
'https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz')]
assert m_touch.call_count == 1
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ deps =
pytest
virtualenv
py3: coveralls
backports.tempfile
# makes it possible to override pytest args, e.g.
# tox -- tests/test_graph.py
commands = pytest {posargs:tests/}
Expand Down

0 comments on commit 721e7c5

Please sign in to comment.