hybrid_platforms_conductor 32.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. checksums.yaml +7 -0
  2. data/bin/check-node +24 -0
  3. data/bin/deploy +12 -0
  4. data/bin/dump_nodes_json +12 -0
  5. data/bin/free_ips +23 -0
  6. data/bin/free_veids +17 -0
  7. data/bin/get_impacted_nodes +43 -0
  8. data/bin/last_deploys +56 -0
  9. data/bin/nodes_to_deploy +104 -0
  10. data/bin/report +10 -0
  11. data/bin/run +39 -0
  12. data/bin/setup +11 -0
  13. data/bin/ssh_config +14 -0
  14. data/bin/test +13 -0
  15. data/bin/topograph +54 -0
  16. data/lib/hybrid_platforms_conductor/action.rb +82 -0
  17. data/lib/hybrid_platforms_conductor/actions_executor.rb +307 -0
  18. data/lib/hybrid_platforms_conductor/bitbucket.rb +123 -0
  19. data/lib/hybrid_platforms_conductor/cmd_runner.rb +188 -0
  20. data/lib/hybrid_platforms_conductor/cmdb.rb +34 -0
  21. data/lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb +78 -0
  22. data/lib/hybrid_platforms_conductor/common_config_dsl/confluence.rb +43 -0
  23. data/lib/hybrid_platforms_conductor/common_config_dsl/file_system_tests.rb +110 -0
  24. data/lib/hybrid_platforms_conductor/common_config_dsl/idempotence_tests.rb +38 -0
  25. data/lib/hybrid_platforms_conductor/config.rb +263 -0
  26. data/lib/hybrid_platforms_conductor/confluence.rb +119 -0
  27. data/lib/hybrid_platforms_conductor/connector.rb +84 -0
  28. data/lib/hybrid_platforms_conductor/credentials.rb +127 -0
  29. data/lib/hybrid_platforms_conductor/current_dir_monitor.rb +42 -0
  30. data/lib/hybrid_platforms_conductor/deployer.rb +598 -0
  31. data/lib/hybrid_platforms_conductor/executable.rb +145 -0
  32. data/lib/hybrid_platforms_conductor/hpc_plugins/action/bash.rb +44 -0
  33. data/lib/hybrid_platforms_conductor/hpc_plugins/action/interactive.rb +44 -0
  34. data/lib/hybrid_platforms_conductor/hpc_plugins/action/my_action.rb.sample +79 -0
  35. data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +63 -0
  36. data/lib/hybrid_platforms_conductor/hpc_plugins/action/ruby.rb +69 -0
  37. data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +61 -0
  38. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/config.rb +78 -0
  39. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_ip.rb +104 -0
  40. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_keys.rb +114 -0
  41. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/my_cmdb.rb.sample +129 -0
  42. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/platform_handlers.rb +66 -0
  43. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +156 -0
  44. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +702 -0
  45. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +292 -0
  46. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/docker.rb +148 -0
  47. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/my_provisioner.rb.sample +103 -0
  48. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +125 -0
  49. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +522 -0
  50. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/proxmox_waiter.rb +707 -0
  51. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/reserve_proxmox_container +122 -0
  52. data/lib/hybrid_platforms_conductor/hpc_plugins/report/confluence.rb +69 -0
  53. data/lib/hybrid_platforms_conductor/hpc_plugins/report/mediawiki.rb +164 -0
  54. data/lib/hybrid_platforms_conductor/hpc_plugins/report/my_report_plugin.rb.sample +88 -0
  55. data/lib/hybrid_platforms_conductor/hpc_plugins/report/stdout.rb +61 -0
  56. data/lib/hybrid_platforms_conductor/hpc_plugins/report/templates/confluence_inventory.html.erb +33 -0
  57. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +137 -0
  58. data/lib/hybrid_platforms_conductor/hpc_plugins/test/can_be_checked.rb +21 -0
  59. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +112 -0
  60. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_from_scratch.rb +35 -0
  61. data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +28 -0
  62. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +44 -0
  63. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_from_scratch.rb +36 -0
  64. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +49 -0
  65. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +25 -0
  66. data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +46 -0
  67. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +45 -0
  68. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system_hdfs.rb +45 -0
  69. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +25 -0
  70. data/lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb +77 -0
  71. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +38 -0
  72. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_conf.rb +56 -0
  73. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_masters_ok.rb +54 -0
  74. data/lib/hybrid_platforms_conductor/hpc_plugins/test/linear_strategy.rb +47 -0
  75. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +82 -0
  76. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +120 -0
  77. data/lib/hybrid_platforms_conductor/hpc_plugins/test/my_test_plugin.rb.sample +143 -0
  78. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +74 -0
  79. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +85 -0
  80. data/lib/hybrid_platforms_conductor/hpc_plugins/test/private_ips.rb +38 -0
  81. data/lib/hybrid_platforms_conductor/hpc_plugins/test/public_ips.rb +38 -0
  82. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre-meltdown-checker.sh +1930 -0
  83. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +56 -0
  84. data/lib/hybrid_platforms_conductor/hpc_plugins/test/veids.rb +31 -0
  85. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +159 -0
  86. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +122 -0
  87. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/my_test_report.rb.sample +48 -0
  88. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/stdout.rb +120 -0
  89. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/_confluence_errors_status.html.erb +46 -0
  90. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/_confluence_gauge.html.erb +49 -0
  91. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/confluence.html.erb +242 -0
  92. data/lib/hybrid_platforms_conductor/io_router.rb +70 -0
  93. data/lib/hybrid_platforms_conductor/json_dumper.rb +88 -0
  94. data/lib/hybrid_platforms_conductor/logger_helpers.rb +319 -0
  95. data/lib/hybrid_platforms_conductor/mutex_dir +76 -0
  96. data/lib/hybrid_platforms_conductor/nodes_handler.rb +597 -0
  97. data/lib/hybrid_platforms_conductor/parallel_threads.rb +97 -0
  98. data/lib/hybrid_platforms_conductor/platform_handler.rb +188 -0
  99. data/lib/hybrid_platforms_conductor/platforms_handler.rb +118 -0
  100. data/lib/hybrid_platforms_conductor/plugin.rb +53 -0
  101. data/lib/hybrid_platforms_conductor/plugins.rb +101 -0
  102. data/lib/hybrid_platforms_conductor/provisioner.rb +181 -0
  103. data/lib/hybrid_platforms_conductor/report.rb +31 -0
  104. data/lib/hybrid_platforms_conductor/reports_handler.rb +84 -0
  105. data/lib/hybrid_platforms_conductor/services_handler.rb +274 -0
  106. data/lib/hybrid_platforms_conductor/test.rb +141 -0
  107. data/lib/hybrid_platforms_conductor/test_by_service.rb +22 -0
  108. data/lib/hybrid_platforms_conductor/test_report.rb +282 -0
  109. data/lib/hybrid_platforms_conductor/tests_runner.rb +590 -0
  110. data/lib/hybrid_platforms_conductor/thycotic.rb +92 -0
  111. data/lib/hybrid_platforms_conductor/topographer.rb +859 -0
  112. data/lib/hybrid_platforms_conductor/topographer/plugin.rb +20 -0
  113. data/lib/hybrid_platforms_conductor/topographer/plugins/graphviz.rb +127 -0
  114. data/lib/hybrid_platforms_conductor/topographer/plugins/json.rb +72 -0
  115. data/lib/hybrid_platforms_conductor/topographer/plugins/my_topographer_output_plugin.rb.sample +37 -0
  116. data/lib/hybrid_platforms_conductor/topographer/plugins/svg.rb +30 -0
  117. data/lib/hybrid_platforms_conductor/version.rb +5 -0
  118. data/spec/hybrid_platforms_conductor_test.rb +159 -0
  119. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/bash_spec.rb +43 -0
  120. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/interactive_spec.rb +18 -0
  121. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +102 -0
  122. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/ruby_spec.rb +108 -0
  123. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/scp_spec.rb +79 -0
  124. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions_spec.rb +199 -0
  125. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connection_spec.rb +212 -0
  126. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +125 -0
  127. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb +50 -0
  128. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connectable_nodes_spec.rb +28 -0
  129. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +448 -0
  130. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +313 -0
  131. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb +32 -0
  132. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +134 -0
  133. data/spec/hybrid_platforms_conductor_test/api/actions_executor/logging_spec.rb +256 -0
  134. data/spec/hybrid_platforms_conductor_test/api/actions_executor/parallel_spec.rb +338 -0
  135. data/spec/hybrid_platforms_conductor_test/api/actions_executor/timeout_spec.rb +101 -0
  136. data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +165 -0
  137. data/spec/hybrid_platforms_conductor_test/api/config_spec.rb +238 -0
  138. data/spec/hybrid_platforms_conductor_test/api/deployer/check_spec.rb +9 -0
  139. data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +243 -0
  140. data/spec/hybrid_platforms_conductor_test/api/deployer/parse_deploy_output_spec.rb +104 -0
  141. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +131 -0
  142. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/docker/Dockerfile +10 -0
  143. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/docker_spec.rb +123 -0
  144. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/podman_spec.rb +211 -0
  145. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/config_dsl_spec.rb +126 -0
  146. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/create_spec.rb +290 -0
  147. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/destroy_spec.rb +43 -0
  148. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/ip_spec.rb +60 -0
  149. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/proxmox.json +3 -0
  150. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/destroy_vm_spec.rb +82 -0
  151. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/expired_containers_spec.rb +786 -0
  152. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/ips_assignment_spec.rb +112 -0
  153. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/other_lxc_containers_resources_spec.rb +190 -0
  154. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/pve_node_resources_spec.rb +200 -0
  155. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/retries_spec.rb +35 -0
  156. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/vm_ids_assignment_spec.rb +67 -0
  157. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/start_spec.rb +79 -0
  158. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/state_spec.rb +28 -0
  159. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/stop_spec.rb +41 -0
  160. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/config_spec.rb +33 -0
  161. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_ip_spec.rb +64 -0
  162. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_keys_spec.rb +133 -0
  163. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/platform_handlers_spec.rb +19 -0
  164. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +446 -0
  165. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb +127 -0
  166. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/git_diff_impacts_spec.rb +318 -0
  167. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +132 -0
  168. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/platform_handlers_plugins_api_spec.rb +60 -0
  169. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/several_platforms_spec.rb +58 -0
  170. data/spec/hybrid_platforms_conductor_test/api/platform_handler_spec.rb +97 -0
  171. data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +104 -0
  172. data/spec/hybrid_platforms_conductor_test/api/plugins_spec.rb +243 -0
  173. data/spec/hybrid_platforms_conductor_test/api/reports_handler_spec.rb +44 -0
  174. data/spec/hybrid_platforms_conductor_test/api/services_handler/actions_to_deploy_spec.rb +121 -0
  175. data/spec/hybrid_platforms_conductor_test/api/services_handler/deploy_allowed_spec.rb +142 -0
  176. data/spec/hybrid_platforms_conductor_test/api/services_handler/log_info_spec.rb +101 -0
  177. data/spec/hybrid_platforms_conductor_test/api/services_handler/package_spec.rb +388 -0
  178. data/spec/hybrid_platforms_conductor_test/api/services_handler/parse_deploy_output_spec.rb +274 -0
  179. data/spec/hybrid_platforms_conductor_test/api/services_handler/prepare_for_deploy_spec.rb +264 -0
  180. data/spec/hybrid_platforms_conductor_test/api/tests_runner/common_spec.rb +194 -0
  181. data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +37 -0
  182. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_check_spec.rb +194 -0
  183. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_spec.rb +137 -0
  184. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_ssh_spec.rb +257 -0
  185. data/spec/hybrid_platforms_conductor_test/api/tests_runner/platform_spec.rb +110 -0
  186. data/spec/hybrid_platforms_conductor_test/api/tests_runner/reports_spec.rb +367 -0
  187. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb +111 -0
  188. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb +29 -0
  189. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb +166 -0
  190. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb2.rb +93 -0
  191. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others.rb +60 -0
  192. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others2.rb +58 -0
  193. data/spec/hybrid_platforms_conductor_test/executables/check-node_spec.rb +35 -0
  194. data/spec/hybrid_platforms_conductor_test/executables/deploy_spec.rb +35 -0
  195. data/spec/hybrid_platforms_conductor_test/executables/get_impacted_nodes_spec.rb +158 -0
  196. data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +173 -0
  197. data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +283 -0
  198. data/spec/hybrid_platforms_conductor_test/executables/options/actions_executor_spec.rb +28 -0
  199. data/spec/hybrid_platforms_conductor_test/executables/options/cmd_runner_spec.rb +28 -0
  200. data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +67 -0
  201. data/spec/hybrid_platforms_conductor_test/executables/options/deployer_spec.rb +251 -0
  202. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_handler_spec.rb +111 -0
  203. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_selectors_spec.rb +71 -0
  204. data/spec/hybrid_platforms_conductor_test/executables/options/reports_handler_spec.rb +54 -0
  205. data/spec/hybrid_platforms_conductor_test/executables/options/tests_runner_spec.rb +139 -0
  206. data/spec/hybrid_platforms_conductor_test/executables/report_spec.rb +60 -0
  207. data/spec/hybrid_platforms_conductor_test/executables/run_spec.rb +173 -0
  208. data/spec/hybrid_platforms_conductor_test/executables/ssh_config_spec.rb +35 -0
  209. data/spec/hybrid_platforms_conductor_test/executables/test_spec.rb +41 -0
  210. data/spec/hybrid_platforms_conductor_test/helpers/actions_executor_helpers.rb +98 -0
  211. data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +92 -0
  212. data/spec/hybrid_platforms_conductor_test/helpers/cmdb_helpers.rb +37 -0
  213. data/spec/hybrid_platforms_conductor_test/helpers/config_helpers.rb +20 -0
  214. data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +130 -0
  215. data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +149 -0
  216. data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +812 -0
  217. data/spec/hybrid_platforms_conductor_test/helpers/executables_helpers.rb +96 -0
  218. data/spec/hybrid_platforms_conductor_test/helpers/nodes_handler_helpers.rb +20 -0
  219. data/spec/hybrid_platforms_conductor_test/helpers/platform_handler_helpers.rb +35 -0
  220. data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +127 -0
  221. data/spec/hybrid_platforms_conductor_test/helpers/plugins_helpers.rb +48 -0
  222. data/spec/hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers.rb +789 -0
  223. data/spec/hybrid_platforms_conductor_test/helpers/reports_handler_helpers.rb +29 -0
  224. data/spec/hybrid_platforms_conductor_test/helpers/services_handler_helpers.rb +20 -0
  225. data/spec/hybrid_platforms_conductor_test/helpers/tests_runner_helpers.rb +38 -0
  226. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id1.rb +22 -0
  227. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id2.rb +22 -0
  228. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type/test_plugin_id3.rb +26 -0
  229. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type2/test_plugin_id4.rb +26 -0
  230. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +225 -0
  231. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test2.rb +11 -0
  232. data/spec/hybrid_platforms_conductor_test/report_plugin.rb +35 -0
  233. data/spec/hybrid_platforms_conductor_test/test_action.rb +66 -0
  234. data/spec/hybrid_platforms_conductor_test/test_connector.rb +151 -0
  235. data/spec/hybrid_platforms_conductor_test/test_plugins/global.rb +30 -0
  236. data/spec/hybrid_platforms_conductor_test/test_plugins/node.rb +53 -0
  237. data/spec/hybrid_platforms_conductor_test/test_plugins/node_check.rb +47 -0
  238. data/spec/hybrid_platforms_conductor_test/test_plugins/node_ssh.rb +42 -0
  239. data/spec/hybrid_platforms_conductor_test/test_plugins/platform.rb +50 -0
  240. data/spec/hybrid_platforms_conductor_test/test_plugins/several_checks.rb +50 -0
  241. data/spec/hybrid_platforms_conductor_test/test_provisioner.rb +95 -0
  242. data/spec/hybrid_platforms_conductor_test/tests_report_plugin.rb +49 -0
  243. data/spec/spec_helper.rb +111 -0
  244. metadata +566 -0
