docker_storage_test.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import pytest
  2. from openshift_checks import OpenShiftCheckException
  3. from openshift_checks.docker_storage import DockerStorage
  4. def dummy_check(execute_module=None):
  5. def dummy_exec(self, status, task_vars):
  6. raise Exception("dummy executor called")
  7. return DockerStorage(execute_module=execute_module or dummy_exec)
  8. @pytest.mark.parametrize('is_containerized, group_names, is_active', [
  9. (False, ["masters", "etcd"], False),
  10. (False, ["masters", "nodes"], True),
  11. (True, ["etcd"], True),
  12. ])
  13. def test_is_active(is_containerized, group_names, is_active):
  14. task_vars = dict(
  15. openshift=dict(common=dict(is_containerized=is_containerized)),
  16. group_names=group_names,
  17. )
  18. assert DockerStorage.is_active(task_vars=task_vars) == is_active
  19. non_atomic_task_vars = {"openshift": {"common": {"is_atomic": False}}}
  20. @pytest.mark.parametrize('docker_info, failed, expect_msg', [
  21. (
  22. dict(failed=True, msg="Error connecting: Error while fetching server API version"),
  23. True,
  24. ["Is docker running on this host?"],
  25. ),
  26. (
  27. dict(msg="I have no info"),
  28. True,
  29. ["missing info"],
  30. ),
  31. (
  32. dict(info={
  33. "Driver": "devicemapper",
  34. "DriverStatus": [("Pool Name", "docker-docker--pool")],
  35. }),
  36. False,
  37. [],
  38. ),
  39. (
  40. dict(info={
  41. "Driver": "devicemapper",
  42. "DriverStatus": [("Data loop file", "true")],
  43. }),
  44. True,
  45. ["loopback devices with the Docker devicemapper storage driver"],
  46. ),
  47. (
  48. dict(info={
  49. "Driver": "overlay2",
  50. "DriverStatus": []
  51. }),
  52. False,
  53. [],
  54. ),
  55. (
  56. dict(info={
  57. "Driver": "overlay",
  58. }),
  59. True,
  60. ["unsupported Docker storage driver"],
  61. ),
  62. (
  63. dict(info={
  64. "Driver": "unsupported",
  65. }),
  66. True,
  67. ["unsupported Docker storage driver"],
  68. ),
  69. ])
  70. def test_check_storage_driver(docker_info, failed, expect_msg):
  71. def execute_module(module_name, module_args, tmp=None, task_vars=None):
  72. if module_name == "yum":
  73. return {}
  74. if module_name != "docker_info":
  75. raise ValueError("not expecting module " + module_name)
  76. return docker_info
  77. check = dummy_check(execute_module=execute_module)
  78. check._check_dm_usage = lambda status, task_vars: dict() # stub out for this test
  79. result = check.run(tmp=None, task_vars=non_atomic_task_vars)
  80. if failed:
  81. assert result["failed"]
  82. else:
  83. assert not result.get("failed", False)
  84. for word in expect_msg:
  85. assert word in result["msg"]
  86. enough_space = {
  87. "Pool Name": "docker--vg-docker--pool",
  88. "Data Space Used": "19.92 MB",
  89. "Data Space Total": "8.535 GB",
  90. "Metadata Space Used": "40.96 kB",
  91. "Metadata Space Total": "25.17 MB",
  92. }
  93. not_enough_space = {
  94. "Pool Name": "docker--vg-docker--pool",
  95. "Data Space Used": "10 GB",
  96. "Data Space Total": "10 GB",
  97. "Metadata Space Used": "42 kB",
  98. "Metadata Space Total": "43 kB",
  99. }
  100. @pytest.mark.parametrize('task_vars, driver_status, vg_free, success, expect_msg', [
  101. (
  102. {"max_thinpool_data_usage_percent": "not a float"},
  103. enough_space,
  104. "12g",
  105. False,
  106. ["is not a percentage"],
  107. ),
  108. (
  109. {},
  110. {}, # empty values from driver status
  111. "bogus", # also does not parse as bytes
  112. False,
  113. ["Could not interpret", "as bytes"],
  114. ),
  115. (
  116. {},
  117. enough_space,
  118. "12.00g",
  119. True,
  120. [],
  121. ),
  122. (
  123. {},
  124. not_enough_space,
  125. "0.00",
  126. False,
  127. ["data usage", "metadata usage", "higher than threshold"],
  128. ),
  129. ])
  130. def test_dm_usage(task_vars, driver_status, vg_free, success, expect_msg):
  131. check = dummy_check()
  132. check._get_vg_free = lambda pool, task_vars: vg_free
  133. result = check._check_dm_usage(driver_status, task_vars)
  134. result_success = not result.get("failed")
  135. assert result_success is success
  136. for msg in expect_msg:
  137. assert msg in result["msg"]
  138. @pytest.mark.parametrize('pool, command_returns, raises, returns', [
  139. (
  140. "foo-bar",
  141. { # vgs missing
  142. "msg": "[Errno 2] No such file or directory",
  143. "failed": True,
  144. "cmd": "/sbin/vgs",
  145. "rc": 2,
  146. },
  147. "Failed to run /sbin/vgs",
  148. None,
  149. ),
  150. (
  151. "foo", # no hyphen in name - should not happen
  152. {},
  153. "name does not have the expected format",
  154. None,
  155. ),
  156. (
  157. "foo-bar",
  158. dict(stdout=" 4.00g\n"),
  159. None,
  160. "4.00g",
  161. ),
  162. (
  163. "foo-bar",
  164. dict(stdout="\n"), # no matching VG
  165. "vgs did not find this VG",
  166. None,
  167. )
  168. ])
  169. def test_vg_free(pool, command_returns, raises, returns):
  170. def execute_module(module_name, module_args, tmp=None, task_vars=None):
  171. if module_name != "command":
  172. raise ValueError("not expecting module " + module_name)
  173. return command_returns
  174. check = dummy_check(execute_module=execute_module)
  175. if raises:
  176. with pytest.raises(OpenShiftCheckException) as err:
  177. check._get_vg_free(pool, {})
  178. assert raises in str(err.value)
  179. else:
  180. ret = check._get_vg_free(pool, {})
  181. assert ret == returns
  182. @pytest.mark.parametrize('string, expect_bytes', [
  183. ("12", 12.0),
  184. ("12 k", 12.0 * 1024),
  185. ("42.42 MB", 42.42 * 1024**2),
  186. ("12g", 12.0 * 1024**3),
  187. ])
  188. def test_convert_to_bytes(string, expect_bytes):
  189. got = DockerStorage._convert_to_bytes(string)
  190. assert got == expect_bytes
  191. @pytest.mark.parametrize('string', [
  192. "bork",
  193. "42 Qs",
  194. ])
  195. def test_convert_to_bytes_error(string):
  196. with pytest.raises(ValueError) as err:
  197. DockerStorage._convert_to_bytes(string)
  198. assert "Cannot convert" in str(err.value)
  199. assert string in str(err.value)