Skip to content

Commit

Permalink
test: unit tests for openstack manager
Browse files Browse the repository at this point in the history
  • Loading branch information
yanksyoon committed Mar 11, 2024
1 parent 4a47f2a commit c818eaa
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 0 deletions.
16 changes: 16 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,19 @@ def clouds_yaml_fixture(cloud_name: str) -> dict:
}
}
}


@pytest.fixture(name="multi_clouds_yaml")
def multi_clouds_yaml_fixture(clouds_yaml: dict) -> dict:
"""Testing clouds.yaml with multiple clouds."""
clouds_yaml["clouds"]["unused_cloud"] = {
"auth": {
"auth_url": secrets.token_hex(16),
"project_name": secrets.token_hex(16),
"project_domain_name": secrets.token_hex(16),
"username": secrets.token_hex(16),
"user_domain_name": secrets.token_hex(16),
"password": secrets.token_hex(16),
}
}
return clouds_yaml
184 changes: 184 additions & 0 deletions tests/unit/test_openstack_manager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.
import secrets
from unittest.mock import MagicMock

import keystoneauth1.exceptions
Expand Down Expand Up @@ -29,6 +30,17 @@ def projects_fixture() -> list:
return list(fakes.generate_fake_resources(project.Project, count=3))


def test__create_connection(multi_clouds_yaml: dict, openstack_connect_mock: MagicMock):
"""
arrange: given a cloud config yaml dict with multiple clouds.
act: when _create_connection is called.
assert: connection with first cloud in the config is used.
"""
openstack_manager._create_connection(cloud_config=multi_clouds_yaml)

openstack_connect_mock.assert_called_once_with(CLOUD_NAME)


def test_list_projects(clouds_yaml: dict, openstack_connect_mock: MagicMock, projects):
"""
arrange: Mocked clouds.yaml data.
Expand Down Expand Up @@ -73,3 +85,175 @@ def test_list_projects_missing_credentials_error(
assert "Unauthorized to connect to OpenStack." in str(exc)

openstack_connect_mock.assert_called_once_with(CLOUD_NAME)


def test__build_image_command():
"""
arrange: given a mock Github runner application and proxy config.
act: when _build_image_command is called.
assert: command for build image bash script with args are returned.
"""
test_runner_info = openstack_manager.RunnerApplication(
os="linux",
architecture="x64",
download_url=(test_download_url := "https://testdownloadurl.com"),
filename="test_filename",
temp_download_token=secrets.token_hex(16),
)
test_proxy_config = openstack_manager.ProxyConfig(
http=(test_http_proxy := "http://proxy.test"),
https=(test_https_proxy := "https://proxy.test"),
no_proxy=(test_no_proxy := "http://no.proxy"),
use_aproxy=False,
)

command = openstack_manager._build_image_command(
runner_info=test_runner_info, proxies=test_proxy_config
)
assert command == [
"/usr/bin/bash",
openstack_manager.BUILD_OPENSTACK_IMAGE_SCRIPT_FILENAME,
test_download_url,
test_http_proxy,
test_https_proxy,
test_no_proxy,
f"""[Service]
Environment="HTTP_PROXY=http://proxy.test"
Environment="HTTPS_PROXY=https://proxy.test"
Environment="NO_PROXY=http://no.proxy"
""",
'{"proxies": {"default": {"httpProxy": "http://proxy.test", "httpsProxy": '
'"https://proxy.test", "noProxy": "http://no.proxy"}}}',
], "Unexpected build image command."


def test_build_image_runner_binary_error():
"""
arrange: given a mocked github client get_runner_application function that raises an error.
act: when build_image is called.
assert: ImageBuildError is raised.
"""
mock_github_client = MagicMock(spec=openstack_manager.GithubClient)
mock_github_client.get_runner_application.side_effect = openstack_manager.RunnerBinaryError

with pytest.raises(openstack_manager.ImageBuildError) as exc:
openstack_manager.build_image(
arch=MagicMock(),
cloud_config=MagicMock(),
github_client=mock_github_client,
path=MagicMock(),
)

assert "Failed to fetch runner application." in str(exc)


def test_build_build_image_script_error(monkeypatch: pytest.MonkeyPatch):
"""
arrange: given a monkeypatched execute_command function that raises an error.
act: when build_image is called.
assert: ImageBuildError is raised.
"""
monkeypatch.setattr(
openstack_manager,
"execute_command",
MagicMock(side_effect=openstack_manager.SubprocessError),
)

with pytest.raises(openstack_manager.ImageBuildError) as exc:
openstack_manager.build_image(
arch=MagicMock(),
cloud_config=MagicMock(),
github_client=MagicMock(),
path=MagicMock(),
)

assert "Failed to build image." in str(exc)


def test_build_image_delete_image_error(monkeypatch: pytest.MonkeyPatch, clouds_yaml: dict):
"""
arrange: given a mocked openstack connection that returns existing images and delete_image
that returns False (failed to delete image).
act: when bulid_image is called.
assert: ImageBuildError is raised.
"""
mock_connection = MagicMock(spec=openstack_manager.openstack.connection.Connection)
mock_connection.delete_image.return_value = False
monkeypatch.setattr(
openstack_manager,
"_create_conection",
MagicMock(spec=openstack_manager._create_connection, return_value=mock_connection),
)

with pytest.raises(openstack_manager.ImageBuildError) as exc:
openstack_manager.build_image(
arch=MagicMock(),
cloud_config=MagicMock(),
github_client=MagicMock(),
path=MagicMock(),
proxies=MagicMock(),
)

assert "Failed to delete duplicate image on Openstack." in str(exc)


def test_build_image_delete_image_error(monkeypatch: pytest.MonkeyPatch):
"""
arrange: given a mocked connection that raises OpenStackCloudException on create_image.
act: when bulid_image is called.
assert: ImageBuildError is raised.
"""
monkeypatch.setattr(
openstack_manager,
"execute_command",
MagicMock(spec=openstack_manager.execute_command),
)
mock_connection = MagicMock(spec=openstack_manager.openstack.connection.Connection)
mock_connection.create_image.side_effect = openstack_manager.OpenStackCloudException
monkeypatch.setattr(
openstack_manager,
"_create_connection",
MagicMock(spec=openstack_manager._create_connection, return_value=mock_connection),
)

with pytest.raises(openstack_manager.ImageBuildError) as exc:
openstack_manager.build_image(
arch=MagicMock(),
cloud_config=MagicMock(),
github_client=MagicMock(),
path=MagicMock(),
proxies=None,
)

assert "Failed to upload image." in str(exc)


def test_build_image(monkeypatch: pytest.MonkeyPatch):
"""
arrange: given monkeypatched execute_command and mocked openstack connection.
act: when build_image is called.
assert: Openstack image is successfully created.
"""
monkeypatch.setattr(
openstack_manager,
"execute_command",
MagicMock(spec=openstack_manager.execute_command),
)
mock_connection = MagicMock(spec=openstack_manager.openstack.connection.Connection)
monkeypatch.setattr(
openstack_manager,
"_create_connection",
MagicMock(spec=openstack_manager._create_connection, return_value=mock_connection),
)

openstack_manager.build_image(
arch=MagicMock(),
cloud_config=MagicMock(),
github_client=MagicMock(),
path=MagicMock(),
)

0 comments on commit c818eaa

Please sign in to comment.