@@ -0,0 +1,149 @@
1
+ module HybridPlatformsConductorTest
2
+
3
+ module Helpers
4
+
5
+ module DeployerHelpers
6
+
7
+ # Expect a given action to be setting up the mutex on a given node
8
+ #
9
+ # Parameters::
10
+ # * *action* (Hash<Symbol,Object>): The action to check
11
+ # * *node* (String): The concerned node
12
+ # * *sudo* (Boolean): Is sudo supposed to be used? [default: true]
13
+ def expect_action_to_lock_node(action, node, sudo: true)
14
+ expect(action[:scp].size).to eq 1
15
+ expect(action[:scp].first[0]).to match /^.+\/mutex_dir$/
16
+ expect(action[:scp].first[1]).to eq '.'
17
+ expect(action[:remote_bash]).to eq "while ! #{sudo ? 'sudo ' : ''}./mutex_dir lock /tmp/hybrid_platforms_conductor_deploy_lock \"$(ps -o ppid= -p $$)\"; do echo -e 'Another deployment is running on #{node}. Waiting for it to finish to continue...' ; sleep 5 ; done"
18
+ end
19
+
20
+ # Expect a given action to be releasing the mutex on a given node
21
+ #
22
+ # Parameters::
23
+ # * *action* (Hash<Symbol,Object>): The action to check
24
+ # * *node* (String): The concerned node
25
+ # * *sudo* (Boolean): Is sudo supposed to be used? [default: true]
26
+ def expect_action_to_unlock_node(action, node, sudo: true)
27
+ expect(action).to eq(remote_bash: "#{sudo ? 'sudo ' : ''}./mutex_dir unlock /tmp/hybrid_platforms_conductor_deploy_lock")
28
+ end
29
+
30
+ # Expect a given set of actions to be a deployment
31
+ #
32
+ # Parameters::
33
+ # * *actions* (Object): Actions
34
+ # * *nodes* (String or Array<String>): Node (or list of nodes) that should be checked
35
+ # * *check* (Boolean): Is the deploy only a check? [default: false]
36
+ # * *sudo* (Boolean): Is sudo supposed to be used? [default: true]
37
+ # * *expected_actions* (Array<Object>): Additional expected actions [default: []]
38
+ # * *mocked_result* (Hash<String, [Object, String, String]>): Expected result of the actions, per node, or nil for success [default: nil]
39
+ # Result::
40
+ # * Hash<String, [Integer or Symbol, String, String] >: Expected result of those expected actions
41
+ def expect_actions_to_deploy_on(actions, nodes, check: false, sudo: true, expected_actions: [], mocked_result: nil)
42
+ nodes = [nodes] if nodes.is_a?(String)
43
+ mocked_result = Hash[nodes.map { |node| [node, [0, "#{check ? 'Check' : 'Deploy'} successful", '']] }] if mocked_result.nil?
44
+ expect(actions.size).to eq nodes.size
45
+ nodes.each do |node|
46
+ expect(actions.key?(node)).to eq true
47
+ expect(actions[node].size).to eq(2 + expected_actions.size)
48
+ expect_action_to_lock_node(actions[node][0], node, sudo: sudo)
49
+ expect(actions[node][1..-2]).to eq expected_actions
50
+ expect(actions[node][-1]).to eq(bash: "echo \"#{check ? 'Checking' : 'Deploying'} on #{node}\"")
51
+ end
52
+ mocked_result
53
+ end
54
+
55
+ # Expect a given set of actions to be unlock deployments to a list of nodes
56
+ #
57
+ # Parameters::
58
+ # * *actions* (Object): Actions
59
+ # * *nodes* (String or Array<String>): Node (or list of nodes) that should be checked
60
+ # * *sudo* (Boolean): Is sudo supposed to be used? [default: true]
61
+ def expect_actions_to_unlock(actions, nodes, sudo: true)
62
+ nodes = [nodes] if nodes.is_a?(String)
63
+ expect(actions.size).to eq nodes.size
64
+ nodes.each do |node|
65
+ expect(actions.key?(node)).to eq true
66
+ expect_action_to_unlock_node(actions[node], node, sudo: sudo)
67
+ end
68
+ Hash[nodes.map { |node| [node, [0, 'Release mutex successful', '']] }]
69
+ end
70
+
71
+ # Expect a given set of actions to upload log files on a list of nodes
72
+ #
73
+ # Parameters::
74
+ # * *actions* (Object): Actions
75
+ # * *nodes* (String or Array<String>): Node (or list of nodes) that should be checked
76
+ # * *sudo* (Boolean): Is sudo supposed to be used? [default: true]
77
+ def expect_actions_to_upload_logs(actions, nodes, sudo: true)
78
+ nodes = [nodes] if nodes.is_a?(String)
79
+ expect(actions.size).to eq nodes.size
80
+ nodes.each do |node|
81
+ expect(actions.key?(node)).to eq true
82
+ expect(actions[node][:remote_bash]).to eq "#{sudo ? 'sudo ' : ''}mkdir -p /var/log/deployments"
83
+ expect(actions[node][:scp].first[1]).to eq '/var/log/deployments'
84
+ expect(actions[node][:scp][:group]).to eq 'root'
85
+ expect(actions[node][:scp][:owner]).to eq 'root'
86
+ expect(actions[node][:scp][:sudo]).to eq sudo
87
+ end
88
+ Hash[nodes.map { |node| [node, [0, 'Logs uploaded', '']] }]
89
+ end
90
+
91
+ # Expect some logs to have the following information.
92
+ # Expected logs format:
93
+ #
94
+ # date: 2019-08-14 17:02:57
95
+ # user: muriel
96
+ # debug: Yes
97
+ # repo_name: my_remote_platform
98
+ # commit_id: c0d16b1b7ae286ae4a059185957e08f0ddc95517
99
+ # commit_message: Test commit
100
+ # diff_files:
101
+ # ===== STDOUT =====
102
+ # Deploy successful
103
+ # ===== STDERR =====
104
+ #
105
+ # Parameters::
106
+ # * *logs* (String): The logs content
107
+ # * *stdout* (String): Expected STDOUT
108
+ # * *stderr* (String): Expected STDERR
109
+ # * *properties* (Hash<Symbol, String or Regexp>): Expected properties values, per name. Values can be exact strings or regexps.
110
+ def expect_logs_to_be(logs, stdout, stderr, properties)
111
+ lines = logs.split("\n")
112
+ idx_stdout = lines.index('===== STDOUT =====')
113
+ expect(idx_stdout).not_to eq nil
114
+ idx_stderr = lines.index('===== STDERR =====')
115
+ expect(idx_stderr).not_to eq nil
116
+ logs_properties = Hash[lines[0..idx_stdout - 1].map do |property_line|
117
+ property_fields = property_line.split(': ')
118
+ [
119
+ property_fields.first.to_sym,
120
+ property_fields[1..-1].join(': ')
121
+ ]
122
+ end]
123
+ expect(logs_properties.size).to eq properties.size
124
+ properties.each do |expected_property, expected_property_value|
125
+ expect(logs_properties.key?(expected_property)).to eq true
126
+ if expected_property_value.is_a?(String)
127
+ expect(logs_properties[expected_property]).to eq expected_property_value
128
+ else
129
+ expect(logs_properties[expected_property]).to match expected_property_value
130
+ end
131
+ end
132
+ expect(lines[idx_stdout + 1..idx_stderr - 1].join("\n")).to eq stdout
133
+ expect(lines[idx_stderr + 1..-1].join("\n")).to eq stderr
134
+ end
135
+
136
+ # Get a test Deployer
137
+ #
138
+ # Result::
139
+ # * Deployer: Deployer on which we can do testing
140
+ def test_deployer
141
+ @deployer = HybridPlatformsConductor::Deployer.new logger: logger, logger_stderr: logger, config: test_config, cmd_runner: test_cmd_runner, nodes_handler: test_nodes_handler, actions_executor: test_actions_executor, services_handler: test_services_handler unless @deployer
142
+ @deployer
143
+ end
144
+
145
+ end
146
+
147
+ end
148
+
149
+ end
@@ -0,0 +1,812 @@
1
+ module HybridPlatformsConductorTest
2
+
3
+ module Helpers
4
+
5
+ module DeployerTestHelpers
6
+
7
+ # Define deployment specs that are common for check mode and real deployment
8
+ #
9
+ # Parameters::
10
+ # * *check_mode* (Boolean): Are we in check-mode? [default: true]
11
+ def deploy_specs_for(check_mode: true)
12
+ expected_deploy_result = [0, "#{check_mode ? 'Check' : 'Deploy'} successful", '']
13
+ platform_name = check_mode ? 'platform' : 'my_remote_platform'
14
+
15
+ context "testing deployment#{check_mode ? ' in why-run mode' : ''}" do
16
+
17
+ # Get expected actions for a deployment
18
+ #
19
+ # Parameters::
20
+ # * *services* (Hash<String, Array<String> >): Expected nodes that should be deployed, with their corresponding services [default: { 'node' => %w[service] }]
21
+ # * *sudo* (Boolean): Do we expect sudo to be used in commands? [default: true]
22
+ # * *check_mode* (Boolean): Are we testing in check mode? [default: @check_mode]
23
+ # * *mocked_deploy_result* (Hash or nil): Mocked result of the deployment actions, or nil to use the helper's default [default: nil]
24
+ # * *additional_expected_actions* (Array): Additional expected actions [default: []]
25
+ # * *expect_concurrent_actions* (Boolean): Are actions expected to be run in parallel? [default: false]
26
+ # * *expect_actions_timeout* (Integer or nil): Expected timeout in actions, or nil for none [default: nil]
27
+ def expected_actions_for_deploy_on(
28
+ services: { 'node' => %w[service] },
29
+ sudo: true,
30
+ check_mode: @check_mode,
31
+ mocked_deploy_result: nil,
32
+ additional_expected_actions: [],
33
+ expect_concurrent_actions: false,
34
+ expect_actions_timeout: nil
35
+ )
36
+ actions = [
37
+ # First run, we expect the mutex to be setup, and the deployment actions to be run
38
+ proc do |actions_per_nodes, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
39
+ expect(timeout).to eq expect_actions_timeout
40
+ expect(concurrent).to eq expect_concurrent_actions
41
+ expect(log_to_dir).to eq 'run_logs'
42
+ expect_actions_to_deploy_on(
43
+ actions_per_nodes,
44
+ services.keys,
45
+ check: check_mode,
46
+ sudo: sudo,
47
+ mocked_result: mocked_deploy_result,
48
+ expected_actions: additional_expected_actions
49
+ )
50
+ end,
51
+ # Second run, we expect the mutex to be released
52
+ proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, services.keys, sudo: sudo) }
53
+ ]
54
+ services.each do |node, node_services|
55
+ expect(test_services_handler).to receive(:actions_to_deploy_on).with(node, node_services, check_mode) do
56
+ [{ bash: "echo \"#{check_mode ? 'Checking' : 'Deploying'} on #{node}\"" }]
57
+ end
58
+ end
59
+ # Third run, we expect logs to be uploaded on the node (only if not check mode)
60
+ unless check_mode
61
+ services.each do |node, node_services|
62
+ expect(test_services_handler).to receive(:log_info_for).with(node, node_services) do
63
+ {
64
+ repo_name_0: 'platform',
65
+ commit_id_0: '123456',
66
+ commit_message_0: 'Test commit'
67
+ }
68
+ end
69
+ end
70
+ actions << proc { |actions_per_nodes| expect_actions_to_upload_logs(actions_per_nodes, services.keys, sudo: sudo) }
71
+ end
72
+ actions
73
+ end
74
+
75
+ # Prepare a platform ready to test deployments on.
76
+ #
77
+ # Parameters::
78
+ # * *nodes_info* (Hash): Node info to give the platform [default: 1 node having 1 service]
79
+ # * *expect_default_actions* (Boolean): Should we expect default actions? [default: true]
80
+ # * *expect_sudo* (Boolean): Do we expect sudo to be used in commands? [default: true]
81
+ # * *expect_secrets* (Hash): Secrets to be expected during deployment [default: {}]
82
+ # * *expect_local_environment* (Boolean): Expected local environment flag [default: false]
83
+ # * *expect_additional_actions* (Array): Additional expected actions [default: []]
84
+ # * *expect_concurrent_actions* (Boolean): Are actions expected to be run in parallel? [default: false]
85
+ # * *expect_actions_timeout* (Integer or nil): Expected timeout in actions, or nil for none [default: nil]
86
+ # * *check_mode* (Boolean): Are we testing in check mode? [default: @check_mode]
87
+ # * *additional_config* (String): Additional configuration to set [default: '']
88
+ # * Proc: Code called once the platform is ready for testing the deployer
89
+ # * Parameters::
90
+ # * *repository* (String): Path to the repository
91
+ def with_platform_to_deploy(
92
+ nodes_info: { nodes: { 'node' => { services: %w[service] } } },
93
+ expect_default_actions: true,
94
+ expect_sudo: true,
95
+ expect_secrets: {},
96
+ expect_local_environment: false,
97
+ expect_additional_actions: [],
98
+ expect_concurrent_actions: false,
99
+ expect_actions_timeout: nil,
100
+ check_mode: @check_mode,
101
+ additional_config: ''
102
+ )
103
+ platform_name = check_mode ? 'platform' : 'my_remote_platform'
104
+ with_test_platform(nodes_info, !check_mode, additional_config) do |repository|
105
+ with_connections_mocked_on(nodes_info[:nodes].keys) do
106
+ # Mock the ServicesHandler accesses
107
+ expect_services_to_deploy = Hash[nodes_info[:nodes].map do |node, node_info|
108
+ [node, node_info[:services]]
109
+ end]
110
+ unless check_mode
111
+ expect(test_services_handler).to receive(:deploy_allowed?).with(
112
+ services: expect_services_to_deploy,
113
+ secrets: expect_secrets,
114
+ local_environment: expect_local_environment
115
+ ) do
116
+ nil
117
+ end
118
+ end
119
+ expect(test_services_handler).to receive(:package).with(
120
+ services: expect_services_to_deploy,
121
+ secrets: expect_secrets,
122
+ local_environment: expect_local_environment
123
+ )
124
+ expect(test_services_handler).to receive(:prepare_for_deploy).with(
125
+ services: expect_services_to_deploy,
126
+ secrets: expect_secrets,
127
+ local_environment: expect_local_environment,
128
+ why_run: check_mode
129
+ )
130
+ expect_actions_executor_runs(expected_actions_for_deploy_on(
131
+ services: expect_services_to_deploy,
132
+ check_mode: check_mode,
133
+ sudo: expect_sudo,
134
+ additional_expected_actions: expect_additional_actions,
135
+ expect_concurrent_actions: expect_concurrent_actions,
136
+ expect_actions_timeout: expect_actions_timeout
137
+ )) if expect_default_actions
138
+ test_deployer.use_why_run = true if check_mode
139
+ yield repository
140
+ end
141
+ end
142
+ end
143
+
144
+ # Prepare a directory with certificates
145
+ #
146
+ # Parameters::
147
+ # * Proc: Code called with the directory created with a mocked certificate
148
+ # * Parameters::
149
+ # * *certs_dir* (String): Directory containing certificates
150
+ def with_certs_dir
151
+ with_repository do |repository|
152
+ certs_dir = "#{repository}/certificates"
153
+ FileUtils.mkdir_p certs_dir
154
+ File.write("#{certs_dir}/test_cert.crt", 'Hello')
155
+ yield certs_dir
156
+ end
157
+ end
158
+
159
+ before :each do
160
+ @check_mode = check_mode
161
+ end
162
+
163
+ it 'deploys on 1 node' do
164
+ with_platform_to_deploy do
165
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
166
+ end
167
+ end
168
+
169
+ it 'deploys on 1 node having several services' do
170
+ with_platform_to_deploy(nodes_info: { nodes: { 'node' => { services: %w[service1 service2 service3] } } }) do
171
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
172
+ end
173
+ end
174
+
175
+ it 'deploys on 1 node in a local environment' do
176
+ with_platform_to_deploy(expect_local_environment: true) do
177
+ test_deployer.local_environment = true
178
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
179
+ expect(test_deployer.local_environment).to eq true
180
+ end
181
+ end
182
+
183
+ it 'deploys on 1 node using root' do
184
+ with_platform_to_deploy(expect_sudo: false) do
185
+ test_actions_executor.connector(:ssh).ssh_user = 'root'
186
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
187
+ end
188
+ end
189
+
190
+ it 'deploys on 1 node using 1 secret' do
191
+ with_platform_to_deploy(expect_secrets: { 'secret1' => 'password1' }) do
192
+ test_deployer.secrets = [{ 'secret1' => 'password1' }]
193
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
194
+ end
195
+ end
196
+
197
+ it 'deploys on 1 node using several secrets' do
198
+ with_platform_to_deploy(expect_secrets: { 'secret1' => 'password1', 'secret2' => 'password2' }) do
199
+ test_deployer.secrets = [{ 'secret1' => 'password1' }, { 'secret2' => 'password2' }]
200
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
201
+ end
202
+ end
203
+
204
+ it 'deploys on 1 node in local environment with certificates to install using hpc_certificates on Debian' do
205
+ with_certs_dir do |certs_dir|
206
+ with_platform_to_deploy(
207
+ nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
208
+ expect_local_environment: true,
209
+ expect_additional_actions: [
210
+ { remote_bash: 'sudo apt update && sudo apt install -y ca-certificates' },
211
+ {
212
+ remote_bash: 'sudo update-ca-certificates',
213
+ scp: {
214
+ certs_dir => '/usr/local/share/ca-certificates',
215
+ :sudo => true
216
+ }
217
+ }
218
+ ]
219
+ ) do
220
+ ENV['hpc_certificates'] = certs_dir
221
+ test_deployer.local_environment = true
222
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
223
+ end
224
+ end
225
+ end
226
+
227
+ it 'deploys on 1 node with certificates to install using hpc_certificates on Debian but ignores them in non-local environment' do
228
+ with_certs_dir do |certs_dir|
229
+ with_platform_to_deploy(nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } }) do
230
+ ENV['hpc_certificates'] = certs_dir
231
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
232
+ end
233
+ end
234
+ end
235
+
236
+ it 'deploys on 1 node with certificates to install using hpc_certificates on Debian using root' do
237
+ with_certs_dir do |certs_dir|
238
+ with_platform_to_deploy(
239
+ nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
240
+ expect_sudo: false,
241
+ expect_local_environment: true,
242
+ expect_additional_actions: [
243
+ { remote_bash: 'apt update && apt install -y ca-certificates' },
244
+ {
245
+ remote_bash: 'update-ca-certificates',
246
+ scp: {
247
+ certs_dir => '/usr/local/share/ca-certificates',
248
+ :sudo => false
249
+ }
250
+ }
251
+ ]
252
+ ) do
253
+ ENV['hpc_certificates'] = certs_dir
254
+ test_actions_executor.connector(:ssh).ssh_user = 'root'
255
+ test_deployer.local_environment = true
256
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
257
+ end
258
+ end
259
+ end
260
+
261
+ it 'deploys on 1 node with certificates to install using hpc_certificates on CentOS' do
262
+ with_certs_dir do |certs_dir|
263
+ with_platform_to_deploy(
264
+ nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
265
+ expect_local_environment: true,
266
+ expect_additional_actions: [
267
+ { remote_bash: 'sudo yum install -y ca-certificates' },
268
+ {
269
+ remote_bash: ['sudo update-ca-trust enable', 'sudo update-ca-trust extract'],
270
+ scp: {
271
+ "#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
272
+ :sudo => true
273
+ }
274
+ }
275
+ ]
276
+ ) do
277
+ ENV['hpc_certificates'] = certs_dir
278
+ test_deployer.local_environment = true
279
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
280
+ end
281
+ end
282
+ end
283
+
284
+ it 'deploys on 1 node with certificates to install using hpc_certificates on CentOS using root' do
285
+ with_certs_dir do |certs_dir|
286
+ with_platform_to_deploy(
287
+ nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
288
+ expect_sudo: false,
289
+ expect_local_environment: true,
290
+ expect_additional_actions: [
291
+ { remote_bash: 'yum install -y ca-certificates' },
292
+ {
293
+ remote_bash: ['update-ca-trust enable', 'update-ca-trust extract'],
294
+ scp: {
295
+ "#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
296
+ :sudo => false
297
+ }
298
+ }
299
+ ]
300
+ ) do
301
+ ENV['hpc_certificates'] = certs_dir
302
+ test_actions_executor.connector(:ssh).ssh_user = 'root'
303
+ test_deployer.local_environment = true
304
+ expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
305
+ end
306
+ end
307
+ end
308
+
309
+ it 'deploys on several nodes' do
310
+ with_platform_to_deploy(nodes_info: { nodes: {
311
+ 'node1' => { services: %w[service1] },
312
+ 'node2' => { services: %w[service2] },
313
+ 'node3' => { services: %w[service3] }
314
+ } }) do
315
+ expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
316
+ 'node1' => expected_deploy_result,
317
+ 'node2' => expected_deploy_result,
318
+ 'node3' => expected_deploy_result
319
+ )
320
+ end
321
+ end
322
+
323
+ it 'deploys on several nodes in parallel' do
324
+ with_platform_to_deploy(
325
+ nodes_info: {
326
+ nodes: {
327
+ 'node1' => { services: %w[service1] },
328
+ 'node2' => { services: %w[service2] },
329
+ 'node3' => { services: %w[service3] }
330
+ }
331
+ },
332
+ expect_concurrent_actions: true
333
+ ) do
334
+ test_deployer.concurrent_execution = true
335
+ expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
336
+ 'node1' => expected_deploy_result,
337
+ 'node2' => expected_deploy_result,
338
+ 'node3' => expected_deploy_result
339
+ )
340
+ end
341
+ end
342
+
343
+ it 'deploys on several nodes with timeout' do
344
+ with_platform_to_deploy(
345
+ nodes_info: {
346
+ nodes: {
347
+ 'node1' => { services: %w[service1] },
348
+ 'node2' => { services: %w[service2] },
349
+ 'node3' => { services: %w[service3] }
350
+ }
351
+ },
352
+ expect_actions_timeout: 5
353
+ ) do
354
+ test_deployer.timeout = 5
355
+ expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
356
+ 'node1' => expected_deploy_result,
357
+ 'node2' => expected_deploy_result,
358
+ 'node3' => expected_deploy_result
359
+ )
360
+ end
361
+ end
362
+
363
+ context 'checking deployment retries' do
364
+
365
+ # Prepare a platform ready to test deployments' retries on.
366
+ #
367
+ # Parameters::
368
+ # * *nodes_info* (Hash): Node info to give the platform [default: { nodes: { 'node' => {} } }]
369
+ # * Proc: Code called once the platform is ready for testing the deployer
370
+ # * Parameters::
371
+ # * *repository* (String): Path to the repository
372
+ def with_platform_to_retry_deploy(nodes_info: { nodes: { 'node' => { services: %w[service] } } })
373
+ with_platform_to_deploy(
374
+ nodes_info: nodes_info,
375
+ expect_default_actions: false,
376
+ additional_config: "
377
+ for_nodes([#{nodes_info[:nodes].keys.map { |node| "'#{node}'" }.join(', ')}]) do
378
+ retry_deploy_for_errors_on_stdout [
379
+ 'stdout non-deterministic error'
380
+ ]
381
+ retry_deploy_for_errors_on_stderr [
382
+ 'stderr non-deterministic error',
383
+ /stderr regexp error \\d+/
384
+ ]
385
+ end
386
+ for_nodes([#{nodes_info[:nodes].keys.map { |node| "'#{node}'" }.join(', ')}]) do
387
+ retry_deploy_for_errors_on_stdout [
388
+ /stdout regexp error \\d+/
389
+ ]
390
+ end
391
+ "
392
+ ) do |repository|
393
+ yield repository
394
+ end
395
+ end
396
+
397
+ # Mock a sequential list of deployments
398
+ #
399
+ # Parameters::
400
+ # * *statuses* (Array<Hash<String,Status> or Status>)>): List of mocked deployment statuses per node name, or just the status for the default node.
401
+ # A status is a triplet [Integer or Symbol, String, String]: exit status, stdout and stderr.
402
+ def mock_deploys_with(statuses)
403
+ expect_actions_executor_runs(statuses.map do |status|
404
+ status = { 'node' => status } if status.is_a?(Array)
405
+ expected_actions_for_deploy_on(
406
+ services: Hash[status.keys.map { |node| [node, %w[service]] }],
407
+ mocked_deploy_result: status
408
+ )
409
+ end.flatten)
410
+ end
411
+
412
+ it 'restarts deployment for a non-deterministic error' do
413
+ with_platform_to_retry_deploy do
414
+ test_deployer.nbr_retries_on_error = 1
415
+ mock_deploys_with [
416
+ [1, "Error: This is a stdout non-deterministic error\nDeploy failed\n", ''],
417
+ [0, 'Deploy ok', '']
418
+ ]
419
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
420
+ 0,
421
+ <<~EOS,
422
+ Error: This is a stdout non-deterministic error
423
+ Deploy failed
424
+
425
+ Deployment exit status code: 1
426
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
427
+ Deploy ok
428
+ EOS
429
+ <<~EOS
430
+ !!! 1 retriable errors detected in this deployment:
431
+ * stdout non-deterministic error
432
+
433
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
434
+
435
+ EOS
436
+ ])
437
+ end
438
+ end
439
+
440
+ it 'restarts deployment for a non-deterministic error matched with a Regexp' do
441
+ with_platform_to_retry_deploy do
442
+ test_deployer.nbr_retries_on_error = 1
443
+ mock_deploys_with [
444
+ [1, "Error: This is a stdout regexp error 42\nDeploy failed\n", ''],
445
+ [0, 'Deploy ok', '']
446
+ ]
447
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
448
+ 0,
449
+ <<~EOS,
450
+ Error: This is a stdout regexp error 42
451
+ Deploy failed
452
+
453
+ Deployment exit status code: 1
454
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
455
+ Deploy ok
456
+ EOS
457
+ <<~EOS
458
+ !!! 1 retriable errors detected in this deployment:
459
+ * /stdout regexp error \\d+/ matched 'stdout regexp error 42'
460
+
461
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
462
+
463
+ EOS
464
+ ])
465
+ end
466
+ end
467
+
468
+ it 'restarts deployment for a non-deterministic error on stderr' do
469
+ with_platform_to_retry_deploy do
470
+ test_deployer.nbr_retries_on_error = 1
471
+ mock_deploys_with [
472
+ [1, '', "Error: This is a stderr non-deterministic error\nDeploy failed\n"],
473
+ [0, 'Deploy ok', '']
474
+ ]
475
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
476
+ 0,
477
+ <<~EOS,
478
+
479
+ Deployment exit status code: 1
480
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
481
+ Deploy ok
482
+ EOS
483
+ <<~EOS
484
+ Error: This is a stderr non-deterministic error
485
+ Deploy failed
486
+ !!! 1 retriable errors detected in this deployment:
487
+ * stderr non-deterministic error
488
+
489
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
490
+
491
+ EOS
492
+ ])
493
+ end
494
+ end
495
+
496
+ it 'restarts deployment for a non-deterministic error on stderr matched with a Regexp' do
497
+ with_platform_to_retry_deploy do
498
+ test_deployer.nbr_retries_on_error = 1
499
+ mock_deploys_with [
500
+ [1, '', "Error: This is a stderr regexp error 42\nDeploy failed\n"],
501
+ [0, 'Deploy ok', '']
502
+ ]
503
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
504
+ 0,
505
+ <<~EOS,
506
+
507
+ Deployment exit status code: 1
508
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
509
+ Deploy ok
510
+ EOS
511
+ <<~EOS
512
+ Error: This is a stderr regexp error 42
513
+ Deploy failed
514
+ !!! 1 retriable errors detected in this deployment:
515
+ * /stderr regexp error \\d+/ matched 'stderr regexp error 42'
516
+
517
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
518
+
519
+ EOS
520
+ ])
521
+ end
522
+ end
523
+
524
+ it 'stops restarting deployments for a non-deterministic error when errors has disappeared, even if retries were remaining' do
525
+ with_platform_to_retry_deploy do
526
+ test_deployer.nbr_retries_on_error = 5
527
+ mock_deploys_with [
528
+ [1, "Error: This is a stdout non-deterministic error 1\nDeploy failed", ''],
529
+ [1, "Error: This is a stdout non-deterministic error 2\nDeploy failed", ''],
530
+ [0, 'Deploy ok', '']
531
+ ]
532
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
533
+ 0,
534
+ <<~EOS,
535
+ Error: This is a stdout non-deterministic error 1
536
+ Deploy failed
537
+ Deployment exit status code: 1
538
+ !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
539
+ Error: This is a stdout non-deterministic error 2
540
+ Deploy failed
541
+
542
+ Deployment exit status code: 1
543
+ !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
544
+ Deploy ok
545
+ EOS
546
+ <<~EOS
547
+ !!! 1 retriable errors detected in this deployment:
548
+ * stdout non-deterministic error
549
+
550
+ !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
551
+ !!! 1 retriable errors detected in this deployment:
552
+ * stdout non-deterministic error
553
+
554
+
555
+ !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
556
+
557
+ EOS
558
+ ])
559
+ end
560
+ end
561
+
562
+ it 'stops restarting deployments for a non-deterministic error that became deterministic, even if retries were remaining' do
563
+ with_platform_to_retry_deploy do
564
+ test_deployer.nbr_retries_on_error = 5
565
+ mock_deploys_with [
566
+ [1, "Error: This is a stdout non-deterministic error 1\nDeploy failed", ''],
567
+ [1, "Error: This is a stdout non-deterministic error 2\nDeploy failed", ''],
568
+ [1, "Error: This is a stdout deterministic error 3\nDeploy failed", '']
569
+ ]
570
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
571
+ 1,
572
+ <<~EOS,
573
+ Error: This is a stdout non-deterministic error 1
574
+ Deploy failed
575
+ Deployment exit status code: 1
576
+ !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
577
+ Error: This is a stdout non-deterministic error 2
578
+ Deploy failed
579
+
580
+ Deployment exit status code: 1
581
+ !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
582
+ Error: This is a stdout deterministic error 3
583
+ Deploy failed
584
+ EOS
585
+ <<~EOS
586
+ !!! 1 retriable errors detected in this deployment:
587
+ * stdout non-deterministic error
588
+
589
+ !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
590
+ !!! 1 retriable errors detected in this deployment:
591
+ * stdout non-deterministic error
592
+
593
+
594
+ !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
595
+
596
+ EOS
597
+ ])
598
+ end
599
+ end
600
+
601
+ it 'does not restart deployment for a deterministic error' do
602
+ with_platform_to_retry_deploy do
603
+ test_deployer.nbr_retries_on_error = 5
604
+ mock_deploys_with [
605
+ [1, "Error: This is a stdout deterministic error\nDeploy failed\n", '']
606
+ ]
607
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
608
+ 1,
609
+ <<~EOS,
610
+ Error: This is a stdout deterministic error
611
+ Deploy failed
612
+ EOS
613
+ ''
614
+ ])
615
+ end
616
+ end
617
+
618
+ it 'does not restart deployment for a non-deterministic error logged during a successful deploy' do
619
+ with_platform_to_retry_deploy do
620
+ test_deployer.nbr_retries_on_error = 5
621
+ mock_deploys_with [
622
+ [0, "Error: This is a stdout non-deterministic error\nDeploy failed\n", '']
623
+ ]
624
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
625
+ 0,
626
+ <<~EOS,
627
+ Error: This is a stdout non-deterministic error
628
+ Deploy failed
629
+ EOS
630
+ ''
631
+ ])
632
+ end
633
+ end
634
+
635
+ it 'does not restart deployment for a non-deterministic error if retries are 0' do
636
+ with_platform_to_retry_deploy do
637
+ test_deployer.nbr_retries_on_error = 0
638
+ mock_deploys_with [
639
+ [1, "Error: This is a stdout non-deterministic error\nDeploy failed\n", '']
640
+ ]
641
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
642
+ 1,
643
+ <<~EOS,
644
+ Error: This is a stdout non-deterministic error
645
+ Deploy failed
646
+ EOS
647
+ ''
648
+ ])
649
+ end
650
+ end
651
+
652
+ it 'restarts deployment for non-deterministic errors with a limited amount of retries' do
653
+ with_platform_to_retry_deploy do
654
+ test_deployer.nbr_retries_on_error = 2
655
+ mock_deploys_with [
656
+ [1, "Error: This is a stdout non-deterministic error 1\nDeploy failed", ''],
657
+ [1, "Error: This is a stdout non-deterministic error 2\nDeploy failed", ''],
658
+ [1, "Error: This is a stdout non-deterministic error 3\nDeploy failed", '']
659
+ ]
660
+ expect(test_deployer.deploy_on('node')).to eq('node' => [
661
+ 1,
662
+ <<~EOS,
663
+ Error: This is a stdout non-deterministic error 1
664
+ Deploy failed
665
+ Deployment exit status code: 1
666
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
667
+ Error: This is a stdout non-deterministic error 2
668
+ Deploy failed
669
+
670
+ Deployment exit status code: 1
671
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
672
+ Error: This is a stdout non-deterministic error 3
673
+ Deploy failed
674
+ EOS
675
+ <<~EOS
676
+ !!! 1 retriable errors detected in this deployment:
677
+ * stdout non-deterministic error
678
+
679
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
680
+ !!! 1 retriable errors detected in this deployment:
681
+ * stdout non-deterministic error
682
+
683
+
684
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
685
+
686
+ EOS
687
+ ])
688
+ end
689
+ end
690
+
691
+ it 'restarts deployment for non-deterministic errors only on nodes needing it' do
692
+ with_platform_to_retry_deploy(nodes_info: { nodes: {
693
+ 'node1' => { services: %w[service] },
694
+ 'node2' => { services: %w[service] },
695
+ 'node3' => { services: %w[service] },
696
+ 'node4' => { services: %w[service] }
697
+ } }) do
698
+ test_deployer.nbr_retries_on_error = 2
699
+ # Some nodes deploy successfully,
700
+ # others have deterministic errors,
701
+ # others have non-deterministic errors being corrected
702
+ # others have non-deterministic errors not being corrected
703
+ mock_deploys_with [
704
+ {
705
+ 'node1' => [1, "Error: This is a stdout non-deterministic error\n[node1] Deploy failed\n", ''],
706
+ 'node2' => [0, '[node2] Deploy ok', ''],
707
+ 'node3' => [1, "Error: This is a stdout non-deterministic error\n[node3] Deploy failed\n", ''],
708
+ 'node4' => [1, "Error: This is a stdout non-deterministic error\n[node4] Deploy failed\n", '']
709
+ },
710
+ {
711
+ 'node1' => [0, '[node1] Deploy ok', ''],
712
+ 'node3' => [1, "Error: This is a stdout deterministic error\n[node3] Deploy failed\n", ''],
713
+ 'node4' => [1, "Error: This is a stdout non-deterministic error\n[node4] Deploy failed\n", '']
714
+ },
715
+ {
716
+ 'node4' => [1, "Error: This is a stdout non-deterministic error\n[node4] Deploy failed\n", '']
717
+ }
718
+ ]
719
+ expect(test_deployer.deploy_on(%w[node1 node2 node3 node4])).to eq(
720
+ 'node1' => [
721
+ 0,
722
+ <<~EOS,
723
+ Error: This is a stdout non-deterministic error
724
+ [node1] Deploy failed
725
+
726
+ Deployment exit status code: 1
727
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
728
+ [node1] Deploy ok
729
+ EOS
730
+ <<~EOS
731
+ !!! 1 retriable errors detected in this deployment:
732
+ * stdout non-deterministic error
733
+
734
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
735
+
736
+ EOS
737
+ ],
738
+ 'node2' => [
739
+ 0,
740
+ '[node2] Deploy ok',
741
+ ''
742
+ ],
743
+ 'node3' => [
744
+ 1,
745
+ <<~EOS,
746
+ Error: This is a stdout non-deterministic error
747
+ [node3] Deploy failed
748
+
749
+ Deployment exit status code: 1
750
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
751
+ Error: This is a stdout deterministic error
752
+ [node3] Deploy failed
753
+
754
+ EOS
755
+ <<~EOS
756
+ !!! 1 retriable errors detected in this deployment:
757
+ * stdout non-deterministic error
758
+
759
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
760
+
761
+ EOS
762
+ ],
763
+ 'node4' => [
764
+ 1,
765
+ <<~EOS,
766
+ Error: This is a stdout non-deterministic error
767
+ [node4] Deploy failed
768
+
769
+ Deployment exit status code: 1
770
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
771
+ Error: This is a stdout non-deterministic error
772
+ [node4] Deploy failed
773
+
774
+
775
+ Deployment exit status code: 1
776
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
777
+ Error: This is a stdout non-deterministic error
778
+ [node4] Deploy failed
779
+
780
+ EOS
781
+ <<~EOS
782
+ !!! 1 retriable errors detected in this deployment:
783
+ * stdout non-deterministic error
784
+
785
+ !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
786
+ !!! 1 retriable errors detected in this deployment:
787
+ * stdout non-deterministic error
788
+
789
+
790
+ !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
791
+
792
+ EOS
793
+ ]
794
+ )
795
+ end
796
+ end
797
+
798
+ end
799
+
800
+ end
801
+
802
+ end
803
+
804
+ end
805
+
806
+ end
807
+
808
+ end
809
+
810
+ RSpec.configure do |c|
811
+ c.extend HybridPlatformsConductorTest::Helpers::DeployerTestHelpers
812
+ end