Example #1
0
def test_save_config(config: Config) -> None:
    """Saving the configuration to the yaml file works."""
    config.data = {"a": "b"}

    config.save()  # act

    with open(config.config_path, "r") as file_cursor:
        assert "a:" in file_cursor.read()
Example #2
0
def test_load_handles_file_not_found(config: Config) -> None:
    """
    Given: An inexistent config file.
    When: configuration is loaded.
    Then: A ConfigError is returned.
    """
    config.config_path = "inexistent.yaml"

    with pytest.raises(ConfigError):
        config.load()
Example #3
0
def test_get_an_inexistent_key_raises_error(config: Config) -> None:
    """If the key you're trying to fetch doesn't exist, raise a KeyError exception."""
    config.data = {
        "reports": {
            "second": "value"
        },
    }

    with pytest.raises(ConfigError):
        config.get("reports.inexistent")
Example #4
0
def set_active_project(config: Config, project_id: str) -> None:
    """Set the active project.

    Raises:
        ConfigError: If the project to activate doesn't exist.
    """
    _check_project(config, project_id)
    config["active_project"] = project_id
    config.save()
    log.info(f"The project {project_id} is now active")
Example #5
0
def test_get_can_fetch_nested_items_with_dots(config: Config) -> None:
    """Fetching values of configuration keys using dot notation works."""
    config.data = {
        "first": {
            "second": "value"
        },
    }

    result = config.get("first.second")

    assert result == "value"
Example #6
0
def test_get_returns_the_default_if_it_doesnt_exist(config: Config) -> None:
    """
    Given: An inexistent config key.
    When: The user calls the get method with a default value.
    Then: The default value is returned
    """
    config.data = {"a": "b"}

    result = config.get("inexistent", "default_value")

    assert result == "default_value"
Example #7
0
def test_load_handles_wrong_file_format(yaml_mock: Mock,
                                        config: Config) -> None:
    """
    Given: A config file with wrong yaml format.
    When: configuration is loaded.
    Then: A ConfigError is returned.
    """
    yaml_mock.return_value.load.side_effect = ParserError(
        "error",
        FileMarkMock(),
        "problem",
        FileMarkMock(),
    )

    with pytest.raises(ConfigError):
        config.load()
Example #8
0
def load_config(config_path: str) -> Config:
    """Configure the Config object."""
    try:
        return Config(config_path)
    except ConfigError as error:
        log.error(str(error))
        sys.exit(1)
Example #9
0
def project_status(config: Config, aws: AWS) -> ProjectStatus:
    """Fetch the status of the autoscaling groups of the active project.

    Raises:
        ConfigError: If there are no active projects, no configured projects or
            the active project doesn't exist.
    """
    project: ProjectStatus = {}
    active_project = get_active_project(config)

    for environment in ["Production", "Staging"]:
        try:
            autoscaler_name = config.get(
                f"projects.{active_project}."
                f"aws.autoscaling_groups.{environment.lower()}"
            )
            if not isinstance(autoscaler_name, str):
                raise ConfigError("The autoscaler name is not a string")
            autoscaler_info = aws.get_autoscaling_group(autoscaler_name)
        except ConfigError:
            autoscaler_info = {}

        project[environment] = autoscaler_info

    return project
Example #10
0
def fixture_config(tmpdir_factory: TempdirFactory) -> Config:
    """Configure the Config object for the tests."""
    data = tmpdir_factory.mktemp("data")
    config_file = str(data.join("config.yaml"))
    copyfile("tests/assets/config.yaml", config_file)
    config = Config(config_file)

    return config
Example #11
0
def test_project_handles_none_projects(config: Config) -> None:
    """
    Given: A configuration with no configured projects.
    When: Asked for the project.
    Then: A ConfigError exception is raised.
    """
    config.data["projects"] = {}

    with pytest.raises(ConfigError):
        services.get_active_project(config)
