hybrid_platforms_conductor 33.0.0 → 33.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/bin/check-node +0 -1
  4. data/bin/deploy +0 -1
  5. data/bin/get_impacted_nodes +0 -1
  6. data/bin/last_deploys +8 -7
  7. data/bin/nodes_to_deploy +2 -2
  8. data/bin/setup +6 -6
  9. data/bin/topograph +1 -1
  10. data/lib/hybrid_platforms_conductor/action.rb +4 -4
  11. data/lib/hybrid_platforms_conductor/actions_executor.rb +37 -42
  12. data/lib/hybrid_platforms_conductor/bitbucket.rb +5 -4
  13. data/lib/hybrid_platforms_conductor/cmd_runner.rb +13 -12
  14. data/lib/hybrid_platforms_conductor/cmdb.rb +2 -2
  15. data/lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb +2 -1
  16. data/lib/hybrid_platforms_conductor/common_config_dsl/confluence.rb +2 -1
  17. data/lib/hybrid_platforms_conductor/common_config_dsl/file_system_tests.rb +5 -4
  18. data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +4 -3
  19. data/lib/hybrid_platforms_conductor/common_config_dsl/idempotence_tests.rb +2 -2
  20. data/lib/hybrid_platforms_conductor/config.rb +7 -4
  21. data/lib/hybrid_platforms_conductor/confluence.rb +1 -1
  22. data/lib/hybrid_platforms_conductor/connector.rb +5 -2
  23. data/lib/hybrid_platforms_conductor/core_extensions/symbol/zero.rb +24 -0
  24. data/lib/hybrid_platforms_conductor/credentials.rb +39 -36
  25. data/lib/hybrid_platforms_conductor/current_dir_monitor.rb +4 -1
  26. data/lib/hybrid_platforms_conductor/deployer.rb +95 -96
  27. data/lib/hybrid_platforms_conductor/executable.rb +20 -15
  28. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/config.rb +10 -7
  29. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_ip.rb +1 -1
  30. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_keys.rb +2 -2
  31. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/platform_handlers.rb +4 -4
  32. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +2 -0
  33. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +45 -49
  34. data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +6 -5
  35. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +68 -66
  36. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +13 -0
  37. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +39 -38
  38. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +5 -4
  39. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/docker.rb +43 -45
  40. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +18 -20
  41. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +118 -117
  42. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/proxmox_waiter.rb +39 -43
  43. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/reserve_proxmox_container +9 -13
  44. data/lib/hybrid_platforms_conductor/hpc_plugins/report/confluence.rb +2 -2
  45. data/lib/hybrid_platforms_conductor/hpc_plugins/report/mediawiki.rb +28 -21
  46. data/lib/hybrid_platforms_conductor/hpc_plugins/report/stdout.rb +26 -22
  47. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/cli.rb +8 -6
  48. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/thycotic.rb +7 -4
  49. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +3 -3
  50. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +4 -2
  51. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +0 -1
  52. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +21 -19
  53. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +2 -2
  54. data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +2 -2
  55. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +19 -21
  56. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system_hdfs.rb +19 -21
  57. data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +2 -3
  58. data/lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb +2 -2
  59. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +1 -1
  60. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_conf.rb +21 -22
  61. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_masters_ok.rb +10 -12
  62. data/lib/hybrid_platforms_conductor/hpc_plugins/test/linear_strategy.rb +9 -9
  63. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +2 -2
  64. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +2 -2
  65. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +10 -9
  66. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +2 -2
  67. data/lib/hybrid_platforms_conductor/hpc_plugins/test/private_ips.rb +5 -5
  68. data/lib/hybrid_platforms_conductor/hpc_plugins/test/public_ips.rb +5 -5
  69. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +4 -6
  70. data/lib/hybrid_platforms_conductor/hpc_plugins/test/veids.rb +3 -3
  71. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +25 -24
  72. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +2 -2
  73. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/stdout.rb +8 -6
  74. data/lib/hybrid_platforms_conductor/io_router.rb +14 -13
  75. data/lib/hybrid_platforms_conductor/json_dumper.rb +2 -2
  76. data/lib/hybrid_platforms_conductor/log.rb +2 -2
  77. data/lib/hybrid_platforms_conductor/logger_helpers.rb +19 -16
  78. data/lib/hybrid_platforms_conductor/nodes_handler.rb +89 -71
  79. data/lib/hybrid_platforms_conductor/parallel_threads.rb +7 -11
  80. data/lib/hybrid_platforms_conductor/platform_handler.rb +7 -7
  81. data/lib/hybrid_platforms_conductor/platforms_handler.rb +5 -3
  82. data/lib/hybrid_platforms_conductor/plugin.rb +2 -2
  83. data/lib/hybrid_platforms_conductor/plugins.rb +13 -8
  84. data/lib/hybrid_platforms_conductor/provisioner.rb +4 -4
  85. data/lib/hybrid_platforms_conductor/report.rb +2 -2
  86. data/lib/hybrid_platforms_conductor/reports_handler.rb +3 -2
  87. data/lib/hybrid_platforms_conductor/secrets_reader.rb +2 -2
  88. data/lib/hybrid_platforms_conductor/services_handler.rb +32 -29
  89. data/lib/hybrid_platforms_conductor/test_only_remote_node.rb +1 -1
  90. data/lib/hybrid_platforms_conductor/test_report.rb +15 -18
  91. data/lib/hybrid_platforms_conductor/tests_runner.rb +116 -118
  92. data/lib/hybrid_platforms_conductor/thycotic.rb +28 -19
  93. data/lib/hybrid_platforms_conductor/topographer.rb +200 -190
  94. data/lib/hybrid_platforms_conductor/topographer/plugins/graphviz.rb +8 -8
  95. data/lib/hybrid_platforms_conductor/topographer/plugins/json.rb +4 -4
  96. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  97. data/spec/hybrid_platforms_conductor_test.rb +6 -6
  98. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/bash_spec.rb +16 -11
  99. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/interactive_spec.rb +1 -1
  100. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +23 -18
  101. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/ruby_spec.rb +67 -49
  102. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/scp_spec.rb +20 -14
  103. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions_spec.rb +63 -50
  104. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connection_spec.rb +35 -35
  105. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +12 -8
  106. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +4 -7
  107. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +21 -22
  108. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb +23 -24
  109. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connectable_nodes_spec.rb +10 -6
  110. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +73 -54
  111. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +145 -126
  112. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb +3 -3
  113. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +29 -25
  114. data/spec/hybrid_platforms_conductor_test/api/actions_executor/logging_spec.rb +106 -91
  115. data/spec/hybrid_platforms_conductor_test/api/actions_executor/parallel_spec.rb +272 -244
  116. data/spec/hybrid_platforms_conductor_test/api/actions_executor/timeout_spec.rb +10 -12
  117. data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +36 -36
  118. data/spec/hybrid_platforms_conductor_test/api/config_spec.rb +24 -22
  119. data/spec/hybrid_platforms_conductor_test/api/deployer/check_spec.rb +4 -2
  120. data/spec/hybrid_platforms_conductor_test/api/deployer/config_dsl_spec.rb +7 -11
  121. data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +34 -26
  122. data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +21 -21
  123. data/spec/hybrid_platforms_conductor_test/api/deployer/parse_deploy_output_spec.rb +55 -59
  124. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +36 -62
  125. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/podman_spec.rb +17 -17
  126. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/config_dsl_spec.rb +4 -4
  127. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/create_spec.rb +44 -51
  128. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/destroy_spec.rb +3 -3
  129. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/ip_spec.rb +12 -16
  130. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/destroy_vm_spec.rb +31 -19
  131. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/expired_containers_spec.rb +324 -266
  132. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/ips_assignment_spec.rb +89 -61
  133. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/other_lxc_containers_resources_spec.rb +117 -93
  134. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/pve_node_resources_spec.rb +71 -54
  135. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/retries_spec.rb +10 -8
  136. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/vm_ids_assignment_spec.rb +80 -60
  137. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/start_spec.rb +1 -1
  138. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/state_spec.rb +1 -1
  139. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/stop_spec.rb +1 -1
  140. data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/cli_spec.rb +21 -20
  141. data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/thycotic_spec.rb +70 -55
  142. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/config_spec.rb +8 -10
  143. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_ip_spec.rb +33 -24
  144. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_keys_spec.rb +64 -51
  145. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/platform_handlers_spec.rb +3 -3
  146. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +50 -51
  147. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb +91 -81
  148. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/config_dsl_spec.rb +14 -16
  149. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/git_diff_impacts_spec.rb +51 -75
  150. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +35 -26
  151. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/platform_handlers_plugins_api_spec.rb +24 -16
  152. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/several_platforms_spec.rb +29 -19
  153. data/spec/hybrid_platforms_conductor_test/api/platform_handler_spec.rb +4 -4
  154. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/config_dsl_spec.rb +2 -2
  155. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/deploy_output_parsing_spec.rb +6 -6
  156. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +57 -99
  157. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/inventory_spec.rb +4 -4
  158. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +32 -35
  159. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +10 -10
  160. data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +38 -27
  161. data/spec/hybrid_platforms_conductor_test/api/plugins_spec.rb +46 -52
  162. data/spec/hybrid_platforms_conductor_test/api/reports_handler_spec.rb +2 -2
  163. data/spec/hybrid_platforms_conductor_test/api/services_handler/actions_to_deploy_spec.rb +90 -58
  164. data/spec/hybrid_platforms_conductor_test/api/services_handler/deploy_allowed_spec.rb +38 -34
  165. data/spec/hybrid_platforms_conductor_test/api/services_handler/log_info_spec.rb +11 -9
  166. data/spec/hybrid_platforms_conductor_test/api/services_handler/package_spec.rb +193 -171
  167. data/spec/hybrid_platforms_conductor_test/api/services_handler/parse_deploy_output_spec.rb +66 -54
  168. data/spec/hybrid_platforms_conductor_test/api/services_handler/prepare_for_deploy_spec.rb +147 -133
  169. data/spec/hybrid_platforms_conductor_test/api/tests_runner/common_spec.rb +69 -49
  170. data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +4 -3
  171. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_check_spec.rb +8 -5
  172. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_spec.rb +8 -5
  173. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_ssh_spec.rb +30 -27
  174. data/spec/hybrid_platforms_conductor_test/api/tests_runner/platform_spec.rb +12 -9
  175. data/spec/hybrid_platforms_conductor_test/api/tests_runner/reports_spec.rb +48 -47
  176. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb +5 -5
  177. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +5 -5
  178. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb +5 -5
  179. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb +9 -9
  180. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/{test_cmdb2.rb → test_cmdb_2.rb} +6 -6
  181. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others.rb +3 -3
  182. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/{test_cmdb_others2.rb → test_cmdb_others_2.rb} +2 -2
  183. data/spec/hybrid_platforms_conductor_test/docs_spec.rb +1 -1
  184. data/spec/hybrid_platforms_conductor_test/executables/{check-node_spec.rb → check_node_spec.rb} +4 -6
  185. data/spec/hybrid_platforms_conductor_test/executables/deploy_spec.rb +4 -6
  186. data/spec/hybrid_platforms_conductor_test/executables/get_impacted_nodes_spec.rb +76 -77
  187. data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +13 -15
  188. data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +289 -307
  189. data/spec/hybrid_platforms_conductor_test/executables/options/actions_executor_spec.rb +4 -6
  190. data/spec/hybrid_platforms_conductor_test/executables/options/cmd_runner_spec.rb +3 -5
  191. data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +8 -9
  192. data/spec/hybrid_platforms_conductor_test/executables/options/deployer_spec.rb +12 -14
  193. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_handler_spec.rb +9 -10
  194. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_selectors_spec.rb +9 -10
  195. data/spec/hybrid_platforms_conductor_test/executables/options/reports_handler_spec.rb +1 -1
  196. data/spec/hybrid_platforms_conductor_test/executables/options/tests_runner_spec.rb +22 -22
  197. data/spec/hybrid_platforms_conductor_test/executables/report_spec.rb +22 -16
  198. data/spec/hybrid_platforms_conductor_test/executables/run_spec.rb +32 -32
  199. data/spec/hybrid_platforms_conductor_test/executables/ssh_config_spec.rb +7 -9
  200. data/spec/hybrid_platforms_conductor_test/executables/test_spec.rb +3 -5
  201. data/spec/hybrid_platforms_conductor_test/helpers/actions_executor_helpers.rb +2 -2
  202. data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +4 -3
  203. data/spec/hybrid_platforms_conductor_test/helpers/cmdb_helpers.rb +2 -2
  204. data/spec/hybrid_platforms_conductor_test/helpers/config_helpers.rb +1 -1
  205. data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +12 -13
  206. data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +216 -14
  207. data/spec/hybrid_platforms_conductor_test/helpers/executables_helpers.rb +11 -11
  208. data/spec/hybrid_platforms_conductor_test/helpers/nodes_handler_helpers.rb +1 -1
  209. data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +39 -28
  210. data/spec/hybrid_platforms_conductor_test/helpers/plugins_helpers.rb +1 -1
  211. data/spec/hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers.rb +86 -111
  212. data/spec/hybrid_platforms_conductor_test/helpers/reports_handler_helpers.rb +1 -1
  213. data/spec/hybrid_platforms_conductor_test/helpers/serverless_chef_helpers.rb +3 -3
  214. data/spec/hybrid_platforms_conductor_test/helpers/services_handler_helpers.rb +1 -1
  215. data/spec/hybrid_platforms_conductor_test/helpers/tests_runner_helpers.rb +1 -1
  216. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/{test_plugin_id1.rb → test_plugin_id_1.rb} +0 -0
  217. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/{test_plugin_id2.rb → test_plugin_id_2.rb} +0 -0
  218. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type/{test_plugin_id3.rb → test_plugin_id_3.rb} +0 -0
  219. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/{test_plugin_type2/test_plugin_id4.rb → test_plugin_type_2/test_plugin_id_4.rb} +0 -0
  220. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +1 -1
  221. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/{test2.rb → test_2.rb} +0 -0
  222. data/spec/hybrid_platforms_conductor_test/rubocop_spec.rb +31 -0
  223. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json +3 -3
  224. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/nodes/node.json +3 -3
  225. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/libraries/default.rb +1 -0
  226. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/libraries/default.rb +1 -0
  227. data/spec/hybrid_platforms_conductor_test/shared_examples/deployer.rb +952 -0
  228. data/spec/hybrid_platforms_conductor_test/test_connector.rb +3 -3
  229. data/spec/hybrid_platforms_conductor_test/test_log_no_read_plugin.rb +3 -1
  230. data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +3 -1
  231. data/spec/hybrid_platforms_conductor_test/test_plugins/global.rb +1 -0
  232. data/spec/hybrid_platforms_conductor_test/test_plugins/node.rb +1 -0
  233. data/spec/hybrid_platforms_conductor_test/test_plugins/node_check.rb +1 -0
  234. data/spec/hybrid_platforms_conductor_test/test_plugins/platform.rb +1 -0
  235. data/spec/hybrid_platforms_conductor_test/test_plugins/several_checks.rb +2 -2
  236. data/spec/hybrid_platforms_conductor_test/test_secrets_reader_plugin.rb +4 -4
  237. data/spec/hybrid_platforms_conductor_test/tests_report_plugin.rb +5 -6
  238. data/spec/spec_helper.rb +17 -18
  239. data/tools/check_md +16 -20
  240. data/tools/generate_mermaid +1 -1
  241. metadata +43 -13
  242. data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +0 -1152
