holado 0.2.2__py3-none-any.whl → 0.2.3__py3-none-any.whl

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.

Potentially problematic release.


This version of holado might be problematic. Click here for more details.

Files changed (523) hide show
  1. {holado-0.2.2.dist-info → holado-0.2.3.dist-info}/METADATA +13 -9
  2. holado-0.2.3.dist-info/RECORD +535 -0
  3. holado_ais/__init__.py +33 -0
  4. holado_ais/ais/MaritimeIdentificationDigits.csv +295 -0
  5. holado_ais/ais/ais_manager.py +151 -0
  6. holado_ais/ais/ais_messages.py +203 -0
  7. holado_ais/ais/ais_payload.py +35 -0
  8. holado_ais/ais/enums.py +37 -0
  9. holado_ais/ais/patch_pyais.py +1303 -0
  10. holado_ais/tests/behave/steps/__init__.py +17 -0
  11. holado_ais/tests/behave/steps/ais/__init__.py +0 -0
  12. holado_ais/tests/behave/steps/ais/ais_manager_steps.py +50 -0
  13. holado_ais/tests/behave/steps/ais/ais_messages_steps.py +182 -0
  14. holado_binary/__init__.py +17 -0
  15. holado_binary/ipc/binary.py +125 -0
  16. holado_binary/ipc/bit_series.py +307 -0
  17. holado_binary/tests/behave/steps/__init__.py +17 -0
  18. holado_binary/tests/behave/steps/ipc/binary_steps.py +57 -0
  19. holado_binary/tests/behave/steps/ipc/bit_series_steps.py +131 -0
  20. holado_context/__init__.py +16 -0
  21. holado_context/tests/behave/steps/__init__.py +16 -0
  22. holado_context/tests/behave/steps/private/__init__.py +16 -0
  23. holado_context/tests/behave/steps/private/common/context_steps.py +36 -0
  24. holado_core/__init__.py +32 -0
  25. holado_core/common/__init__.py +0 -0
  26. holado_core/common/actors/actions.py +97 -0
  27. holado_core/common/actors/actor.py +226 -0
  28. holado_core/common/actors/element_actor.py +32 -0
  29. holado_core/common/actors/find_actor.py +106 -0
  30. holado_core/common/actors/tree_actor.py +32 -0
  31. holado_core/common/actors/verify_actions.py +69 -0
  32. holado_core/common/block/base.py +122 -0
  33. holado_core/common/block/block_manager.py +173 -0
  34. holado_core/common/block/block_method.py +46 -0
  35. holado_core/common/block/block_steps.py +37 -0
  36. holado_core/common/block/function.py +42 -0
  37. holado_core/common/block/scope_function.py +28 -0
  38. holado_core/common/block/scope_manager.py +238 -0
  39. holado_core/common/block/scope_steps.py +141 -0
  40. holado_core/common/criterias/and_criteria.py +61 -0
  41. holado_core/common/criterias/criteria.py +78 -0
  42. holado_core/common/criterias/or_criteria.py +64 -0
  43. holado_core/common/criterias/tools/criteria_context.py +20 -0
  44. holado_core/common/criterias/tools/criteria_parameters.py +18 -0
  45. holado_core/common/drivers/driver.py +153 -0
  46. holado_core/common/drivers/element_driver.py +30 -0
  47. holado_core/common/drivers/element_internal_api.py +239 -0
  48. holado_core/common/drivers/internal_api.py +40 -0
  49. holado_core/common/drivers/tree_driver.py +30 -0
  50. holado_core/common/drivers/tree_internal_api.py +176 -0
  51. holado_core/common/exceptions/__init__.py +0 -0
  52. holado_core/common/exceptions/element_exception.py +28 -0
  53. holado_core/common/exceptions/exceptions.py +24 -0
  54. holado_core/common/exceptions/functional_exception.py +21 -0
  55. holado_core/common/exceptions/holado_exception.py +25 -0
  56. holado_core/common/exceptions/technical_exception.py +27 -0
  57. holado_core/common/exceptions/timeout_exception.py +20 -0
  58. holado_core/common/exceptions/verify_exception.py +20 -0
  59. holado_core/common/finders/after_in_tree_finder.py +87 -0
  60. holado_core/common/finders/element_finder.py +60 -0
  61. holado_core/common/finders/else_finder.py +105 -0
  62. holado_core/common/finders/finder.py +478 -0
  63. holado_core/common/finders/or_finder.py +98 -0
  64. holado_core/common/finders/then_finder.py +157 -0
  65. holado_core/common/finders/tools/enums.py +30 -0
  66. holado_core/common/finders/tools/find_builder.py +118 -0
  67. holado_core/common/finders/tools/find_context.py +405 -0
  68. holado_core/common/finders/tools/find_info.py +27 -0
  69. holado_core/common/finders/tools/find_parameters.py +240 -0
  70. holado_core/common/finders/tools/find_updater.py +95 -0
  71. holado_core/common/finders/tools/finder_info.py +26 -0
  72. holado_core/common/finders/tree_finder.py +146 -0
  73. holado_core/common/handlers/__init__.py +0 -0
  74. holado_core/common/handlers/abstracts/base_redo.py +695 -0
  75. holado_core/common/handlers/abstracts/get_or_create.py +120 -0
  76. holado_core/common/handlers/element_holder.py +122 -0
  77. holado_core/common/handlers/enums.py +23 -0
  78. holado_core/common/handlers/exceptions/redo_exceptions.py +28 -0
  79. holado_core/common/handlers/features/resource_by_name.py +187 -0
  80. holado_core/common/handlers/features/resource_by_type.py +174 -0
  81. holado_core/common/handlers/redo.py +119 -0
  82. holado_core/common/handlers/wait.py +127 -0
  83. holado_core/common/inspectors/element_inspector.py +57 -0
  84. holado_core/common/inspectors/inspector.py +221 -0
  85. holado_core/common/inspectors/tools/inspect_builder.py +169 -0
  86. holado_core/common/inspectors/tools/inspect_context.py +69 -0
  87. holado_core/common/inspectors/tools/inspect_parameters.py +181 -0
  88. holado_core/common/inspectors/tree_inspector.py +73 -0
  89. holado_core/common/resource/persisted_data_manager.py +113 -0
  90. holado_core/common/resource/persisted_method_to_call_manager.py +133 -0
  91. holado_core/common/resource/resource_manager.py +143 -0
  92. holado_core/common/tables/__init__.py +1 -0
  93. holado_core/common/tables/comparators/__init__.py +0 -0
  94. holado_core/common/tables/comparators/boolean_table_cell_comparator.py +25 -0
  95. holado_core/common/tables/comparators/bytes_table_cell_comparator.py +25 -0
  96. holado_core/common/tables/comparators/datetime_table_cell_comparator.py +24 -0
  97. holado_core/common/tables/comparators/float_table_cell_comparator.py +31 -0
  98. holado_core/common/tables/comparators/integer_table_cell_comparator.py +25 -0
  99. holado_core/common/tables/comparators/internal_table_cell_comparator.py +30 -0
  100. holado_core/common/tables/comparators/string_table_cell_comparator.py +24 -0
  101. holado_core/common/tables/comparators/string_table_comparator.py +29 -0
  102. holado_core/common/tables/comparators/string_table_row_comparator.py +29 -0
  103. holado_core/common/tables/comparators/table_cell_comparator.py +40 -0
  104. holado_core/common/tables/comparators/table_comparator.py +209 -0
  105. holado_core/common/tables/comparators/table_comparator_manager.py +60 -0
  106. holado_core/common/tables/comparators/table_row_comparator.py +116 -0
  107. holado_core/common/tables/comparators/table_with_header_comparator.py +68 -0
  108. holado_core/common/tables/converters/__init__.py +0 -0
  109. holado_core/common/tables/converters/table_converter.py +194 -0
  110. holado_core/common/tables/enums.py +23 -0
  111. holado_core/common/tables/table.py +261 -0
  112. holado_core/common/tables/table_cell.py +126 -0
  113. holado_core/common/tables/table_manager.py +366 -0
  114. holado_core/common/tables/table_row.py +169 -0
  115. holado_core/common/tables/table_with_header.py +236 -0
  116. holado_core/common/tools/__init__.py +0 -0
  117. holado_core/common/tools/comparators/comparator.py +151 -0
  118. holado_core/common/tools/comparators/object_comparator.py +21 -0
  119. holado_core/common/tools/converters/converter.py +107 -0
  120. holado_core/common/tools/path_manager.py +185 -0
  121. holado_core/common/tools/string_tools.py +135 -0
  122. holado_core/common/tools/tools.py +172 -0
  123. holado_core/common/transport/__init__.py +0 -0
  124. holado_core/common/transport/crc.py +40 -0
  125. holado_core/tests/behave/steps/__init__.py +20 -0
  126. holado_core/tests/behave/steps/common/__init__.py +0 -0
  127. holado_core/tests/behave/steps/common/common_steps.py +136 -0
  128. holado_core/tests/behave/steps/common/config_steps.py +42 -0
  129. holado_core/tests/behave/steps/common/resource_steps.py +62 -0
  130. holado_core/tests/behave/steps/common/tables_steps.py +537 -0
  131. holado_core/tools/__init__.py +0 -0
  132. holado_core/tools/abstracts/__init__.py +0 -0
  133. holado_core/tools/abstracts/blocking_command_service.py +56 -0
  134. holado_core/tools/abstracts/service.py +48 -0
  135. holado_data/__init__.py +31 -0
  136. holado_data/data/generator/base.py +93 -0
  137. holado_data/data/generator/python_generator.py +30 -0
  138. holado_data/tests/behave/steps/__init__.py +17 -0
  139. holado_data/tests/behave/steps/data/generator_steps.py +91 -0
  140. holado_data/tests/behave/steps/tools/utils_steps.py +60 -0
  141. holado_db/__init__.py +32 -0
  142. holado_db/tests/behave/steps/__init__.py +18 -0
  143. holado_db/tests/behave/steps/tools/db/db_client_steps.py +134 -0
  144. holado_db/tests/behave/steps/tools/db/postgresql_client_steps.py +59 -0
  145. holado_db/tests/behave/steps/tools/db/sqlite_client_steps.py +57 -0
  146. holado_db/tools/db/clients/base/db_client.py +206 -0
  147. holado_db/tools/db/clients/postgresql/postgresql_client.py +65 -0
  148. holado_db/tools/db/clients/sqlite/sqlite_client.py +56 -0
  149. holado_db/tools/db/db_manager.py +109 -0
  150. holado_db/tools/db/query/base/query_builder.py +87 -0
  151. holado_db/tools/db/query/pypika/pypika_query_builder.py +193 -0
  152. holado_db/tools/db/query/query_manager.py +77 -0
  153. holado_docker/__init__.py +25 -0
  154. holado_docker/sdk/docker/docker_client.py +268 -0
  155. holado_docker/sdk/docker/docker_service.py +71 -0
  156. holado_docker/tests/behave/steps/__init__.py +16 -0
  157. holado_docker/tests/behave/steps/tools/docker_steps.py +33 -0
  158. holado_docker/tools/docker_controler/__init__.py +26 -0
  159. holado_docker/tools/docker_controler/docker_controler_client.py +36 -0
  160. holado_docker/tools/docker_controler/docker_controler_server.py +31 -0
  161. holado_docker/tools/docker_controler/proto/compile_proto.py +60 -0
  162. holado_docker/tools/docker_controler/proto/definitions/docker_controler.proto +63 -0
  163. holado_docker/tools/docker_controler/proto/generated/docker_controler_pb2.py +52 -0
  164. holado_docker/tools/docker_controler/proto/generated/docker_controler_pb2_grpc.py +233 -0
  165. holado_grpc/__init__.py +32 -0
  166. holado_grpc/api/rpc/TODO.txt +4 -0
  167. holado_grpc/api/rpc/grpc_client.py +181 -0
  168. holado_grpc/api/rpc/grpc_manager.py +81 -0
  169. holado_grpc/ipc/rpc/__init__.py +0 -0
  170. holado_grpc/ipc/rpc/grpc_compiler.py +45 -0
  171. holado_grpc/ipc/rpc/grpc_services.py +165 -0
  172. holado_grpc/tests/behave/steps/__init__.py +16 -0
  173. holado_grpc/tests/behave/steps/api/grpc_client_steps.py +173 -0
  174. holado_grpc/tests/behave/steps/private/__init__.py +16 -0
  175. holado_grpc/tests/behave/steps/private/api/grpc_steps.py +77 -0
  176. holado_helper/__init__.py +35 -0
  177. holado_helper/debug/README.txt +32 -0
  178. holado_helper/debug/memory/memory_profiler.py +106 -0
  179. holado_helper/docker/init_user.sh +24 -0
  180. holado_helper/docker/logging.conf +42 -0
  181. holado_helper/docker/run_holado_test_nonreg_in_docker.sh +120 -0
  182. holado_helper/docker/run_terminal_in_docker-with_docker_control.sh +103 -0
  183. holado_helper/docker/run_terminal_in_docker.sh +101 -0
  184. holado_helper/holado_module_template/__init__.py +31 -0
  185. holado_helper/holado_module_template/test/behave/steps/__init__.py +16 -0
  186. holado_helper/holado_module_template/test/behave/steps/private/__init__.py +16 -0
  187. holado_helper/script/action.py +109 -0
  188. holado_helper/script/action_script.py +477 -0
  189. holado_helper/script/any_action_script.py +126 -0
  190. holado_helper/script/behave_action_script.py +99 -0
  191. holado_helper/script/csv_action_script.py +142 -0
  192. holado_helper/script/initialize_script.py +115 -0
  193. holado_helper/script/input_output_script.py +136 -0
  194. holado_helper/script/job.py +75 -0
  195. holado_helper/script/json_action_script.py +104 -0
  196. holado_helper/script/script.py +110 -0
  197. holado_json/__init__.py +16 -0
  198. holado_json/ipc/json.py +125 -0
  199. holado_json/ipc/json_converter.py +69 -0
  200. holado_json/ipc/json_types.py +183 -0
  201. holado_json/tests/behave/steps/__init__.py +16 -0
  202. holado_json/tests/behave/steps/ipc/__init__.py +0 -0
  203. holado_json/tests/behave/steps/ipc/json_steps.py +120 -0
  204. holado_keycloak/__init__.py +16 -0
  205. holado_keycloak/tests/behave/steps/__init__.py +16 -0
  206. holado_keycloak/tests/behave/steps/tools/keycloak_client_steps.py +59 -0
  207. holado_keycloak/tools/keycloak/__init__.py +0 -0
  208. holado_keycloak/tools/keycloak/keycloak_client.py +61 -0
  209. holado_logging/__init__.py +36 -0
  210. holado_logging/common/logging/holado_logger.py +75 -0
  211. holado_logging/common/logging/log_config.py +128 -0
  212. holado_logging/common/logging/log_manager.py +292 -0
  213. holado_multitask/__init__.py +33 -0
  214. holado_multitask/multiprocessing/context/process_context.py +35 -0
  215. holado_multitask/multiprocessing/function_process.py +102 -0
  216. holado_multitask/multiprocessing/periodic_function_process.py +135 -0
  217. holado_multitask/multiprocessing/process.py +196 -0
  218. holado_multitask/multiprocessing/processesmanager.py +133 -0
  219. holado_multitask/multitasking/multitask_manager.py +439 -0
  220. holado_multitask/multithreading/__init__.py +0 -0
  221. holado_multitask/multithreading/context/thread_context.py +84 -0
  222. holado_multitask/multithreading/functionthreaded.py +129 -0
  223. holado_multitask/multithreading/loopfunctionthreaded.py +45 -0
  224. holado_multitask/multithreading/loopthread.py +100 -0
  225. holado_multitask/multithreading/periodicfunctionthreaded.py +136 -0
  226. holado_multitask/multithreading/reflection/inspect.py +47 -0
  227. holado_multitask/multithreading/reflection/sys.py +29 -0
  228. holado_multitask/multithreading/reflection/traceback.py +35 -0
  229. holado_multitask/multithreading/thread.py +177 -0
  230. holado_multitask/multithreading/threadsmanager.py +162 -0
  231. holado_multitask/multithreading/timer.py +48 -0
  232. holado_multitask/tests/behave/steps/__init__.py +17 -0
  233. holado_multitask/tests/behave/steps/multiprocessing_steps.py +138 -0
  234. holado_multitask/tests/behave/steps/multithreading_steps.py +129 -0
  235. holado_protobuf/__init__.py +61 -0
  236. holado_protobuf/ipc/protobuf/__init__.py +0 -0
  237. holado_protobuf/ipc/protobuf/abstracts/type.py +45 -0
  238. holado_protobuf/ipc/protobuf/protobuf_compiler.py +118 -0
  239. holado_protobuf/ipc/protobuf/protobuf_converter.py +153 -0
  240. holado_protobuf/ipc/protobuf/protobuf_messages.py +965 -0
  241. holado_protobuf/ipc/protobuf/protobuf_modifier.py +65 -0
  242. holado_protobuf/ipc/protobuf/types/__init__.py +0 -0
  243. holado_protobuf/ipc/protobuf/types/google/__init__.py +0 -0
  244. holado_protobuf/ipc/protobuf/types/google/protobuf.py +124 -0
  245. holado_protobuf/tests/behave/steps/__init__.py +16 -0
  246. holado_protobuf/tests/behave/steps/ipc/protobuf_steps.py +297 -0
  247. holado_python/__init__.py +35 -0
  248. holado_python/common/enums.py +34 -0
  249. holado_python/common/iterables.py +30 -0
  250. holado_python/common/tools/comparators/boolean_comparator.py +37 -0
  251. holado_python/common/tools/comparators/bytes_comparator.py +48 -0
  252. holado_python/common/tools/comparators/datetime_comparator.py +74 -0
  253. holado_python/common/tools/comparators/float_comparator.py +97 -0
  254. holado_python/common/tools/comparators/integer_comparator.py +37 -0
  255. holado_python/common/tools/comparators/string_comparator.py +99 -0
  256. holado_python/common/tools/comparators/type_comparator.py +31 -0
  257. holado_python/common/tools/datetime.py +279 -0
  258. holado_python/standard_library/csv.py +207 -0
  259. holado_python/standard_library/hashlib.py +82 -0
  260. holado_python/standard_library/multiprocessing.py +62 -0
  261. holado_python/standard_library/queue.py +79 -0
  262. holado_python/standard_library/socket/blocking_socket.py +136 -0
  263. holado_python/standard_library/socket/echo_server.py +28 -0
  264. holado_python/standard_library/socket/message_socket.py +91 -0
  265. holado_python/standard_library/socket/non_blocking_socket.py +151 -0
  266. holado_python/standard_library/socket/socket.py +148 -0
  267. holado_python/standard_library/ssl/resources/certificates/NOTES.txt +5 -0
  268. holado_python/standard_library/ssl/resources/certificates/localhost.crt +19 -0
  269. holado_python/standard_library/ssl/resources/certificates/localhost.key +28 -0
  270. holado_python/standard_library/ssl/ssl.py +81 -0
  271. holado_python/standard_library/typing.py +192 -0
  272. holado_python/tests/behave/steps/__init__.py +27 -0
  273. holado_python/tests/behave/steps/builtins/str_steps.py +45 -0
  274. holado_python/tests/behave/steps/convert_steps.py +59 -0
  275. holado_python/tests/behave/steps/iterable_steps.py +87 -0
  276. holado_python/tests/behave/steps/standard_library/csv_steps.py +134 -0
  277. holado_python/tests/behave/steps/standard_library/datetime_steps.py +163 -0
  278. holado_python/tests/behave/steps/standard_library/hashlib_steps.py +57 -0
  279. holado_python/tests/behave/steps/standard_library/multiprocessing_steps.py +56 -0
  280. holado_python/tests/behave/steps/standard_library/queue_steps.py +358 -0
  281. holado_python/tests/behave/steps/standard_library/socket_steps.py +258 -0
  282. holado_python/tests/behave/steps/standard_library/ssl_steps.py +67 -0
  283. holado_rabbitmq/__init__.py +28 -0
  284. holado_rabbitmq/tests/behave/steps/__init__.py +17 -0
  285. holado_rabbitmq/tests/behave/steps/tools/rabbitmq_client_steps.py +537 -0
  286. holado_rabbitmq/tests/behave/steps/tools/rabbitmq_server_steps.py +64 -0
  287. holado_rabbitmq/tools/rabbitmq/rabbitmq_blocking_client.py +311 -0
  288. holado_rabbitmq/tools/rabbitmq/rabbitmq_client.py +675 -0
  289. holado_rabbitmq/tools/rabbitmq/rabbitmq_manager.py +173 -0
  290. holado_rabbitmq/tools/rabbitmq/rabbitmq_select_client.py +428 -0
  291. holado_rabbitmq/tools/rabbitmq/rabbitmq_server.py +24 -0
  292. holado_redis/__init__.py +17 -0
  293. holado_redis/tests/behave/steps/__init__.py +16 -0
  294. holado_redis/tests/behave/steps/tools/redis_client_steps.py +101 -0
  295. holado_redis/tools/redis/TODO.txt +7 -0
  296. holado_redis/tools/redis/redis_client.py +190 -0
  297. holado_redis/tools/redis/redis_manager.py +38 -0
  298. holado_report/__init__.py +27 -0
  299. holado_report/report/analyze/execution_historic_manager.py +96 -0
  300. holado_report/report/analyze/scenario_duration_manager.py +245 -0
  301. holado_report/report/builders/detailed_scenario_failed_report_builder.py +146 -0
  302. holado_report/report/builders/json_execution_historic_report_builder.py +123 -0
  303. holado_report/report/builders/report_builder.py +64 -0
  304. holado_report/report/builders/short_scenario_failed_report_builder.py +76 -0
  305. holado_report/report/builders/summary_report_builder.py +89 -0
  306. holado_report/report/builders/summary_scenario_failed_report_builder.py +56 -0
  307. holado_report/report/builders/summary_scenario_report_builder.py +74 -0
  308. holado_report/report/execution_historic.py +141 -0
  309. holado_report/report/report_manager.py +256 -0
  310. holado_report/report/reports/base_report.py +163 -0
  311. holado_report/report/reports/feature_report.py +106 -0
  312. holado_report/report/reports/scenario_report.py +64 -0
  313. holado_rest/__init__.py +24 -0
  314. holado_rest/api/rest/TODO.txt +2 -0
  315. holado_rest/api/rest/rest_client.py +113 -0
  316. holado_rest/api/rest/rest_manager.py +62 -0
  317. holado_rest/tests/behave/steps/__init__.py +16 -0
  318. holado_rest/tests/behave/steps/api/__init__.py +0 -0
  319. holado_rest/tests/behave/steps/api/rest_client_steps.py +141 -0
  320. holado_rest/tests/behave/steps/private/__init__.py +16 -0
  321. holado_rest/tests/behave/steps/private/api/__init__.py +0 -0
  322. holado_rest/tests/behave/steps/private/api/rest_steps.py +70 -0
  323. holado_s3/__init__.py +17 -0
  324. holado_s3/tests/behave/steps/__init__.py +17 -0
  325. holado_s3/tests/behave/steps/private/__init__.py +16 -0
  326. holado_s3/tests/behave/steps/private/tools/s3_steps.py +89 -0
  327. holado_s3/tests/behave/steps/tools/s3_client_steps.py +403 -0
  328. holado_s3/tests/behave/steps/tools/s3_server_steps.py +57 -0
  329. holado_s3/tools/s3/__init__.py +0 -0
  330. holado_s3/tools/s3/boto3_s3_client.py +59 -0
  331. holado_s3/tools/s3/minio_client.py +75 -0
  332. holado_s3/tools/s3/moto_server.py +52 -0
  333. holado_scripting/__init__.py +53 -0
  334. holado_scripting/common/tools/dynamic_text_manager.py +73 -0
  335. holado_scripting/common/tools/evaluate_parameters.py +210 -0
  336. holado_scripting/common/tools/expression_evaluator.py +387 -0
  337. holado_scripting/common/tools/variable_manager.py +321 -0
  338. holado_scripting/tests/behave/steps/__init__.py +22 -0
  339. holado_scripting/tests/behave/steps/common/tools/variable_convert_steps.py +158 -0
  340. holado_scripting/tests/behave/steps/common/tools/variable_new_steps.py +130 -0
  341. holado_scripting/tests/behave/steps/common/tools/variable_steps.py +108 -0
  342. holado_scripting/tests/behave/steps/common/tools/variable_verify_steps.py +160 -0
  343. holado_scripting/tests/behave/steps/scenario/function_steps.py +77 -0
  344. holado_scripting/tests/behave/steps/scenario/if_steps.py +87 -0
  345. holado_scripting/tests/behave/steps/scenario/loop_steps.py +119 -0
  346. holado_scripting/text/base/base_function.py +25 -0
  347. holado_scripting/text/base/base_verify_function.py +25 -0
  348. holado_scripting/text/base/text_inspecter.py +204 -0
  349. holado_scripting/text/interpreter/exceptions/interpreter_exception.py +25 -0
  350. holado_scripting/text/interpreter/functions/function_cast.py +60 -0
  351. holado_scripting/text/interpreter/functions/function_convert.py +57 -0
  352. holado_scripting/text/interpreter/functions/function_dynamic_value.py +40 -0
  353. holado_scripting/text/interpreter/functions/function_escape_all_bytes.py +35 -0
  354. holado_scripting/text/interpreter/functions/function_exists_variable.py +39 -0
  355. holado_scripting/text/interpreter/functions/function_hex_to_bytes.py +49 -0
  356. holado_scripting/text/interpreter/functions/function_hex_to_int.py +53 -0
  357. holado_scripting/text/interpreter/functions/function_to_base_64.py +41 -0
  358. holado_scripting/text/interpreter/functions/function_to_bytes.py +50 -0
  359. holado_scripting/text/interpreter/functions/function_to_hex.py +42 -0
  360. holado_scripting/text/interpreter/text_interpreter.py +216 -0
  361. holado_scripting/text/verifier/exceptions/verifier_exception.py +21 -0
  362. holado_scripting/text/verifier/functions/verify_function_extract_in.py +35 -0
  363. holado_scripting/text/verifier/functions/verify_function_match_pattern.py +63 -0
  364. holado_scripting/text/verifier/text_verifier.py +103 -0
  365. holado_sftp/__init__.py +16 -0
  366. holado_sftp/tests/behave/steps/__init__.py +17 -0
  367. holado_sftp/tests/behave/steps/private/__init__.py +16 -0
  368. holado_sftp/tests/behave/steps/private/tools/sftp_steps.py +78 -0
  369. holado_sftp/tests/behave/steps/tools/sftp_client_steps.py +94 -0
  370. holado_sftp/tests/behave/steps/tools/sftp_server_steps.py +82 -0
  371. holado_sftp/tools/sftp/__init__.py +0 -0
  372. holado_sftp/tools/sftp/sftp_client.py +103 -0
  373. holado_sftp/tools/sftp/sftp_server.py +39 -0
  374. holado_swagger/__init__.py +31 -0
  375. holado_swagger/swagger_hub/mockserver/mockserver_client.py +82 -0
  376. holado_swagger/swagger_hub/mockserver/mockserver_manager.py +32 -0
  377. holado_swagger/tests/behave/steps/__init__.py +16 -0
  378. holado_swagger/tests/behave/steps/swagger_hub/mockserver_steps.py +74 -0
  379. holado_system/system/command/command.py +216 -0
  380. holado_system/system/command/command_result.py +128 -0
  381. holado_system/system/command/curl_command.py +101 -0
  382. holado_system/system/command/exceptions.py +59 -0
  383. holado_system/system/filesystem/file.py +76 -0
  384. holado_system/system/global_system.py +187 -0
  385. holado_system/tests/behave/steps/__init__.py +18 -0
  386. holado_system/tests/behave/steps/system/commands_steps.py +92 -0
  387. holado_system/tests/behave/steps/system/file_steps.py +215 -0
  388. holado_system/tests/behave/steps/system/system_steps.py +84 -0
  389. holado_test/__init__.py +27 -0
  390. holado_test/behave/__init__.py +0 -0
  391. holado_test/behave/behave.py +397 -0
  392. holado_test/behave/behave_environment.py +143 -0
  393. holado_test/behave/behave_function.py +33 -0
  394. holado_test/behave/behave_manager.py +555 -0
  395. holado_test/behave/independant_runner.py +68 -0
  396. holado_test/behave/scenario/__init__.py +0 -0
  397. holado_test/behave/scenario/behave_step_tools.py +157 -0
  398. holado_test/common/context/feature_context.py +79 -0
  399. holado_test/common/context/scenario_context.py +217 -0
  400. holado_test/common/context/step_context.py +66 -0
  401. holado_test/common/exceptions/undefined_step_exception.py +21 -0
  402. holado_test/scenario/step_tools.py +523 -0
  403. holado_test/scenario/tester_tools.py +52 -0
  404. holado_test/test_config.py +26 -0
  405. holado_test/tests/behave/steps/__init__.py +18 -0
  406. holado_test/tests/behave/steps/scenario/exception_steps.py +87 -0
  407. holado_test/tests/behave/steps/scenario/scenario_steps.py +87 -0
  408. holado_test/tests/behave/steps/scenario/tester_steps.py +65 -0
  409. holado_value/__init__.py +24 -0
  410. holado_value/common/tables/comparators/table_2_value_table_cell_comparator.py +195 -0
  411. holado_value/common/tables/comparators/table_2_value_table_comparator.py +27 -0
  412. holado_value/common/tables/comparators/table_2_value_table_row_comparator.py +27 -0
  413. holado_value/common/tables/comparators/table_2_value_table_with_header_comparator.py +27 -0
  414. holado_value/common/tables/converters/value_table_converter.py +217 -0
  415. holado_value/common/tables/value_table.py +29 -0
  416. holado_value/common/tables/value_table_cell.py +67 -0
  417. holado_value/common/tables/value_table_manager.py +58 -0
  418. holado_value/common/tables/value_table_row.py +44 -0
  419. holado_value/common/tables/value_table_with_header.py +28 -0
  420. holado_value/common/tools/unique_value_manager.py +108 -0
  421. holado_value/common/tools/value.py +164 -0
  422. holado_value/common/tools/value_types.py +35 -0
  423. holado_value/tests/behave/steps/__init__.py +16 -0
  424. holado_value/tests/behave/steps/private/__init__.py +16 -0
  425. holado_ws/__init__.py +16 -0
  426. holado_ws/api/ws/TODO.txt +2 -0
  427. holado_ws/tests/behave/steps/__init__.py +16 -0
  428. holado_ws/tests/behave/steps/api/web_service_steps.py +189 -0
  429. holado_yaml/__init__.py +31 -0
  430. holado_yaml/tests/behave/steps/__init__.py +16 -0
  431. holado_yaml/tests/behave/steps/yaml_steps.py +64 -0
  432. holado_yaml/yaml/yaml_manager.py +86 -0
  433. test_holado/Dockerfile_test_holado +82 -0
  434. test_holado/__init__.py +4 -0
  435. test_holado/__main__.py +25 -0
  436. test_holado/build_docker_image_to_test_holado_in_docker.sh +7 -0
  437. test_holado/environment.py +42 -0
  438. test_holado/features/NonReg/api/REST.feature +21 -0
  439. test_holado/features/NonReg/api/gRPC.feature +122 -0
  440. test_holado/features/NonReg/common/multiprocessing/simple.feature +60 -0
  441. test_holado/features/NonReg/common/system/commands.feature +43 -0
  442. test_holado/features/NonReg/common/system/system.feature +20 -0
  443. test_holado/features/NonReg/common/tables/table.feature +239 -0
  444. test_holado/features/NonReg/common/tables/value_table_conversion.feature +29 -0
  445. test_holado/features/NonReg/common/tools/DateTime.feature +88 -0
  446. test_holado/features/NonReg/common/tools/UniqueValueManager.feature +43 -0
  447. test_holado/features/NonReg/holado_ais/ais_message-bitarray_to_nmea.feature +135 -0
  448. test_holado/features/NonReg/holado_protobuf/protobuf.feature +291 -0
  449. test_holado/features/NonReg/holado_python/convert.feature +20 -0
  450. test_holado/features/NonReg/holado_python/iterable.feature +61 -0
  451. test_holado/features/NonReg/holado_python/standard_library/socket.feature +101 -0
  452. test_holado/features/NonReg/holado_python/standard_library/socket_with_ssl.feature +180 -0
  453. test_holado/features/NonReg/holado_scripting/common/tools/dynamic_text_manager.feature +18 -0
  454. test_holado/features/NonReg/holado_scripting/common/tools/expression_evaluator.feature +185 -0
  455. test_holado/features/NonReg/holado_scripting/common/tools/variable_manager.feature +71 -0
  456. test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.error.feature +21 -0
  457. test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.feature +120 -0
  458. test_holado/features/NonReg/holado_yaml/yaml.feature +218 -0
  459. test_holado/features/NonReg/ipc/bit_series.error.feature +33 -0
  460. test_holado/features/NonReg/ipc/bit_series.feature +131 -0
  461. test_holado/features/NonReg/ipc/json.feature +20 -0
  462. test_holado/features/NonReg/scenario/scenario.feature +139 -0
  463. test_holado/features/NonReg/test_steps/behave.feature +275 -0
  464. test_holado/features/NonReg/test_steps/common.feature +100 -0
  465. test_holado/features/NonReg/tools/RabbitMQ.feature +445 -0
  466. test_holado/features/NonReg/tools/RabbitMQ_steps.feature +276 -0
  467. test_holado/features/NonReg/tools/S3/boto3_client.feature +73 -0
  468. test_holado/features/NonReg/tools/S3/minio_client.feature +75 -0
  469. test_holado/features/NonReg/tools/db_sqlite3.feature +41 -0
  470. test_holado/features/NonReg/tools/sFTP.feature +25 -0
  471. test_holado/features/Test/logger.feature +28 -0
  472. test_holado/features/__init__.py +0 -0
  473. test_holado/logging.conf +41 -0
  474. test_holado/resources/proto/definitions/protobuf/custom_types/field_types.proto +24 -0
  475. test_holado/resources/proto/definitions/protobuf/protobuf.dev/tutorial/addressbook.proto +56 -0
  476. test_holado/resources/proto/generated/protobuf/custom_types/field_types_pb2.py +34 -0
  477. test_holado/resources/proto/generated/protobuf/protobuf/dev/tutorial/addressbook_pb2.py +34 -0
  478. test_holado/resources/scripts/list_tags.sh +2 -0
  479. test_holado/resources/scripts/update_resources_proto_generated.py +70 -0
  480. test_holado/steps/__init__.py +0 -0
  481. test_holado/steps/private_steps.py +20 -0
  482. test_holado/steps/public_steps.py +23 -0
  483. test_holado/test_holado_session_context.py +43 -0
  484. test_holado/tools/django/README.txt +3 -0
  485. test_holado/tools/django/api_grpc/api_grpc/__init__.py +0 -0
  486. test_holado/tools/django/api_grpc/api_grpc/api1/__init__.py +0 -0
  487. test_holado/tools/django/api_grpc/api_grpc/api1/admin.py +3 -0
  488. test_holado/tools/django/api_grpc/api_grpc/api1/apps.py +6 -0
  489. test_holado/tools/django/api_grpc/api_grpc/api1/migrations/__init__.py +0 -0
  490. test_holado/tools/django/api_grpc/api_grpc/api1/models.py +3 -0
  491. test_holado/tools/django/api_grpc/api_grpc/api1/proto/__init__.py +0 -0
  492. test_holado/tools/django/api_grpc/api_grpc/api1/proto/account.proto +27 -0
  493. test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2.py +33 -0
  494. test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2_grpc.py +199 -0
  495. test_holado/tools/django/api_grpc/api_grpc/api1/serializers.py +12 -0
  496. test_holado/tools/django/api_grpc/api_grpc/api1/services.py +11 -0
  497. test_holado/tools/django/api_grpc/api_grpc/api1/tests.py +3 -0
  498. test_holado/tools/django/api_grpc/api_grpc/api1/views.py +3 -0
  499. test_holado/tools/django/api_grpc/api_grpc/asgi.py +16 -0
  500. test_holado/tools/django/api_grpc/api_grpc/settings.py +126 -0
  501. test_holado/tools/django/api_grpc/api_grpc/urls.py +27 -0
  502. test_holado/tools/django/api_grpc/api_grpc/wsgi.py +16 -0
  503. test_holado/tools/django/api_grpc/db.sqlite3 +0 -0
  504. test_holado/tools/django/api_grpc/manage.py +27 -0
  505. test_holado/tools/django/api_grpc/manual_test_commands.txt +25 -0
  506. test_holado/tools/django/api_rest/api_rest/__init__.py +0 -0
  507. test_holado/tools/django/api_rest/api_rest/api1/__init__.py +0 -0
  508. test_holado/tools/django/api_rest/api_rest/api1/admin.py +3 -0
  509. test_holado/tools/django/api_rest/api_rest/api1/apps.py +6 -0
  510. test_holado/tools/django/api_rest/api_rest/api1/migrations/__init__.py +0 -0
  511. test_holado/tools/django/api_rest/api_rest/api1/models.py +3 -0
  512. test_holado/tools/django/api_rest/api_rest/api1/serializers.py +15 -0
  513. test_holado/tools/django/api_rest/api_rest/api1/tests.py +3 -0
  514. test_holado/tools/django/api_rest/api_rest/api1/views.py +24 -0
  515. test_holado/tools/django/api_rest/api_rest/asgi.py +16 -0
  516. test_holado/tools/django/api_rest/api_rest/settings.py +133 -0
  517. test_holado/tools/django/api_rest/api_rest/urls.py +32 -0
  518. test_holado/tools/django/api_rest/api_rest/wsgi.py +16 -0
  519. test_holado/tools/django/api_rest/db.sqlite3 +0 -0
  520. test_holado/tools/django/api_rest/manage.py +22 -0
  521. holado-0.2.2.dist-info/RECORD +0 -17
  522. {holado-0.2.2.dist-info → holado-0.2.3.dist-info}/WHEEL +0 -0
  523. {holado-0.2.2.dist-info → holado-0.2.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,135 @@
1
+
2
+ #################################################
3
+ # HolAdo (Holistic Automation do)
4
+ #
5
+ # (C) Copyright 2021-2025 by Eric Klumpp
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ # The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
12
+ #################################################
13
+
14
+ from builtins import super
15
+ import logging
16
+ import time
17
+ from holado_core.common.tools.tools import Tools
18
+ from holado_core.common.exceptions.technical_exception import TechnicalException
19
+ from holado_multitask.multiprocessing.process import InterruptableProcess
20
+ from holado_multitask.multiprocessing.function_process import FunctionProcess
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class PeriodicFunctionProcess(InterruptableProcess):
26
+ '''
27
+ Execute periodically in a process given function with given arguments.
28
+
29
+ Implementation uses a precise timer, in order to globally satisfy the desired periodicity (with a precision of around a nanosecond, depending to system latency).
30
+ But implementation is quite simple, function is executed around each timer ticks : it is based on waits after function execution of the time needed to satisfy periodicity.
31
+ If function execution is greater than periodicity, a warning is logged, and function is run immediately without waiting next timer tick.
32
+
33
+ For fast periodicity, it is recommended to disable logs by setting property 'do_log' to False (and also 'do_log_warning' if needed).
34
+ '''
35
+
36
+ def __init__(self, period_seconds, target, args=None, kwargs=None, name=None, default_wait_timeout=None, register_process=True, delay_before_run_sec=None, nb_times=None):
37
+ super().__init__(name if name is not None else f"PeriodicFunctionProcess({repr(target)})", default_wait_timeout=default_wait_timeout, register_process=register_process, delay_before_run_sec=delay_before_run_sec)
38
+
39
+ self.__period_seconds = period_seconds
40
+ if self.__period_seconds < 1e-8:
41
+ raise TechnicalException(f"Periodicity must be at least 10ns")
42
+ self.__nb_times = nb_times
43
+ self.__function_process = FunctionProcess(target, args, kwargs)
44
+ self.__do_log = True
45
+ self.__do_log_warning = True
46
+
47
+ if isinstance(self.__period_seconds, int) or self.__period_seconds % 1 < 1e-9 or self.__period_seconds % 1 > 1 - 1e-9:
48
+ self.__timer = Tools.timer_s
49
+ self.__timer_period = self.__period_seconds
50
+ self.__timer_unity = "s"
51
+ self.__timer_s_value = 1
52
+ else:
53
+ self.__timer = Tools.timer_ns
54
+ self.__timer_period = self.__period_seconds * 1e9
55
+ self.__timer_unity = "ns"
56
+ self.__timer_s_value = 1e9
57
+
58
+ @property
59
+ def function_process(self):
60
+ return self.__function_process
61
+
62
+ @property
63
+ def do_log(self):
64
+ return self.__do_log
65
+
66
+ @do_log.setter
67
+ def do_log(self, do_log):
68
+ self.__do_log = do_log
69
+
70
+ @property
71
+ def do_log_warning(self):
72
+ return self.__do_log_warning
73
+
74
+ @do_log_warning.setter
75
+ def do_log_warning(self, do_log):
76
+ self.__do_log_warning = do_log
77
+
78
+ def run(self):
79
+ # Start running by superclass run
80
+ super().run()
81
+
82
+ logger.info(f"[{self.name}] Process managing periodic function.")
83
+
84
+ start = self.__timer()
85
+ count = 0
86
+ while not self.is_interrupted:
87
+ # Process function
88
+ if self.do_log:
89
+ logger.info(f"[{self.name}] Processing periodic iteration {count+1}...")
90
+ beg = self.__timer()
91
+ try:
92
+ self.__function_process.run()
93
+ except Exception as exc:
94
+ msg = "{} Exception catched while processing function:\n [{}]".format(self.name, repr(exc))
95
+ logger.exception(msg)
96
+ finally:
97
+ count += 1
98
+ iter_dur = self.__timer() - beg
99
+
100
+ # Define next iteration timer
101
+ next_timer = start + count * self.__timer_period
102
+ wait_duration = next_timer - self.__timer()
103
+ skip_wait = wait_duration < 0
104
+ if skip_wait:
105
+ if self.do_log_warning:
106
+ logger.warning(f"[{self.name}] {count}'th iteration finished too late (of {-wait_duration} {self.__timer_unity}) to process next iteration on time (duration: {iter_dur} {self.__timer_unity} ; periodicity: {self.__timer_period} {self.__timer_unity}). Processing immediatelly next iteration")
107
+
108
+ while wait_duration + self.__timer_period < 0:
109
+ if self.do_log_warning:
110
+ logger.warning(f"[{self.name}] Failed to process {count+1}'th iteration, its activity period is passed")
111
+ count += 1
112
+ next_timer = start + count * self.__timer_period
113
+ wait_duration = next_timer - self.__timer()
114
+
115
+ # Stop if nb_times is reached
116
+ if self.__nb_times is not None:
117
+ if count >= self.__nb_times:
118
+ break
119
+
120
+ # Wait periodicity
121
+ if not skip_wait:
122
+ if self.do_log:
123
+ logger.info(f"[{self.name}] Waiting {wait_duration} {self.__timer_unity} to process next periodic function...")
124
+ while not self.is_interrupted:
125
+ if wait_duration > 0.1 * self.__timer_s_value:
126
+ time.sleep(0.1)
127
+ wait_duration = next_timer - self.__timer()
128
+ else:
129
+ if wait_duration > 1e-9 * self.__timer_s_value:
130
+ time.sleep(wait_duration / self.__timer_s_value)
131
+ break
132
+
133
+ logger.info(f"[{self.name}] Process of periodic function has finished.")
134
+
135
+
@@ -0,0 +1,196 @@
1
+
2
+ #################################################
3
+ # HolAdo (Holistic Automation do)
4
+ #
5
+ # (C) Copyright 2021-2025 by Eric Klumpp
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ # The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
12
+ #################################################
13
+
14
+ from holado.holado_config import Config
15
+ import logging
16
+ import multiprocessing
17
+ import time
18
+ from holado.common.context.session_context import SessionContext
19
+ from holado_multitask.multitasking.multitask_manager import MultitaskManager
20
+ from holado_python.standard_library.typing import Typing
21
+ from holado.common.handlers.undefined import undefined_argument
22
+ from holado_core.common.exceptions.technical_exception import TimeoutTechnicalException
23
+ from holado_core.common.exceptions.functional_exception import FunctionalException
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ class Process(multiprocessing.context.Process):
29
+ """ Helper class managing a multiprocessing process.
30
+ WARNING: Do not use, it is under construction
31
+ """
32
+
33
+ def __init__(self, name, default_wait_timeout = None, register_process = True, delay_before_run_sec=None):
34
+ super().__init__()
35
+
36
+ if default_wait_timeout is None:
37
+ default_wait_timeout = Config.timeout_seconds * 1000
38
+
39
+ self.__name = name
40
+ self.__unique_name = SessionContext.instance().multitask_manager.prepare_process(name)
41
+ self.__default_wait_timeout = default_wait_timeout
42
+ self.__delay_before_run_sec = delay_before_run_sec
43
+
44
+ # Put process as daemon
45
+ self.daemon = True
46
+
47
+ # Manage process status
48
+ # self._is_lock = threading.Lock()
49
+ # self._is_idle = threading.Event()
50
+ # self._is_idle.set()
51
+
52
+ # Register process
53
+ if register_process:
54
+ # Registered name has to be unique
55
+ SessionContext.instance().processes_manager.register_process(self.__unique_name, self)
56
+
57
+ @property
58
+ def name(self):
59
+ return self.__name
60
+
61
+ @property
62
+ def unique_name(self):
63
+ return self.__unique_name
64
+
65
+ @property
66
+ def default_wait_timeout(self):
67
+ return self.__default_wait_timeout
68
+
69
+ @default_wait_timeout.setter
70
+ def default_wait_timeout(self, timeout):
71
+ self.__default_wait_timeout = timeout
72
+
73
+ @property
74
+ def delay_before_run_seconds(self):
75
+ return self.__delay_before_run_sec
76
+
77
+ def start(self)->None:
78
+ super().start()
79
+ SessionContext.instance().multitask_manager.set_process_id(self.__unique_name, MultitaskManager.get_process_id(process=self))
80
+
81
+ def run(self)->None:
82
+ SessionContext.instance().multitask_manager.set_process_thread_uid(self.__unique_name, MultitaskManager.get_thread_uid())
83
+ super().run()
84
+
85
+ def join(self, timeout=undefined_argument, raise_if_still_alive=True):
86
+ """
87
+ See Process.join documentation for default behavior.
88
+
89
+ This implementation tries to avoid deadlocks by special and default timeout value undefined_argument.
90
+ With any other timeout value, including None, default behavior is happening.
91
+ If timeout argument is undefined_argument, it means that it should stop by itself without deadlock.
92
+ In this case, a timeout value Config.join_timeout_seconds is used.
93
+
94
+ If argument raise_if_still_alive is True (default) and if process is still alive after join, an exception is raised.
95
+ If timeout is undefined_argument, a TimeoutTechnicalException is raised, else a FunctionalException.
96
+ """
97
+ timeout_str = "long and finite" if timeout is undefined_argument else f"{timeout}s" if timeout else "none"
98
+ logger.debug(f"Joining process '{self.name}' ; timeout={timeout_str} ...")
99
+
100
+ real_timeout = timeout if timeout is not undefined_argument else Config.join_timeout_seconds
101
+ super().join(real_timeout)
102
+
103
+ logger.debug(f"End of joining process '{self.name}' ; timeout={timeout_str} ; alive:{self.is_alive()}")
104
+
105
+ if self.is_alive():
106
+ if raise_if_still_alive:
107
+ if timeout is undefined_argument:
108
+ raise TimeoutTechnicalException(f"Process '{self.name}' is still alive after join")
109
+ else:
110
+ raise FunctionalException(f"Process '{self.name}' is still alive after join")
111
+ else:
112
+ logger.error(f"Process '{self.name}' is still alive after join")
113
+
114
+ def wait_before_run(self):
115
+ if self.delay_before_run_seconds is not None:
116
+ try:
117
+ time.sleep(self.delay_before_run_seconds)
118
+ except Exception as exc:
119
+ logger.exception(f"Exception while waiting delay before run (delay: {self.delay_before_run_seconds} ; type: {Typing.get_object_class_fullname(self.delay_before_run_seconds)})")
120
+
121
+ # def wait_is_idle(self, timeout=None):
122
+ # """ Wait event self._is_idle"""
123
+ # self._wait(self.__is_idle, "is idle", timeout=timeout)
124
+ #
125
+ # def _wait(self, event, event_details, timeout=None):
126
+ # """ Wait given threading.Event"""
127
+ # is_set = False
128
+ # wait_round_counter = 0
129
+ # round_wait_seconds = 1
130
+ # if timeout is None:
131
+ # timeout = self.__default_wait_timeout
132
+ #
133
+ # logger.debug("[{}] Waiting {}...".format(self.name, event_details))
134
+ # while not is_set:
135
+ # wait_round_counter += 1
136
+ # is_set = event.wait(round_wait_seconds)
137
+ #
138
+ # if not is_set:
139
+ # if wait_round_counter * round_wait_seconds * 1000 > timeout:
140
+ # raise TimeoutError("[{}] Timeout when waiting {}".format(self.name, event_details))
141
+ # elif wait_round_counter % 10 == 0:
142
+ # logger.debug("[{}] Still waiting {} (round {})".format(self.name, event_details, wait_round_counter))
143
+ # logger.debug("[{}] Finished waiting {}...".format(self.name, event_details))
144
+
145
+ class InterruptableProcess(Process):
146
+ """ Helper class managing a process interruptable.
147
+ It gives only the interface, sub-classes must implement if it is really interruptable and how.
148
+ """
149
+
150
+ def __init__(self, name, default_wait_timeout = None, register_process = True, delay_before_run_sec=None):
151
+ super().__init__(name, default_wait_timeout = default_wait_timeout, register_process = register_process, delay_before_run_sec=delay_before_run_sec)
152
+
153
+ # Manage interrupt
154
+ # self.__interrupt_lock = threading.Lock()
155
+ # self.__interrupt_event = threading.Event()
156
+
157
+ @property
158
+ def is_interruptable(self):
159
+ # return True
160
+ raise NotImplementedError
161
+
162
+ @property
163
+ def is_interrupted(self):
164
+ return False
165
+ # with self.__interrupt_lock:
166
+ # return self.__interrupt_event.is_set()
167
+
168
+ def interrupt(self):
169
+ # if not self.is_interrupted:
170
+ # logger.debug("Interrupt thread '{}'".format(self.name))
171
+ # with self.__interrupt_lock:
172
+ # self.__interrupt_event.set()
173
+ raise NotImplementedError
174
+
175
+ def _raise_if_interrupted(self):
176
+ if self.is_interrupted:
177
+ raise InterruptedError
178
+
179
+
180
+
181
+ class ThreadAsProcess(InterruptableProcess):
182
+ """
183
+ WARNING: Do not use, it is under construction
184
+ """
185
+ def __init__(self, thread):
186
+ super().__init__()
187
+ self.__thread = thread
188
+
189
+ def run(self):
190
+ # Start running by superclass run
191
+ super().run()
192
+
193
+ return self.__thread.run()
194
+
195
+
196
+
@@ -0,0 +1,133 @@
1
+
2
+ #################################################
3
+ # HolAdo (Holistic Automation do)
4
+ #
5
+ # (C) Copyright 2021-2025 by Eric Klumpp
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ # The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
12
+ #################################################
13
+
14
+ import threading
15
+ import logging
16
+ from holado_core.common.exceptions.technical_exception import TechnicalException
17
+ import holado_multitask.multiprocessing as hmm
18
+ from holado.common.handlers.undefined import undefined_argument
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class ProcessesManager(object):
24
+ """
25
+ Helper class to manage running processes.
26
+ """
27
+
28
+
29
+ def __init__(self, multitask_manager):
30
+ self.__multitask_manager = multitask_manager
31
+ self.__managed_processes_lock = threading.Lock()
32
+ self.__managed_processes = {}
33
+
34
+ def register_process(self, name, process):
35
+ with self.__managed_processes_lock:
36
+ if name in self.__managed_processes:
37
+ logger.error(f"A process with name '{name}' is already registered, it will be overwritten: {self.__managed_processes[name]}")
38
+ else:
39
+ logger.debug(f"Registered process with name '{name}': {process}")
40
+ self.__managed_processes[name] = process
41
+
42
+ def unregister_process(self, name):
43
+ with self.__managed_processes_lock:
44
+ if name in self.__managed_processes:
45
+ if self.__managed_processes[name].is_alive():
46
+ logger.warn(f"Unregistering process with name '{name}' whereas it is still alive")
47
+ else:
48
+ logger.debug(f"Unregistered process with name '{name}'")
49
+ del self.__managed_processes[name]
50
+ else:
51
+ raise Exception("Not registered process of name '{}'".format(name))
52
+
53
+
54
+ def get_process(self, name):
55
+ with self.__managed_processes_lock:
56
+ if name in self.__managed_processes:
57
+ return self.__managed_processes[name]
58
+ else:
59
+ raise Exception("Unregistered process of name '{}'".format(name))
60
+
61
+
62
+ def interrupt_process(self, name, with_join=True, join_timeout=undefined_argument, raise_if_not_interruptable=True):
63
+ process = self.get_process(name)
64
+ if process.is_alive():
65
+ if self.is_interruptable(process=process):
66
+ try:
67
+ process.interrupt()
68
+ except Exception as exc:
69
+ # logger.exception("Failed to interrupt process of name '{}'".format(name))
70
+ raise exc
71
+
72
+ if with_join:
73
+ process.join(join_timeout)
74
+ elif raise_if_not_interruptable:
75
+ raise TechnicalException("Thread '{}' is not interruptable".format(name))
76
+
77
+
78
+
79
+ def join_process(self, name, timeout=undefined_argument):
80
+ process = self.get_process(name)
81
+ if process.is_alive():
82
+ process.join(timeout)
83
+
84
+
85
+ def interrupt_all_processes(self, with_join=True, join_timeout=undefined_argument):
86
+ """Interrupt all processes that are interruptable."""
87
+ names = self.get_process_names()
88
+ for name in names:
89
+ try:
90
+ if self.is_interruptable(name=name):
91
+ self.interrupt_process(name, with_join=False)
92
+ except Exception:
93
+ logger.exception("Failed to interrupt process of name '{}'".format(name))
94
+
95
+ if with_join:
96
+ self.join_all_processes(timeout=join_timeout, skip_not_interruptable=True)
97
+
98
+
99
+ def join_all_processes(self, timeout=undefined_argument, skip_not_interruptable=False):
100
+ names = self.get_process_names()
101
+ for name in names:
102
+ if skip_not_interruptable and self.is_interruptable(name=name):
103
+ continue
104
+ self.join_process(name, timeout=timeout)
105
+
106
+
107
+ def unregister_all_processes(self, keep_alive=True):
108
+ names = self.get_process_names()
109
+ for name in names:
110
+ process = self.get_process(name)
111
+ if not keep_alive or keep_alive and not process.is_alive():
112
+ self.unregister_process(name)
113
+
114
+
115
+ def get_process_names(self):
116
+ with self.__managed_processes_lock:
117
+ return sorted(list( self.__managed_processes.keys() ))
118
+
119
+
120
+ def get_alive_process_names(self):
121
+ with self.__managed_processes_lock:
122
+ res = sorted(list( self.__managed_processes.keys() ))
123
+ res = [name for name in res if self.__managed_processes[name].is_alive()]
124
+
125
+
126
+ def is_interruptable(self, process=None, name=None):
127
+ if name is not None:
128
+ process = self.get_process(name)
129
+ if process is None:
130
+ raise TechnicalException("At least one argument must be not None")
131
+
132
+ return isinstance(process, hmm.process.InterruptableProcess) and process.is_interruptable
133
+