openmodule 14.0.2__tar.gz → 14.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. {openmodule-14.0.2 → openmodule-14.0.4}/ChangeLog +10 -10
  2. {openmodule-14.0.2/openmodule.egg-info → openmodule-14.0.4}/PKG-INFO +1 -1
  3. {openmodule-14.0.2 → openmodule-14.0.4}/docs/known_issues.md +13 -0
  4. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/base.py +4 -2
  5. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/sentry.py +23 -15
  6. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/kv_store.py +21 -7
  7. {openmodule-14.0.2 → openmodule-14.0.4/openmodule.egg-info}/PKG-INFO +1 -1
  8. openmodule-14.0.4/openmodule.egg-info/pbr.json +1 -0
  9. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_model.py +1 -2
  10. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_sentry.py +60 -16
  11. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_kv_store.py +28 -5
  12. openmodule-14.0.2/openmodule.egg-info/pbr.json +0 -1
  13. {openmodule-14.0.2 → openmodule-14.0.4}/.gitlab-ci.yml +0 -0
  14. {openmodule-14.0.2 → openmodule-14.0.4}/AUTHORS +0 -0
  15. {openmodule-14.0.2 → openmodule-14.0.4}/LICENSE +0 -0
  16. {openmodule-14.0.2 → openmodule-14.0.4}/README.md +0 -0
  17. {openmodule-14.0.2 → openmodule-14.0.4}/docs/access_service.md +0 -0
  18. {openmodule-14.0.2 → openmodule-14.0.4}/docs/anonymization.md +0 -0
  19. {openmodule-14.0.2 → openmodule-14.0.4}/docs/cleanup.md +0 -0
  20. {openmodule-14.0.2 → openmodule-14.0.4}/docs/coding_standard.md +0 -0
  21. {openmodule-14.0.2 → openmodule-14.0.4}/docs/commands.md +0 -0
  22. {openmodule-14.0.2 → openmodule-14.0.4}/docs/connection_status_listener.md +0 -0
  23. {openmodule-14.0.2 → openmodule-14.0.4}/docs/csv_export.md +0 -0
  24. {openmodule-14.0.2 → openmodule-14.0.4}/docs/database.md +0 -0
  25. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated.md +0 -0
  26. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/README.md +0 -0
  27. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/access_service/openmodule/models/access_service.py +0 -0
  28. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/access_service/openmodule/utils/access_service.py +0 -0
  29. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/access_service/openmodule_test/access_service.py +0 -0
  30. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/access_service/tests/test_utils_access_service.py +0 -0
  31. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/api/openmodule/utils/api.py +0 -0
  32. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/api/openmodule_test/api.py +0 -0
  33. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/api/tests/test_utils_api.py +0 -0
  34. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/package_reader/openmodule/utils/package_reader.py +0 -0
  35. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/package_reader/openmodule_test/fake_package_creator.py +0 -0
  36. {openmodule-14.0.2 → openmodule-14.0.4}/docs/deprecated_code/package_reader/tests/test_package_reader.py +0 -0
  37. {openmodule-14.0.2 → openmodule-14.0.4}/docs/event_sending.md +0 -0
  38. {openmodule-14.0.2 → openmodule-14.0.4}/docs/getting_started.md +0 -0
  39. {openmodule-14.0.2 → openmodule-14.0.4}/docs/health.md +0 -0
  40. {openmodule-14.0.2 → openmodule-14.0.4}/docs/images/broker.drawio.png +0 -0
  41. {openmodule-14.0.2 → openmodule-14.0.4}/docs/migrations.md +0 -0
  42. {openmodule-14.0.2 → openmodule-14.0.4}/docs/package_reader.md +0 -0
  43. {openmodule-14.0.2 → openmodule-14.0.4}/docs/rpc.md +0 -0
  44. {openmodule-14.0.2 → openmodule-14.0.4}/docs/sentry.md +0 -0
  45. {openmodule-14.0.2 → openmodule-14.0.4}/docs/settings.md +0 -0
  46. {openmodule-14.0.2 → openmodule-14.0.4}/docs/settings_provider.md +0 -0
  47. {openmodule-14.0.2 → openmodule-14.0.4}/docs/testing.md +0 -0
  48. {openmodule-14.0.2 → openmodule-14.0.4}/docs/translation.md +0 -0
  49. {openmodule-14.0.2 → openmodule-14.0.4}/docs/utils.md +0 -0
  50. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/__init__.py +0 -0
  51. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/alert.py +0 -0
  52. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/config.py +0 -0
  53. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/connection_status.py +0 -0
  54. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/core.py +0 -0
  55. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/database/custom_types.py +0 -0
  56. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/database/database.py +0 -0
  57. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/database/env.py +0 -0
  58. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/database/migration.py +0 -0
  59. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/dispatcher.py +0 -0
  60. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/health.py +0 -0
  61. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/logging.py +0 -0
  62. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/messaging.py +0 -0
  63. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/__init__.py +0 -0
  64. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/access_service.py +0 -0
  65. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/alert.py +0 -0
  66. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/io.py +0 -0
  67. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/kv_store.py +0 -0
  68. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/presence.py +0 -0
  69. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/privacy.py +0 -0
  70. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/rpc.py +0 -0
  71. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/settings.py +0 -0
  72. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/validation.py +0 -0
  73. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/models/vehicle.py +0 -0
  74. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/rpc/__init__.py +0 -0
  75. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/rpc/client.py +0 -0
  76. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/rpc/common.py +0 -0
  77. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/rpc/server.py +0 -0
  78. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/threading.py +0 -0
  79. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/__init__.py +0 -0
  80. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/access_service.py +0 -0
  81. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/charset.py +0 -0
  82. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/cleanup.py +0 -0
  83. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/csv_export.py +0 -0
  84. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/databox.py +0 -0
  85. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/db_helper.py +0 -0
  86. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/eventlog.py +0 -0
  87. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/io.py +0 -0
  88. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/matching.py +0 -0
  89. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/misc_functions.py +0 -0
  90. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/package_reader.py +0 -0
  91. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/presence.py +0 -0
  92. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/schema.py +0 -0
  93. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/settings.py +0 -0
  94. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/translation.py +0 -0
  95. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule/utils/validation.py +0 -0
  96. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule.egg-info/SOURCES.txt +0 -0
  97. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule.egg-info/dependency_links.txt +0 -0
  98. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule.egg-info/not-zip-safe +0 -0
  99. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule.egg-info/requires.txt +0 -0
  100. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule.egg-info/top_level.txt +0 -0
  101. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_commands/__init__.py +0 -0
  102. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_commands/setup.cfg +0 -0
  103. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_commands/setup.py +0 -0
  104. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_commands/translate.py +0 -0
  105. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/__init__.py +0 -0
  106. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/alert.py +0 -0
  107. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/connection_status.py +0 -0
  108. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/core.py +0 -0
  109. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/database.py +0 -0
  110. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/eventlistener.py +0 -0
  111. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/files.py +0 -0
  112. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/gate.py +0 -0
  113. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/health.py +0 -0
  114. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/interrupt.py +0 -0
  115. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/io_simulator.py +0 -0
  116. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/package_reader.py +0 -0
  117. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/presence.py +0 -0
  118. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/requirements.txt +0 -0
  119. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/rpc.py +0 -0
  120. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/sentry.py +0 -0
  121. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/settings.py +0 -0
  122. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/setup.cfg +0 -0
  123. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/setup.py +0 -0
  124. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/utils.py +0 -0
  125. {openmodule-14.0.2 → openmodule-14.0.4}/openmodule_test/zeromq.py +0 -0
  126. {openmodule-14.0.2 → openmodule-14.0.4}/requirements.txt +0 -0
  127. {openmodule-14.0.2 → openmodule-14.0.4}/setup.cfg +0 -0
  128. {openmodule-14.0.2 → openmodule-14.0.4}/setup.py +0 -0
  129. {openmodule-14.0.2 → openmodule-14.0.4}/test-requirements.txt +0 -0
  130. {openmodule-14.0.2 → openmodule-14.0.4}/tests/__init__.py +0 -0
  131. {openmodule-14.0.2 → openmodule-14.0.4}/tests/config.py +0 -0
  132. {openmodule-14.0.2 → openmodule-14.0.4}/tests/database_models_migration.py +0 -0
  133. {openmodule-14.0.2 → openmodule-14.0.4}/tests/database_models_test.py +0 -0
  134. {openmodule-14.0.2 → openmodule-14.0.4}/tests/invalid_database/alembic/README +0 -0
  135. {openmodule-14.0.2 → openmodule-14.0.4}/tests/invalid_database/alembic/__init__.py +0 -0
  136. {openmodule-14.0.2 → openmodule-14.0.4}/tests/invalid_database/alembic/env.py +0 -0
  137. {openmodule-14.0.2 → openmodule-14.0.4}/tests/invalid_database/alembic/script.py.mako +0 -0
  138. {openmodule-14.0.2 → openmodule-14.0.4}/tests/invalid_database/alembic/versions/ff26e54332f9_datetime_models.py +0 -0
  139. {openmodule-14.0.2 → openmodule-14.0.4}/tests/invalid_database/alembic.ini +0 -0
  140. {openmodule-14.0.2 → openmodule-14.0.4}/tests/invalid_database/makemigration.sh +0 -0
  141. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_double_column_delete_error/alembic/__init__.py +0 -0
  142. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_double_column_delete_error/alembic/env.py +0 -0
  143. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_double_column_delete_error/alembic/script.py.mako +0 -0
  144. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_double_column_delete_error/alembic/versions/812a3e5b8517_initial.py +0 -0
  145. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_double_column_delete_error/alembic/versions/a7ea100a784f_key_error.py +0 -0
  146. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_double_column_delete_error/alembic.ini +0 -0
  147. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_double_column_delete_error/makemigration.sh +0 -0
  148. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_no_such_table_error/alembic/__init__.py +0 -0
  149. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_no_such_table_error/alembic/env.py +0 -0
  150. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_no_such_table_error/alembic/script.py.mako +0 -0
  151. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_no_such_table_error/alembic/versions/812a3e5b8517_initial.py +0 -0
  152. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_no_such_table_error/alembic/versions/a7ea100a784f_no_such_table_error.py +0 -0
  153. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_no_such_table_error/alembic.ini +0 -0
  154. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_no_such_table_error/makemigration.sh +0 -0
  155. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/__init__.py +0 -0
  156. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic/__init__.py +0 -0
  157. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic/env.py +0 -0
  158. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic/script.py.mako +0 -0
  159. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic/versions/19789aa5361c_initial.py +0 -0
  160. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic/versions/19d887929ae7_alter.py +0 -0
  161. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic/versions/__init__.py +0 -0
  162. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic.ini +0 -0
  163. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/alembic_migration_test_database.sqlite3 +0 -0
  164. {openmodule-14.0.2 → openmodule-14.0.4}/tests/migration_test_database/makemigration.sh +0 -0
  165. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/configs/config.py +0 -0
  166. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/configs/test_config.py +0 -0
  167. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/configs/test_config_1.py +0 -0
  168. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/standard_schemes/DEFAULT-10.yml +0 -0
  169. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/standard_schemes/DEFAULT-20.yml +0 -0
  170. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/standard_schemes/LEGACY-0.yml +0 -0
  171. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/translation/locale/de/LC_MESSAGES/translation.mo +0 -0
  172. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/translation/locale/de/LC_MESSAGES/translation.po +0 -0
  173. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/translation/locale/en/LC_MESSAGES/translation.mo +0 -0
  174. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/translation/locale/en/LC_MESSAGES/translation.po +0 -0
  175. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/translation/locale/translation.pot +0 -0
  176. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/translation/translate.sh +0 -0
  177. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/A-10.yml +0 -0
  178. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/A-20.yml +0 -0
  179. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/DEFAULT-10.yml +0 -0
  180. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/DEFAULT-20.yml +0 -0
  181. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/DEFAULT-30.yml +0 -0
  182. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/LEGACY-0.yml +0 -0
  183. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/TEST-10.yml +0 -0
  184. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/TEST-20.yml +0 -0
  185. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/TEST-30.yml +0 -0
  186. {openmodule-14.0.2 → openmodule-14.0.4}/tests/resources/utils_matching/TEST-40.yml +0 -0
  187. {openmodule-14.0.2 → openmodule-14.0.4}/tests/sentry_main.py +0 -0
  188. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/alembic/__init__.py +0 -0
  189. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/alembic/env.py +0 -0
  190. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/alembic/script.py.mako +0 -0
  191. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/alembic/versions/7bd4fcd38fde_removed_nfc_and_pin.py +0 -0
  192. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/alembic/versions/9ca98a2e5674_added_parksettings_id.py +0 -0
  193. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/alembic/versions/c821971f9230_initial.py +0 -0
  194. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/alembic.ini +0 -0
  195. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_access_service_database/makemigration.sh +0 -0
  196. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_alembic_migrations.py +0 -0
  197. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_alert.py +0 -0
  198. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_checks.py +0 -0
  199. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_config.py +0 -0
  200. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_connection_status.py +0 -0
  201. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_core.py +0 -0
  202. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_database/alembic/__init__.py +0 -0
  203. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_database/alembic/env.py +0 -0
  204. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_database/alembic/script.py.mako +0 -0
  205. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_database/alembic/versions/32b8c728abbf_initial.py +0 -0
  206. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_database/alembic.ini +0 -0
  207. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_database/makemigration.sh +0 -0
  208. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_database.py +0 -0
  209. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_dispatcher.py +0 -0
  210. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_health.py +0 -0
  211. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_interrupt.py +0 -0
  212. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_io_listen.py +0 -0
  213. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_database/alembic/__init__.py +0 -0
  214. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_database/alembic/env.py +0 -0
  215. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_database/alembic/script.py.mako +0 -0
  216. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_database/alembic/versions/9c5c944221f4_deprecated_kv_entry_example.py +0 -0
  217. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_database/alembic/versions/c55a69026a25_initial.py +0 -0
  218. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_database/alembic.ini +0 -0
  219. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_database/makemigration.sh +0 -0
  220. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_multiple_database/alembic/README +0 -0
  221. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_multiple_database/alembic/__init__.py +0 -0
  222. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_multiple_database/alembic/env.py +0 -0
  223. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_multiple_database/alembic/script.py.mako +0 -0
  224. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_multiple_database/alembic/versions/cdb3214131a9_initial.py +0 -0
  225. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_multiple_database/alembic.ini +0 -0
  226. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_kv_store_multiple_database/makemigration.sh +0 -0
  227. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_logging.py +0 -0
  228. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_messaging.py +0 -0
  229. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_mockrpcclient.py +0 -0
  230. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_rpc.py +0 -0
  231. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_schema.py +0 -0
  232. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_test_alert.py +0 -0
  233. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_test_gate.py +0 -0
  234. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_test_zeromq.py +0 -0
  235. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_access_service.py +0 -0
  236. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_charset.py +0 -0
  237. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_cleanup.py +0 -0
  238. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_csv_export.py +0 -0
  239. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_databox.py +0 -0
  240. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_eventlog.py +0 -0
  241. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_kv_store_multiple.py +0 -0
  242. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_matching.py +0 -0
  243. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_misc_functions.py +0 -0
  244. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_package_reader.py +0 -0
  245. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_presence.py +0 -0
  246. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_settings.py +0 -0
  247. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_validation.py +0 -0
  248. {openmodule-14.0.2 → openmodule-14.0.4}/tests/test_utils_vehicle.py +0 -0
  249. {openmodule-14.0.2 → openmodule-14.0.4}/tox.ini +0 -0
