fuel-ccp/fuel_ccp/tests/test_build.py

274 lines
9.2 KiB
Python

import collections
import os
import fixtures
import mock
import testscenarios
from fuel_ccp import build
from fuel_ccp.tests import base
BASE_DOCKERFILE = u"""FROM debian:jessie
MAINTAINER Foo Bar <foo@bar.org>
RUN apt-get install \
curl \
&& apt-get clean"""
COMPONENT_DOCKERFILE = u"""FROM {}ccp/ms-debian-base
MAINTAINER Foo Bar <foo@bar.org>
RUN apt-get -y install \
mysql-server \
&& apt-get clean"""
class TestBuild(base.TestCase):
@staticmethod
def __create_dockerfile_objects():
return collections.OrderedDict([
('ms-debian-base', {
'name': 'ms-debian-base',
'path': '/home/test/microservices/ms-base/docker/'
'Dockerfile',
'is_jinja2': False,
'parent': None,
'children': [],
'build_result': 'Success',
'push_result': 'Success'
},),
('ms-mysql', {
'name': 'ms-mysql',
'path': '/home/test/microservices/ms-mysql/docker/'
'Dockerfile',
'is_jinja2': False,
'parent': None,
'children': [],
'build_result': 'Success',
'push_result': 'Success'
},)
])
@mock.patch("docker.Client")
@mock.patch("fuel_ccp.build.build_dockerfile")
@mock.patch("fuel_ccp.build.submit_dockerfile_processing")
@mock.patch("fuel_ccp.build.create_rendered_dockerfile")
def test_process_dockerfile_middle(
self, render_mock, submit_dockerfile_processing_mock,
build_dockerfile_mock, dc_mock):
dockerfiles = {
'root': {
'name': 'root',
'full_name': 'ms/root',
'parent': None,
'children': ['middle'],
'match': False,
'path': '/tmp'
},
'middle': {
'name': 'middle',
'full_name': 'ms/middle',
'parent': 'root',
'children': ['leaf'],
'match': True,
'path': '/tmp',
'build_result': 'Success'
},
'leaf': {
'name': 'leaf',
'full_name': 'ms/leaf',
'parent': 'middle',
'children': [],
'match': False,
'path': '/tmp'
}
}
for dockerfile in dockerfiles.values():
if dockerfile['parent']:
dockerfile['parent'] = dockerfiles[dockerfile['parent']]
for i in range(len(dockerfile['children'])):
dockerfile['children'][i] = (
dockerfiles[dockerfile['children'][i]]
)
build.process_dockerfile(
dockerfiles["middle"], mock.ANY, mock.ANY, mock.ANY, mock.ANY,
["root", "middle", "leaf"])
submit_dockerfile_processing_mock.assert_called_once_with(
dockerfiles["leaf"], mock.ANY, mock.ANY, mock.ANY,
mock.ANY, ["root", "middle", "leaf"])
@mock.patch("docker.Client")
@mock.patch("fuel_ccp.build.build_dockerfile")
@mock.patch("fuel_ccp.build.submit_dockerfile_processing")
@mock.patch("fuel_ccp.build.create_rendered_dockerfile")
def test_process_dockerfile_parent_build_failed(
self, render_mock, submit_dockerfile_processing_mock,
build_dockerfile_mock, dc_mock):
dockerfiles = {
'parent': {
'name': 'parent',
'full_name': 'ms/parent',
'parent': None,
'children': ['child'],
'match': True,
'path': '/tmp',
'build_result': 'Failure'
},
'child': {
'name': 'child',
'full_name': 'ms/child',
'parent': 'parent',
'children': [],
'match': True,
'path': '/tmp'
}
}
for dockerfile in dockerfiles.values():
if dockerfile['parent']:
dockerfile['parent'] = dockerfiles[dockerfile['parent']]
for i in range(len(dockerfile['children'])):
dockerfile['children'][i] = (
dockerfiles[dockerfile['children'][i]]
)
build.process_dockerfile(
dockerfiles["parent"], mock.ANY, mock.ANY, mock.ANY, mock.ANY,
[])
submit_dockerfile_processing_mock.assert_not_called()
@mock.patch("docker.Client")
@mock.patch("fuel_ccp.build.build_dockerfile")
@mock.patch("fuel_ccp.build.submit_dockerfile_processing")
@mock.patch("fuel_ccp.build.create_rendered_dockerfile")
def test_process_dockerfile_middle_keep_consistency_off(
self, render_mock, submit_dockerfile_processing_mock,
build_dockerfile_mock, dc_mock):
dockerfiles = {
'root': {
'name': 'root',
'full_name': 'ms/root',
'parent': None,
'children': ['middle'],
'match': False,
'path': '/tmp'
},
'middle': {
'name': 'middle',
'full_name': 'ms/middle',
'parent': 'root',
'children': ['leaf'],
'match': True,
'path': '/tmp'
},
'leaf': {
'name': 'leaf',
'full_name': 'ms/leaf',
'parent': 'middle',
'children': [],
'match': False,
'path': '/tmp'
}
}
self.conf["builder"]["keep_image_tree_consistency"] = False
for dockerfile in dockerfiles.values():
if dockerfile['parent']:
dockerfile['parent'] = dockerfiles[dockerfile['parent']]
for i in range(len(dockerfile['children'])):
dockerfile['children'][i] = (
dockerfiles[dockerfile['children'][i]]
)
build.process_dockerfile(dockerfiles["middle"], mock.ANY, mock.ANY,
mock.ANY, mock.ANY, [])
self.assertTrue(not submit_dockerfile_processing_mock.called)
def test_match_not_ready_base_dockerfiles(self):
dockerfile = {
'name': 'mariadb',
'match': True,
'parent': {
'name': 'base-tools',
'match': False,
'parent': {
'name': 'base',
'match': False,
'parent': None
}
}
}
build.match_not_ready_base_dockerfiles(dockerfile, [])
self.assertEqual(dockerfile['parent']['match'], True)
self.assertEqual(dockerfile['parent']['parent']['match'], True)
def test_get_summary_succeeded(self):
dockerfiles = self.__create_dockerfile_objects()
self.assertTrue(build._get_summary(dockerfiles))
def test_get_summary_not_pushed(self):
dockerfiles = self.__create_dockerfile_objects()
dockerfiles['ms-debian-base']['push_result'] = 'Exists'
dockerfiles['ms-mysql']['push_result'] = 'Exists'
self.assertTrue(build._get_summary(dockerfiles))
def test_get_summary_build_failed(self):
dockerfiles = self.__create_dockerfile_objects()
dockerfiles['ms-debian-base']['build_result'] = 'Failure'
self.assertFalse(build._get_summary(dockerfiles))
def test_get_summary_push_failed(self):
dockerfiles = self.__create_dockerfile_objects()
dockerfiles['ms-debian-base']['push_result'] = 'Failure'
self.assertFalse(build._get_summary(dockerfiles))
class TestRenderDockerfile(testscenarios.WithScenarios, base.TestCase):
scenarios = [
('empty', {
'config': {'render': {}},
'source': '',
'result': ('', set(), None),
}),
('one_source', {
'config': {'render': {}, 'sources': {'one': {}}},
'source': '{{ copy_sources("one", "/tmp") }}',
'result': ('COPY one /tmp', {'one'}, None),
}),
('wrong_source', {
'config': {'render': {}, 'sources': {'one': {}}},
'source': '{{ copy_sources("wrong", "/tmp") }}',
'exception': Exception('No such source: wrong'),
}),
('one_from', {
'config': {'render': {}},
'source': 'FROM {{ image_spec("one") }}',
'result': ('FROM ccp/one:latest', set(), 'one'),
}),
]
config = None
source = None
result = None
exception = None
def test_render_dockerfile(self):
tmp_dir = self.useFixture(fixtures.TempDir()).path
fname = os.path.join(tmp_dir, 'Dockerfile.j2')
with open(fname, 'w') as f:
f.write(self.source)
if not self.exception:
res = build.render_dockerfile(fname, 'name', self.config)
self.assertEqual(res, self.result)
else:
exc = self.assertRaises(ValueError, build.render_dockerfile,
fname, 'name', self.config)
self.assertEqual(exc.args[0], self.exception.args[0])