Skip to content

Commit

Permalink
Add unit tests for apps ci package
Browse files Browse the repository at this point in the history
This commit adds unit tests for apps ci package testing various aspects of the different scripts and utils we have which are used for development and deploying of apps.
  • Loading branch information
sonicaj committed Oct 19, 2024
1 parent 5002d51 commit 50c8a9f
Show file tree
Hide file tree
Showing 8 changed files with 514 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ jobs:
PYTHONPATH=$(pwd) pytest apps_validation/pytest/unit/
PYTHONPATH=$(pwd) pytest catalog_reader/pytest/unit/
PYTHONPATH=$(pwd) pytest apps_schema/pytest/unit/
PYTHONPATH=$(pwd) pytest apps_ci/pytest/unit/
23 changes: 23 additions & 0 deletions apps_ci/pytest/unit/test_get_apps_to_publish.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import collections

import pytest

from apps_ci.scripts.catalog_update import get_apps_to_publish


@pytest.mark.parametrize('isdir,', [
[True, True, True],
[True, False, False],
[False, False, False]
])
def test_get_apps_to_publish(mocker, isdir):
mocker.patch('os.listdir', side_effect=[
['community'],
['app1', 'app2']
])
mocker.patch('os.path.isdir', side_effect=isdir)
mocker.patch('apps_ci.scripts.catalog_update.version_has_been_bumped', return_value=True)
mocker.patch('apps_ci.scripts.catalog_update.get_app_version', return_value='1.0.1')

result = get_apps_to_publish('/path/to/catalog')
assert isinstance(result, collections.defaultdict)
55 changes: 55 additions & 0 deletions apps_ci/pytest/unit/test_get_changed_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import collections
import os

import pytest

from apps_ci.git import get_changed_apps
from apps_exceptions import CatalogDoesNotExist


@pytest.mark.parametrize('path, base_branch, path_exists, is_train_valid, should_work', [
(
'/valid/path/to/catalog',
'master',
True,
True,
True
),
(
'/valid/path/to/catalog',
'master',
True,
False,
True
),
(
'/invalid/path/to/catalog',
'master',
False,
False,
False
)
])
def test_get_changed_apps(mocker, path, base_branch, path_exists, is_train_valid, should_work):
mocker.patch('os.path.exists', return_value=path_exists)
mock_subprocess_run = mocker.patch('subprocess.run')
mock_subprocess_run.return_value.stdout = b'''
ix-dev/community/actual-budget/1.1.9/values.yaml
ix-dev/community/another-app/1.0.0/metadata.yaml
ix-dev/community/another-app/1.0.0/upgrade_info.json
'''
mock_get_ci_development_directory = mocker.patch('catalog_reader.dev_directory.get_ci_development_directory')
mock_get_ci_development_directory.return_value = '/mock/ci/development'
mocker.patch('apps_ci.git.is_train_valid', return_value=is_train_valid)
if should_work:
result = get_changed_apps(path, base_branch)

os.path.exists.assert_called_once_with(path)
mock_subprocess_run.assert_called_once_with(
['git', '-C', path, '--no-pager', 'diff', '--name-only', base_branch],
capture_output=True, check=True,
)
assert isinstance(result, collections.defaultdict)
else:
with pytest.raises(CatalogDoesNotExist):
get_changed_apps(path, base_branch)
97 changes: 97 additions & 0 deletions apps_ci/pytest/unit/test_is_main_dep.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import pathlib
import textwrap

import pytest

from apps_ci.images_info import is_main_dep
from apps_exceptions import AppDoesNotExist, ValidationErrors


@pytest.mark.parametrize('yaml_data, dep_name, is_dir, is_file, should_work', [
(
textwrap.dedent(
'''
images:
image:
repository: ABC
tag: some_tag
db_image:
repository: ABC
tag: some_tag
'''
),
'ABC',
True,
True,
True
),
(
textwrap.dedent(
'''
images:
image:
repository: ABC
tag: some_tag
db_image:
repository: ABC
tag: some_tag
'''
),
'ABC',
False,
False,
False
),
(
textwrap.dedent(
'''
images:
image:
repository: some_repo
tag: some_tag
db_image:
repository: some_repo
tag: some_tag
'''
),
'ABC',
True,
True,
False
),
(
textwrap.dedent(
'''
images:
image:
repository: ABC
tag: some_tag
db_image:
repository: ABC
tag: some_tag
'''
),
'ABC',
True,
False,
False
),
])
def test_is_main_dep(mocker, yaml_data, dep_name, is_dir, is_file, should_work):
mock_file = mocker.mock_open(read_data=yaml_data)
mocker.patch('builtins.open', mock_file)
mocker.patch('pathlib.Path.is_dir', return_value=is_dir)
mocker.patch('pathlib.Path.is_file', return_value=is_file)
if should_work:
result = is_main_dep(pathlib.Path('/valid/path'), dep_name)
assert result is True
elif dep_name not in yaml_data:
result = is_main_dep(pathlib.Path('/valid/path'), dep_name)
assert result is False
else:
with pytest.raises((AppDoesNotExist, ValidationErrors)):
is_main_dep(pathlib.Path('/valid/path'), dep_name)
56 changes: 56 additions & 0 deletions apps_ci/pytest/unit/test_publish_updated_apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import collections

import pytest

from apps_ci.scripts.catalog_update import publish_updated_apps


