docker_image_availability_test.py 11 KB

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