Example #12
0
def test_active_project_unhappy_path(
    runner: CliRunner, caplog: LogCaptureFixture, config: Config
) -> None:
    """
    Given: A drode program without any active project
    When: The active subcommand is called.
    Then: The exception is gracefully handled.
    """
    del config.data["active_project"]
    config.save()

    result = runner.invoke(cli, ["active"])

    assert result.exit_code == 1
    assert (
        "drode.entrypoints.cli",
        logging.ERROR,
        "There are more than one project configured but none is marked as active. "
        "Please use drode set command to define one.",
    ) in caplog.record_tuples
Example #13
0
def test_set_active_project_handles_inexistent(config: Config) -> None:
    """
    Given: A configuration without configured projects.
    When: Activating an inexistent project.
    Then: A ConfigError exception is raised.
    """
    config.data = {
        "projects": {"test_project_1": {}},
    }

    with pytest.raises(ConfigError):
        services.set_active_project(config, "inexistent_project")
Example #14
0
def test_config_can_fetch_nested_items_with_dictionary_notation(
        config: Config) -> None:
    """Fetching values of configuration keys using the dictionary notation works."""
    config.data = {
        "first": {
            "second": "value"
        },
    }

    result = config["first"]["second"]

    assert result == "value"
Example #15
0
def test_project_returns_only_project_if_just_one(config: Config) -> None:
    """
    Given: A configuration with just one project.
    When: Asked for the project.
    Then: The project is returned.
    """
    config.data = {
        "projects": {"test_project_1": {}},
    }

    result = services.get_active_project(config)

    assert result == "test_project_1"
Example #16
0
def test_set_active_project_works_if_existent(
    config: Config, caplog: LogCaptureFixture
) -> None:
    """
    Given: A configuration with configured project.
    When: Set that project as active.
    Then: The project is activated and the configuration is saved.
    """
    config.data = {
        "projects": {"project_1": {}},
    }

    services.set_active_project(config, "project_1")  # act

    # Reload the config from the file
    Config(config.config_path)
    assert config["active_project"] == "project_1"
    assert (
        "drode.services",
        logging.INFO,
        "The project project_1 is now active",
    ) in caplog.record_tuples
Example #17
0
def test_project_handles_inexistent_active_project(config: Config) -> None:
    """
    Given: A configuration with an active project that doesn't exist.
    When: Asked for the project.
    Then: A ConfigError exception is raised.
    """
    config.data = {
        "active_project": "inexistent_project",
        "projects": {"test_project_1": {}},
    }

    with pytest.raises(ConfigError):
        services.get_active_project(config)
Example #18
0
def test_status_unhappy_path(
    runner: CliRunner,
    fake_dependencies: FakeDeps,
    caplog: LogCaptureFixture,
    config: Config,
) -> None:
    """
    Given: A wrong configured drode program.
    When: The status command is called.
    Then: The exception is handled gracefuly.
    """
    del config.data["active_project"]
    config.save()

    result = runner.invoke(cli, ["status"], obj=fake_dependencies)

    assert result.exit_code == 1
    assert (
        "drode.entrypoints.cli",
        logging.ERROR,
        "There are more than one project configured but none is marked as active. "
        "Please use drode set command to define one.",
    ) in caplog.record_tuples
Example #19
0
def test_project_handles_several_projects_and_no_active(config: Config) -> None:
    """
    Given: A configuration with more than one projects but none activated.
    When: Asked for the project.
    Then: A ConfigError exception is raised.
    """
    config.data = {
        "active_project": None,
        "projects": {
            "test_project_1": {},
            "test_project_2": {},
        },
    }

    with pytest.raises(ConfigError):
        services.get_active_project(config)
Example #20
0
def test_project_returns_active_project_if_set(config: Config) -> None:
    """
    Given: A configuration with two projects and one activated.
    When: Asked for the project.
    Then: The activated project is returned.
    """
    config.data = {
        "active_project": "test_project_2",
        "projects": {
            "test_project_1": {},
            "test_project_2": {},
        },
    }

    result = services.get_active_project(config)

    assert result == "test_project_2"
Example #21
0
def test_config_load(config: Config) -> None:
    """Loading the configuration from the yaml file works."""
    config.load()  # act

    assert config.data["verbose"] == "info"
Example #22
0
def test_set_can_set_nested_items_with_dots(config: Config) -> None:
    """Setting values of configuration keys using dot notation works."""
    config.set("storage.type", "tinydb")  # act