@pytest.mark.parametrize('version, app_name, isdir, listdir_ver, should_work', [
(
'1.0.1',
'test_app',
[True, True, True],
['1.0.0', '1.0.1'],
True
),
(
'1.0.0',
'test_app',
[False],
['1.0.0'],
False
),
(
'1.0.1',
'test_app',
[True, True, True],
['1.0.0'],
True
),
])
def test_publish_updated_apps(mocker, capsys, version, app_name, isdir, listdir_ver, should_work):
to_publish_apps = collections.defaultdict(list)
to_publish_apps[version].append({'name': app_name, 'version': version})
mocker.patch('os.path.isdir', side_effect=isdir)
mocker.patch('os.makedirs')
mocker.patch('os.listdir', return_value=listdir_ver)
mocker.patch('os.path.exists', side_effect=[False, True])
mocker.patch('shutil.copy')
mocker.patch('shutil.copytree')
mocker.patch('shutil.move')
mocker.patch('shutil.rmtree')

mocker.patch('apps_ci.scripts.catalog_update.get_apps_to_publish', return_value=to_publish_apps)
mocker.patch('apps_ci.scripts.catalog_update.get_to_keep_versions', return_value=[version])

if should_work:
publish_updated_apps('/path/to/catalog')
expected_out = (
f'\x1b[92mOK\x1b[0m]\tPublished '
f'\'{app_name}\' having \'{version}\' version '
f'to \'{version}\' train successfully!'
)
assert expected_out in capsys.readouterr().out

else:
assert publish_updated_apps('/path/to/catalog') is None
75 changes: 75 additions & 0 deletions apps_ci/pytest/unit/test_rename_versioned_dir.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import pathlib

import pytest

from apps_ci.version_bump import rename_versioned_dir, bump_version
from apps_exceptions import AppDoesNotExist, ValidationErrors


@pytest.mark.parametrize('version, new_version, train_name, is_dir, should_work', [
(
'1.0.0',
'1.0.1',
'community',
[True, False, False],
True
),
(
'1.0',
'1.0.1',
'community',
[True, False, False],
False
),
(
'1.0.0',
'1.0.1',
'community',
[False, True, True],
False
),
(
'1.0.0',
'1.0.1',
'stable',
[True, True, True],
False
),
])
def test_rename_versioned_dir(mocker, version, new_version, train_name, is_dir, should_work):
mocker.patch('pathlib.Path.is_dir', side_effect=is_dir)
mocker.patch('pathlib.Path.rename', return_value=None)
if should_work:
result = rename_versioned_dir(version, new_version, train_name, pathlib.Path('/valid/path'))
assert result is None
else:
with pytest.raises((AppDoesNotExist, ValidationErrors)):
rename_versioned_dir(version, new_version, train_name, pathlib.Path('/valid/path'))


@pytest.mark.parametrize('version, bump, expected', [
(
'1.0.0',
'minor',
'1.1.0'
),
(
'1.0.0',
'major',
'2.0.0'
),
(
'1.0.0',
'patch',
'1.0.1'
)
])
def test_bump_version(version, bump, expected):
result = bump_version(version, bump)
assert result == expected


def test_bump_version_Fail():
with pytest.raises(ValueError):
bump_version('1.0', 'minor')
73 changes: 73 additions & 0 deletions apps_ci/pytest/unit/test_update_app_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import pytest

from apps_ci.scripts.bump_version import update_app_version
from apps_exceptions import AppDoesNotExist, ValidationErrors


@pytest.mark.parametrize('path, bump, dep, dep_version, yaml, expected_out', [
(
'/valid/path',
'minor',
'some_repo',
'1.0.2',
'''
version: 1.0.0
icon_url: https://www.chia.net/wp-content/uploads/2022/09/chia-logo.svg
sources:
- https://hub.docker.com/r/emby/embyserver
''',
'\x1b[92mOK\x1b[0m]\tUpdated app \'path\', '
'set app_version to \'1.0.2\' and bumped version from '
'\'1.0.0\' to \'1.1.0\'\n'
)
])
def test_update_app_version(mocker, capsys, path, bump, dep, dep_version, yaml, expected_out):
mocker.patch('os.path.exists', return_value=True)
mocker.patch('pathlib.Path.is_file', return_value=True)
mock_file = mocker.mock_open(read_data=yaml)
mocker.patch('builtins.open', mock_file)
mocker.patch('apps_ci.scripts.bump_version.is_main_dep', return_value=True)
mocker.patch('apps_ci.scripts.bump_version.rename_versioned_dir', return_value=None)
update_app_version(path, bump, dep, dep_version)
assert expected_out in capsys.readouterr().out


@pytest.mark.parametrize('path, bump, dep, dep_version, exists, is_file, yaml', [
(
'/valid/path',
'minor',
'some_repo',
'1.0.2',
False,
True,
'''
version: 1.0.0
icon_url: https://www.chia.net/wp-content/uploads/2022/09/chia-logo.svg
sources:
- https://hub.docker.com/r/emby/embyserver
'''
),
(
'/valid/path',
'minor',
'some_repo',
'1.0.2',
True,
False,
'''
version: 1.0.0
icon_url: https://www.chia.net/wp-content/uploads/2022/09/chia-logo.svg
sources:
- https://hub.docker.com/r/emby/embyserver
'''
),
])
def test_update_app_version_Errors(mocker, path, bump, dep, dep_version, exists, is_file, yaml):
mocker.patch('os.path.exists', return_value=exists)
mocker.patch('pathlib.Path.is_file', return_value=is_file)
mock_file = mocker.mock_open(read_data=yaml)
mocker.patch('builtins.open', mock_file)
mocker.patch('apps_ci.scripts.bump_version.is_main_dep', return_value=True)
mocker.patch('apps_ci.scripts.bump_version.rename_versioned_dir', return_value=None)
with pytest.raises((AppDoesNotExist, ValidationErrors)):
update_app_version(path, bump, dep, dep_version)
Loading

0 comments on commit 50c8a9f

Please sign in to comment.