docker_image_availability_test.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. import pytest
  2. from openshift_checks.docker_image_availability import DockerImageAvailability, DEPLOYMENT_IMAGE_INFO
  3. @pytest.fixture()
  4. def task_vars():
  5. return dict(
  6. openshift=dict(
  7. common=dict(
  8. is_containerized=False,
  9. is_atomic=False,
  10. ),
  11. docker=dict(),
  12. ),
  13. openshift_service_type='origin',
  14. openshift_deployment_type='origin',
  15. openshift_image_tag='',
  16. group_names=['oo_nodes_to_config', 'oo_masters_to_config'],
  17. )
  18. @pytest.mark.parametrize('deployment_type, is_containerized, group_names, expect_active', [
  19. ("invalid", True, [], False),
  20. ("", True, [], False),
  21. ("origin", False, [], False),
  22. ("openshift-enterprise", False, [], False),
  23. ("origin", False, ["oo_nodes_to_config", "oo_masters_to_config"], True),
  24. ("openshift-enterprise", False, ["oo_etcd_to_config"], False),
  25. ("origin", True, ["nfs"], False),
  26. ("openshift-enterprise", True, ["lb"], False),
  27. ])
  28. def test_is_active(task_vars, deployment_type, is_containerized, group_names, expect_active):
  29. task_vars['openshift_deployment_type'] = deployment_type
  30. task_vars['openshift']['common']['is_containerized'] = is_containerized
  31. task_vars['group_names'] = group_names
  32. assert DockerImageAvailability(None, task_vars).is_active() == expect_active
  33. @pytest.mark.parametrize("is_containerized,is_atomic", [
  34. (True, True),
  35. (False, False),
  36. (True, False),
  37. (False, True),
  38. ])
  39. def test_all_images_available_locally(task_vars, is_containerized, is_atomic):
  40. def execute_module(module_name, module_args, *_):
  41. if module_name == "yum":
  42. return {}
  43. assert module_name == "docker_image_facts"
  44. assert 'name' in module_args
  45. assert module_args['name']
  46. return {
  47. 'images': [module_args['name']],
  48. }
  49. task_vars['openshift']['common']['is_containerized'] = is_containerized
  50. task_vars['openshift']['common']['is_atomic'] = is_atomic
  51. result = DockerImageAvailability(execute_module, task_vars).run()
  52. assert not result.get('failed', False)
  53. @pytest.mark.parametrize("available_locally", [
  54. False,
  55. True,
  56. ])
  57. def test_all_images_available_remotely(task_vars, available_locally):
  58. def execute_module(module_name, *_):
  59. if module_name == 'docker_image_facts':
  60. return {'images': [], 'failed': available_locally}
  61. return {}
  62. task_vars['openshift_docker_additional_registries'] = ["docker.io", "registry.access.redhat.com"]
  63. task_vars['openshift_image_tag'] = 'v3.4'
  64. check = DockerImageAvailability(execute_module, task_vars)
  65. check._module_retry_interval = 0
  66. result = check.run()
  67. assert not result.get('failed', False)
  68. def test_all_images_unavailable(task_vars):
  69. def execute_module(module_name=None, *args):
  70. if module_name == "wait_for":
  71. return {}
  72. elif module_name == "command":
  73. return {'failed': True}
  74. return {} # docker_image_facts failure
  75. task_vars['openshift_docker_additional_registries'] = ["docker.io"]
  76. task_vars['openshift_deployment_type'] = "openshift-enterprise"
  77. task_vars['openshift_image_tag'] = 'latest'
  78. check = DockerImageAvailability(execute_module, task_vars)
  79. check._module_retry_interval = 0
  80. actual = check.run()
  81. assert actual['failed']
  82. assert "required container images are not available" in actual['msg']
  83. @pytest.mark.parametrize("message,extra_words", [
  84. (
  85. "docker image update failure",
  86. ["docker image update failure"],
  87. ),
  88. (
  89. "No package matching 'skopeo' found available, installed or updated",
  90. ["dependencies can be installed via `yum`"]
  91. ),
  92. ])
  93. def test_skopeo_update_failure(task_vars, message, extra_words):
  94. def execute_module(module_name=None, *_):
  95. if module_name == "yum":
  96. return {
  97. "failed": True,
  98. "msg": message,
  99. }
  100. return {}
  101. task_vars['openshift_docker_additional_registries'] = ["unknown.io"]
  102. task_vars['openshift_deployment_type'] = "openshift-enterprise"
  103. check = DockerImageAvailability(execute_module, task_vars)
  104. check._module_retry_interval = 0
  105. actual = check.run()
  106. assert actual["failed"]
  107. for word in extra_words:
  108. assert word in actual["msg"]
  109. @pytest.mark.parametrize(
  110. "image, registries, connection_test_failed, skopeo_failed, "
  111. "expect_success, expect_registries_reached", [
  112. (
  113. "spam/eggs:v1", ["test.reg"],
  114. True, True,
  115. False,
  116. {"test.reg": False, "docker.io": False},
  117. ),
  118. (
  119. "spam/eggs:v1", ["test.reg"],
  120. False, True,
  121. False,
  122. {"test.reg": True, "docker.io": True},
  123. ),
  124. (
  125. "eggs.reg/spam/eggs:v1", ["test.reg"],
  126. False, False,
  127. True,
  128. {"eggs.reg": True},
  129. ),
  130. ])
  131. def test_registry_availability(image, registries, connection_test_failed, skopeo_failed,
  132. expect_success, expect_registries_reached):
  133. def execute_module(module_name=None, *_):
  134. if module_name == "wait_for":
  135. return dict(msg="msg", failed=connection_test_failed)
  136. elif module_name == "command":
  137. return dict(msg="msg", failed=skopeo_failed)
  138. tv = task_vars()
  139. tv.update({"openshift_docker_additional_registries": registries})
  140. check = DockerImageAvailability(execute_module, tv)
  141. check._module_retry_interval = 0
  142. available = check.is_available_skopeo_image(image)
  143. assert available == expect_success
  144. assert expect_registries_reached == check.reachable_registries
  145. @pytest.mark.parametrize("deployment_type, is_containerized, groups, oreg_url, expected", [
  146. ( # standard set of stuff required on nodes
  147. "origin", False, ['oo_nodes_to_config'], "",
  148. set([
  149. 'openshift/origin-pod:vtest',
  150. 'openshift/origin-deployer:vtest',
  151. 'openshift/origin-docker-registry:vtest',
  152. 'openshift/origin-haproxy-router:vtest',
  153. 'cockpit/kubernetes:latest', # origin version of registry-console
  154. ])
  155. ),
  156. ( # set a different URL for images
  157. "origin", False, ['oo_nodes_to_config'], 'foo.io/openshift/origin-${component}:${version}',
  158. set([
  159. 'foo.io/openshift/origin-pod:vtest',
  160. 'foo.io/openshift/origin-deployer:vtest',
  161. 'foo.io/openshift/origin-docker-registry:vtest',
  162. 'foo.io/openshift/origin-haproxy-router:vtest',
  163. 'cockpit/kubernetes:latest', # AFAICS this is not built from the URL
  164. ])
  165. ),
  166. (
  167. "origin", True, ['oo_nodes_to_config', 'oo_masters_to_config', 'oo_etcd_to_config'], "",
  168. set([
  169. # images running on top of openshift
  170. 'openshift/origin-pod:vtest',
  171. 'openshift/origin-deployer:vtest',
  172. 'openshift/origin-docker-registry:vtest',
  173. 'openshift/origin-haproxy-router:vtest',
  174. 'cockpit/kubernetes:latest',
  175. # containerized component images
  176. 'openshift/origin:vtest',
  177. 'openshift/node:vtest',
  178. 'openshift/openvswitch:vtest',
  179. 'registry.access.redhat.com/rhel7/etcd',
  180. ])
  181. ),
  182. ( # enterprise images
  183. "openshift-enterprise", True, ['oo_nodes_to_config'], 'foo.io/openshift3/ose-${component}:f13ac45',
  184. set([
  185. 'foo.io/openshift3/ose-pod:f13ac45',
  186. 'foo.io/openshift3/ose-deployer:f13ac45',
  187. 'foo.io/openshift3/ose-docker-registry:f13ac45',
  188. 'foo.io/openshift3/ose-haproxy-router:f13ac45',
  189. # registry-console is not constructed/versioned the same as the others.
  190. 'openshift3/registry-console:vtest',
  191. # containerized images aren't built from oreg_url
  192. 'openshift3/node:vtest',
  193. 'openshift3/openvswitch:vtest',
  194. ])
  195. ),
  196. (
  197. "openshift-enterprise", True, ['oo_etcd_to_config', 'lb'], 'foo.io/openshift3/ose-${component}:f13ac45',
  198. set([
  199. 'registry.access.redhat.com/rhel7/etcd',
  200. # lb does not yet come in a containerized version
  201. ])
  202. ),
  203. ])
  204. def test_required_images(deployment_type, is_containerized, groups, oreg_url, expected):
  205. task_vars = dict(
  206. openshift=dict(
  207. common=dict(
  208. is_containerized=is_containerized,
  209. is_atomic=False,
  210. ),
  211. ),
  212. openshift_deployment_type=deployment_type,
  213. group_names=groups,
  214. oreg_url=oreg_url,
  215. openshift_image_tag='vtest',
  216. )
  217. assert expected == DockerImageAvailability(task_vars=task_vars).required_images()
  218. @pytest.mark.parametrize("task_vars, expected", [
  219. (
  220. dict(
  221. openshift_deployment_type="origin",
  222. openshift_image_tag="vtest",
  223. ),
  224. "cockpit/kubernetes:latest",
  225. ), (
  226. dict(
  227. openshift_deployment_type="openshift-enterprise",
  228. openshift_image_tag="vtest",
  229. ),
  230. "openshift3/registry-console:vtest",
  231. ), (
  232. dict(
  233. openshift_deployment_type="openshift-enterprise",
  234. openshift_image_tag="v3.7.0-alpha.0",
  235. openshift_cockpit_deployer_prefix="registry.example.com/spam/",
  236. ),
  237. "registry.example.com/spam/registry-console:v3.7",
  238. ), (
  239. dict(
  240. openshift_deployment_type="origin",
  241. openshift_image_tag="v3.7.0-alpha.0",
  242. openshift_cockpit_deployer_prefix="registry.example.com/eggs/",
  243. openshift_cockpit_deployer_version="spam",
  244. ),
  245. "registry.example.com/eggs/kubernetes:spam",
  246. ),
  247. ])
  248. def test_registry_console_image(task_vars, expected):
  249. info = DEPLOYMENT_IMAGE_INFO[task_vars["openshift_deployment_type"]]
  250. tag = task_vars["openshift_image_tag"]
  251. assert expected == DockerImageAvailability(task_vars=task_vars)._registry_console_image(tag, info)
  252. def test_containerized_etcd():
  253. task_vars = dict(
  254. openshift=dict(
  255. common=dict(
  256. is_containerized=True,
  257. ),
  258. ),
  259. openshift_deployment_type="origin",
  260. group_names=['oo_etcd_to_config'],
  261. )
  262. expected = set(['registry.access.redhat.com/rhel7/etcd'])
  263. assert expected == DockerImageAvailability(task_vars=task_vars).required_images()