@@ -1,6 +1,16 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ v14.0.4
5
+ -------
6
+
7
+ * OM-945 Fix Trace parent in ZMQMessage
8
+
9
+ v14.0.3
10
+ -------
11
+
12
+ * OM-941 Sentry Bugfix
13
+
4
14
  v14.0.2
5
15
  -------
6
16
 
@@ -164,9 +174,6 @@ v12.0.0.rc0
164
174
  * fixed testcases and removed backend (deprecated in v11)
165
175
  * newer settings-models
166
176
  * settings models update
167
- * made gate\_control/day\_mode have no scope
168
- * schedule exports utility
169
- * SettingsProvider docs
170
177
 
171
178
  v11.1.1
172
179
  -------
@@ -194,15 +201,8 @@ v11.0.2
194
201
  * Update database.md [skip ci]
195
202
  * Update database.md [skip ci]
196
203
  * Update database.md [skip ci]
197
- * Update database.md [skip ci]
198
204
  * Major Refactoring and many new functionality (v2 parking system refactor and redesign)
199
205
 
200
206
  v10.0.5
201
207
  -------
202
208
 
203
- * fixed problem in presence listener
204
- * README for settings + backend
205
-
206
- v10.0.4
207
- -------
208
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openmodule
3
- Version: 14.0.2
3
+ Version: 14.0.4
4
4
  Summary: Libraries for developing the arivo openmodule
