scenarios_zero_downtime.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. from materialize.checks.actions import (
  10. Action,
  11. BumpVersion,
  12. GitResetHard,
  13. Initialize,
  14. Manipulate,
  15. Validate,
  16. )
  17. from materialize.checks.checks import Check
  18. from materialize.checks.executors import Executor
  19. from materialize.checks.features import Features
  20. from materialize.checks.mzcompose_actions import (
  21. MzcomposeAction,
  22. PromoteMz,
  23. StartMz,
  24. WaitReadyMz,
  25. )
  26. from materialize.checks.scenarios import Scenario
  27. from materialize.checks.scenarios_upgrade import (
  28. get_last_version,
  29. get_minor_versions,
  30. get_previous_version,
  31. start_mz_read_only,
  32. )
  33. from materialize.mz_version import MzVersion
  34. from materialize.mzcompose import get_default_system_parameters
  35. def wait_ready_and_promote(mz_service: str) -> list[MzcomposeAction]:
  36. return [WaitReadyMz(mz_service), PromoteMz(mz_service)]
  37. class ZeroDowntimeRestartEntireMz(Scenario):
  38. def actions(self) -> list[Action]:
  39. system_parameter_defaults = get_default_system_parameters(zero_downtime=True)
  40. return [
  41. StartMz(
  42. self,
  43. mz_service="mz_1",
  44. system_parameter_defaults=system_parameter_defaults,
  45. ),
  46. Initialize(self, mz_service="mz_1"),
  47. start_mz_read_only(
  48. self,
  49. deploy_generation=1,
  50. mz_service="mz_2",
  51. system_parameter_defaults=system_parameter_defaults,
  52. ),
  53. Manipulate(self, phase=1, mz_service="mz_1"),
  54. *wait_ready_and_promote("mz_2"),
  55. start_mz_read_only(
  56. self,
  57. deploy_generation=2,
  58. mz_service="mz_3",
  59. system_parameter_defaults=system_parameter_defaults,
  60. ),
  61. Manipulate(self, phase=2, mz_service="mz_2"),
  62. *wait_ready_and_promote("mz_3"),
  63. start_mz_read_only(
  64. self,
  65. deploy_generation=3,
  66. mz_service="mz_4",
  67. system_parameter_defaults=system_parameter_defaults,
  68. ),
  69. Validate(self, mz_service="mz_3"),
  70. *wait_ready_and_promote("mz_4"),
  71. Validate(self, mz_service="mz_4"),
  72. ]
  73. class ZeroDowntimeRestartEntireMzForcedMigrations(Scenario):
  74. def actions(self) -> list[Action]:
  75. system_parameter_defaults = get_default_system_parameters(zero_downtime=True)
  76. return [
  77. StartMz(
  78. self,
  79. mz_service="mz_1",
  80. system_parameter_defaults=system_parameter_defaults,
  81. ),
  82. Initialize(self, mz_service="mz_1"),
  83. start_mz_read_only(
  84. self,
  85. deploy_generation=1,
  86. mz_service="mz_2",
  87. system_parameter_defaults=system_parameter_defaults,
  88. force_migrations="all",
  89. ),
  90. Manipulate(self, phase=1, mz_service="mz_1"),
  91. *wait_ready_and_promote("mz_2"),
  92. start_mz_read_only(
  93. self,
  94. deploy_generation=2,
  95. mz_service="mz_3",
  96. system_parameter_defaults=system_parameter_defaults,
  97. force_migrations="all",
  98. ),
  99. Manipulate(self, phase=2, mz_service="mz_2"),
  100. *wait_ready_and_promote("mz_3"),
  101. start_mz_read_only(
  102. self,
  103. deploy_generation=3,
  104. mz_service="mz_4",
  105. system_parameter_defaults=system_parameter_defaults,
  106. force_migrations="all",
  107. ),
  108. Validate(self, mz_service="mz_3"),
  109. *wait_ready_and_promote("mz_4"),
  110. Validate(self, mz_service="mz_4"),
  111. ]
  112. class ZeroDowntimeUpgradeEntireMz(Scenario):
  113. """0dt upgrade of the entire Mz instance from the last released version."""
  114. def base_version(self) -> MzVersion:
  115. return get_last_version()
  116. def actions(self) -> list[Action]:
  117. print(f"Upgrading from tag {self.base_version()}")
  118. system_parameter_defaults = get_default_system_parameters(
  119. self.base_version(), zero_downtime=True
  120. )
  121. return [
  122. StartMz(
  123. self,
  124. tag=self.base_version(),
  125. mz_service="mz_1",
  126. system_parameter_defaults=system_parameter_defaults,
  127. ),
  128. Initialize(self, mz_service="mz_1"),
  129. start_mz_read_only(
  130. self,
  131. tag=None,
  132. deploy_generation=1,
  133. mz_service="mz_2",
  134. system_parameter_defaults=system_parameter_defaults,
  135. ),
  136. Manipulate(self, phase=1, mz_service="mz_1"),
  137. *wait_ready_and_promote("mz_2"),
  138. Manipulate(self, phase=2, mz_service="mz_2"),
  139. start_mz_read_only(
  140. self,
  141. tag=None,
  142. deploy_generation=2,
  143. mz_service="mz_3",
  144. system_parameter_defaults=system_parameter_defaults,
  145. ),
  146. Validate(self, mz_service="mz_2"),
  147. *wait_ready_and_promote("mz_3"),
  148. Validate(self, mz_service="mz_3"),
  149. ]
  150. class ZeroDowntimeBumpedVersion(Scenario):
  151. """0dt upgrade of the entire Mz instance from the current version to a
  152. version with just the version number bumped."""
  153. def actions(self) -> list[Action]:
  154. system_parameter_defaults = get_default_system_parameters(
  155. self.base_version(), zero_downtime=True
  156. )
  157. return [
  158. StartMz(
  159. self,
  160. mz_service="mz_1",
  161. system_parameter_defaults=system_parameter_defaults,
  162. ),
  163. Initialize(self, mz_service="mz_1"),
  164. start_mz_read_only(
  165. self,
  166. deploy_generation=1,
  167. mz_service="mz_2",
  168. system_parameter_defaults=system_parameter_defaults,
  169. ),
  170. Manipulate(self, phase=1, mz_service="mz_1"),
  171. BumpVersion(),
  172. *wait_ready_and_promote("mz_2"),
  173. Manipulate(self, phase=2, mz_service="mz_2"),
  174. start_mz_read_only(
  175. self,
  176. deploy_generation=2,
  177. mz_service="mz_3",
  178. system_parameter_defaults=system_parameter_defaults,
  179. publish=False, # Allows us to build the image during the test in CI
  180. ),
  181. Validate(self, mz_service="mz_2"),
  182. *wait_ready_and_promote("mz_3"),
  183. Validate(self, mz_service="mz_3"),
  184. GitResetHard(), # Undo the previous version bump in case we need to run the mz container
  185. ]
  186. class ZeroDowntimeUpgradeEntireMzTwoVersions(Scenario):
  187. """0dt upgrade of the entire Mz instance starting from the previous
  188. released version and passing through the last released version."""
  189. def base_version(self) -> MzVersion:
  190. return get_previous_version()
  191. def actions(self) -> list[Action]:
  192. print(f"Upgrade path: {self.base_version()} -> {get_last_version()} -> current")
  193. system_parameter_defaults = get_default_system_parameters(
  194. self.base_version(), zero_downtime=True
  195. )
  196. return [
  197. # Start with previous_version
  198. StartMz(
  199. self,
  200. tag=self.base_version(),
  201. mz_service="mz_1",
  202. system_parameter_defaults=system_parameter_defaults,
  203. ),
  204. Initialize(self, mz_service="mz_1"),
  205. # Upgrade to last_version
  206. start_mz_read_only(
  207. self,
  208. tag=get_last_version(),
  209. deploy_generation=1,
  210. mz_service="mz_2",
  211. system_parameter_defaults=system_parameter_defaults,
  212. ),
  213. Manipulate(self, phase=1, mz_service="mz_1"),
  214. *wait_ready_and_promote("mz_2"),
  215. # Upgrade to current source
  216. start_mz_read_only(
  217. self,
  218. tag=None,
  219. deploy_generation=2,
  220. mz_service="mz_3",
  221. system_parameter_defaults=system_parameter_defaults,
  222. ),
  223. Manipulate(self, phase=2, mz_service="mz_2"),
  224. *wait_ready_and_promote("mz_3"),
  225. start_mz_read_only(
  226. self,
  227. tag=None,
  228. deploy_generation=3,
  229. mz_service="mz_4",
  230. system_parameter_defaults=system_parameter_defaults,
  231. ),
  232. Validate(self, mz_service="mz_3"),
  233. *wait_ready_and_promote("mz_4"),
  234. Validate(self, mz_service="mz_4"),
  235. ]
  236. class ZeroDowntimeUpgradeEntireMzFourVersions(Scenario):
  237. """Test 0dt upgrade from X-4 -> X-3 -> X-2 -> X-1 -> X"""
  238. def __init__(
  239. self,
  240. checks: list[type[Check]],
  241. executor: Executor,
  242. features: Features,
  243. seed: str | None = None,
  244. ):
  245. self.minor_versions = get_minor_versions()
  246. super().__init__(checks, executor, features, seed)
  247. def base_version(self) -> MzVersion:
  248. return self.minor_versions[3]
  249. def actions(self) -> list[Action]:
  250. print(
  251. f"Upgrade path: {self.minor_versions[3]} -> {self.minor_versions[2]} -> {get_previous_version()} -> {get_last_version()} -> current"
  252. )
  253. system_parameter_defaults = get_default_system_parameters(
  254. self.base_version(), zero_downtime=True
  255. )
  256. return [
  257. StartMz(
  258. self,
  259. tag=self.minor_versions[3],
  260. mz_service="mz_1",
  261. system_parameter_defaults=system_parameter_defaults,
  262. ),
  263. Initialize(self, mz_service="mz_1"),
  264. start_mz_read_only(
  265. self,
  266. tag=self.minor_versions[2],
  267. deploy_generation=1,
  268. mz_service="mz_2",
  269. system_parameter_defaults=system_parameter_defaults,
  270. ),
  271. Manipulate(self, phase=1, mz_service="mz_1"),
  272. *wait_ready_and_promote("mz_2"),
  273. start_mz_read_only(
  274. self,
  275. tag=get_previous_version(),
  276. deploy_generation=2,
  277. mz_service="mz_3",
  278. system_parameter_defaults=system_parameter_defaults,
  279. ),
  280. Manipulate(self, phase=2, mz_service="mz_2"),
  281. *wait_ready_and_promote("mz_3"),
  282. start_mz_read_only(
  283. self,
  284. tag=get_last_version(),
  285. deploy_generation=3,
  286. mz_service="mz_4",
  287. system_parameter_defaults=system_parameter_defaults,
  288. ),
  289. Validate(self, mz_service="mz_3"),
  290. *wait_ready_and_promote("mz_4"),
  291. start_mz_read_only(
  292. self,
  293. tag=None,
  294. deploy_generation=4,
  295. mz_service="mz_5",
  296. system_parameter_defaults=system_parameter_defaults,
  297. ),
  298. Validate(self, mz_service="mz_4"),
  299. *wait_ready_and_promote("mz_5"),
  300. Validate(self, mz_service="mz_5"),
  301. ]