test_smartos_imgadm.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. # coding: utf-8
  2. # Python libs
  3. from __future__ import absolute_import, print_function, unicode_literals
  4. # Salt libs
  5. import salt.beacons.smartos_imgadm as imgadm
  6. from tests.support.mixins import LoaderModuleMockMixin
  7. from tests.support.mock import MagicMock, patch
  8. # Salt testing libs
  9. from tests.support.unit import TestCase
  10. # Mock Results
  11. MOCK_CLEAN_STATE = {"first_run": True, "images": []}
  12. MOCK_IMAGE_NONE = {}
  13. MOCK_IMAGE_ONE = {
  14. "00000000-0000-0000-0000-000000000001": {
  15. "description": "Example Image 1",
  16. "name": "example-1",
  17. "os": "smartos",
  18. "published": "2018-01-01T00:42:00Z",
  19. "source": "https://images.joyent.com",
  20. "version": "18.1.0",
  21. },
  22. }
  23. MOCK_IMAGE_TWO = {
  24. "00000000-0000-0000-0000-000000000001": {
  25. "description": "Example Image 1",
  26. "name": "example-1",
  27. "os": "smartos",
  28. "published": "2018-01-01T00:42:00Z",
  29. "source": "https://images.joyent.com",
  30. "version": "18.1.0",
  31. },
  32. "00000000-0000-0000-0000-000000000002": {
  33. "description": "Example Image 2",
  34. "name": "example-2",
  35. "os": "smartos",
  36. "published": "2018-01-01T00:42:00Z",
  37. "source": "https://images.joyent.com",
  38. "version": "18.2.0",
  39. },
  40. }
  41. class SmartOSImgAdmBeaconTestCase(TestCase, LoaderModuleMockMixin):
  42. """
  43. Test case for salt.beacons.imgadm
  44. """
  45. def setup_loader_modules(self):
  46. return {imgadm: {"__context__": {}, "__salt__": {}}}
  47. def test_non_list_config(self):
  48. """
  49. We only have minimal validation so we test that here
  50. """
  51. assert imgadm.validate({}) == (
  52. False,
  53. "Configuration for imgadm beacon must be a list!",
  54. )
  55. def test_imported_startup(self):
  56. """
  57. Test with one image and startup_import_event
  58. """
  59. # NOTE: this should yield 1 imported event
  60. with patch.dict(imgadm.IMGADM_STATE, MOCK_CLEAN_STATE), patch.dict(
  61. imgadm.__salt__, {"imgadm.list": MagicMock(return_value=MOCK_IMAGE_ONE)}
  62. ):
  63. config = [{"startup_import_event": True}]
  64. assert imgadm.validate(config) == (True, "Valid beacon configuration")
  65. ret = imgadm.beacon(config)
  66. res = [
  67. {
  68. "description": "Example Image 1",
  69. "name": "example-1",
  70. "os": "smartos",
  71. "published": "2018-01-01T00:42:00Z",
  72. "source": "https://images.joyent.com",
  73. "tag": "imported/00000000-0000-0000-0000-000000000001",
  74. "version": "18.1.0",
  75. }
  76. ]
  77. assert ret == res
  78. def test_imported_nostartup(self):
  79. """
  80. Test with one image and startup_import_event unset/false
  81. """
  82. # NOTE: this should yield 0 imported event
  83. with patch.dict(imgadm.IMGADM_STATE, MOCK_CLEAN_STATE), patch.dict(
  84. imgadm.__salt__, {"imgadm.list": MagicMock(return_value=MOCK_IMAGE_ONE)}
  85. ):
  86. config = []
  87. assert imgadm.validate(config) == (True, "Valid beacon configuration")
  88. assert imgadm.beacon(config) == []
  89. def test_imported(self):
  90. """
  91. Test with one image and a new image added on the 2nd pass
  92. """
  93. # NOTE: this should yield 1 imported event
  94. with patch.dict(imgadm.IMGADM_STATE, MOCK_CLEAN_STATE), patch.dict(
  95. imgadm.__salt__,
  96. {"imgadm.list": MagicMock(side_effect=[MOCK_IMAGE_ONE, MOCK_IMAGE_TWO])},
  97. ):
  98. config = []
  99. assert imgadm.validate(config) == (True, "Valid beacon configuration")
  100. # Initial pass (Initialized state and do not yield imported images at startup)
  101. imgadm.beacon(config)
  102. # Second pass (After importing a new image)
  103. ret = imgadm.beacon(config)
  104. res = [
  105. {
  106. "description": "Example Image 2",
  107. "name": "example-2",
  108. "os": "smartos",
  109. "published": "2018-01-01T00:42:00Z",
  110. "source": "https://images.joyent.com",
  111. "tag": "imported/00000000-0000-0000-0000-000000000002",
  112. "version": "18.2.0",
  113. }
  114. ]
  115. assert ret == res
  116. def test_deleted(self):
  117. """
  118. Test with two images and one gets deletes
  119. """
  120. # NOTE: this should yield 1 deleted event
  121. with patch.dict(imgadm.IMGADM_STATE, MOCK_CLEAN_STATE), patch.dict(
  122. imgadm.__salt__,
  123. {"imgadm.list": MagicMock(side_effect=[MOCK_IMAGE_TWO, MOCK_IMAGE_ONE])},
  124. ):
  125. config = []
  126. assert imgadm.validate(config) == (True, "Valid beacon configuration")
  127. # Initial pass (Initialized state and do not yield imported images at startup)
  128. imgadm.beacon(config)
  129. # Second pass (After deleting one image)
  130. ret = imgadm.beacon(config)
  131. res = [
  132. {
  133. "description": "Example Image 2",
  134. "name": "example-2",
  135. "os": "smartos",
  136. "published": "2018-01-01T00:42:00Z",
  137. "source": "https://images.joyent.com",
  138. "tag": "deleted/00000000-0000-0000-0000-000000000002",
  139. "version": "18.2.0",
  140. }
  141. ]
  142. assert ret == res
  143. def test_complex(self):
  144. """
  145. Test with one image, delete both, import 2
  146. """
  147. # NOTE: this should yield 1 delete and 2 import events
  148. with patch.dict(imgadm.IMGADM_STATE, MOCK_CLEAN_STATE), patch.dict(
  149. imgadm.__salt__,
  150. {
  151. "imgadm.list": MagicMock(
  152. side_effect=[MOCK_IMAGE_ONE, MOCK_IMAGE_NONE, MOCK_IMAGE_TWO]
  153. )
  154. },
  155. ):
  156. config = []
  157. assert imgadm.validate(config), (True, "Valid beacon configuration")
  158. # Initial pass (Initialized state and do not yield imported images at startup)
  159. imgadm.beacon(config)
  160. # Second pass (After deleting one image)
  161. ret = imgadm.beacon(config)
  162. res = [
  163. {
  164. "description": "Example Image 1",
  165. "name": "example-1",
  166. "os": "smartos",
  167. "published": "2018-01-01T00:42:00Z",
  168. "source": "https://images.joyent.com",
  169. "tag": "deleted/00000000-0000-0000-0000-000000000001",
  170. "version": "18.1.0",
  171. }
  172. ]
  173. assert ret == res
  174. # Third pass (After importing two images)
  175. ret = imgadm.beacon(config)
  176. res = [
  177. {
  178. "description": "Example Image 1",
  179. "name": "example-1",
  180. "os": "smartos",
  181. "published": "2018-01-01T00:42:00Z",
  182. "source": "https://images.joyent.com",
  183. "tag": "imported/00000000-0000-0000-0000-000000000001",
  184. "version": "18.1.0",
  185. },
  186. {
  187. "description": "Example Image 2",
  188. "name": "example-2",
  189. "os": "smartos",
  190. "published": "2018-01-01T00:42:00Z",
  191. "source": "https://images.joyent.com",
  192. "tag": "imported/00000000-0000-0000-0000-000000000002",
  193. "version": "18.2.0",
  194. },
  195. ]
  196. assert len(ret) == 2
  197. for item in ret:
  198. assert item in res