@@ -45,7 +45,7 @@ module HybridPlatformsConductorTest
45
45
  #
46
46
  # Parameters::
47
47
  # * *options_parser* (OptionParser): The option parser to complete
48
- def options_parse(options_parser)
48
+ def options_parse(_options_parser)
49
49
  @calls << [:options_parse]
50
50
  end
51
51
 
@@ -102,7 +102,7 @@ module HybridPlatformsConductorTest
102
102
  # * *bash_cmds* (String): Bash commands to execute
103
103
  def remote_bash(bash_cmds)
104
104
  @calls << [:remote_bash, bash_cmds]
105
- @remote_bash_code.call(@stdout_io, @stderr_io, self) unless @remote_bash_code.nil?
105
+ @remote_bash_code&.call(@stdout_io, @stderr_io, self)
106
106
  end
107
107
 
108
108
  # Execute an interactive shell on the remote node
@@ -140,7 +140,7 @@ module HybridPlatformsConductorTest
140
140
  extra_opts[:owner] = owner if owner
141
141
  extra_opts[:group] = group if group
142
142
  @calls << [:remote_copy, from, to] + (extra_opts.empty? ? [] : [extra_opts])
143
- @remote_copy_code.call(@stdout_io, @stderr_io, self) unless @remote_copy_code.nil?
143
+ @remote_copy_code&.call(@stdout_io, @stderr_io, self)
144
144
  end
145
145
 
146
146
  # Integer: The current desired timeout
@@ -4,7 +4,9 @@ module HybridPlatformsConductorTest
4
4
  class TestLogNoReadPlugin < HybridPlatformsConductor::Log
5
5
 
6
6
  class << self
7
+
7
8
  attr_accessor :calls
9
+
8
10
  end
9
11
 
10
12
  # Get actions to save logs
@@ -29,7 +31,7 @@ module HybridPlatformsConductorTest
29
31
  node: node,
30
32
  services: services,
31
33
  # Don't store the date
32
- deployment_info: deployment_info.select { |k, _v| k != :date },
34
+ deployment_info: deployment_info.reject { |k, _v| k == :date },
33
35
  exit_status: exit_status,
34
36
  stdout: stdout,
35
37
  stderr: stderr
@@ -4,7 +4,9 @@ module HybridPlatformsConductorTest
4
4
  class TestLogPlugin < HybridPlatformsConductor::Log
5
5
 
6
6
  class << self
7
+
7
8
  attr_accessor :calls
9
+
8
10
  end
9
11
 
10
12
  # Get actions to save logs
@@ -29,7 +31,7 @@ module HybridPlatformsConductorTest
29
31
  node: node,
30
32
  services: services,
31
33
  # Don't store the date
32
- deployment_info: deployment_info.select { |k, _v| k != :date },
34
+ deployment_info: deployment_info.reject { |k, _v| k == :date },
33
35
  exit_status: exit_status,
34
36
  stdout: stdout,
35
37
  stderr: stderr
@@ -20,6 +20,7 @@ module HybridPlatformsConductorTest
20
20
  # Check my_test_plugin.rb.sample documentation for signature details.
21
21
  def test
22
22
  raise 'Failing test' if Global.fail
23
+
23
24
  Global.nbr_runs += 1
24
25
  end
25
26
 
@@ -33,6 +33,7 @@ module HybridPlatformsConductorTest
33
33
  # Check my_test_plugin.rb.sample documentation for signature details.
34
34
  def test_for_node
35
35
  raise "Failing test #{@name} for #{@node}" if Node.fail_for.key?(@name) && Node.fail_for[@name].include?(@node)
36
+
36
37
  sleep_time = Node.sleeps.dig(@name, @node)
37
38
  sleep sleep_time unless sleep_time.nil?
38
39
  Node.runs << [@name, @node]
@@ -29,6 +29,7 @@ module HybridPlatformsConductorTest
29
29
  # Check my_test_plugin.rb.sample documentation for signature details.
