Esempio n. 1
0
def initialize(tmp_path: Path) -> Config:
    """Do basic initialization and return a configuration.

    This shared logic can be used either with `SetupTest`, which assumes an
    ASGI application and an async test, or with non-async tests such as the
    tests of the command-line interface.

    Parameters
    ----------
    tmp_path : `pathlib.Path`
        The path for temporary files.

    Returns
    -------
    config : `gafaelfawr.config.Config`
        The generated config, using the same defaults as `SetupTest`.
    """
    settings_path = build_settings(tmp_path, "github")
    config_dependency.set_settings_path(str(settings_path))
    config = config_dependency()
    if not os.environ.get("REDIS_6379_TCP_PORT"):
        redis_dependency.is_mocked = True

    # Initialize the database.  Non-SQLite databases need to be reset between
    # tests.
    should_reset = not urlparse(config.database_url).scheme == "sqlite"
    initialize_database(config, reset=should_reset)

    return config
Esempio n. 2
0
def test_update_service_tokens_error(
    tmp_path: Path,
    config: Config,
    mock_kubernetes: MockKubernetesApi,
    caplog: LogCaptureFixture,
) -> None:
    asyncio.run(initialize_database(config, reset=True))
    caplog.clear()

    def error_callback(method: str, *args: Any) -> None:
        if method == "list_cluster_custom_object":
            raise ApiException(status=500, reason="Some error")

    mock_kubernetes.error_callback = error_callback
    runner = CliRunner()
    result = runner.invoke(main, ["update-service-tokens"])

    assert result.exit_code == 1
    assert parse_log(caplog) == [
        {
            "event": "Unable to list GafaelfawrServiceToken objects",
            "error": "Kubernetes API error: (500)\nReason: Some error\n",
            "severity": "error",
        },
        {
            "error": "Kubernetes API error: (500)\nReason: Some error\n",
            "event": "Failed to update service token secrets",
            "severity": "error",
        },
    ]
Esempio n. 3
0
def test_update_service_tokens(tmp_path: Path, config: Config,
                               mock_kubernetes: MockKubernetesApi) -> None:
    asyncio.run(initialize_database(config, reset=True))
    asyncio.run(
        mock_kubernetes.create_namespaced_custom_object(
            "gafaelfawr.lsst.io",
            "v1alpha1",
            "mobu",
            "gafaelfawrservicetokens",
            {
                "apiVersion": "gafaelfawr.lsst.io/v1alpha1",
                "kind": "GafaelfawrServiceToken",
                "metadata": {
                    "name": "gafaelfawr-secret",
                    "namespace": "mobu",
                    "generation": 1,
                },
                "spec": {
                    "service": "mobu",
                    "scopes": ["admin:token"],
                },
            },
        ))

    runner = CliRunner()
    result = runner.invoke(main, ["update-service-tokens"])

    assert result.exit_code == 0
    assert mock_kubernetes.get_all_objects_for_test("Secret")
Esempio n. 4
0
def run_app(tmp_path: Path, settings_path: Path) -> Iterator[SeleniumConfig]:
    """Run the application as a separate process for Selenium access.

    Parameters
    ----------
    tmp_path : `pathlib.Path`
        The temporary directory for testing.
    settings_path : `pathlib.Path`
        The path to the settings file.
    """
    config_dependency.set_settings_path(str(settings_path))
    config = config_dependency()
    initialize_database(config)

    token_path = tmp_path / "token"
    app_source = APP_TEMPLATE.format(
        settings_path=str(settings_path),
        token_path=str(token_path),
    )
    app_path = tmp_path / "testing.py"
    with app_path.open("w") as f:
        f.write(app_source)

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("127.0.0.1", 0))
    port = s.getsockname()[1]

    cmd = ["uvicorn", "--fd", "0", "testing:app"]
    logging.info("Starting server with command %s", " ".join(cmd))
    p = subprocess.Popen(cmd, cwd=str(tmp_path), stdin=s.fileno())
    s.close()

    logging.info("Waiting for server to start")
    _wait_for_server(port)

    try:
        selenium_config = SeleniumConfig(
            token=Token.from_str(token_path.read_text()),
            url=f"http://localhost:{port}",
        )
        yield selenium_config
    finally:
        p.terminate()
Esempio n. 5
0
def init(settings: str) -> None:
    """Initialize the database storage."""
    config_dependency.set_settings_path(settings)
    config = config_dependency()
    initialize_database(config)