<commit_before>import logging
import typing as tp
from functools import partial

import pytest
from plumbum import ProcessExecutionError

from benchbuild.environments.adapters.podman import (
    remove_container,
    ContainerCreateError,
)
from benchbuild.environments.domain import declarative as decl
from benchbuild.environments.domain import commands, events
from benchbuild.environments.service_layer import messagebus, handlers
from benchbuild.environments.service_layer import unit_of_work as uow
from benchbuild.utils.cmd import cp, which

LOG = logging.getLogger(__name__)


@pytest.fixture
def image_uow() -> uow.ImageUnitOfWork:
    return uow.BuildahImageUOW()


@pytest.fixture
def container_uow() -> uow.ContainerUnitOfWork:
    return uow.PodmanContainerUOW()


@pytest.fixture
def publish(image_uow,
            container_uow) -> tp.Callable[[messagebus.Message], None]:
    evt_handlers = {
        events.LayerCreated: [],
        events.ImageCreated: [],
        events.ContainerCreated: [],
        events.ContainerStartFailed: [],
        events.ContainerStarted: [],
        events.LayerCreationFailed: [],
        events.DebugImageKept: [],
        events.ImageCreationFailed: []
    }

    cmd_handlers = {
        commands.CreateImage:
            handlers.bootstrap(handlers.create_image, image_uow),
        commands.CreateBenchbuildBase:
            handlers.bootstrap(handlers.create_benchbuild_base, image_uow),
        commands.RunProjectContainer:
            handlers.bootstrap(handlers.run_project_container, container_uow),
        commands.ExportImage:
            handlers.bootstrap(handlers.export_image_handler, image_uow),
        commands.ImportImage:
            handlers.bootstrap(handlers.import_image_handler, image_uow),
        commands.DeleteImage:
            handlers.bootstrap(handlers.delete_image_handler, image_uow),
    }

    yield partial(messagebus.handle, cmd_handlers, evt_handlers)

    images = list(image_uow.registry.images.values())
    for image in images:
        image_uow.registry.remove(image)

    containers = list(container_uow.registry.containers.values())
    for container in containers:
        remove_container(container.container_id)


@pytest.fixture
def true_image() -> decl.ContainerImage:

    def prepare_container() -> None:
        true_path = which('true').strip()
        cp(true_path, 'true')

    return decl.ContainerImage() \
        .from_('scratch') \
        .context(prepare_container) \
        .workingdir('/') \
        .entrypoint('/true')


def test_image_creation(true_image, publish, image_uow) -> None:
    name = 'benchbuild-e2e-test_image_creation'

    maybe_image = image_uow.registry.find(name)
    assert maybe_image is None

    cmd = commands.CreateImage(name, true_image)
    publish(cmd)
    maybe_image = image_uow.registry.find(name)

    assert maybe_image is not None


def test_image_run_no_args(true_image, publish) -> None:
    name = 'benchbuild-e2e-test_image_run'

    cmd = commands.CreateImage(name, true_image)
    publish(cmd)

    run_cmd_no_args = commands.RunProjectContainer(name, name, '/')
    try:
        publish(run_cmd_no_args)
    except ContainerCreateError:
        assert False, "RunProjectContainer was unable to create a container."
    except ProcessExecutionError:
        assert False, "RunProjectContainer raised an unexpected exception"


def test_image_run_args(true_image, publish) -> None:
    name = 'benchbuild-e2e-test_image_run'

    cmd = commands.CreateImage(name, true_image)
    publish(cmd)

    run_cmd_args = commands.RunProjectContainer(
        name, name, '/', ('arg1', 'arg2')
    )
    try:
        publish(run_cmd_args)
    except ContainerCreateError:
        assert False, "RunProjectContainer was unable to create a container."
    except ProcessExecutionError:
        assert False, "RunProjectContainer raised an unexpected exception"
<commit_msg>test(environments): add test that triggers issue #472<commit_after>import typing as tp
from functools import partial

import pytest
from plumbum import ProcessExecutionError

from benchbuild.environments.adapters.podman import (
    remove_container,
    ContainerCreateError,
)
from benchbuild.environments.domain import declarative as decl
from benchbuild.environments.domain import commands, events
from benchbuild.environments.service_layer import messagebus, handlers
from benchbuild.environments.service_layer import unit_of_work as uow
from benchbuild.settings import CFG
from benchbuild.utils import settings
from benchbuild.utils.cmd import cp, which


@pytest.fixture
def config():
    settings.setup_config(CFG)
    yield CFG
    settings.setup_config(CFG)