30
30
  def test_on_check_node(stdout, stderr, exit_status)
31
31
  raise 'Failing test' if NodeCheck.fail_for.include? @node
32
+
32
33
  NodeCheck.runs << [@name, @node, stdout, stderr, exit_status]
33
34
  end
34
35
 
@@ -30,6 +30,7 @@ module HybridPlatformsConductorTest
30
30
  def test_on_platform
31
31
  platform_name = @platform.name
32
32
  raise 'Failing test' if Platform.fail_for.include? platform_name
33
+
33
34
  sleep_time = Platform.sleeps.dig(@name, platform_name)
34
35
  sleep sleep_time unless sleep_time.nil?
35
36
  Platform.runs << [@name, platform_name]
@@ -32,14 +32,14 @@ module HybridPlatformsConductorTest
32
32
  # Check my_test_plugin.rb.sample documentation for signature details.
33
33
  def test_on_node
34
34
  {
35
- "test_#{@node}.sh" => proc do |stdout, stderr, exit_code|
35
+ "test_#{@node}.sh" => proc do |stdout, stderr|
36
36
  SeveralChecks.runs << [@name, @node, "Node SSH test: #{stdout.join("\n")} - #{stderr.join("\n")}"]
37
37
  end
38
38
  }
39
39
  end
40
40
 
41
41
  # Check my_test_plugin.rb.sample documentation for signature details.
42
- def test_on_check_node(stdout, stderr, exit_status)
42
+ def test_on_check_node(stdout, _stderr, _exit_status)
43
43
  SeveralChecks.runs << [@name, @node, "Node check-node test: #{stdout}"]
44
44
  end
45
45
 
@@ -6,9 +6,9 @@ module HybridPlatformsConductorTest
6
6
  class TestSecretsReaderPlugin < HybridPlatformsConductor::SecretsReader
7
7
 
8
8
  class << self
9
- attr_accessor :calls
10
- attr_accessor :deployer
11
- attr_accessor :mocked_secrets
9
+
10
+ attr_accessor :calls, :deployer, :mocked_secrets
11
+
12
12
  end
13
13
 
14
14
  # Return secrets for a given service to be deployed on a node.
@@ -25,7 +25,7 @@ module HybridPlatformsConductorTest
25
25
  # * Hash: The secrets
26
26
  def secrets_for(node, service)
27
27
  # Get the name by looking into the plugins' map
28
- plugin_name, _plugin = TestSecretsReaderPlugin.deployer.instance_variable_get(:@secrets_readers).find { |plugin_name, plugin| plugin == self }
28
+ plugin_name, _plugin = TestSecretsReaderPlugin.deployer.instance_variable_get(:@secrets_readers).find { |_plugin_name, plugin| plugin == self }
29
29
  TestSecretsReaderPlugin.calls << {
30
30
  instance: plugin_name,
31
31
  node: node,
@@ -4,9 +4,11 @@ module HybridPlatformsConductorTest
4
4
  class TestsReportPlugin < HybridPlatformsConductor::TestReport
5
5
 
6
6
  class << self
7
+
7
8
  # Reports (that can be compared), per report name
8
9
  # Array< Hash<Symbol, Object> >
9
10
  attr_accessor :reports
11
+
10
12
  end
11
13
 
12
14
  # Handle tests reports
@@ -15,12 +17,9 @@ module HybridPlatformsConductorTest
15
17
  global_tests: report_from(global_tests),
16
18
  platform_tests: report_from(platform_tests),
17
19
  node_tests: report_from(node_tests),
18
- errors_per_test: Hash[group_errors(node_tests, :test_name).map do |test_name, errors|
19
- [
20
- test_name,
21
- errors.map { |error| error.split("\n").first }
22
- ]
23
- end],
20
+ errors_per_test: group_errors(node_tests, :test_name).transform_values do |errors|
21
+ errors.map { |error| error.split("\n").first }
22
+ end,
24
23
  nodes_by_nodes_list: nodes_by_nodes_list
25
24
  }
26
25
  end
data/spec/spec_helper.rb CHANGED
@@ -32,7 +32,7 @@ RSpec.configure do |config|
32
32
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
33
 
34
34
  # Increase the diffs length being output, as some tests are dealing with a few lines of stdout
35
- expectations.max_formatted_output_length = 65536
35
+ expectations.max_formatted_output_length = 65_536
36
36
 
37
37
  end
38
38
 
@@ -55,57 +55,56 @@ RSpec.configure do |config|
55
55
  # triggering implicit auto-inclusion in groups with matching metadata.
56
56
  config.shared_context_metadata_behavior = :apply_to_host_groups
57
57
 
58
- # The settings below are suggested to provide a good initial experience
59
- # with RSpec, but feel free to customize to your heart's content.
60
- =begin
58
+ # The settings below are suggested to provide a good initial experience
59
+ # with RSpec, but feel free to customize to your heart's content.
60
+
61
61
  # This allows you to limit a spec run to individual examples or groups
62
62
  # you care about by tagging them with `:focus` metadata. When nothing
63
63
  # is tagged with `:focus`, all examples get run. RSpec also provides
64
64
  # aliases for `it`, `describe`, and `context` that include `:focus`
65
65
  # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
66
- config.filter_run_when_matching :focus
66
+ # config.filter_run_when_matching :focus
67
67
 
68
68
  # Allows RSpec to persist some state between runs in order to support
69
69
  # the `--only-failures` and `--next-failure` CLI options. We recommend
70
70
  # you configure your source control system to ignore this file.
71
- config.example_status_persistence_file_path = "spec/examples.txt"
71
+ # config.example_status_persistence_file_path = "spec/examples.txt"
72
72
 
73
73
  # Limits the available syntax to the non-monkey patched syntax that is
74
74
  # recommended. For more details, see:
75
75
  # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
76
76
  # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
77
77
  # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
78
- config.disable_monkey_patching!
78
+ # config.disable_monkey_patching!
79
79
 
80
80
  # This setting enables warnings. It's recommended, but in some cases may
81
81
  # be too noisy due to issues in dependencies.
82
- config.warnings = true
82
+ # config.warnings = true
83
83
 
84
84
  # Many RSpec users commonly either run the entire suite or an individual
85
85
  # file, and it's useful to allow more verbose output when running an
86
86
  # individual spec file.
87
- if config.files_to_run.one?
88
- # Use the documentation formatter for detailed output,
89
- # unless a formatter has already been configured
90
- # (e.g. via a command-line flag).
91
- config.default_formatter = "doc"
92
- end
87
+ # if config.files_to_run.one?
88
+ # # Use the documentation formatter for detailed output,
89
+ # # unless a formatter has already been configured
90
+ # # (e.g. via a command-line flag).
91
+ # config.default_formatter = "doc"
92
+ # end
93
93
 
94
94
  # Print the 10 slowest examples and example groups at the
95
95
  # end of the spec run, to help surface which specs are running
96
96
  # particularly slow.
97
- config.profile_examples = 10
97
+ # config.profile_examples = 10
98
98
 
99
99
  # Run specs in random order to surface order dependencies. If you find an
100
100
  # order dependency and want to debug it, you can fix the order by providing
101
101
  # the seed, which is printed after each run.
102
102
  # --seed 1234
103
- config.order = :random
103
+ # config.order = :random
104
104
 
105
105
  # Seed global randomization in this process using the `--seed` CLI option.
106
106
  # Setting this allows you to use `--seed` to deterministically reproduce
107
107
  # test failures related to randomization by passing the same `--seed` value
108
108
  # as the one that triggered the failure.
109
- Kernel.srand config.seed
110
- =end
109
+ # Kernel.srand config.seed
111
110
  end
data/tools/check_md CHANGED
@@ -18,7 +18,7 @@ def link_to_file(link, file)
18
18
  if link_file == ''
19
19
  file
20
20
  elsif link_file.start_with?('/')
21
- link_file[1..-1]
21
+ link_file[1..]
22
22
  else
23
23
  File.expand_path("#{File.dirname(file)}/#{link_file}").gsub("#{Dir.pwd}/", '')
24
24
  end
@@ -29,22 +29,20 @@ end
29
29
  # Parameters::
30
30
  # * *file* (String): Markdown file to be parsed
31
31
  def parse_md(file)
32
- unless @info.key?(file)
33
- puts "Parsing #{file}..."
34
- content = File.read(file)
35
- @info[file] = {
36
- anchors: content.scan(/<a name="([^"]*)"><\/a>/).map { |(anchor)| anchor },
37
- links: content.scan(/\[[^\]]*\]\(([^\)]*)\)/).map { |(link)| link }
38
- }
39
- # Parse linked files
40
- @info[file][:links].each do |link|
41
- puts "Found #{file} => #{link}"
42
- end
43
- @info[file][:links].each do |link|
44
- unless link.start_with?('http')
45
- linked_file = link_to_file(link, file)
46
- parse_md(linked_file) if File.exist?(linked_file) && linked_file.end_with?('.md')
47
- end
32
+ return if @info.key?(file)
33
+
34
+ puts "Parsing #{file}..."
35
+ content = File.read(file)
36
+ @info[file] = {
37
+ anchors: content.scan(%r{<a name="([^"]*)"></a>}).map { |(anchor)| anchor },
38
+ links: content.scan(/\[[^\]]*\]\(([^)]*)\)/).map { |(link)| link }
39
+ }
40
+ # Parse linked files
41
+ @info[file][:links].each do |link|
42
+ puts "Found #{file} => #{link}"
43
+ unless link.start_with?('http')
44
+ linked_file = link_to_file(link, file)
45
+ parse_md(linked_file) if File.exist?(linked_file) && linked_file.end_with?('.md')
48
46
  end
49
47
  end
50
48
  end
@@ -63,9 +61,7 @@ errors = []
63
61
  anchor = link.split('#')[1]
