<commit_before>"""
Copyright (c) 2017 Red Hat, Inc
All rights reserved.

This software may be modified and distributed under the terms
of the BSD license. See the LICENSE file for details.
"""

from __future__ import unicode_literals

from dockerfile_parse import DockerfileParser

from atomic_reactor.plugin import PluginFailedException
from atomic_reactor.build import InsideBuilder, BuildResult
from atomic_reactor.util import ImageName, CommandResult
from atomic_reactor.inner import DockerBuildWorkflow

from tests.docker_mock import mock_docker
from flexmock import flexmock
import pytest
from tests.constants import MOCK_SOURCE


class MockDockerTasker(object):
    def inspect_image(self, name):
        return {}

    def build_image_from_path(self):
        return True


class X(object):
    pass


class MockInsideBuilder(object):
    def __init__(self, failed=False, image_id=None):
        self.tasker = MockDockerTasker()
        self.base_image = ImageName(repo='Fedora', tag='22')
        self.image_id = image_id or 'asd'
        self.image = 'image'
        self.failed = failed
        self.df_path = 'some'
        self.df_dir = 'some'

        def simplegen(x, y):
            yield "some\u2018".encode('utf-8')
        flexmock(self.tasker, build_image_from_path=simplegen)

    @property
    def source(self):
        result = X()
        setattr(result, 'dockerfile_path', '/')
        setattr(result, 'path', '/tmp')
        return result

    def pull_base_image(self, source_registry, insecure=False):
        pass

    def get_built_image_info(self):
        return {'Id': 'some'}

    def inspect_built_image(self):
        return None

    def ensure_not_built(self):
        pass


@pytest.mark.parametrize('is_failed', [
    True,
    False,
])
@pytest.mark.parametrize('image_id', ['sha256:12345', '12345'])
def test_build(is_failed, image_id):
    """
    tests docker build api plugin working
    """
    flexmock(DockerfileParser, content='df_content')
    mock_docker()
    fake_builder = MockInsideBuilder(image_id=image_id)
    flexmock(InsideBuilder).new_instances(fake_builder)

    workflow = DockerBuildWorkflow(MOCK_SOURCE, 'test-image')
    flexmock(CommandResult).should_receive('is_failed').and_return(is_failed)
    error = "error message"
    error_detail = "{u'message': u\"%s\"}" % error
    if is_failed:
        flexmock(CommandResult, error=error, error_detail=error_detail)
        with pytest.raises(PluginFailedException):
            workflow.build_docker_image()
    else:
        workflow.build_docker_image()

    assert isinstance(workflow.buildstep_result['docker_api'], BuildResult)
    assert workflow.build_result == workflow.buildstep_result['docker_api']
    assert workflow.build_result.is_failed() == is_failed

    if is_failed:
        assert workflow.build_result.fail_reason == error
        assert '\\' not in workflow.plugins_errors['docker_api']
        assert error in workflow.plugins_errors['docker_api']
    else:
        assert workflow.build_result.image_id.startswith('sha256:')
        assert workflow.build_result.image_id.count(':') == 1<commit_msg>Add docker_api test for syntax error<commit_after>"""
Copyright (c) 2017 Red Hat, Inc
All rights reserved.

This software may be modified and distributed under the terms
of the BSD license. See the LICENSE file for details.
"""

from __future__ import unicode_literals

import docker
import requests

from dockerfile_parse import DockerfileParser

from atomic_reactor.plugin import PluginFailedException
from atomic_reactor.build import InsideBuilder, BuildResult
from atomic_reactor.util import ImageName, CommandResult
from atomic_reactor.inner import DockerBuildWorkflow

from tests.docker_mock import mock_docker
from flexmock import flexmock
import pytest
from tests.constants import MOCK_SOURCE


class MockDockerTasker(object):
    def inspect_image(self, name):
        return {}

    def build_image_from_path(self):
        return True


class X(object):
    pass


class MockInsideBuilder(object):
    def __init__(self, failed=False, image_id=None):
        self.tasker = MockDockerTasker()
        self.base_image = ImageName(repo='Fedora', tag='22')
        self.image_id = image_id or 'asd'
        self.image = 'image'
        self.failed = failed
        self.df_path = 'some'
        self.df_dir = 'some'

        def simplegen(x, y):
            yield "some\u2018".encode('utf-8')
        flexmock(self.tasker, build_image_from_path=simplegen)

    @property
    def source(self):
        result = X()
        setattr(result, 'dockerfile_path', '/')
        setattr(result, 'path', '/tmp')
        return result

    def pull_base_image(self, source_registry, insecure=False):
        pass

    def get_built_image_info(self):
        return {'Id': 'some'}

    def inspect_built_image(self):
        return None

    def ensure_not_built(self):
        pass


@pytest.mark.parametrize('is_failed', [
    True,
    False,
])
@pytest.mark.parametrize('image_id', ['sha256:12345', '12345'])
def test_build(is_failed, image_id):
    """
    tests docker build api plugin working
    """
    flexmock(DockerfileParser, content='df_content')
    mock_docker()
    fake_builder = MockInsideBuilder(image_id=image_id)
    flexmock(InsideBuilder).new_instances(fake_builder)

    workflow = DockerBuildWorkflow(MOCK_SOURCE, 'test-image')
    flexmock(CommandResult).should_receive('is_failed').and_return(is_failed)
    error = "error message"
    error_detail = "{u'message': u\"%s\"}" % error
    if is_failed:
        flexmock(CommandResult, error=error, error_detail=error_detail)
        with pytest.raises(PluginFailedException):
            workflow.build_docker_image()
    else:
        workflow.build_docker_image()

    assert isinstance(workflow.buildstep_result['docker_api'], BuildResult)
    assert workflow.build_result == workflow.buildstep_result['docker_api']
    assert workflow.build_result.is_failed() == is_failed

    if is_failed:
        assert workflow.build_result.fail_reason == error
        assert '\\' not in workflow.plugins_errors['docker_api']
        assert error in workflow.plugins_errors['docker_api']
    else:
        assert workflow.build_result.image_id.startswith('sha256:')
        assert workflow.build_result.image_id.count(':') == 1


def test_syntax_error():
    """
    tests reporting of syntax errors
    """
    flexmock(DockerfileParser, content='df_content')
    mock_docker()
    fake_builder = MockInsideBuilder()

    def raise_exc(*args, **kwargs):
        explanation = ("Syntax error - can't find = in \"CMD\". "
                       "Must be of the form: name=value")
        http_error = requests.HTTPError('500 Server Error')
        raise docker.errors.APIError(message='foo',
                                     response=http_error,
                                     explanation=explanation)
        yield {}

    fake_builder.tasker.build_image_from_path = raise_exc
    flexmock(InsideBuilder).new_instances(fake_builder)
    workflow = DockerBuildWorkflow(MOCK_SOURCE, 'test-image')
    with pytest.raises(PluginFailedException):
        workflow.build_docker_image()

    assert isinstance(workflow.buildstep_result['docker_api'], BuildResult)
    assert workflow.build_result == workflow.buildstep_result['docker_api']
    assert workflow.build_result.is_failed()
    assert "Syntax error" in workflow.build_result.fail_reason
{'fraction_non_alphanumeric': 0.09864447725137565, 'fraction_numerical': 0.007918400214736276, 'mean_word_length': 3.5273390036452006, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4491116', 'n_tokens_mistral': 2321, 'n_tokens_neox': 2179, 'n_words': 491}