@pytest.fixture
def image_uow() -> uow.ImageUnitOfWork:
    return uow.BuildahImageUOW()


@pytest.fixture
def container_uow() -> uow.ContainerUnitOfWork:
    return uow.PodmanContainerUOW()


@pytest.fixture
def publish(image_uow,
            container_uow) -> tp.Callable[[messagebus.Message], None]:
    evt_handlers = {
        events.LayerCreated: [],
        events.ImageCreated: [],
        events.ContainerCreated: [],
        events.ContainerStartFailed: [],
        events.ContainerStarted: [],
        events.LayerCreationFailed: [],
        events.DebugImageKept: [],
        events.ImageCreationFailed: []
    }

    cmd_handlers = {
        commands.CreateImage:
            handlers.bootstrap(handlers.create_image, image_uow),
        commands.CreateBenchbuildBase:
            handlers.bootstrap(handlers.create_benchbuild_base, image_uow),
        commands.RunProjectContainer:
            handlers.bootstrap(handlers.run_project_container, container_uow),
        commands.ExportImage:
            handlers.bootstrap(handlers.export_image_handler, image_uow),
        commands.ImportImage:
            handlers.bootstrap(handlers.import_image_handler, image_uow),
        commands.DeleteImage:
            handlers.bootstrap(handlers.delete_image_handler, image_uow),
    }

    yield partial(messagebus.handle, cmd_handlers, evt_handlers)

    images = list(image_uow.registry.images.values())
    for image in images:
        image_uow.registry.remove(image)

    containers = list(container_uow.registry.containers.values())
    for container in containers:
        remove_container(container.container_id)


@pytest.fixture
def true_image() -> decl.ContainerImage:

    def prepare_container() -> None:
        true_path = which('true').strip()
        cp(true_path, 'true')

    return decl.ContainerImage() \
        .from_('scratch') \
        .context(prepare_container) \
        .workingdir('/') \
        .entrypoint('/true')


@pytest.fixture
def no_entrypoint() -> decl.ContainerImage:

    def prepare_container() -> None:
        true_path = which('true').strip()
        cp(true_path, 'true')

    return decl.ContainerImage() \
        .from_('scratch') \
        .context(prepare_container) \
        .workingdir('/') \
        .command('/true')


def test_image_creation(true_image, publish, image_uow) -> None:
    name = 'benchbuild-e2e-test_image_creation'

    maybe_image = image_uow.registry.find(name)
    assert maybe_image is None

    cmd = commands.CreateImage(name, true_image)
    publish(cmd)
    maybe_image = image_uow.registry.find(name)

    assert maybe_image is not None


def test_image_run_no_args(true_image, publish) -> None:
    name = 'benchbuild-e2e-test_image_run'

    cmd = commands.CreateImage(name, true_image)
    publish(cmd)

    run_cmd_no_args = commands.RunProjectContainer(name, name, '/')
    try:
        publish(run_cmd_no_args)
    except ContainerCreateError:
        assert False, "RunProjectContainer was unable to create a container."
    except ProcessExecutionError:
        assert False, "RunProjectContainer raised an unexpected exception"


def test_image_run_args(true_image, publish) -> None:
    name = 'benchbuild-e2e-test_image_run'

    cmd = commands.CreateImage(name, true_image)
    publish(cmd)

    run_cmd_args = commands.RunProjectContainer(
        name, name, '/', ('arg1', 'arg2')
    )
    try:
        publish(run_cmd_args)
    except ContainerCreateError:
        assert False, "RunProjectContainer was unable to create a container."
    except ProcessExecutionError:
        assert False, "RunProjectContainer raised an unexpected exception"


def test_interactive_without_entrypoint(no_entrypoint, publish, config) -> None:
    name = 'benchbuild-e2e-test_interactive_without_entrypoint'

    cmd = commands.CreateImage(name, no_entrypoint)
    publish(cmd)

    run_cmd_args = commands.RunProjectContainer(
        name, name, '/', ('arg1', 'arg2')
    )
    config["container"]["interactive"] = True
    try:
        publish(run_cmd_args)
    except ContainerCreateError:
        assert False, "RunProjectContainer was unable to create a container."
    except ProcessExecutionError:
        assert False, "RunProjectContainer raised an unexpected exception"

{'fraction_non_alphanumeric': 0.09291689905186838, 'fraction_numerical': 0.0017847183491355272, 'mean_word_length': 3.494235588972431, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2825369', 'n_tokens_mistral': 2629, 'n_tokens_neox': 2590, 'n_words': 531}