5
5
  Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
6
6
  Author: ARIVO
@@ -5,7 +5,20 @@ version. The changelog may contain many other notes aswell.
5
5
 
6
6
  The version numbers below always note the _version through which the issue was fixed_.
7
7
 
8
+ ## 14.0.4
9
+
10
+ * fixed ZMQMessage using `sentry-trace` and `baggage` from wrong sentry span
11
+
12
+ ## 14.0.3
13
+
14
+ * fixed not traced topics (io) using sentry scope from different thread leading to possible race condition
15
+
16
+ ## 14.0.2
17
+
18
+ * fixed sentry trace for multithreaded `MessageDispatcher` and `RPCServer`
19
+
8
20
  ## 13.6.0
21
+
9
22
  * fixed message dispatcher trying to handle messages after shutdown was called
10
23
 
11
24
  ## 13.1.2
@@ -139,14 +139,16 @@ class ZMQMessage(OpenModuleModel):
139
139
  timestamp: datetime = Field(default_factory=lambda: datetime.utcnow())
140
140
  name: str = Field(default_factory=lambda: settings.NAME)
141
141
  type: str
142
- baggage: Optional[str] = Field(default_factory=sentry.get_baggage)
143
- sentry_trace: Optional[str] = Field(default_factory=sentry.get_traceparent, alias="sentry-trace")
142
+ baggage: Optional[str] = None
143
+ sentry_trace: Optional[str] = Field(default=None, alias="sentry-trace")
144
144
 
