1
0
mirror of synced 2026-01-02 03:02:26 -05:00
Files
airbyte/octavia-cli/unit_tests/test_entrypoint.py

223 lines
9.4 KiB
Python

#
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
#
from typing import List, Optional
import click
import pkg_resources
import pytest
from airbyte_api_client.model.workspace_id_request_body import WorkspaceIdRequestBody
from click.testing import CliRunner
from octavia_cli import entrypoint
from octavia_cli.api_http_headers import ApiHttpHeader
@click.command()
@click.pass_context
def dumb(ctx):
pass
@pytest.mark.parametrize(
"option_based_api_http_headers, api_http_headers_file_path",
[
([("foo", "bar")], "api_http_headers_file_path"),
([], None),
(None, None),
],
)
def test_set_context_object(mocker, option_based_api_http_headers, api_http_headers_file_path):
mocker.patch.object(entrypoint, "TelemetryClient")
mocker.patch.object(entrypoint, "build_user_agent")
mocker.patch.object(entrypoint, "merge_api_headers")
mocker.patch.object(entrypoint, "get_api_client")
mocker.patch.object(entrypoint, "get_workspace_id")
mocker.patch.object(entrypoint, "check_is_initialized")
mocker.patch.object(entrypoint, "get_anonymous_data_collection")
mock_ctx = mocker.Mock(obj={})
built_context = entrypoint.set_context_object(
mock_ctx, "my_airbyte_url", "my_workspace_id", "enable_telemetry", option_based_api_http_headers, api_http_headers_file_path
)
entrypoint.TelemetryClient.assert_called_with("enable_telemetry")
mock_ctx.ensure_object.assert_called_with(dict)
assert built_context.obj == {
"OCTAVIA_VERSION": pkg_resources.require("octavia-cli")[0].version,
"TELEMETRY_CLIENT": entrypoint.TelemetryClient.return_value,
"WORKSPACE_ID": entrypoint.get_workspace_id.return_value,
"API_CLIENT": entrypoint.get_api_client.return_value,
"PROJECT_IS_INITIALIZED": entrypoint.check_is_initialized.return_value,
"ANONYMOUS_DATA_COLLECTION": entrypoint.get_anonymous_data_collection.return_value,
}
entrypoint.build_user_agent.assert_called_with(built_context.obj["OCTAVIA_VERSION"])
entrypoint.merge_api_headers.assert_called_with(option_based_api_http_headers, api_http_headers_file_path)
entrypoint.get_api_client.assert_called_with(
"my_airbyte_url", entrypoint.build_user_agent.return_value, entrypoint.merge_api_headers.return_value
)
def test_set_context_object_error(mocker):
mocker.patch.object(entrypoint, "TelemetryClient")
mock_ctx = mocker.Mock(obj={})
mock_ctx.ensure_object.side_effect = NotImplementedError()
with pytest.raises(NotImplementedError):
entrypoint.set_context_object(
mock_ctx, "my_airbyte_url", "my_workspace_id", "enable_telemetry", [("foo", "bar")], "api_http_headers_file_path"
)
entrypoint.TelemetryClient.return_value.send_command_telemetry.assert_called_with(
mock_ctx, error=mock_ctx.ensure_object.side_effect
)
@pytest.mark.parametrize(
"options, expected_exit_code",
[
(["--airbyte-url", "test-airbyte-url"], 0),
(["--airbyte-url", "test-airbyte-url", "--enable-telemetry"], 0),
(["--airbyte-url", "test-airbyte-url", "--enable-telemetry foo"], 2),
(["--airbyte-url", "test-airbyte-url", "--disable-telemetry"], 0),
(["--airbyte-url", "test-airbyte-url", "--api-http-headers-file-path", "path-does-not-exist"], 2),
(["--airbyte-url", "test-airbyte-url", "--api-http-headers-file-path", "path-exists"], 0),
(["--airbyte-url", "test-airbyte-url", "--api-http-header", "Content-Type", "application/json"], 0),
(
[
"--airbyte-url",
"test-airbyte-url",
"--api-http-header",
"Content-Type",
"application/json",
"--api-http-header",
"Authorization",
"'Bearer XXX'",
],
0,
),
(
[
"--airbyte-url",
"test-airbyte-url",
"--api-http-header",
"Content-Type",
"--api-http-header",
"Authorization",
"'Bearer XXX'",
],
2,
),
],
)
def test_octavia(tmp_path, mocker, options, expected_exit_code):
if "path-exists" in options:
tmp_file = tmp_path / "path_exists.yaml"
tmp_file.write_text("foobar")
options[options.index("path-exists")] = tmp_file
mocker.patch.object(entrypoint, "click")
mocker.patch.object(
entrypoint,
"set_context_object",
mocker.Mock(return_value=mocker.Mock(obj={"WORKSPACE_ID": "api-defined-workspace-id", "PROJECT_IS_INITIALIZED": True})),
)
entrypoint.octavia.add_command(dumb)
runner = CliRunner()
result = runner.invoke(entrypoint.octavia, options + ["dumb"], obj={})
expected_message = "🐙 - Octavia is targetting your Airbyte instance running at test-airbyte-url on workspace api-defined-workspace-id."
assert result.exit_code == expected_exit_code
if expected_exit_code == 0:
entrypoint.click.style.assert_called_with(expected_message, fg="green")
entrypoint.click.echo.assert_called_with(entrypoint.click.style.return_value)
def test_octavia_not_initialized(mocker):
mocker.patch.object(entrypoint, "click")
mocker.patch.object(
entrypoint,
"set_context_object",
mocker.Mock(return_value=mocker.Mock(obj={"WORKSPACE_ID": "api-defined-workspace-id", "PROJECT_IS_INITIALIZED": False})),
)
entrypoint.octavia.add_command(dumb)
runner = CliRunner()
result = runner.invoke(entrypoint.octavia, ["--airbyte-url", "test-airbyte-url", "dumb"], obj={})
entrypoint.click.style.assert_called_with("🐙 - Project is not yet initialized.", fg="red", bold=True)
entrypoint.click.echo.assert_called_with(entrypoint.click.style.return_value)
assert result.exit_code == 0
@pytest.mark.parametrize(
"api_http_headers",
[
None,
[],
[ApiHttpHeader(name="Authorization", value="Basic dXNlcjE6cGFzc3dvcmQ=")],
[ApiHttpHeader(name="Authorization", value="Basic dXNlcjE6cGFzc3dvcmQ="), ApiHttpHeader(name="Header", value="header_value")],
],
)
def test_get_api_client(mocker, api_http_headers: Optional[List[str]]):
mocker.patch.object(entrypoint, "airbyte_api_client")
mocker.patch.object(entrypoint, "check_api_health")
mocker.patch.object(entrypoint, "set_api_headers_on_api_client")
api_client = entrypoint.get_api_client("test-url", "test-user-agent", api_http_headers)
entrypoint.airbyte_api_client.Configuration.assert_called_with(host="test-url/api")
entrypoint.airbyte_api_client.ApiClient.assert_called_with(entrypoint.airbyte_api_client.Configuration.return_value)
assert entrypoint.airbyte_api_client.ApiClient.return_value.user_agent == "test-user-agent"
if api_http_headers:
entrypoint.set_api_headers_on_api_client.assert_called_with(entrypoint.airbyte_api_client.ApiClient.return_value, api_http_headers)
entrypoint.check_api_health.assert_called_with(entrypoint.airbyte_api_client.ApiClient.return_value)
assert api_client == entrypoint.airbyte_api_client.ApiClient.return_value
def test_get_workspace_id_user_defined(mocker):
mock_api_client = mocker.Mock()
mocker.patch.object(entrypoint, "check_workspace_exists")
mocker.patch.object(entrypoint, "workspace_api")
assert entrypoint.get_workspace_id(mock_api_client, "user-defined-workspace-id") == "user-defined-workspace-id"
entrypoint.check_workspace_exists.assert_called_with(mock_api_client, "user-defined-workspace-id")
def test_get_workspace_id_api_defined(mocker):
mock_api_client = mocker.Mock()
mocker.patch.object(entrypoint, "check_workspace_exists")
mocker.patch.object(entrypoint, "workspace_api")
mock_api_instance = entrypoint.workspace_api.WorkspaceApi.return_value
mock_api_instance.list_workspaces.return_value = mocker.Mock(workspaces=[{"workspaceId": "api-defined-workspace-id"}])
assert entrypoint.get_workspace_id(mock_api_client, None) == "api-defined-workspace-id"
entrypoint.workspace_api.WorkspaceApi.assert_called_with(mock_api_client)
mock_api_instance.list_workspaces.assert_called_with(_check_return_type=False)
def test_get_anonymous_data_collection(mocker, mock_api_client):
mocker.patch.object(entrypoint, "workspace_api")
mock_api_instance = entrypoint.workspace_api.WorkspaceApi.return_value
assert (
entrypoint.get_anonymous_data_collection(mock_api_client, "my_workspace_id")
== mock_api_instance.get_workspace.return_value.get.return_value
)
entrypoint.workspace_api.WorkspaceApi.assert_called_with(mock_api_client)
mock_api_instance.get_workspace.assert_called_with(WorkspaceIdRequestBody("my_workspace_id"), _check_return_type=False)
def test_commands_in_octavia_group():
octavia_commands = entrypoint.octavia.commands.values()
for command in entrypoint.AVAILABLE_COMMANDS:
assert command in octavia_commands
@pytest.mark.parametrize(
"command",
[entrypoint.delete, entrypoint._import],
)
def test_not_implemented_commands(command):
runner = CliRunner()
result = runner.invoke(command)
assert result.exit_code == 1
assert result.output.endswith("not yet implemented.\n")
def test_available_commands():
assert entrypoint.AVAILABLE_COMMANDS == [
entrypoint.list_commands._list,
entrypoint.init_commands.init,
entrypoint.generate_commands.generate,
entrypoint.apply_commands.apply,
]