64
62
  linked_file = link_to_file(link, file)
65
63
  if @info.key?(linked_file)
66
- if anchor.nil?
67
- '*'
68
- elsif @info[linked_file][:anchors].include?(anchor)
64
+ if anchor.nil? || @info[linked_file][:anchors].include?(anchor)
69
65
  '*'
70
66
  else
71
67
  errors << "[#{file} -> #{link}] - Destination has no anchor named #{anchor}"
@@ -64,7 +64,7 @@ def gen_mermaid(file)
64
64
  markdown << line
65
65
  end
66
66
  end
67
- File.write(file, markdown.map { |line| "#{line}\n" }.join) if idx_mermaid > 0
67
+ File.write(file, markdown.map { |line| "#{line}\n" }.join) if idx_mermaid.positive?
68
68
  end
69
69
 
70
70
  Tempfile.create('puppeteer') do |puppeteer_file|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hybrid_platforms_conductor
3
3
  version: !ruby/object:Gem::Version
4
- version: 33.0.0
4
+ version: 33.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-15 00:00:00.000000000 Z
11
+ date: 2021-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: range_operators
@@ -290,6 +290,34 @@ dependencies:
290
290
  - - "~>"
291
291
  - !ruby/object:Gem::Version
292
292
  version: '0.0'
293
+ - !ruby/object:Gem::Dependency
294
+ name: rubocop
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - "~>"
298
+ - !ruby/object:Gem::Version
299
+ version: '1.16'
300
+ type: :development
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - "~>"
305
+ - !ruby/object:Gem::Version
306
+ version: '1.16'
307
+ - !ruby/object:Gem::Dependency
308
+ name: rubocop-rspec
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - "~>"
312
+ - !ruby/object:Gem::Version
313
+ version: '2.4'
314
+ type: :development
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - "~>"
319
+ - !ruby/object:Gem::Version
320
+ version: '2.4'
293
321
  description: Provides a complete toolset to help DevOps maintain, deploy, monitor
294
322
  and test multiple platforms using various technologies
295
323
  email:
@@ -667,6 +695,7 @@ files:
667
695
  - lib/hybrid_platforms_conductor/config.rb
668
696
  - lib/hybrid_platforms_conductor/confluence.rb
669
697
  - lib/hybrid_platforms_conductor/connector.rb
698
+ - lib/hybrid_platforms_conductor/core_extensions/symbol/zero.rb
670
699
  - lib/hybrid_platforms_conductor/credentials.rb
671
700
  - lib/hybrid_platforms_conductor/current_dir_monitor.rb
672
701
  - lib/hybrid_platforms_conductor/deployer.rb
@@ -857,11 +886,11 @@ files:
857
886
  - spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb
858
887
  - spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb
859
888
  - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb
860
- - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb2.rb
889
+ - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_2.rb
861
890
  - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others.rb
862
- - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others2.rb
891
+ - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others_2.rb
863
892
  - spec/hybrid_platforms_conductor_test/docs_spec.rb
864
- - spec/hybrid_platforms_conductor_test/executables/check-node_spec.rb
893
+ - spec/hybrid_platforms_conductor_test/executables/check_node_spec.rb
865
894
  - spec/hybrid_platforms_conductor_test/executables/deploy_spec.rb
866
895
  - spec/hybrid_platforms_conductor_test/executables/get_impacted_nodes_spec.rb
867
896
  - spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb
@@ -884,7 +913,6 @@ files:
884
913
  - spec/hybrid_platforms_conductor_test/helpers/config_helpers.rb
885
914
  - spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb
886
915
  - spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb
887
- - spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb
888
916
  - spec/hybrid_platforms_conductor_test/helpers/executables_helpers.rb
889
917
  - spec/hybrid_platforms_conductor_test/helpers/nodes_handler_helpers.rb
890
918
  - spec/hybrid_platforms_conductor_test/helpers/platform_handler_helpers.rb
@@ -895,13 +923,14 @@ files:
895
923
  - spec/hybrid_platforms_conductor_test/helpers/serverless_chef_helpers.rb
896
924
  - spec/hybrid_platforms_conductor_test/helpers/services_handler_helpers.rb
897
925
  - spec/hybrid_platforms_conductor_test/helpers/tests_runner_helpers.rb
898
- - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id1.rb
899
- - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id2.rb
900
- - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type/test_plugin_id3.rb
901
- - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type2/test_plugin_id4.rb
926
+ - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id_1.rb
927
+ - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id_2.rb
928
+ - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type/test_plugin_id_3.rb
929
+ - spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type_2/test_plugin_id_4.rb
902
930
  - spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb
903
- - spec/hybrid_platforms_conductor_test/platform_handler_plugins/test2.rb
931
+ - spec/hybrid_platforms_conductor_test/platform_handler_plugins/test_2.rb
904
932
  - spec/hybrid_platforms_conductor_test/report_plugin.rb
933
+ - spec/hybrid_platforms_conductor_test/rubocop_spec.rb
905
934
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/chef_versions.yml
906
935
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json
907
936
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/policyfiles/test_policy.rb
@@ -939,6 +968,7 @@ files:
939
968
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/node2.json
940
969
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_1.rb
941
970
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_2.rb
971
+ - spec/hybrid_platforms_conductor_test/shared_examples/deployer.rb
942
972
  - spec/hybrid_platforms_conductor_test/test_action.rb
943
973
  - spec/hybrid_platforms_conductor_test/test_connector.rb
944
974
  - spec/hybrid_platforms_conductor_test/test_log_no_read_plugin.rb
@@ -965,9 +995,9 @@ require_paths:
965
995
  - lib
966
996
  required_ruby_version: !ruby/object:Gem::Requirement
967
997
  requirements:
968
- - - ">="
998
+ - - "~>"
969
999
  - !ruby/object:Gem::Version
970
- version: '0'
1000
+ version: '2.6'
971
1001
  required_rubygems_version: !ruby/object:Gem::Requirement
972
1002
  requirements:
973
1003
  - - ">="
@@ -1,1152 +0,0 @@
1
- require 'timeout'
2
-
3
- module HybridPlatformsConductorTest
4
-
5
- module Helpers
6
-
7
- module DeployerTestHelpers
8
-
9
- # Define deployment specs that are common for check mode and real deployment
10
- #
11
- # Parameters::
12
- # * *check_mode* (Boolean): Are we in check-mode? [default: true]
13
- def deploy_specs_for(check_mode: true)
14
- expected_deploy_result = [0, "#{check_mode ? 'Check' : 'Deploy'} successful", '']
15
- platform_name = check_mode ? 'platform' : 'my_remote_platform'
16
-
17
- context "testing deployment#{check_mode ? ' in why-run mode' : ''}" do
18
-
19
- # Get expected actions for a deployment
20
- #
21
- # Parameters::
22
- # * *services* (Hash<String, Array<String> >): Expected nodes that should be deployed, with their corresponding services [default: { 'node' => %w[service] }]
23
- # * *sudo* (String or nil): sudo supposed to be used, or nil if none [default: 'sudo -u root']
24
- # * *check_mode* (Boolean): Are we testing in check mode? [default: @check_mode]
25
- # * *mocked_deploy_result* (Hash or nil): Mocked result of the deployment actions, or nil to use the helper's default [default: nil]
26
- # * *additional_expected_actions* (Array): Additional expected actions [default: []]
27
- # * *expect_concurrent_actions* (Boolean): Are actions expected to be run in parallel? [default: false]
28
- # * *expect_actions_timeout* (Integer or nil): Expected timeout in actions, or nil for none [default: nil]
29
- def expected_actions_for_deploy_on(
30
- services: { 'node' => %w[service] },
31
- sudo: 'sudo -u root',
32
- check_mode: @check_mode,
33
- mocked_deploy_result: nil,
34
- additional_expected_actions: [],
35
- expect_concurrent_actions: false,
36
- expect_actions_timeout: nil
37
- )
38
- actions = [
39
- # First run, we expect the mutex to be setup, and the deployment actions to be run
40
- proc do |actions_per_nodes, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
41
- expect(timeout).to eq expect_actions_timeout
42
- expect(concurrent).to eq expect_concurrent_actions
43
- expect(log_to_dir).to eq 'run_logs'
44
- expect_actions_to_deploy_on(
45
- actions_per_nodes,
46
- services.keys,
47
- check: check_mode,
48
- sudo: sudo,
49
- mocked_result: mocked_deploy_result,
50
- expected_actions: additional_expected_actions
51
- )
52
- end,
53
- # Second run, we expect the mutex to be released
54
- proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, services.keys, sudo: sudo) }
55
- ]
56
- services.each do |node, node_services|
57
- expect(test_services_handler).to receive(:actions_to_deploy_on).with(node, node_services, check_mode) do
58
- [{ bash: "echo \"#{check_mode ? 'Checking' : 'Deploying'} on #{node}\"" }]
59
- end
60
- end
61
- # Third run, we expect logs to be uploaded on the node (only if not check mode)
62
- unless check_mode
63
- services.each do |node, node_services|
64
- expect(test_services_handler).to receive(:log_info_for).with(node, node_services) do
65
- {
66
- repo_name_0: 'platform',
67
- commit_id_0: '123456',
68
- commit_message_0: 'Test commit'
69
- }
70
- end
71
- end
72
- actions << proc { |actions_per_nodes| expect_actions_to_upload_logs(actions_per_nodes, services.keys) }
73
- end
74
- actions
75
- end
76
-
77
- # Prepare a platform ready to test deployments on.
78
- #
79
- # Parameters::
80
- # * *nodes_info* (Hash): Node info to give the platform [default: 1 node having 1 service]
81
- # * *expect_services_to_deploy* (Hash<String,Array<String>>): Expected services to be deployed [default: all services from nodes_info]
82
- # * *expect_deploy_allowed* (Boolean): Should we expect the call to deploy_allowed? [default: true]
83
- # * *expect_package* (Boolean): Should we expect packaging? [default: true]
84
- # * *expect_prepare_for_deploy* (Boolean): Should we expect calls to prepare for deploy? [default: true]
85
- # * *expect_connections_to_nodes* (Boolean): Should we expect connections to nodes? [default: true]
86
- # * *expect_default_actions* (Boolean): Should we expect default actions? [default: true]
87
- # * *expect_sudo* (String or nil): Expected sudo command, or nil if none [default: 'sudo -u root']
88
- # * *expect_secrets* (Hash): Secrets to be expected during deployment [default: {}]
89
- # * *expect_local_environment* (Boolean): Expected local environment flag [default: false]
90
- # * *expect_additional_actions* (Array): Additional expected actions [default: []]
91
- # * *expect_concurrent_actions* (Boolean): Are actions expected to be run in parallel? [default: false]
92
- # * *expect_actions_timeout* (Integer or nil): Expected timeout in actions, or nil for none [default: nil]
93
- # * *check_mode* (Boolean): Are we testing in check mode? [default: @check_mode]
94
- # * *additional_config* (String): Additional configuration to set [default: '']
95
- # * Proc: Code called once the platform is ready for testing the deployer
96
- # * Parameters::
97
- # * *repository* (String): Path to the repository
98
- def with_platform_to_deploy(
99
- nodes_info: { nodes: { 'node' => { services: %w[service] } } },
100
- expect_services_to_deploy: Hash[nodes_info[:nodes].map { |node, node_info| [node, node_info[:services]] }],
101
- expect_deploy_allowed: true,
102
- expect_package: true,
103
- expect_prepare_for_deploy: true,
104
- expect_connections_to_nodes: true,
105
- expect_default_actions: true,
106
- expect_sudo: 'sudo -u root',
107
- expect_secrets: {},
108
- expect_local_environment: false,
109
- expect_additional_actions: [],
110
- expect_concurrent_actions: false,
111
- expect_actions_timeout: nil,
112
- check_mode: @check_mode,
113
- additional_config: ''
114
- )
115
- platform_name = check_mode ? 'platform' : 'my_remote_platform'
116
- with_test_platform(nodes_info, !check_mode, additional_config + "\nsend_logs_to :test_log") do |repository|
117
- # Mock the ServicesHandler accesses
118
- if !check_mode && expect_deploy_allowed
119
- expect(test_services_handler).to receive(:deploy_allowed?).with(
120
- services: expect_services_to_deploy,
121
- secrets: expect_secrets,
122
- local_environment: expect_local_environment
123
- ) do
124
- nil
125
- end
126
- end
127
- if expect_package
128
- expect(test_services_handler).to receive(:package).with(
129
- services: expect_services_to_deploy,
130
- secrets: expect_secrets,
131
- local_environment: expect_local_environment
132
- )
133
- else
134
- expect(test_services_handler).not_to receive(:package)
135
- end
136
- if expect_prepare_for_deploy
137
- expect(test_services_handler).to receive(:prepare_for_deploy).with(
138
- services: expect_services_to_deploy,
139
- secrets: expect_secrets,
140
- local_environment: expect_local_environment,
141
- why_run: check_mode
142
- )
143
- else
144
- expect(test_services_handler).not_to receive(:prepare_for_deploy)
145
- end
146
- test_deployer.use_why_run = true if check_mode
147
- if expect_connections_to_nodes
148
- with_connections_mocked_on(expect_services_to_deploy.keys) do
149
- expect_actions_executor_runs(expected_actions_for_deploy_on(
150
- services: expect_services_to_deploy,
151
- check_mode: check_mode,
152
- sudo: expect_sudo,
153
- additional_expected_actions: expect_additional_actions,
154
- expect_concurrent_actions: expect_concurrent_actions,
155
- expect_actions_timeout: expect_actions_timeout
156
- )) if expect_default_actions
157
- yield repository
158
- end
159
- else
160
- yield repository
161
- end
162
- end
163
- end
164
-
165
- # Prepare a directory with certificates
166
- #
167
- # Parameters::
168
- # * Proc: Code called with the directory created with a mocked certificate
169
- # * Parameters::
170
- # * *certs_dir* (String): Directory containing certificates
171
- def with_certs_dir
172
- with_repository do |repository|
173
- certs_dir = "#{repository}/certificates"
174
- FileUtils.mkdir_p certs_dir
175
- File.write("#{certs_dir}/test_cert.crt", 'Hello')
176
- yield certs_dir
177
- end
178
- end
179
-
180
- before :each do
181
- @check_mode = check_mode
182
- end
183
-
184
- it 'deploys on 1 node' do
185
- with_platform_to_deploy do
186
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
187
- end
188
- end
189
-
190
- it 'deploys on 1 node having several services' do
191
- with_platform_to_deploy(nodes_info: { nodes: { 'node' => { services: %w[service1 service2 service3] } } }) do
192
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
193
- end
194
- end
195
-
196
- it 'deploys on 1 node in a local environment' do
197
- with_platform_to_deploy(expect_local_environment: true) do
198
- test_deployer.local_environment = true
199
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
200
- expect(test_deployer.local_environment).to eq true
201
- end
202
- end
203
-
204
- it 'deploys on 1 node using root' do
205
- with_platform_to_deploy(expect_sudo: nil) do
206
- test_actions_executor.connector(:ssh).ssh_user = 'root'
207
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
208
- end
209
- end
210
-
211
- it 'deploys on 1 node using an alternate sudo' do
212
- with_platform_to_deploy(
213
- expect_sudo: 'other_sudo --user root',
214
- additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }'
215
- ) do
216
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
217
- end
218
- end
219
-
220
- it 'deploys on 1 node using 1 secret' do
221
- with_platform_to_deploy(expect_secrets: { 'secret1' => 'password1' }) do
222
- test_deployer.override_secrets('secret1' => 'password1')
223
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
224
- end
225
- end
226
-
227
- it 'deploys on 1 node in local environment with certificates to install using hpc_certificates on Debian' do
228
- with_certs_dir do |certs_dir|
229
- with_platform_to_deploy(
230
- nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
231
- expect_local_environment: true,
232
- expect_additional_actions: [
233
- { remote_bash: 'sudo -u root apt update && sudo -u root apt install -y ca-certificates' },
234
- {
235
- remote_bash: 'sudo -u root update-ca-certificates',
236
- scp: {
237
- certs_dir => '/usr/local/share/ca-certificates',
238
- :sudo => true
239
- }
240
- }
241
- ]
242
- ) do
243
- ENV['hpc_certificates'] = certs_dir
244
- test_deployer.local_environment = true
245
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
246
- end
247
- end
248
- end
249
-
250
- it 'deploys on 1 node in local environment with certificates to install using hpc_certificates on Debian and an alternate sudo' do
251
- with_certs_dir do |certs_dir|
252
- with_platform_to_deploy(
253
- nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
254
- expect_sudo: 'other_sudo --user root',
255
- expect_local_environment: true,
256
- expect_additional_actions: [
257
- { remote_bash: 'other_sudo --user root apt update && other_sudo --user root apt install -y ca-certificates' },
258
- {
259
- remote_bash: 'other_sudo --user root update-ca-certificates',
260
- scp: {
261
- certs_dir => '/usr/local/share/ca-certificates',
262
- :sudo => true
263
- }
264
- }
265
- ],
266
- additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }'
267
- ) do
268
- ENV['hpc_certificates'] = certs_dir
269
- test_deployer.local_environment = true
270
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
271
- end
272
- end
273
- end
274
-
275
- it 'deploys on 1 node with certificates to install using hpc_certificates on Debian but ignores them in non-local environment' do
276
- with_certs_dir do |certs_dir|
277
- with_platform_to_deploy(nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } }) do
278
- ENV['hpc_certificates'] = certs_dir
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 Debian using root' do
285
- with_certs_dir do |certs_dir|
286
- with_platform_to_deploy(
287
- nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
288
- expect_sudo: nil,
289
- expect_local_environment: true,
290
- expect_additional_actions: [
291
- { remote_bash: 'apt update && apt install -y ca-certificates' },
292
- {
293
- remote_bash: 'update-ca-certificates',
294
- scp: {
295
- certs_dir => '/usr/local/share/ca-certificates',
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 1 node with certificates to install using hpc_certificates on CentOS' do
310
- with_certs_dir do |certs_dir|
311
- with_platform_to_deploy(
312
- nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
313
- expect_local_environment: true,
314
- expect_additional_actions: [
315
- { remote_bash: 'sudo -u root yum install -y ca-certificates' },
316
- {
317
- remote_bash: ['sudo -u root update-ca-trust enable', 'sudo -u root update-ca-trust extract'],
318
- scp: {
319
- "#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
320
- :sudo => true
321
- }
322
- }
323
- ]
324
- ) do
325
- ENV['hpc_certificates'] = certs_dir
326
- test_deployer.local_environment = true
327
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
328
- end
329
- end
330
- end
331
-
332
- it 'deploys on 1 node with certificates to install using hpc_certificates on CentOS and an alternate sudo' do
333
- with_certs_dir do |certs_dir|
334
- with_platform_to_deploy(
335
- nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
336
- expect_sudo: 'other_sudo --user root',
337
- expect_local_environment: true,
338
- expect_additional_actions: [
339
- { remote_bash: 'other_sudo --user root yum install -y ca-certificates' },
340
- {
341
- remote_bash: ['other_sudo --user root update-ca-trust enable', 'other_sudo --user root update-ca-trust extract'],
342
- scp: {
343
- "#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
344
- :sudo => true
345
- }
346
- }
347
- ],
348
- additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }'
349
- ) do
350
- ENV['hpc_certificates'] = certs_dir
351
- test_deployer.local_environment = true
352
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
353
- end
354
- end
355
- end
356
-
357
- it 'deploys on 1 node with certificates to install using hpc_certificates on CentOS using root' do
358
- with_certs_dir do |certs_dir|
359
- with_platform_to_deploy(
360
- nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
361
- expect_sudo: nil,
362
- expect_local_environment: true,
363
- expect_additional_actions: [
364
- { remote_bash: 'yum install -y ca-certificates' },
365
- {
366
- remote_bash: ['update-ca-trust enable', 'update-ca-trust extract'],
367
- scp: {
368
- "#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
369
- :sudo => false
370
- }
371
- }
372
- ]
373
- ) do
374
- ENV['hpc_certificates'] = certs_dir
375
- test_actions_executor.connector(:ssh).ssh_user = 'root'
376
- test_deployer.local_environment = true
377
- expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
378
- end
379
- end
380
- end
381
-
382
- it 'deploys on several nodes' do
383
- with_platform_to_deploy(nodes_info: { nodes: {
384
- 'node1' => { services: %w[service1] },
385
- 'node2' => { services: %w[service2] },
386
- 'node3' => { services: %w[service3] }
387
- } }) do
388
- expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
389
- 'node1' => expected_deploy_result,
390
- 'node2' => expected_deploy_result,
391
- 'node3' => expected_deploy_result
392
- )
393
- end
394
- end
395
-
396
- it 'deploys on several nodes in parallel' do
397
- with_platform_to_deploy(
398
- nodes_info: {
399
- nodes: {
400
- 'node1' => { services: %w[service1] },
401
- 'node2' => { services: %w[service2] },
402
- 'node3' => { services: %w[service3] }
403
- }
404
- },
405
- expect_concurrent_actions: true
406
- ) do
407
- test_deployer.concurrent_execution = true
408
- expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
409
- 'node1' => expected_deploy_result,
410
- 'node2' => expected_deploy_result,
411
- 'node3' => expected_deploy_result
412
- )
413
- end
414
- end
415
-
416
- it 'deploys on several nodes with timeout' do
417
- with_platform_to_deploy(
418
- nodes_info: {
419
- nodes: {
420
- 'node1' => { services: %w[service1] },
421
- 'node2' => { services: %w[service2] },
422
- 'node3' => { services: %w[service3] }
423
- }
424
- },
425
- expect_actions_timeout: 5
426
- ) do
427
- test_deployer.timeout = 5
428
- expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
429
- 'node1' => expected_deploy_result,
430
- 'node2' => expected_deploy_result,
431
- 'node3' => expected_deploy_result
432
- )
433
- end
434
- end
435
-
436
- it 'fails when packaging timeout has been reached while taking the futex' do
437
- with_platform_to_deploy(
438
- additional_config: 'packaging_timeout 1',
439
- expect_package: false,
440
- expect_prepare_for_deploy: false,
441
- expect_connections_to_nodes: false
442
- ) do
443
- # Simulate another process taking the packaging futex
444
- futex_file = HybridPlatformsConductor::Deployer.const_get(:PACKAGING_FUTEX_FILE)
445
- Futex.new(futex_file).open do
446
- # Expect the error to be raised within 2 seconds (as it should timeout after 1 second)
447
- begin
448
- Timeout::timeout(2) {
449
- expect { test_deployer.deploy_on('node') }.to raise_error(
450
- Futex::CantLock,
451
- /can't get exclusive access to the file #{Regexp.escape(futex_file)} because of the lock at #{Regexp.escape(futex_file)}\.lock, after 1\.\d+s of waiting/
452
- )
453
- }
454
- rescue Timeout::Error
455
- raise 'The packaging timeout (set to 1 seconds) did not fire within 2 seconds. Looks like it is not working properly.'
456
- end
457
- end
458
- end
459
- end
460
-
461
- context 'checking deployment retries' do
462
-
463
- # Prepare a platform ready to test deployments' retries on.
464
- #
465
- # Parameters::
466
- # * *nodes_info* (Hash): Node info to give the platform [default: { nodes: { 'node' => {} } }]
467
- # * Proc: Code called once the platform is ready for testing the deployer
468
- # * Parameters::
469
- # * *repository* (String): Path to the repository
470
- def with_platform_to_retry_deploy(nodes_info: { nodes: { 'node' => { services: %w[service] } } })
471
- with_platform_to_deploy(
472
- nodes_info: nodes_info,
473
- expect_default_actions: false,
474
- additional_config: "
475
- for_nodes([#{nodes_info[:nodes].keys.map { |node| "'#{node}'" }.join(', ')}]) do
476
- retry_deploy_for_errors_on_stdout [
477
- 'stdout non-deterministic error'
478
- ]
479
- retry_deploy_for_errors_on_stderr [
480
- 'stderr non-deterministic error',
481
- /stderr regexp error \\d+/
482
- ]
483
- end
484
- for_nodes([#{nodes_info[:nodes].keys.map { |node| "'#{node}'" }.join(', ')}]) do
485
- retry_deploy_for_errors_on_stdout [
486
- /stdout regexp error \\d+/
487
- ]
488
- end
489
- "
490
- ) do |repository|
491
- yield repository
492
- end
493
- end
494
-
495
- # Mock a sequential list of deployments
496
- #
497
- # Parameters::
498
- # * *statuses* (Array<Hash<String,Status> or Status>)>): List of mocked deployment statuses per node name, or just the status for the default node.
499
- # A status is a triplet [Integer or Symbol, String, String]: exit status, stdout and stderr.
500
- def mock_deploys_with(statuses)
501
- expect_actions_executor_runs(statuses.map do |status|
502
- status = { 'node' => status } if status.is_a?(Array)
503
- expected_actions_for_deploy_on(
504
- services: Hash[status.keys.map { |node| [node, %w[service]] }],
505
- mocked_deploy_result: status
506
- )
507
- end.flatten)
508
- end
509
-
510
- it 'restarts deployment for a non-deterministic error' do
511
- with_platform_to_retry_deploy do
512
- test_deployer.nbr_retries_on_error = 1
513
- mock_deploys_with [
514
- [1, "Error: This is a stdout non-deterministic error\nDeploy failed\n", ''],
515
- [0, 'Deploy ok', '']
516
- ]
517
- expect(test_deployer.deploy_on('node')).to eq('node' => [
518
- 0,
519
- <<~EOS,
520
- Error: This is a stdout non-deterministic error
521
- Deploy failed
522
-
523
- Deployment exit status code: 1
524
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
525
- Deploy ok
526
- EOS
527
- <<~EOS
528
- !!! 1 retriable errors detected in this deployment:
529
- * stdout non-deterministic error
530
-
531
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
532
-
533
- EOS
534
- ])
535
- end
536
- end
537
-
538
- it 'restarts deployment for a non-deterministic error matched with a Regexp' do
539
- with_platform_to_retry_deploy do
540
- test_deployer.nbr_retries_on_error = 1
541
- mock_deploys_with [
542
- [1, "Error: This is a stdout regexp error 42\nDeploy failed\n", ''],
543
- [0, 'Deploy ok', '']
544
- ]
545
- expect(test_deployer.deploy_on('node')).to eq('node' => [
546
- 0,
547
- <<~EOS,
548
- Error: This is a stdout regexp error 42
549
- Deploy failed
550
-
551
- Deployment exit status code: 1
552
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
553
- Deploy ok
554
- EOS
555
- <<~EOS
556
- !!! 1 retriable errors detected in this deployment:
557
- * /stdout regexp error \\d+/ matched 'stdout regexp error 42'
558
-
559
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
560
-
561
- EOS
562
- ])
563
- end
564
- end
565
-
566
- it 'restarts deployment for a non-deterministic error on stderr' do
567
- with_platform_to_retry_deploy do
568
- test_deployer.nbr_retries_on_error = 1
569
- mock_deploys_with [
570
- [1, '', "Error: This is a stderr non-deterministic error\nDeploy failed\n"],
571
- [0, 'Deploy ok', '']
572
- ]
573
- expect(test_deployer.deploy_on('node')).to eq('node' => [
574
- 0,
575
- <<~EOS,
576
-
577
- Deployment exit status code: 1
578
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
579
- Deploy ok
580
- EOS
581
- <<~EOS
582
- Error: This is a stderr non-deterministic error
583
- Deploy failed
584
- !!! 1 retriable errors detected in this deployment:
585
- * stderr non-deterministic error
586
-
587
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
588
-
589
- EOS
590
- ])
591
- end
592
- end
593
-
594
- it 'restarts deployment for a non-deterministic error on stderr matched with a Regexp' do
595
- with_platform_to_retry_deploy do
596
- test_deployer.nbr_retries_on_error = 1
597
- mock_deploys_with [
598
- [1, '', "Error: This is a stderr regexp error 42\nDeploy failed\n"],
599
- [0, 'Deploy ok', '']
600
- ]
601
- expect(test_deployer.deploy_on('node')).to eq('node' => [
602
- 0,
603
- <<~EOS,
604
-
605
- Deployment exit status code: 1
606
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
607
- Deploy ok
608
- EOS
609
- <<~EOS
610
- Error: This is a stderr regexp error 42
611
- Deploy failed
612
- !!! 1 retriable errors detected in this deployment:
613
- * /stderr regexp error \\d+/ matched 'stderr regexp error 42'
614
-
615
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
616
-
617
- EOS
618
- ])
619
- end
620
- end
621
-
622
- it 'stops restarting deployments for a non-deterministic error when errors has disappeared, even if retries were remaining' do
623
- with_platform_to_retry_deploy do
624
- test_deployer.nbr_retries_on_error = 5
625
- mock_deploys_with [
626
- [1, "Error: This is a stdout non-deterministic error 1\nDeploy failed", ''],
627
- [1, "Error: This is a stdout non-deterministic error 2\nDeploy failed", ''],
628
- [0, 'Deploy ok', '']
629
- ]
630
- expect(test_deployer.deploy_on('node')).to eq('node' => [
631
- 0,
632
- <<~EOS,
633
- Error: This is a stdout non-deterministic error 1
634
- Deploy failed
635
- Deployment exit status code: 1
636
- !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
637
- Error: This is a stdout non-deterministic error 2
638
- Deploy failed
639
-
640
- Deployment exit status code: 1
641
- !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
642
- Deploy ok
643
- EOS
644
- <<~EOS
645
- !!! 1 retriable errors detected in this deployment:
646
- * stdout non-deterministic error
647
-
648
- !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
649
- !!! 1 retriable errors detected in this deployment:
650
- * stdout non-deterministic error
651
-
652
-
653
- !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
654
-
655
- EOS
656
- ])
657
- end
658
- end
659
-
660
- it 'stops restarting deployments for a non-deterministic error that became deterministic, even if retries were remaining' do
661
- with_platform_to_retry_deploy do
662
- test_deployer.nbr_retries_on_error = 5
663
- mock_deploys_with [
664
- [1, "Error: This is a stdout non-deterministic error 1\nDeploy failed", ''],
665
- [1, "Error: This is a stdout non-deterministic error 2\nDeploy failed", ''],
666
- [1, "Error: This is a stdout deterministic error 3\nDeploy failed", '']
667
- ]
668
- expect(test_deployer.deploy_on('node')).to eq('node' => [
669
- 1,
670
- <<~EOS,
671
- Error: This is a stdout non-deterministic error 1
672
- Deploy failed
673
- Deployment exit status code: 1
674
- !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
675
- Error: This is a stdout non-deterministic error 2
676
- Deploy failed
677
-
678
- Deployment exit status code: 1
679
- !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
680
- Error: This is a stdout deterministic error 3
681
- Deploy failed
682
- EOS
683
- <<~EOS
684
- !!! 1 retriable errors detected in this deployment:
685
- * stdout non-deterministic error
686
-
687
- !!! Retry deployment due to non-deterministic error (4 remaining attempts)...
688
- !!! 1 retriable errors detected in this deployment:
689
- * stdout non-deterministic error
690
-
691
-
692
- !!! Retry deployment due to non-deterministic error (3 remaining attempts)...
693
-
694
- EOS
695
- ])
696
- end
697
- end
698
-
699
- it 'does not restart deployment for a deterministic error' do
700
- with_platform_to_retry_deploy do
701
- test_deployer.nbr_retries_on_error = 5
702
- mock_deploys_with [
703
- [1, "Error: This is a stdout deterministic error\nDeploy failed\n", '']
704
- ]
705
- expect(test_deployer.deploy_on('node')).to eq('node' => [
706
- 1,
707
- <<~EOS,
708
- Error: This is a stdout deterministic error
709
- Deploy failed
710
- EOS
711
- ''
712
- ])
713
- end
714
- end
715
-
716
- it 'does not restart deployment for a non-deterministic error logged during a successful deploy' do
717
- with_platform_to_retry_deploy do
718
- test_deployer.nbr_retries_on_error = 5
719
- mock_deploys_with [
720
- [0, "Error: This is a stdout non-deterministic error\nDeploy failed\n", '']
721
- ]
722
- expect(test_deployer.deploy_on('node')).to eq('node' => [
723
- 0,
724
- <<~EOS,
725
- Error: This is a stdout non-deterministic error
726
- Deploy failed
727
- EOS
728
- ''
729
- ])
730
- end
731
- end
732
-
733
- it 'does not restart deployment for a non-deterministic error if retries are 0' do
734
- with_platform_to_retry_deploy do
735
- test_deployer.nbr_retries_on_error = 0
736
- mock_deploys_with [
737
- [1, "Error: This is a stdout non-deterministic error\nDeploy failed\n", '']
738
- ]
739
- expect(test_deployer.deploy_on('node')).to eq('node' => [
740
- 1,
741
- <<~EOS,
742
- Error: This is a stdout non-deterministic error
743
- Deploy failed
744
- EOS
745
- ''
746
- ])
747
- end
748
- end
749
-
750
- it 'restarts deployment for non-deterministic errors with a limited amount of retries' do
751
- with_platform_to_retry_deploy do
752
- test_deployer.nbr_retries_on_error = 2
753
- mock_deploys_with [
754
- [1, "Error: This is a stdout non-deterministic error 1\nDeploy failed", ''],
755
- [1, "Error: This is a stdout non-deterministic error 2\nDeploy failed", ''],
756
- [1, "Error: This is a stdout non-deterministic error 3\nDeploy failed", '']
757
- ]
758
- expect(test_deployer.deploy_on('node')).to eq('node' => [
759
- 1,
760
- <<~EOS,
761
- Error: This is a stdout non-deterministic error 1
762
- Deploy failed
763
- Deployment exit status code: 1
764
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
765
- Error: This is a stdout non-deterministic error 2
766
- Deploy failed
767
-
768
- Deployment exit status code: 1
769
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
770
- Error: This is a stdout non-deterministic error 3
771
- Deploy failed
772
- EOS
773
- <<~EOS
774
- !!! 1 retriable errors detected in this deployment:
775
- * stdout non-deterministic error
776
-
777
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
778
- !!! 1 retriable errors detected in this deployment:
779
- * stdout non-deterministic error
780
-
781
-
782
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
783
-
784
- EOS
785
- ])
786
- end
787
- end
788
-
789
- it 'restarts deployment for non-deterministic errors only on nodes needing it' do
790
- with_platform_to_retry_deploy(nodes_info: { nodes: {
791
- 'node1' => { services: %w[service] },
792
- 'node2' => { services: %w[service] },
793
- 'node3' => { services: %w[service] },
794
- 'node4' => { services: %w[service] }
795
- } }) do
796
- test_deployer.nbr_retries_on_error = 2
797
- # Some nodes deploy successfully,
798
- # others have deterministic errors,
799
- # others have non-deterministic errors being corrected
800
- # others have non-deterministic errors not being corrected
801
- mock_deploys_with [
802
- {
803
- 'node1' => [1, "Error: This is a stdout non-deterministic error\n[node1] Deploy failed\n", ''],
804
- 'node2' => [0, '[node2] Deploy ok', ''],
805
- 'node3' => [1, "Error: This is a stdout non-deterministic error\n[node3] Deploy failed\n", ''],
806
- 'node4' => [1, "Error: This is a stdout non-deterministic error\n[node4] Deploy failed\n", '']
807
- },
808
- {
809
- 'node1' => [0, '[node1] Deploy ok', ''],
810
- 'node3' => [1, "Error: This is a stdout deterministic error\n[node3] Deploy failed\n", ''],
811
- 'node4' => [1, "Error: This is a stdout non-deterministic error\n[node4] Deploy failed\n", '']
812
- },
813
- {
814
- 'node4' => [1, "Error: This is a stdout non-deterministic error\n[node4] Deploy failed\n", '']
815
- }
816
- ]
817
- expect(test_deployer.deploy_on(%w[node1 node2 node3 node4])).to eq(
818
- 'node1' => [
819
- 0,
820
- <<~EOS,
821
- Error: This is a stdout non-deterministic error
822
- [node1] Deploy failed
823
-
824
- Deployment exit status code: 1
825
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
826
- [node1] Deploy ok
827
- EOS
828
- <<~EOS
829
- !!! 1 retriable errors detected in this deployment:
830
- * stdout non-deterministic error
831
-
832
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
833
-
834
- EOS
835
- ],
836
- 'node2' => [
837
- 0,
838
- '[node2] Deploy ok',
839
- ''
840
- ],
841
- 'node3' => [
842
- 1,
843
- <<~EOS,
844
- Error: This is a stdout non-deterministic error
845
- [node3] Deploy failed
846
-
847
- Deployment exit status code: 1
848
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
849
- Error: This is a stdout deterministic error
850
- [node3] Deploy failed
851
-
852
- EOS
853
- <<~EOS
854
- !!! 1 retriable errors detected in this deployment:
855
- * stdout non-deterministic error
856
-
857
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
858
-
859
- EOS
860
- ],
861
- 'node4' => [
862
- 1,
863
- <<~EOS,
864
- Error: This is a stdout non-deterministic error
865
- [node4] Deploy failed
866
-
867
- Deployment exit status code: 1
868
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
869
- Error: This is a stdout non-deterministic error
870
- [node4] Deploy failed
871
-
872
-
873
- Deployment exit status code: 1
874
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
875
- Error: This is a stdout non-deterministic error
876
- [node4] Deploy failed
877
-
878
- EOS
879
- <<~EOS
880
- !!! 1 retriable errors detected in this deployment:
881
- * stdout non-deterministic error
882
-
883
- !!! Retry deployment due to non-deterministic error (1 remaining attempts)...
884
- !!! 1 retriable errors detected in this deployment:
885
- * stdout non-deterministic error
886
-
887
-
888
- !!! Retry deployment due to non-deterministic error (0 remaining attempts)...
889
-
890
- EOS
891
- ]
892
- )
893
- end
894
- end
895
-
896
- end
897
-
898
- context 'checking secrets handling' do
899
-
900
- it 'calls secrets readers only for nodes and services to be deployed and merges their secrets' do
901
- register_plugins(
902
- :secrets_reader,
903
- {
904
- secrets_reader1: HybridPlatformsConductorTest::TestSecretsReaderPlugin,
905
- secrets_reader2: HybridPlatformsConductorTest::TestSecretsReaderPlugin,
906
- secrets_reader3: HybridPlatformsConductorTest::TestSecretsReaderPlugin
907
- }
908
- )
909
- with_platform_to_deploy(
910
- nodes_info: {
911
- nodes: {
912
- 'node1' => { services: %w[service1 service2] },
913
- 'node2' => { services: %w[service2 service3] },
914
- 'node3' => { services: %w[service3] },
915
- 'node4' => { services: %w[service1 service3] }
916
- }
917
- },
918
- expect_services_to_deploy: {
919
- 'node1' => %w[service1 service2],
920
- 'node2' => %w[service2 service3],
921
- 'node3' => %w[service3]
922
- },
923
- expect_secrets: {
924
- 'node1' => {
925
- 'service1' => {
926
- 'secrets_reader1' => 'Secret value',
927
- 'secrets_reader2' => 'Secret value'
928
- },
929
- 'service2' => {
930
- 'secrets_reader1' => 'Secret value',
931
- 'secrets_reader2' => 'Secret value'
932
- }
933
- },
934
- 'node2' => {
935
- 'service2' => {
936
- 'secrets_reader1' => 'Secret value',
937
- 'secrets_reader2' => 'Secret value',
938
- 'secrets_reader3' => 'Secret value'
939
- },
940
- 'service3' => {
941
- 'secrets_reader1' => 'Secret value',
942
- 'secrets_reader2' => 'Secret value',
943
- 'secrets_reader3' => 'Secret value'
944
- }
945
- },
946
- 'node3' => {
947
- 'service3' => {
948
- 'secrets_reader1' => 'Secret value',
949
- 'secrets_reader2' => 'Secret value'
950
- }
951
- }
952
- },
953
- additional_config: <<~EOS
954
- read_secrets_from %i[secrets_reader1 secrets_reader2]
955
- for_nodes('node2') { read_secrets_from :secrets_reader3 }
956
- EOS
957
- ) do
958
- TestSecretsReaderPlugin.deployer = test_deployer
959
- expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
960
- 'node1' => expected_deploy_result,
961
- 'node2' => expected_deploy_result,
962
- 'node3' => expected_deploy_result
963
- )
964
- expect(HybridPlatformsConductorTest::TestSecretsReaderPlugin.calls).to eq [
965
- { instance: :secrets_reader1, node: 'node1', service: 'service1' },
966
- { instance: :secrets_reader1, node: 'node1', service: 'service2' },
967
- { instance: :secrets_reader2, node: 'node1', service: 'service1' },
968
- { instance: :secrets_reader2, node: 'node1', service: 'service2' },
969
- { instance: :secrets_reader1, node: 'node2', service: 'service2' },
970
- { instance: :secrets_reader1, node: 'node2', service: 'service3' },
971
- { instance: :secrets_reader2, node: 'node2', service: 'service2' },
972
- { instance: :secrets_reader2, node: 'node2', service: 'service3' },
973
- { instance: :secrets_reader3, node: 'node2', service: 'service2' },
974
- { instance: :secrets_reader3, node: 'node2', service: 'service3' },
975
- { instance: :secrets_reader1, node: 'node3', service: 'service3' },
976
- { instance: :secrets_reader2, node: 'node3', service: 'service3' }
977
- ]
978
- end
979
- end
980
-
981
- it 'merges secrets having same values' do
982
- register_plugins(
983
- :secrets_reader,
984
- {
985
- secrets_reader1: HybridPlatformsConductorTest::TestSecretsReaderPlugin,
986
- secrets_reader2: HybridPlatformsConductorTest::TestSecretsReaderPlugin
987
- }
988
- )
989
- with_platform_to_deploy(
990
- nodes_info: {
991
- nodes: {
992
- 'node1' => { services: %w[service1] },
993
- 'node2' => { services: %w[service2] }
994
- }
995
- },
996
- expect_secrets: {
997
- 'global1' => 'value1',
998
- 'global2' => 'value2',
999
- 'global3' => 'value3',
1000
- 'global4' => 'value4'
1001
- },
1002
- additional_config: <<~EOS
1003
- read_secrets_from :secrets_reader1
1004
- for_nodes('node2') { read_secrets_from :secrets_reader2 }
1005
- EOS
1006
- ) do
1007
- TestSecretsReaderPlugin.deployer = test_deployer
1008
- TestSecretsReaderPlugin.mocked_secrets = {
1009
- 'node1' => {
1010
- 'service1' => {
1011
- secrets_reader1: {
1012
- 'global1' => 'value1',
1013
- 'global2' => 'value2'
1014
- }
1015
- }
1016
- },
1017
- 'node2' => {
1018
- 'service2' => {
1019
- secrets_reader1: {
1020
- 'global2' => 'value2',
1021
- 'global3' => 'value3'
1022
- },
1023
- secrets_reader2: {
1024
- 'global3' => 'value3',
1025
- 'global4' => 'value4'
1026
- }
1027
- }
1028
- }
1029
- }
1030
- expect(test_deployer.deploy_on(%w[node1 node2])).to eq(
1031
- 'node1' => expected_deploy_result,
1032
- 'node2' => expected_deploy_result
1033
- )
1034
- expect(HybridPlatformsConductorTest::TestSecretsReaderPlugin.calls).to eq [
1035
- { instance: :secrets_reader1, node: 'node1', service: 'service1' },
1036
- { instance: :secrets_reader1, node: 'node2', service: 'service2' },
1037
- { instance: :secrets_reader2, node: 'node2', service: 'service2' }
1038
- ]
1039
- end
1040
- end
1041
-
1042
- it 'fails when merging secrets having different values' do
1043
- register_plugins(
1044
- :secrets_reader,
1045
- {
1046
- secrets_reader1: HybridPlatformsConductorTest::TestSecretsReaderPlugin,
1047
- secrets_reader2: HybridPlatformsConductorTest::TestSecretsReaderPlugin
1048
- }
1049
- )
1050
- with_platform_to_deploy(
1051
- nodes_info: {
1052
- nodes: {
1053
- 'node1' => { services: %w[service1] },
1054
- 'node2' => { services: %w[service2] }
1055
- }
1056
- },
1057
- expect_deploy_allowed: false,
1058
- expect_package: false,
1059
- expect_prepare_for_deploy: false,
1060
- expect_connections_to_nodes: false,
1061
- additional_config: <<~EOS
1062
- read_secrets_from :secrets_reader1
1063
- for_nodes('node2') { read_secrets_from :secrets_reader2 }
1064
- EOS
1065
- ) do
1066
- TestSecretsReaderPlugin.deployer = test_deployer
1067
- TestSecretsReaderPlugin.mocked_secrets = {
1068
- 'node1' => {
1069
- 'service1' => {
1070
- secrets_reader1: {
1071
- 'global1' => 'value1',
1072
- 'global2' => 'value2'
1073
- }
1074
- }
1075
- },
1076
- 'node2' => {
1077
- 'service2' => {
1078
- secrets_reader1: {
1079
- 'global2' => 'value2',
1080
- 'global3' => {
1081
- 'sub_key' => 'value3'
1082
- }
1083
- },
1084
- secrets_reader2: {
1085
- 'global3' => {
1086
- 'sub_key' => 'Other value'
1087
- },
1088
- 'global4' => 'value4'
1089
- }
1090
- }
1091
- }
1092
- }
1093
- expect { test_deployer.deploy_on(%w[node1 node2]) }.to raise_error 'Secret set at path global3->sub_key by secrets_reader2 for service service2 on node node2 has conflicting values (set debug for value details).'
1094
- expect(HybridPlatformsConductorTest::TestSecretsReaderPlugin.calls).to eq [
1095
- { instance: :secrets_reader1, node: 'node1', service: 'service1' },
1096
- { instance: :secrets_reader1, node: 'node2', service: 'service2' },
1097
- { instance: :secrets_reader2, node: 'node2', service: 'service2' }
1098
- ]
1099
- end
1100
- end
1101
-
1102
- it 'does not call secrets readers when secrets are overridden' do
1103
- register_plugins(
1104
- :secrets_reader,
1105
- {
1106
- secrets_reader1: HybridPlatformsConductorTest::TestSecretsReaderPlugin,
1107
- secrets_reader2: HybridPlatformsConductorTest::TestSecretsReaderPlugin,
1108
- secrets_reader3: HybridPlatformsConductorTest::TestSecretsReaderPlugin
1109
- }
1110
- )
1111
- with_platform_to_deploy(
1112
- nodes_info: {
1113
- nodes: {
1114
- 'node1' => { services: %w[service1] },
1115
- 'node2' => { services: %w[service2] },
1116
- 'node3' => { services: %w[service3] }
1117
- }
1118
- },
1119
- expect_secrets: {
1120
- 'overridden_secrets' => 'value'
1121
- },
1122
- additional_config: <<~EOS
1123
- read_secrets_from %i[secrets_reader1 secrets_reader2]
1124
- for_nodes('node2') { read_secrets_from :secrets_reader3 }
1125
- EOS
1126
- ) do
1127
- TestSecretsReaderPlugin.deployer = test_deployer
1128
- test_deployer.override_secrets('overridden_secrets' => 'value')
1129
- expect(test_deployer.deploy_on(%w[node1 node2 node3])).to eq(
1130
- 'node1' => expected_deploy_result,
1131
- 'node2' => expected_deploy_result,
1132
- 'node3' => expected_deploy_result
1133
- )
1134
- expect(HybridPlatformsConductorTest::TestSecretsReaderPlugin.calls).to eq []
1135
- end
1136
- end
1137
-
1138
- end
1139
-
1140
- end
1141
-
1142
- end
1143
-
1144
- end
1145
-
1146
- end
1147
-
1148
- end
1149
-
1150
- RSpec.configure do |c|
1151
- c.extend HybridPlatformsConductorTest::Helpers::DeployerTestHelpers
1152
- end