145
145
  _tz_timestamp = timezone_validator("timestamp")
146
146
 
147
147
  def publish_on_topic(self, pub_socket: zmq.Socket, topic: str):
148
148
  assert isinstance(topic, str), "topic must be a string"
149
149
 
150
+ self.baggage = sentry.get_baggage()
151
+ self.sentry_trace = sentry.get_traceparent()
150
152
  pub_socket.send_multipart((topic.encode("utf8"), self.json_bytes()))
151
153
 
152
154
  def dict(self, **kwargs):
@@ -36,8 +36,6 @@ def continue_trace_zmq_message_receive(topic: str, message: dict, **kwargs):
36
36
  :param topic: The topic of the message (as received from the ZMQ socket and decoded)
37
37
  :param message: The ZMQMessage as a dict (as received from the ZMQ socket and json loaded)
38
38
  """
39
- if topic in _topics_to_ignore:
40
- return noop_context()
41
39
  return _continue_trace_zmq_message(topic, message, "topic.receive", **kwargs)
42
40
 
43
41
 
@@ -59,6 +57,7 @@ def trace(
59
57
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
60
58
  trace_headers: Optional[dict] = None,
61
59
  force_new_transaction: bool = False,
60
+ force_no_trace: bool = False,
62
61
  **span_kwargs) -> Callable[[Callable], Callable]:
63
62
  ...
64
63
 
@@ -69,6 +68,7 @@ def trace(
69
68
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
70
69
  trace_headers: Optional[dict] = None,
71
70
  force_new_transaction: bool = False,
71
+ force_no_trace: bool = False,
72
72
  **span_kwargs) -> Union[Callable, Generator[sentry_sdk.tracing.Span, None, None]]:
73
73
  ...
74
74
 
@@ -79,6 +79,7 @@ def trace(
79
79
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
80
80
  trace_headers: Optional[dict] = None,
81
81
  force_new_transaction: bool = False,
82
+ force_no_trace: bool = False,
82
83
  **span_kwargs) -> Callable:
83
84
  ...
84
85
 
@@ -88,6 +89,7 @@ def trace(
88
89
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
89
90
  trace_headers: Optional[dict] = None,
90
91
  force_new_transaction: bool = False,
92
+ force_no_trace: bool = False,
91
93
  **span_kwargs):
92
94
  """
93
95
  Trace a function or a block of code.
