A Python library for code common to TripleO CLI and TripleO UI.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
6.3KB

  1. # Copyright 2019 Red Hat, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. #
  15. """Unit tests for image.builder.buildah"""
  16. import copy
  17. import mock
  18. from concurrent import futures
  19. from concurrent.futures import ThreadPoolExecutor as tpe
  20. from tripleo_common.image.builder.buildah import BuildahBuilder as bb
  21. from tripleo_common.tests import base
  22. from tripleo_common.utils import process
  23. BUILDAH_CMD_BASE = ['sudo', 'buildah']
  24. DEPS = {"base"}
  25. WORK_DIR = '/tmp/kolla'
  26. BUILD_ALL_LIST_CONTAINERS = ['container1', 'container2', 'container3']
  27. BUILD_ALL_DICT_CONTAINERS = {
  28. 'container1': {},
  29. 'container2': {},
  30. 'container3': {}
  31. }
  32. BUILD_ALL_STR_CONTAINER = 'container1'
  33. class ThreadPoolExecutorReturn(object):
  34. _exception = None
  35. class ThreadPoolExecutorReturnFailed(object):
  36. _exception = True
  37. exception_info = "This is a test failure"
  38. class ThreadPoolExecutorReturnSuccess(object):
  39. _exception = False
  40. # Return values for the ThreadPoolExecutor
  41. R_FAILED = (
  42. (
  43. ThreadPoolExecutorReturnSuccess,
  44. ThreadPoolExecutorReturnSuccess,
  45. ThreadPoolExecutorReturnFailed
  46. ),
  47. set()
  48. )
  49. R_OK = (
  50. (
  51. ThreadPoolExecutorReturnSuccess,
  52. ThreadPoolExecutorReturnSuccess,
  53. ThreadPoolExecutorReturnSuccess
  54. ),
  55. set()
  56. )
  57. R_BROKEN = (
  58. (
  59. ThreadPoolExecutorReturnSuccess,
  60. ),
  61. (
  62. ThreadPoolExecutorReturn,
  63. ThreadPoolExecutorReturn
  64. )
  65. )
  66. class TestBuildahBuilder(base.TestCase):
  67. @mock.patch.object(process, 'execute', autospec=True)
  68. def test_build(self, mock_process):
  69. args = copy.copy(BUILDAH_CMD_BASE)
  70. dest = '127.0.0.1:8787/master/fedora-binary-fedora-base:latest'
  71. container_build_path = WORK_DIR + '/' + 'fedora-base'
  72. logfile = '/tmp/kolla/fedora-base/fedora-base-build.log'
  73. buildah_cmd_build = ['bud', '--tls-verify=False', '--logfile',
  74. logfile, '-t', dest, container_build_path]
  75. args.extend(buildah_cmd_build)
  76. bb(WORK_DIR, DEPS).build('fedora-base', container_build_path)
  77. mock_process.assert_called_once_with(
  78. *args,
  79. check_exit_code=True,
  80. run_as_root=False,
  81. use_standard_locale=True
  82. )
  83. @mock.patch.object(process, 'execute', autospec=True)
  84. def test_push(self, mock_process):
  85. args = copy.copy(BUILDAH_CMD_BASE)
  86. dest = '127.0.0.1:8787/master/fedora-binary-fedora-base:latest'
  87. buildah_cmd_push = ['push', '--tls-verify=False', dest,
  88. 'docker://' + dest]
  89. args.extend(buildah_cmd_push)
  90. bb(WORK_DIR, DEPS).push(dest)
  91. mock_process.assert_called_once_with(
  92. *args, run_as_root=False, use_standard_locale=True
  93. )
  94. @mock.patch.object(bb, 'build', autospec=True)
  95. @mock.patch.object(bb, 'push', autospec=True)
  96. def test_generate_container_with_push(self, mock_push, mock_build):
  97. container_name = "fedora-base"
  98. destination = "127.0.0.1:8787/master/fedora-binary-{}:latest"
  99. builder = bb(WORK_DIR, DEPS, push_containers=True)
  100. builder._generate_container(container_name)
  101. mock_build.assert_called_once_with(builder, container_name, "")
  102. mock_push.assert_called_once_with(builder,
  103. destination.format(container_name))
  104. @mock.patch.object(bb, 'build', autospec=True)
  105. @mock.patch.object(bb, 'push', autospec=True)
  106. def test_generate_container_without_push(self, mock_push, mock_build):
  107. container_name = "fedora-base"
  108. builder = bb(WORK_DIR, DEPS, push_containers=False)
  109. builder._generate_container(container_name)
  110. mock_build.assert_called_once_with(builder, container_name, "")
  111. assert not mock_push.called
  112. @mock.patch.object(tpe, 'submit', autospec=True)
  113. @mock.patch.object(futures, 'wait', autospec=True, return_value=R_BROKEN)
  114. @mock.patch.object(process, 'execute', autospec=True)
  115. def test_build_all_list_broken(self, mock_submit, mock_wait, mock_build):
  116. _b = bb(WORK_DIR, DEPS)
  117. self.assertRaises(
  118. SystemError,
  119. _b.build_all,
  120. deps=BUILD_ALL_LIST_CONTAINERS
  121. )
  122. @mock.patch.object(tpe, 'submit', autospec=True)
  123. @mock.patch.object(futures, 'wait', autospec=True, return_value=R_FAILED)
  124. @mock.patch.object(process, 'execute', autospec=True)
  125. def test_build_all_list_failed(self, mock_submit, mock_wait, mock_build):
  126. _b = bb(WORK_DIR, DEPS)
  127. self.assertRaises(
  128. SystemError,
  129. _b.build_all,
  130. deps=BUILD_ALL_LIST_CONTAINERS
  131. )
  132. @mock.patch.object(tpe, 'submit', autospec=True)
  133. @mock.patch.object(futures, 'wait', autospec=True, return_value=R_OK)
  134. @mock.patch.object(process, 'execute', autospec=True)
  135. def test_build_all_list_ok(self, mock_submit, mock_wait, mock_build):
  136. bb(WORK_DIR, DEPS).build_all(deps=BUILD_ALL_LIST_CONTAINERS)
  137. @mock.patch.object(tpe, 'submit', autospec=True)
  138. @mock.patch.object(futures, 'wait', autospec=True, return_value=R_OK)
  139. @mock.patch.object(process, 'execute', autospec=True)
  140. def test_build_all_ok_no_deps(self, mock_submit, mock_wait, mock_build):
  141. bb(WORK_DIR, DEPS).build_all()
  142. @mock.patch.object(tpe, 'submit', autospec=True)
  143. @mock.patch.object(futures, 'wait', autospec=True, return_value=R_OK)
  144. @mock.patch.object(process, 'execute', autospec=True)
  145. def test_build_all_dict_ok(self, mock_submit, mock_wait, mock_build):
  146. bb(WORK_DIR, DEPS).build_all(deps=BUILD_ALL_DICT_CONTAINERS)
  147. @mock.patch.object(tpe, 'submit', autospec=True)
  148. @mock.patch.object(futures, 'wait', autospec=True, return_value=R_OK)
  149. @mock.patch.object(process, 'execute', autospec=True)
  150. def test_build_all_str_ok(self, mock_submit, mock_wait, mock_build):
  151. bb(WORK_DIR, DEPS).build_all(deps=BUILD_ALL_STR_CONTAINER)