-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fill in test coverage for
nextflowtower
- Loading branch information
Bruno Grande
committed
Apr 25, 2023
1 parent
ab0d26a
commit 8e84ae8
Showing
9 changed files
with
203 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,23 @@ | ||
import pytest | ||
from airflow.exceptions import AirflowNotFoundException | ||
from airflow.models.connection import Connection | ||
|
||
from orca.services.base.hook import BaseHook | ||
from orca.services.nextflowtower import ( | ||
NextflowTowerClient, | ||
NextflowTowerConfig, | ||
NextflowTowerHook, | ||
NextflowTowerOps, | ||
) | ||
|
||
|
||
@pytest.fixture | ||
def mock_client(mocker): | ||
mocker.patch("orca.services.nextflowtower.client_factory.NextflowTowerClient") | ||
def client(patch_os_environ): | ||
yield NextflowTowerClient("foo", "bar") | ||
|
||
|
||
@pytest.fixture | ||
def config(): | ||
config = NextflowTowerConfig( | ||
api_endpoint="https://api.tower.nf/", | ||
auth_token="foo", | ||
workspace=123456789, | ||
) | ||
yield config | ||
def config(patch_os_environ): | ||
# Workspace name based on example in responses.py | ||
yield NextflowTowerConfig("foo", "bar", "Foo-Bar/project-2") | ||
|
||
|
||
@pytest.fixture | ||
def mock_ops(config, mock_client): | ||
def ops(config): | ||
yield NextflowTowerOps(config) | ||
|
||
|
||
@pytest.fixture | ||
def connection_uri(config): | ||
bare_url = config.api_endpoint.replace("https://", "") | ||
host, schema = bare_url.rstrip("/").rsplit("/", maxsplit=1) | ||
token = config.auth_token | ||
project = config.project | ||
yield f"sbg://:{token}@{host}/{schema}/?project={project}" | ||
|
||
|
||
@pytest.fixture | ||
def connection(connection_uri): | ||
yield Connection(uri=connection_uri) | ||
|
||
|
||
@pytest.fixture | ||
def patch_get_connection(mocker, connection): | ||
connection_mock = mocker.patch.object(BaseHook, "get_connection") | ||
connection_mock.side_effect = AirflowNotFoundException | ||
yield connection_mock | ||
|
||
|
||
@pytest.fixture | ||
def hook(patch_get_connection): | ||
# The conn_id param doesn't matter because the `patch_get_connection` | ||
# fixture will ensure that the same Connection object is returned | ||
yield NextflowTowerHook("foo") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,12 +11,12 @@ | |
|
||
get_user_info = { | ||
"user": { | ||
"id": 2, | ||
"userName": "bgrande", | ||
"email": "[email protected]", | ||
"id": 100, | ||
"userName": "foo", | ||
"email": "[email protected]", | ||
"firstName": None, | ||
"lastName": None, | ||
"organization": "@Sage-Bionetworks", | ||
"organization": "@Foo-Bar", | ||
"description": None, | ||
"avatar": "REDACTED", | ||
"trusted": True, | ||
|
@@ -36,3 +36,30 @@ | |
"needConsent": False, | ||
"defaultWorkspaceId": None, | ||
} | ||
|
||
|
||
get_user_workspaces_and_orgs = { | ||
"orgsAndWorkspaces": [ | ||
{ | ||
"orgId": 123456789, | ||
"orgName": "Foo-Bar", | ||
"orgLogoUrl": None, | ||
"workspaceId": None, | ||
"workspaceName": None, | ||
}, | ||
{ | ||
"orgId": 123456789, | ||
"orgName": "Foo-Bar", | ||
"orgLogoUrl": None, | ||
"workspaceId": 54321, | ||
"workspaceName": "project-1", | ||
}, | ||
{ | ||
"orgId": 123456789, | ||
"orgName": "Foo-Bar", | ||
"orgLogoUrl": None, | ||
"workspaceId": 98765, | ||
"workspaceName": "project-2", | ||
}, | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import pytest | ||
from requests.exceptions import HTTPError | ||
|
||
from . import responses | ||
|
||
|
||
def test_that_update_kwargs_updates_an_empty_dictionary(client): | ||
kwargs = {} | ||
client.update_kwarg(kwargs, "foo", "bar", 123) | ||
assert "foo" in kwargs | ||
assert "bar" in kwargs["foo"] | ||
assert kwargs["foo"]["bar"] == 123 | ||
|
||
|
||
def test_that_update_kwargs_updates_an_nonempty_dictionary(client): | ||
kwargs = {"foo": {"baz": 456}} | ||
client.update_kwarg(kwargs, "foo", "bar", 123) | ||
assert "bar" in kwargs["foo"] | ||
assert "baz" in kwargs["foo"] | ||
assert kwargs["foo"]["bar"] == 123 | ||
|
||
|
||
def test_that_update_kwargs_fails_with_a_nondictionary_under_first_key(client): | ||
kwargs = {"foo": 123} | ||
with pytest.raises(ValueError): | ||
client.update_kwarg(kwargs, "foo", "bar", 123) | ||
|
||
|
||
def test_that_update_kwargs_fails_with_an_incompatible_type(client): | ||
kwargs = {"foo": {"bar": None}} | ||
with pytest.raises(ValueError): | ||
client.update_kwarg(kwargs, "foo", "bar", 123) | ||
|
||
|
||
def test_that_get_user_info_works(client, mocker): | ||
mock = mocker.patch.object(client, "request_json") | ||
mock.return_value = responses.get_user_info | ||
response = client.get_user_info() | ||
mock.assert_called_once() | ||
assert response == responses.get_user_info["user"] | ||
|
||
|
||
def test_that_get_user_info_fails_with_nonstandard_response(client, mocker): | ||
mock = mocker.patch.object(client, "request_json") | ||
mock.return_value = {"message": "foobar"} | ||
with pytest.raises(HTTPError): | ||
client.get_user_info() | ||
|
||
|
||
def test_that_list_user_workspaces_works(client, mocker): | ||
mocker.patch.object(client, "get_user_info") | ||
mock = mocker.patch.object(client, "request_json") | ||
mock.return_value = responses.get_user_workspaces_and_orgs | ||
response = client.list_user_workspaces() | ||
mock.assert_called_once() | ||
assert len(response) == 2 | ||
|
||
|
||
def test_that_list_user_workspaces_fails_with_nonstandard_response(client, mocker): | ||
mocker.patch.object(client, "get_user_info") | ||
mock = mocker.patch.object(client, "request_json") | ||
mock.return_value = {"message": "foobar"} | ||
with pytest.raises(HTTPError): | ||
client.list_user_workspaces() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import pytest | ||
from airflow.models.connection import Connection | ||
|
||
from orca.services.nextflowtower import NextflowTowerConfig | ||
|
||
|
||
def test_for_validation_error_when_setting_workspace_without_org(): | ||
bad_input = "some-workspace" | ||
with pytest.raises(ValueError): | ||
NextflowTowerConfig("foo", "bar", bad_input) | ||
|
||
|
||
def test_that_config_can_be_configured_with_full_org_workspace_name(patch_os_environ): | ||
good_input = "some-org/some-workspace" | ||
assert NextflowTowerConfig("foo", "bar", good_input) | ||
|
||
|
||
def test_that_parse_connection_can_process_connection_without_host(): | ||
connection = Connection(password="foo") | ||
kwargs = NextflowTowerConfig.parse_connection(connection) | ||
assert kwargs["auth_token"] == "foo" | ||
assert kwargs["api_endpoint"] is None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import pytest | ||
|
||
from orca.services.nextflowtower import NextflowTowerClient, NextflowTowerConfig | ||
|
||
|
||
@pytest.mark.integration | ||
def test_that_a_valid_client_can_be_constructed_and_tested(): | ||
config = NextflowTowerConfig() | ||
assert config.auth_token | ||
assert config.api_endpoint | ||
client = NextflowTowerClient(config.auth_token, config.api_endpoint) | ||
assert client.list_user_workspaces() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import pytest | ||
|
||
from orca.errors import ConfigError | ||
from orca.services.nextflowtower import NextflowTowerConfig, NextflowTowerOps | ||
|
||
from . import responses | ||
|
||
|
||
def test_that_the_workspace_attribute_is_accessible(ops): | ||
assert ops.workspace == "Foo-Bar/project-2" | ||
|
||
|
||
def test_for_an_error_when_the_workspace_attribute_is_missing(patch_os_environ): | ||
config = NextflowTowerConfig() | ||
ops = NextflowTowerOps(config) | ||
with pytest.raises(ConfigError): | ||
ops.workspace | ||
|
||
|
||
def test_that_the_workspace_id_attribute_is_accessible(ops, mocker): | ||
mock = mocker.patch.object(NextflowTowerOps, "client") | ||
response = responses.get_user_workspaces_and_orgs["orgsAndWorkspaces"] | ||
mock.list_user_workspaces.return_value = response | ||
assert ops.workspace_id == 98765 | ||
|
||
|
||
def test_for_error_when_the_workspace_id_does_not_exist(ops, mocker): | ||
mock = mocker.patch.object(NextflowTowerOps, "client") | ||
response = responses.get_user_workspaces_and_orgs["orgsAndWorkspaces"] | ||
# Get rid of relevant entry | ||
response = [item for item in response if item["workspaceName"] != "project-2"] | ||
mock.list_user_workspaces.return_value = response | ||
with pytest.raises(ValueError): | ||
ops.workspace_id |