@@ -97,6 +99,7 @@ def trace(
97
99
  span_kwargs["op"] = op
98
100
  span_kwargs["trace_headers"] = trace_headers
99
101
  span_kwargs["force_new_transaction"] = force_new_transaction
102
+ span_kwargs["force_no_trace"] = force_no_trace
100
103
  if name is None:
101
104
  return _Trace(**span_kwargs)
102
105
  elif callable(name):
@@ -125,7 +128,7 @@ def get_trace_headers(empty_if_not_sampled: bool = False) -> dict:
125
128
  span = sentry_sdk.get_current_span()
126
129
  if span and not span.sampled:
127
130
  return {}
128
- return {"sentry-trace": sentry_sdk.get_traceparent(), "baggage": sentry_sdk.get_baggage()}
131
+ return {"sentry-trace": get_traceparent(), "baggage": get_baggage()}
129
132
 
130
133
 
131
134
  class _Trace:
@@ -137,9 +140,11 @@ class _Trace:
137
140
  force_new_transaction: bool
138
141
  ctx: Any
139
142
 
140
- def __init__(self, *, trace_headers: Optional[dict] = None, force_new_transaction: bool = False, **span_kwargs):
143
+ def __init__(self, *, trace_headers: Optional[dict] = None, force_new_transaction: bool = False,
144
+ force_no_trace: bool = False, **span_kwargs):
141
145
  self.trace_headers = trace_headers
142
146
  self.force_new_transaction = force_new_transaction
147
+ self.force_no_trace = force_no_trace
143
148
  self.span_kwargs = span_kwargs
144
149
 
145
150
  @contextmanager
@@ -149,9 +154,7 @@ class _Trace:
149
154
  Otherwise, start a new span.
150
155
  If given a trace_headers dict, it will continue the trace with the given headers.
151
156
  """
152
- if self.span_kwargs.get("name") in _functions_to_ignore:
153
- yield
154
- return
157
+ force_no_trace = self.force_no_trace or self.span_kwargs.get("name") in _functions_to_ignore
155
158
 
156
159
  def set_context():
157
160
  for key, value in extras.items():
@@ -166,15 +169,19 @@ class _Trace:
166
169
  span = sentry_sdk.get_current_span()
167
170
  if span is None or self.force_new_transaction:
168
171
  with sentry_sdk.isolation_scope():
169
- transaction: Optional[sentry_sdk.tracing.Transaction] = None
170
- if self.trace_headers and "sentry-trace" in self.trace_headers:
171
- transaction = sentry_sdk.continue_trace(self.trace_headers, **self.span_kwargs)
172
- with sentry_sdk.start_transaction(transaction=transaction, **self.span_kwargs) as transaction:
173
- if transaction:
174
- transaction.description = transaction.name
172
+ if force_no_trace:
175
173
  set_context()
176
174
  yield
177
- elif span.sampled:
175
+ else:
176
+ transaction: Optional[sentry_sdk.tracing.Transaction] = None
177
+ if self.trace_headers and "sentry-trace" in self.trace_headers:
178
+ transaction = sentry_sdk.continue_trace(self.trace_headers, **self.span_kwargs)
179
+ with sentry_sdk.start_transaction(transaction=transaction, **self.span_kwargs) as transaction:
180
+ if transaction:
181
+ transaction.description = transaction.name
182
+ set_context()
183
+ yield
184
+ elif not force_no_trace and span.sampled:
178
185
  self.span_kwargs.pop("source", None)
179
186
  with sentry_sdk.start_span(**self.span_kwargs):
180
187
  set_context()
@@ -217,7 +224,8 @@ class _Trace:
217
224
 
218
225
  def _continue_trace_zmq_message(topic: str, message: dict, op: str, **kwargs):
219
226
  name = f"{topic}/{message.get('type', '')}"
220
- return _Trace(trace_headers=message, op=op, name=name, source="zmq", origin="auto.zmq", **kwargs)
227
+ return _Trace(trace_headers=message, op=op, name=name, source="zmq", origin="auto.zmq",
228
+ force_no_trace=topic in _topics_to_ignore, **kwargs)
221
229
 
222
230
 
223
231
  class StoringTransport(sentry_sdk.transport.HttpTransport):
@@ -3,6 +3,7 @@ import logging
3
3
  import random
4
4
  import threading
5
5
  import time
6
+ import uuid
6
7
  import warnings
7
8
  from typing import Type, Optional, List, Union, Dict
8
9
 
@@ -193,7 +194,7 @@ class KVStore:
193
194
  additional_kvs = current_kvs
194
195
  return KVSyncResponse(additions=additional_kvs, changes=changed_kvs, missing=missing_kvs)
195
196
 
196
- def _log_sync_rpc_response(self, rpc_entry: RPCClient.RPCEntry) -> bool:
197
+ def _log_sync_rpc_response(self, rpc_entry: RPCClient.RPCEntry, conn_id: str) -> bool:
197
198
  """
198
199
  Waits for the RPC to finish and logs the response
199
200
  :return: if successful
@@ -203,11 +204,22 @@ class KVStore:
203
204
  rpc_entry.result(ServerSyncResponse)
204
205
  return True
205
206
  except RPCClient.TimeoutError:
206
- self.log.error("Timeout syncing kvs")
207
+ if core().connection_listener.changed(conn_id):
208
+ self.log.warning("Connection loss during sync")
209
+ else:
210
+ self.log.error("Timeout syncing kvs")
207
211
  except RPCClient.CancelError:
208
- self.log.error("Cancelled waiting for result of syncing kvs")
212
+ if core().connection_listener.changed(conn_id):
213
+ self.log.warning("Connection loss during sync")
214
+ else:
215
+ self.log.error("Cancelled waiting for result of syncing kvs")
209
216
  except RPCClient.ValidationError:
210
217
  self.log.exception("Error parsing sync response")
218
+ except RPCClient.RPCServerError as e:
219
+ if len(e.args) > 0 and e.args[0] == "request_timeout" and core().connection_listener.changed(conn_id):
220
+ self.log.warning("Connection loss during sync")
221
+ else:
222
+ self.log.exception("Error on server side in sync")
211
223
  except (RPCClient.ServerHandlerError, RPCClient.ServerValidationError, RPCClient.ServerFilterError):
212
224
  self.log.exception("Error on server side in sync")
213
225
  except Exception:
@@ -215,9 +227,9 @@ class KVStore:
215
227
  return False
216
228
 
217
229
  @sentry.trace
218
- def sync(self) -> bool:
230
+ def sync(self, conn_id: str) -> bool:
219
231
  self.sync_rpc_entry = self.sync_with_server()
220
- success = self._log_sync_rpc_response(self.sync_rpc_entry)
232
+ success = self._log_sync_rpc_response(self.sync_rpc_entry, conn_id)
221
233
  self.sync_rpc_entry = None
222
234
  if success: # if sync was successful cancel retries
223
235
  return True
@@ -291,6 +303,7 @@ class KVStoreHandler:
291
303
 
292
304
  def run(self):
293
305
  """We only sync on startup and on reconnect"""
306
+ conn_id = uuid.uuid4().hex
294
307
  try:
295
308
  while self.running:
296
309
  if self._wait_for_change_to_online():
@@ -305,7 +318,8 @@ class KVStoreHandler:
305
318
  ConnectionStatus.online):
306
319
  # cancel trying to sync if offline
307
320
  break
308
- if store.sync():
321
+ core().connection_listener.changed(conn_id)
322
+ if store.sync(conn_id):
309
323
  # if sync was successful cancel retries
310
324
  break
311
325
  # we try again as long we are still alive
@@ -347,7 +361,7 @@ class KVStoreWithChangedNotification(KVStore):
347
361
  changed += list(old_values.keys())
348
362
  return changed
349
363
 
350
- def _send_changed_notification(self, new_values: Dict[str, str], old_values: Dict[str, str]): # pragma: no cover
364
+ def _send_changed_notification(self, new_values: Dict[str, str], old_values: Dict[str, str]): # pragma: no cover
351
365
  """
352
366
  consider using self._find_changed_kvs when implementing this
353
367
  also make sure your db model has a meaningful `comparison_value` method
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openmodule
3
- Version: 14.0.2
3
+ Version: 14.0.4
4
4
  Summary: Libraries for developing the arivo openmodule
5
5
  Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
6
6
  Author: ARIVO
@@ -0,0 +1 @@
1
+ {"git_version": "3d9ddfd", "is_release": true}
@@ -137,8 +137,7 @@ class ZMQMessageTestCase(TestCase):
137
137
  self.assertEqual(res3, res4)
138
138
 
139
139
  res1.pop("timestamp")
140
- sentry_trace = sentry.get_traceparent()
141
- self.assertDictEqual(res1, {"name": "tä\nst", "type": "tö\tst", "sentry-trace": sentry_trace})
140
+ self.assertDictEqual(res1, {"name": "tä\nst", "type": "tö\tst"})
142
141
 
143
142
 
144
143
  class CostEntryDataTextCase(TestCase):
@@ -173,7 +173,6 @@ class SentryInitTestCase(ZMQTestMixin):
173
173
  self.assertEqual(sentry._topics_to_ignore, ["io"])
174
174
  self.assertEqual(sentry._functions_to_ignore, ["message_handler.openmodule.utils.io.IoListener._on_io_message"])
175
175
 
176
-
177
176
  @override_settings(NAME="test")
178
177
  def test_service_name_generation(self):
179
178
  settings.NAME = "om_service_test_1"
@@ -449,6 +448,7 @@ class SentryTestCase(SentryTestMixin):
449
448
  self.assertEqual(len(envelopes[0].items), 1)
450
449
  self.assertEqual(envelopes[0].items[0].payload.json["transaction"], "not-test-ignore")
451
450
 
451
+
452
452
  class SentryInDispatcherTestCase(SentryTestMixin):
453
453
  def setUp(self):
454
454
  super().setUp()
@@ -488,6 +488,15 @@ class SentryInDispatcherTestCase(SentryTestMixin):
488
488
  with self.assertRaises(TimeoutError):
489
489
  self.get_sent_envelopes()
490
490
 
491
+ def test_io_topic_creates_scope(self):
492
+ scope = sentry_sdk.get_isolation_scope()
493
+ with sentry.continue_trace_zmq_message_receive(
494
+ "io", {"sentry-trace": "e6b4de069f9a4e03b7012bb1eec1af08-a7d7309ad4ccc9ec-1"}):
495
+ self.assertNotEqual(scope, sentry_sdk.get_isolation_scope())
496
+ self.assertEqual(scope, sentry_sdk.get_isolation_scope())
497
+ with self.assertRaises(TimeoutError):
498
+ self.get_sent_envelopes()
499
+
491
500
  def test_multi_worker_dispatcher(self):
492
501
  def handler(*_):
493
502
  envelopes_got.wait(1)
@@ -524,15 +533,27 @@ class SentryUtilsTestCase(SentryTestMixin):
524
533
  sentry.init_sentry("http://test@test/1")
525
534
 
526
535
  def test_zmq_message_fields(self):
536
+ zmq_socket = mock.MagicMock()
537
+ message = ZMQMessage(type="test")
538
+ self.assertIsNone(message.sentry_trace)
539
+ self.assertIsNone(message.baggage)
527
540
  with sentry.trace("test", sampled=True):
528
- msg = ZMQMessage(type="test")
529
- json_data = msg.json_bytes()
530
- self.assertIn(b'"sentry-trace":', json_data)
531
- self.assertIn(b'"baggage":', json_data)
541
+ message.publish_on_topic(zmq_socket, "test")
542
+ traceparent = sentry.get_traceparent()
543
+ baggage = sentry.get_baggage()
544
+ self.assertEqual(message.sentry_trace, traceparent)
545
+ self.assertEqual(message.baggage, baggage)
546
+ self.assertIsNotNone(message.sentry_trace)
547
+ self.assertIsNotNone(message.baggage)
548
+ sent_message = json.loads(zmq_socket.send_multipart.call_args[0][0][1])
549
+ self.assertEqual(sent_message["sentry-trace"], traceparent)
550
+ self.assertEqual(sent_message["baggage"], baggage)
532
551
 
533
552
  def test_continue_from_zmq_message(self):
553
+ zmq_socket = mock.MagicMock()
534
554
  with sentry.trace("test", sampled=True):
535
555
  msg = ZMQMessage(type="test_type")
556
+ msg.publish_on_topic(zmq_socket, "topic_test")
536
557
  trace_id = sentry_sdk.get_current_span().trace_id
537
558
  msg_data = json.loads(msg.json_bytes())
538
559
  with sentry.continue_trace_zmq_message_process("topic_test", msg_data):
@@ -759,7 +780,7 @@ class SentryTraceCpuUsageTestCase(TestCase):
759
780
  import psutil
760
781
  helper = SentryTraceHelper(self.execution_count, self.sleep_time)
761
782
 
762
- self.processes.append(multiprocessing.Process(target=helper.sentry))
783
+ self.processes.append(multiprocessing.Process(target=helper.sentry_io))
763
784
  self.processes.append(multiprocessing.Process(target=helper.fake))
764
785
  for process in self.processes:
765
786
  process.start()
@@ -809,21 +830,45 @@ class SentryTraceHelper:
809
830
  sentry_sdk.start_transaction = self.fake_trace
810
831
  self.sentry()
811
832
 
833
+ @staticmethod
834
+ def make_core(traces_sample_rate=0.001):
835
+ settings.LOG_LEVEL = "WARNING"
836
+ settings.TESTING = True
837
+ settings.DEBUG = False
838
+ sentry_sdk.utils.logger.setLevel(logging.WARNING)
839
+ logging.basicConfig(level=logging.WARNING)
840
+ return init_openmodule(settings, wait_for_broker=False, traces_sample_rate=traces_sample_rate,
841
+ sentry=True, dsn="http://test@test/1")
842
+
812
843
  def trace_all(self):
813
844
  self.sentry(traces_sample_rate=1.0)
814
845
 
846
+ @staticmethod
847
+ def _sentry_traceparent(traces_sample_rate=0.001):
848
+ return f"e6b4de069f9a4e03b7012bb1eec1af08-a7d7309ad4ccc9ec-{int(random.random() < traces_sample_rate)}"
849
+
850
+ def sentry_io(self, traces_sample_rate=0.001):
851
+ core = None
852
+ try:
853
+ core = self.make_core(traces_sample_rate)
854
+ IoListener(core.messages)
855
+ for _ in range(self.execution_count):
856
+ message = {"edge": 1, "gateway": {"gate": "test", "direction": "in"}, "type": "io", "pin": "1",
857
+ "value": 1, "sentry-trace": self._sentry_traceparent(traces_sample_rate)}
858
+ with sentry.continue_trace_zmq_message_receive("io", message):
859
+ core.messages.dispatch("io", message)
860
+ time.sleep(self.sleep_time)
861
+ finally:
862
+ if core:
863
+ shutdown_openmodule()
864
+
815
865
  def sentry(self, traces_sample_rate=0.001):
866
+ from openmodule.models.base import CostEntryData
867
+
816
868
  rpc_server = None
817
869
  core = None
818
870
  try:
819
- from openmodule.models.base import CostEntryData
820
- settings.LOG_LEVEL = "WARNING"
821
- settings.TESTING = True
822
- settings.DEBUG = False
823
- sentry_sdk.utils.logger.setLevel(logging.WARNING)
824
- logging.basicConfig(level=logging.WARNING)
825
- core = init_openmodule(settings, wait_for_broker=False, traces_sample_rate=traces_sample_rate,
826
- sentry=True, dsn="http://test@test/1")
871
+ core = self.make_core(traces_sample_rate)
827
872
  sentry_sdk.get_client().transport.envelope_store = "/tmp/envelope_store"
828
873
  rpc_server = RPCServer(core.context)
829
874
  rpc_server.register_handler("test", "test", CostEntryData, CostEntryData, self.fake_handler,
@@ -831,8 +876,7 @@ class SentryTraceHelper:
831
876
  for _ in range(self.execution_count):
832
877
  # noinspection PyProtectedMember
833
878
  rpc_server._process_rpc_message("rpc-req-test", {
834
- "sentry-trace": f"e6b4de069f9a4e03b7012bb1eec1af08-a7d7309ad4ccc9ec-"
835
- f"{int(random.random() < traces_sample_rate)}",
879
+ "sentry-trace": self._sentry_traceparent(traces_sample_rate),
836
880
  "rpc_id": "ef9a5e77-bc95-404c-94de-9cf7b326c4d5", "resource": settings.RESOURCE, "type": "test",
837
881
  "request": {"entry_type": "rate_change", "value": "test1", "group": "test", "account_id": "test"}})
838
882
  time.sleep(self.sleep_time)
@@ -1,5 +1,6 @@
1
1
  import threading
2
2
  import time
3
+ import uuid
3
4
  from typing import List, Dict
4
5
 
5
6
  from sqlalchemy import Column, String
@@ -7,7 +8,7 @@ from sqlalchemy.exc import SQLAlchemyError
7
8
  from sqlalchemy.ext.declarative import declarative_base
8
9
 
9
10
  from openmodule.config import settings
10
- from openmodule.connection_status import ConnectionStatus
11
+ from openmodule.connection_status import ConnectionStatus, ConnectionStatusMessage
11
12
  from openmodule.core import core
12
13
  from openmodule.models.kv_store import KVSetRequest, KVSetRequestKV, KVSyncRequest, KVSetResponse, KVSyncResponse, \
13
14
  ServerSyncResponse
@@ -317,8 +318,10 @@ class KVStoreRPCTestCase(SQLiteTestMixin, RPCServerTestMixin, OpenModuleCoreTest
317
318
  session.commit()
318
319
 
319
320
  self.kv_store.rpc_client = MockRPCClient(responses={("rpc-websocket", "server_rpc"): start_sync()})
321
+ conn_id = uuid.uuid4().hex
322
+ self.core.connection_listener.changed(conn_id)
320
323
  entry = self.kv_store.sync_with_server()
321
- self.kv_store._log_sync_rpc_response(entry)
324
+ self.kv_store._log_sync_rpc_response(entry, conn_id)
322
325
 
323
326
  def test_sync_errors(self):
324
327
  def raise_error(*_):
@@ -327,31 +330,51 @@ class KVStoreRPCTestCase(SQLiteTestMixin, RPCServerTestMixin, OpenModuleCoreTest
327
330
  def wrong_response(*_):
328
331
  return {}
329
332
 
333
+ conn_id = uuid.uuid4().hex
334
+
330
335
  # status error
336
+ self.core.connection_listener.changed(conn_id)
331
337
  self.rpc_server.register_handler("rpc-websocket", "server_rpc", ServerRPCRequest, ServerSyncResponse,
332
338
  raise_error, register_schema=False)
333
339
  entry = self.kv_store.sync_with_server()
334
340
  with self.assertLogs() as cm:
335
- success = self.kv_store._log_sync_rpc_response(entry)
341
+ success = self.kv_store._log_sync_rpc_response(entry, conn_id)
336
342
  self.assertIn("Error on server side in sync", str(cm.output))
337
343
  self.assertFalse(success)
338
344
 
339
345
  # Un-parseable response
346
+ self.core.connection_listener.changed(conn_id)
340
347
  entry = RPCClient.RPCEntry(0)
341
348
  entry.response = "test"
342
349
  with self.assertLogs() as cm:
343
- success = self.kv_store._log_sync_rpc_response(entry)
350
+ success = self.kv_store._log_sync_rpc_response(entry, conn_id)
344
351
  self.assertIn("Unexpected exception in sync response", str(cm.output))
345
352
  self.assertFalse(success)
346
353
 
347
354
  # timeout
355
+ self.core.connection_listener.changed(conn_id)
348
356
  del self.rpc_server.handlers[("rpc-websocket", "server_rpc")]
349
357
  entry = self.kv_store.sync_with_server()
350
358
  with self.assertLogs() as cm:
351
- success = self.kv_store._log_sync_rpc_response(entry)
359
+ success = self.kv_store._log_sync_rpc_response(entry, conn_id)
352
360
  self.assertIn("Timeout syncing kvs", str(cm.output))
353
361
  self.assertFalse(success)
354
362
 
363
+ def test_connection_loss_warning(self):
364
+ conn_id = uuid.uuid4().hex
365
+ self.core.connection_listener._process_connection_status(
366
+ ConnectionStatusMessage(connected=ConnectionStatus.online))
367
+ self.core.connection_listener.changed(conn_id)
368
+ self.core.connection_listener._process_connection_status(
369
+ ConnectionStatusMessage(connected=ConnectionStatus.shutdown))
370
+ entry = self.kv_store.sync_with_server()
371
+ with self.assertLogs() as cm:
372
+ success = self.kv_store._log_sync_rpc_response(entry, conn_id)
373
+ self.assertIn("Connection loss during sync", str(cm.output))
374
+ self.assertEqual(len(cm.output), 1)
375
+ self.assertFalse(success)
376
+
377
+
355
378
 
356
379
  class KVStoreSyncTriggerTestCase(OpenModuleCoreTestMixin):
357
380
  def setUp(self) -> None:
@@ -1 +0,0 @@
1
- {"git_version": "3399243", "is_release": true}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes