nucliadb 4.0.0.post542__py3-none-any.whl → 6.2.1.post2777__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.
Files changed (418) hide show
  1. migrations/0003_allfields_key.py +1 -35
  2. migrations/0009_upgrade_relations_and_texts_to_v2.py +4 -2
  3. migrations/0010_fix_corrupt_indexes.py +10 -10
  4. migrations/0011_materialize_labelset_ids.py +1 -16
  5. migrations/0012_rollover_shards.py +5 -10
  6. migrations/0014_rollover_shards.py +4 -5
  7. migrations/0015_targeted_rollover.py +5 -10
  8. migrations/0016_upgrade_to_paragraphs_v2.py +25 -28
  9. migrations/0017_multiple_writable_shards.py +2 -4
  10. migrations/0018_purge_orphan_kbslugs.py +5 -7
  11. migrations/0019_upgrade_to_paragraphs_v3.py +25 -28
  12. migrations/0020_drain_nodes_from_cluster.py +3 -3
  13. nucliadb/standalone/tests/unit/test_run.py → migrations/0021_overwrite_vectorsets_key.py +16 -19
  14. nucliadb/tests/unit/test_openapi.py → migrations/0022_fix_paragraph_deletion_bug.py +16 -11
  15. migrations/0023_backfill_pg_catalog.py +80 -0
  16. migrations/0025_assign_models_to_kbs_v2.py +113 -0
  17. migrations/0026_fix_high_cardinality_content_types.py +61 -0
  18. migrations/0027_rollover_texts3.py +73 -0
  19. nucliadb/ingest/fields/date.py → migrations/pg/0001_bootstrap.py +10 -12
  20. migrations/pg/0002_catalog.py +42 -0
  21. nucliadb/ingest/tests/unit/test_settings.py → migrations/pg/0003_catalog_kbid_index.py +5 -3
  22. nucliadb/common/cluster/base.py +30 -16
  23. nucliadb/common/cluster/discovery/base.py +6 -14
  24. nucliadb/common/cluster/discovery/k8s.py +9 -19
  25. nucliadb/common/cluster/discovery/manual.py +1 -3
  26. nucliadb/common/cluster/discovery/utils.py +1 -3
  27. nucliadb/common/cluster/grpc_node_dummy.py +3 -11
  28. nucliadb/common/cluster/index_node.py +10 -19
  29. nucliadb/common/cluster/manager.py +174 -59
  30. nucliadb/common/cluster/rebalance.py +27 -29
  31. nucliadb/common/cluster/rollover.py +353 -194
  32. nucliadb/common/cluster/settings.py +6 -0
  33. nucliadb/common/cluster/standalone/grpc_node_binding.py +13 -64
  34. nucliadb/common/cluster/standalone/index_node.py +4 -11
  35. nucliadb/common/cluster/standalone/service.py +2 -6
  36. nucliadb/common/cluster/standalone/utils.py +2 -6
  37. nucliadb/common/cluster/utils.py +29 -22
  38. nucliadb/common/constants.py +20 -0
  39. nucliadb/common/context/__init__.py +3 -0
  40. nucliadb/common/context/fastapi.py +8 -5
  41. nucliadb/{tests/knowledgeboxes/__init__.py → common/counters.py} +8 -2
  42. nucliadb/common/datamanagers/__init__.py +7 -1
  43. nucliadb/common/datamanagers/atomic.py +22 -4
  44. nucliadb/common/datamanagers/cluster.py +5 -5
  45. nucliadb/common/datamanagers/entities.py +6 -16
  46. nucliadb/common/datamanagers/fields.py +84 -0
  47. nucliadb/common/datamanagers/kb.py +83 -37
  48. nucliadb/common/datamanagers/labels.py +26 -56
  49. nucliadb/common/datamanagers/processing.py +2 -6
  50. nucliadb/common/datamanagers/resources.py +41 -103
  51. nucliadb/common/datamanagers/rollover.py +76 -15
  52. nucliadb/common/datamanagers/synonyms.py +1 -1
  53. nucliadb/common/datamanagers/utils.py +15 -6
  54. nucliadb/common/datamanagers/vectorsets.py +110 -0
  55. nucliadb/common/external_index_providers/base.py +257 -0
  56. nucliadb/{ingest/tests/unit/orm/test_orm_utils.py → common/external_index_providers/exceptions.py} +9 -8
  57. nucliadb/common/external_index_providers/manager.py +101 -0
  58. nucliadb/common/external_index_providers/pinecone.py +933 -0
  59. nucliadb/common/external_index_providers/settings.py +52 -0
  60. nucliadb/common/http_clients/auth.py +3 -6
  61. nucliadb/common/http_clients/processing.py +6 -11
  62. nucliadb/common/http_clients/utils.py +1 -3
  63. nucliadb/common/ids.py +240 -0
  64. nucliadb/common/locking.py +29 -7
  65. nucliadb/common/maindb/driver.py +11 -35
  66. nucliadb/common/maindb/exceptions.py +3 -0
  67. nucliadb/common/maindb/local.py +22 -9
  68. nucliadb/common/maindb/pg.py +206 -111
  69. nucliadb/common/maindb/utils.py +11 -42
  70. nucliadb/common/models_utils/from_proto.py +479 -0
  71. nucliadb/common/models_utils/to_proto.py +60 -0
  72. nucliadb/common/nidx.py +260 -0
  73. nucliadb/export_import/datamanager.py +25 -19
  74. nucliadb/export_import/exporter.py +5 -11
  75. nucliadb/export_import/importer.py +5 -7
  76. nucliadb/export_import/models.py +3 -3
  77. nucliadb/export_import/tasks.py +4 -4
  78. nucliadb/export_import/utils.py +25 -37
  79. nucliadb/health.py +1 -3
  80. nucliadb/ingest/app.py +15 -11
  81. nucliadb/ingest/consumer/auditing.py +21 -19
  82. nucliadb/ingest/consumer/consumer.py +82 -47
  83. nucliadb/ingest/consumer/materializer.py +5 -12
  84. nucliadb/ingest/consumer/pull.py +12 -27
  85. nucliadb/ingest/consumer/service.py +19 -17
  86. nucliadb/ingest/consumer/shard_creator.py +2 -4
  87. nucliadb/ingest/consumer/utils.py +1 -3
  88. nucliadb/ingest/fields/base.py +137 -105
  89. nucliadb/ingest/fields/conversation.py +18 -5
  90. nucliadb/ingest/fields/exceptions.py +1 -4
  91. nucliadb/ingest/fields/file.py +7 -16
  92. nucliadb/ingest/fields/link.py +5 -10
  93. nucliadb/ingest/fields/text.py +9 -4
  94. nucliadb/ingest/orm/brain.py +200 -213
  95. nucliadb/ingest/orm/broker_message.py +181 -0
  96. nucliadb/ingest/orm/entities.py +36 -51
  97. nucliadb/ingest/orm/exceptions.py +12 -0
  98. nucliadb/ingest/orm/knowledgebox.py +322 -197
  99. nucliadb/ingest/orm/processor/__init__.py +2 -700
  100. nucliadb/ingest/orm/processor/auditing.py +4 -23
  101. nucliadb/ingest/orm/processor/data_augmentation.py +164 -0
  102. nucliadb/ingest/orm/processor/pgcatalog.py +84 -0
  103. nucliadb/ingest/orm/processor/processor.py +752 -0
  104. nucliadb/ingest/orm/processor/sequence_manager.py +1 -1
  105. nucliadb/ingest/orm/resource.py +249 -402
  106. nucliadb/ingest/orm/utils.py +4 -4
  107. nucliadb/ingest/partitions.py +3 -9
  108. nucliadb/ingest/processing.py +64 -73
  109. nucliadb/ingest/py.typed +0 -0
  110. nucliadb/ingest/serialize.py +37 -167
  111. nucliadb/ingest/service/__init__.py +1 -3
  112. nucliadb/ingest/service/writer.py +185 -412
  113. nucliadb/ingest/settings.py +10 -20
  114. nucliadb/ingest/utils.py +3 -6
  115. nucliadb/learning_proxy.py +242 -55
  116. nucliadb/metrics_exporter.py +30 -19
  117. nucliadb/middleware/__init__.py +1 -3
  118. nucliadb/migrator/command.py +1 -3
  119. nucliadb/migrator/datamanager.py +13 -13
  120. nucliadb/migrator/migrator.py +47 -30
  121. nucliadb/migrator/utils.py +18 -10
  122. nucliadb/purge/__init__.py +139 -33
  123. nucliadb/purge/orphan_shards.py +7 -13
  124. nucliadb/reader/__init__.py +1 -3
  125. nucliadb/reader/api/models.py +1 -12
  126. nucliadb/reader/api/v1/__init__.py +0 -1
  127. nucliadb/reader/api/v1/download.py +21 -88
  128. nucliadb/reader/api/v1/export_import.py +1 -1
  129. nucliadb/reader/api/v1/knowledgebox.py +10 -10
  130. nucliadb/reader/api/v1/learning_config.py +2 -6
  131. nucliadb/reader/api/v1/resource.py +62 -88
  132. nucliadb/reader/api/v1/services.py +64 -83
  133. nucliadb/reader/app.py +12 -29
  134. nucliadb/reader/lifecycle.py +18 -4
  135. nucliadb/reader/py.typed +0 -0
  136. nucliadb/reader/reader/notifications.py +10 -28
  137. nucliadb/search/__init__.py +1 -3
  138. nucliadb/search/api/v1/__init__.py +1 -2
  139. nucliadb/search/api/v1/ask.py +17 -10
  140. nucliadb/search/api/v1/catalog.py +184 -0
  141. nucliadb/search/api/v1/feedback.py +16 -24
  142. nucliadb/search/api/v1/find.py +36 -36
  143. nucliadb/search/api/v1/knowledgebox.py +89 -60
  144. nucliadb/search/api/v1/resource/ask.py +2 -8
  145. nucliadb/search/api/v1/resource/search.py +49 -70
  146. nucliadb/search/api/v1/search.py +44 -210
  147. nucliadb/search/api/v1/suggest.py +39 -54
  148. nucliadb/search/app.py +12 -32
  149. nucliadb/search/lifecycle.py +10 -3
  150. nucliadb/search/predict.py +136 -187
  151. nucliadb/search/py.typed +0 -0
  152. nucliadb/search/requesters/utils.py +25 -58
  153. nucliadb/search/search/cache.py +149 -20
  154. nucliadb/search/search/chat/ask.py +571 -123
  155. nucliadb/search/{tests/unit/test_run.py → search/chat/exceptions.py} +14 -14
  156. nucliadb/search/search/chat/images.py +41 -17
  157. nucliadb/search/search/chat/prompt.py +817 -266
  158. nucliadb/search/search/chat/query.py +213 -309
  159. nucliadb/{tests/migrations/__init__.py → search/search/cut.py} +8 -8
  160. nucliadb/search/search/fetch.py +43 -36
  161. nucliadb/search/search/filters.py +9 -15
  162. nucliadb/search/search/find.py +214 -53
  163. nucliadb/search/search/find_merge.py +408 -391
  164. nucliadb/search/search/hydrator.py +191 -0
  165. nucliadb/search/search/merge.py +187 -223
  166. nucliadb/search/search/metrics.py +73 -2
  167. nucliadb/search/search/paragraphs.py +64 -106
  168. nucliadb/search/search/pgcatalog.py +233 -0
  169. nucliadb/search/search/predict_proxy.py +1 -1
  170. nucliadb/search/search/query.py +305 -150
  171. nucliadb/search/search/query_parser/exceptions.py +22 -0
  172. nucliadb/search/search/query_parser/models.py +101 -0
  173. nucliadb/search/search/query_parser/parser.py +183 -0
  174. nucliadb/search/search/rank_fusion.py +204 -0
  175. nucliadb/search/search/rerankers.py +270 -0
  176. nucliadb/search/search/shards.py +3 -32
  177. nucliadb/search/search/summarize.py +7 -18
  178. nucliadb/search/search/utils.py +27 -4
  179. nucliadb/search/settings.py +15 -1
  180. nucliadb/standalone/api_router.py +4 -10
  181. nucliadb/standalone/app.py +8 -14
  182. nucliadb/standalone/auth.py +7 -21
  183. nucliadb/standalone/config.py +7 -10
  184. nucliadb/standalone/lifecycle.py +26 -25
  185. nucliadb/standalone/migrations.py +1 -3
  186. nucliadb/standalone/purge.py +1 -1
  187. nucliadb/standalone/py.typed +0 -0
  188. nucliadb/standalone/run.py +3 -6
  189. nucliadb/standalone/settings.py +9 -16
  190. nucliadb/standalone/versions.py +15 -5
  191. nucliadb/tasks/consumer.py +8 -12
  192. nucliadb/tasks/producer.py +7 -6
  193. nucliadb/tests/config.py +53 -0
  194. nucliadb/train/__init__.py +1 -3
  195. nucliadb/train/api/utils.py +1 -2
  196. nucliadb/train/api/v1/shards.py +1 -1
  197. nucliadb/train/api/v1/trainset.py +2 -4
  198. nucliadb/train/app.py +10 -31
  199. nucliadb/train/generator.py +10 -19
  200. nucliadb/train/generators/field_classifier.py +7 -19
  201. nucliadb/train/generators/field_streaming.py +156 -0
  202. nucliadb/train/generators/image_classifier.py +12 -18
  203. nucliadb/train/generators/paragraph_classifier.py +5 -9
  204. nucliadb/train/generators/paragraph_streaming.py +6 -9
  205. nucliadb/train/generators/question_answer_streaming.py +19 -20
  206. nucliadb/train/generators/sentence_classifier.py +9 -15
  207. nucliadb/train/generators/token_classifier.py +48 -39
  208. nucliadb/train/generators/utils.py +14 -18
  209. nucliadb/train/lifecycle.py +7 -3
  210. nucliadb/train/nodes.py +23 -32
  211. nucliadb/train/py.typed +0 -0
  212. nucliadb/train/servicer.py +13 -21
  213. nucliadb/train/settings.py +2 -6
  214. nucliadb/train/types.py +13 -10
  215. nucliadb/train/upload.py +3 -6
  216. nucliadb/train/uploader.py +19 -23
  217. nucliadb/train/utils.py +1 -1
  218. nucliadb/writer/__init__.py +1 -3
  219. nucliadb/{ingest/fields/keywordset.py → writer/api/utils.py} +13 -10
  220. nucliadb/writer/api/v1/export_import.py +67 -14
  221. nucliadb/writer/api/v1/field.py +16 -269
  222. nucliadb/writer/api/v1/knowledgebox.py +218 -68
  223. nucliadb/writer/api/v1/resource.py +68 -88
  224. nucliadb/writer/api/v1/services.py +51 -70
  225. nucliadb/writer/api/v1/slug.py +61 -0
  226. nucliadb/writer/api/v1/transaction.py +67 -0
  227. nucliadb/writer/api/v1/upload.py +114 -113
  228. nucliadb/writer/app.py +6 -43
  229. nucliadb/writer/back_pressure.py +16 -38
  230. nucliadb/writer/exceptions.py +0 -4
  231. nucliadb/writer/lifecycle.py +21 -15
  232. nucliadb/writer/py.typed +0 -0
  233. nucliadb/writer/resource/audit.py +2 -1
  234. nucliadb/writer/resource/basic.py +48 -46
  235. nucliadb/writer/resource/field.py +25 -127
  236. nucliadb/writer/resource/origin.py +1 -2
  237. nucliadb/writer/settings.py +6 -2
  238. nucliadb/writer/tus/__init__.py +17 -15
  239. nucliadb/writer/tus/azure.py +111 -0
  240. nucliadb/writer/tus/dm.py +17 -5
  241. nucliadb/writer/tus/exceptions.py +1 -3
  242. nucliadb/writer/tus/gcs.py +49 -84
  243. nucliadb/writer/tus/local.py +21 -37
  244. nucliadb/writer/tus/s3.py +28 -68
  245. nucliadb/writer/tus/storage.py +5 -56
  246. nucliadb/writer/vectorsets.py +125 -0
  247. nucliadb-6.2.1.post2777.dist-info/METADATA +148 -0
  248. nucliadb-6.2.1.post2777.dist-info/RECORD +343 -0
  249. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2777.dist-info}/WHEEL +1 -1
  250. nucliadb/common/maindb/redis.py +0 -194
  251. nucliadb/common/maindb/tikv.py +0 -433
  252. nucliadb/ingest/fields/layout.py +0 -58
  253. nucliadb/ingest/tests/conftest.py +0 -30
  254. nucliadb/ingest/tests/fixtures.py +0 -764
  255. nucliadb/ingest/tests/integration/consumer/__init__.py +0 -18
  256. nucliadb/ingest/tests/integration/consumer/test_auditing.py +0 -78
  257. nucliadb/ingest/tests/integration/consumer/test_materializer.py +0 -126
  258. nucliadb/ingest/tests/integration/consumer/test_pull.py +0 -144
  259. nucliadb/ingest/tests/integration/consumer/test_service.py +0 -81
  260. nucliadb/ingest/tests/integration/consumer/test_shard_creator.py +0 -68
  261. nucliadb/ingest/tests/integration/ingest/test_ingest.py +0 -684
  262. nucliadb/ingest/tests/integration/ingest/test_processing_engine.py +0 -95
  263. nucliadb/ingest/tests/integration/ingest/test_relations.py +0 -272
  264. nucliadb/ingest/tests/unit/consumer/__init__.py +0 -18
  265. nucliadb/ingest/tests/unit/consumer/test_auditing.py +0 -139
  266. nucliadb/ingest/tests/unit/consumer/test_consumer.py +0 -69
  267. nucliadb/ingest/tests/unit/consumer/test_pull.py +0 -60
  268. nucliadb/ingest/tests/unit/consumer/test_shard_creator.py +0 -140
  269. nucliadb/ingest/tests/unit/consumer/test_utils.py +0 -67
  270. nucliadb/ingest/tests/unit/orm/__init__.py +0 -19
  271. nucliadb/ingest/tests/unit/orm/test_brain.py +0 -247
  272. nucliadb/ingest/tests/unit/orm/test_brain_vectors.py +0 -74
  273. nucliadb/ingest/tests/unit/orm/test_processor.py +0 -131
  274. nucliadb/ingest/tests/unit/orm/test_resource.py +0 -331
  275. nucliadb/ingest/tests/unit/test_cache.py +0 -31
  276. nucliadb/ingest/tests/unit/test_partitions.py +0 -40
  277. nucliadb/ingest/tests/unit/test_processing.py +0 -171
  278. nucliadb/middleware/transaction.py +0 -117
  279. nucliadb/reader/api/v1/learning_collector.py +0 -63
  280. nucliadb/reader/tests/__init__.py +0 -19
  281. nucliadb/reader/tests/conftest.py +0 -31
  282. nucliadb/reader/tests/fixtures.py +0 -136
  283. nucliadb/reader/tests/test_list_resources.py +0 -75
  284. nucliadb/reader/tests/test_reader_file_download.py +0 -273
  285. nucliadb/reader/tests/test_reader_resource.py +0 -353
  286. nucliadb/reader/tests/test_reader_resource_field.py +0 -219
  287. nucliadb/search/api/v1/chat.py +0 -263
  288. nucliadb/search/api/v1/resource/chat.py +0 -174
  289. nucliadb/search/tests/__init__.py +0 -19
  290. nucliadb/search/tests/conftest.py +0 -33
  291. nucliadb/search/tests/fixtures.py +0 -199
  292. nucliadb/search/tests/node.py +0 -466
  293. nucliadb/search/tests/unit/__init__.py +0 -18
  294. nucliadb/search/tests/unit/api/__init__.py +0 -19
  295. nucliadb/search/tests/unit/api/v1/__init__.py +0 -19
  296. nucliadb/search/tests/unit/api/v1/resource/__init__.py +0 -19
  297. nucliadb/search/tests/unit/api/v1/resource/test_chat.py +0 -98
  298. nucliadb/search/tests/unit/api/v1/test_ask.py +0 -120
  299. nucliadb/search/tests/unit/api/v1/test_chat.py +0 -96
  300. nucliadb/search/tests/unit/api/v1/test_predict_proxy.py +0 -98
  301. nucliadb/search/tests/unit/api/v1/test_summarize.py +0 -99
  302. nucliadb/search/tests/unit/search/__init__.py +0 -18
  303. nucliadb/search/tests/unit/search/requesters/__init__.py +0 -18
  304. nucliadb/search/tests/unit/search/requesters/test_utils.py +0 -211
  305. nucliadb/search/tests/unit/search/search/__init__.py +0 -19
  306. nucliadb/search/tests/unit/search/search/test_shards.py +0 -45
  307. nucliadb/search/tests/unit/search/search/test_utils.py +0 -82
  308. nucliadb/search/tests/unit/search/test_chat_prompt.py +0 -270
  309. nucliadb/search/tests/unit/search/test_fetch.py +0 -108
  310. nucliadb/search/tests/unit/search/test_filters.py +0 -125
  311. nucliadb/search/tests/unit/search/test_paragraphs.py +0 -157
  312. nucliadb/search/tests/unit/search/test_predict_proxy.py +0 -106
  313. nucliadb/search/tests/unit/search/test_query.py +0 -153
  314. nucliadb/search/tests/unit/test_app.py +0 -79
  315. nucliadb/search/tests/unit/test_find_merge.py +0 -112
  316. nucliadb/search/tests/unit/test_merge.py +0 -34
  317. nucliadb/search/tests/unit/test_predict.py +0 -525
  318. nucliadb/standalone/tests/__init__.py +0 -19
  319. nucliadb/standalone/tests/conftest.py +0 -33
  320. nucliadb/standalone/tests/fixtures.py +0 -38
  321. nucliadb/standalone/tests/unit/__init__.py +0 -18
  322. nucliadb/standalone/tests/unit/test_api_router.py +0 -61
  323. nucliadb/standalone/tests/unit/test_auth.py +0 -169
  324. nucliadb/standalone/tests/unit/test_introspect.py +0 -35
  325. nucliadb/standalone/tests/unit/test_migrations.py +0 -63
  326. nucliadb/standalone/tests/unit/test_versions.py +0 -68
  327. nucliadb/tests/benchmarks/__init__.py +0 -19
  328. nucliadb/tests/benchmarks/test_search.py +0 -99
  329. nucliadb/tests/conftest.py +0 -32
  330. nucliadb/tests/fixtures.py +0 -735
  331. nucliadb/tests/knowledgeboxes/philosophy_books.py +0 -202
  332. nucliadb/tests/knowledgeboxes/ten_dummy_resources.py +0 -107
  333. nucliadb/tests/migrations/test_migration_0017.py +0 -76
  334. nucliadb/tests/migrations/test_migration_0018.py +0 -95
  335. nucliadb/tests/tikv.py +0 -240
  336. nucliadb/tests/unit/__init__.py +0 -19
  337. nucliadb/tests/unit/common/__init__.py +0 -19
  338. nucliadb/tests/unit/common/cluster/__init__.py +0 -19
  339. nucliadb/tests/unit/common/cluster/discovery/__init__.py +0 -19
  340. nucliadb/tests/unit/common/cluster/discovery/test_k8s.py +0 -172
  341. nucliadb/tests/unit/common/cluster/standalone/__init__.py +0 -18
  342. nucliadb/tests/unit/common/cluster/standalone/test_service.py +0 -114
  343. nucliadb/tests/unit/common/cluster/standalone/test_utils.py +0 -61
  344. nucliadb/tests/unit/common/cluster/test_cluster.py +0 -408
  345. nucliadb/tests/unit/common/cluster/test_kb_shard_manager.py +0 -173
  346. nucliadb/tests/unit/common/cluster/test_rebalance.py +0 -38
  347. nucliadb/tests/unit/common/cluster/test_rollover.py +0 -282
  348. nucliadb/tests/unit/common/maindb/__init__.py +0 -18
  349. nucliadb/tests/unit/common/maindb/test_driver.py +0 -127
  350. nucliadb/tests/unit/common/maindb/test_tikv.py +0 -53
  351. nucliadb/tests/unit/common/maindb/test_utils.py +0 -92
  352. nucliadb/tests/unit/common/test_context.py +0 -36
  353. nucliadb/tests/unit/export_import/__init__.py +0 -19
  354. nucliadb/tests/unit/export_import/test_datamanager.py +0 -37
  355. nucliadb/tests/unit/export_import/test_utils.py +0 -301
  356. nucliadb/tests/unit/migrator/__init__.py +0 -19
  357. nucliadb/tests/unit/migrator/test_migrator.py +0 -87
  358. nucliadb/tests/unit/tasks/__init__.py +0 -19
  359. nucliadb/tests/unit/tasks/conftest.py +0 -42
  360. nucliadb/tests/unit/tasks/test_consumer.py +0 -92
  361. nucliadb/tests/unit/tasks/test_producer.py +0 -95
  362. nucliadb/tests/unit/tasks/test_tasks.py +0 -58
  363. nucliadb/tests/unit/test_field_ids.py +0 -49
  364. nucliadb/tests/unit/test_health.py +0 -86
  365. nucliadb/tests/unit/test_kb_slugs.py +0 -54
  366. nucliadb/tests/unit/test_learning_proxy.py +0 -252
  367. nucliadb/tests/unit/test_metrics_exporter.py +0 -77
  368. nucliadb/tests/unit/test_purge.py +0 -136
  369. nucliadb/tests/utils/__init__.py +0 -74
  370. nucliadb/tests/utils/aiohttp_session.py +0 -44
  371. nucliadb/tests/utils/broker_messages/__init__.py +0 -171
  372. nucliadb/tests/utils/broker_messages/fields.py +0 -197
  373. nucliadb/tests/utils/broker_messages/helpers.py +0 -33
  374. nucliadb/tests/utils/entities.py +0 -78
  375. nucliadb/train/api/v1/check.py +0 -60
  376. nucliadb/train/tests/__init__.py +0 -19
  377. nucliadb/train/tests/conftest.py +0 -29
  378. nucliadb/train/tests/fixtures.py +0 -342
  379. nucliadb/train/tests/test_field_classification.py +0 -122
  380. nucliadb/train/tests/test_get_entities.py +0 -80
  381. nucliadb/train/tests/test_get_info.py +0 -51
  382. nucliadb/train/tests/test_get_ontology.py +0 -34
  383. nucliadb/train/tests/test_get_ontology_count.py +0 -63
  384. nucliadb/train/tests/test_image_classification.py +0 -221
  385. nucliadb/train/tests/test_list_fields.py +0 -39
  386. nucliadb/train/tests/test_list_paragraphs.py +0 -73
  387. nucliadb/train/tests/test_list_resources.py +0 -39
  388. nucliadb/train/tests/test_list_sentences.py +0 -71
  389. nucliadb/train/tests/test_paragraph_classification.py +0 -123
  390. nucliadb/train/tests/test_paragraph_streaming.py +0 -118
  391. nucliadb/train/tests/test_question_answer_streaming.py +0 -239
  392. nucliadb/train/tests/test_sentence_classification.py +0 -143
  393. nucliadb/train/tests/test_token_classification.py +0 -136
  394. nucliadb/train/tests/utils.py +0 -101
  395. nucliadb/writer/layouts/__init__.py +0 -51
  396. nucliadb/writer/layouts/v1.py +0 -59
  397. nucliadb/writer/tests/__init__.py +0 -19
  398. nucliadb/writer/tests/conftest.py +0 -31
  399. nucliadb/writer/tests/fixtures.py +0 -191
  400. nucliadb/writer/tests/test_fields.py +0 -475
  401. nucliadb/writer/tests/test_files.py +0 -740
  402. nucliadb/writer/tests/test_knowledgebox.py +0 -49
  403. nucliadb/writer/tests/test_reprocess_file_field.py +0 -133
  404. nucliadb/writer/tests/test_resources.py +0 -476
  405. nucliadb/writer/tests/test_service.py +0 -137
  406. nucliadb/writer/tests/test_tus.py +0 -203
  407. nucliadb/writer/tests/utils.py +0 -35
  408. nucliadb/writer/tus/pg.py +0 -125
  409. nucliadb-4.0.0.post542.dist-info/METADATA +0 -135
  410. nucliadb-4.0.0.post542.dist-info/RECORD +0 -462
  411. {nucliadb/ingest/tests → migrations/pg}/__init__.py +0 -0
  412. /nucliadb/{ingest/tests/integration → common/external_index_providers}/__init__.py +0 -0
  413. /nucliadb/{ingest/tests/integration/ingest → common/models_utils}/__init__.py +0 -0
  414. /nucliadb/{ingest/tests/unit → search/search/query_parser}/__init__.py +0 -0
  415. /nucliadb/{ingest/tests → tests}/vectors.py +0 -0
  416. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2777.dist-info}/entry_points.txt +0 -0
  417. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2777.dist-info}/top_level.txt +0 -0
  418. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2777.dist-info}/zip-safe +0 -0
@@ -1,408 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
-
21
- from unittest import mock
22
-
23
- import pytest
24
-
25
- from nucliadb.common.cluster import manager
26
- from nucliadb.common.cluster.exceptions import NodeClusterSmall, NoHealthyNodeAvailable
27
- from nucliadb.common.cluster.index_node import IndexNode
28
- from nucliadb.common.cluster.settings import settings
29
- from nucliadb_protos import writer_pb2
30
-
31
-
32
- @pytest.fixture(scope="function")
33
- def available_nodes():
34
- nodes = {
35
- "node-0": IndexNode(
36
- id="node-0", address="node-0", shard_count=1, available_disk=100, dummy=True
37
- ),
38
- "node-30": IndexNode(
39
- id="node-30",
40
- address="node-30",
41
- shard_count=1,
42
- available_disk=30,
43
- dummy=True,
44
- ),
45
- "node-40": IndexNode(
46
- id="node-40",
47
- address="node-40",
48
- shard_count=1,
49
- available_disk=10,
50
- dummy=True,
51
- ),
52
- }
53
- with mock.patch.object(manager, "INDEX_NODES", new=nodes):
54
- yield nodes
55
-
56
-
57
- def test_sorted_primary_nodes_orders_by_available_disk(available_nodes):
58
- with mock.patch.object(settings, "node_replicas", 2):
59
- nodes = manager.sorted_primary_nodes()
60
- assert nodes == ["node-0", "node-30", "node-40"]
61
-
62
-
63
- def test_sorted_primary_nodes_avoid_nodes(available_nodes):
64
- with mock.patch.object(settings, "node_replicas", 2):
65
- excluded_node = "node-0"
66
- nodes = manager.sorted_primary_nodes(avoid_nodes=[excluded_node])
67
- assert nodes == ["node-30", "node-40", "node-0"]
68
-
69
- # even if all are used, still should find nodes
70
- all_nodes = list(available_nodes.keys())
71
- assert manager.sorted_primary_nodes(avoid_nodes=all_nodes) == [
72
- "node-0",
73
- "node-30",
74
- "node-40",
75
- ]
76
-
77
- # check ignore_nodes are ignored while keeping avoid_nodes at the end
78
- all_nodes = list(available_nodes.keys())
79
- assert manager.sorted_primary_nodes(
80
- avoid_nodes=["node-0"], ignore_nodes=["node-30"]
81
- ) == [
82
- "node-40",
83
- "node-0",
84
- ]
85
-
86
-
87
- def test_check_enough_nodes_raises_error_if_not_enough_nodes_are_found(available_nodes):
88
- with mock.patch.object(settings, "node_replicas", 200):
89
- with pytest.raises(NodeClusterSmall):
90
- manager.check_enough_nodes()
91
-
92
-
93
- def test_check_enough_nodes_checks_max_node_replicas_only_if_set(available_nodes):
94
- with mock.patch.object(settings, "max_node_replicas", 0):
95
- with pytest.raises(NodeClusterSmall):
96
- manager.check_enough_nodes()
97
-
98
- with mock.patch.object(settings, "max_node_replicas", -1):
99
- manager.check_enough_nodes()
100
-
101
-
102
- def add_index_node(id: str):
103
- manager.add_index_node(
104
- id=id,
105
- address="nohost",
106
- shard_count=0,
107
- available_disk=100,
108
- dummy=True,
109
- )
110
-
111
-
112
- def add_read_replica_node(id: str, primary_id: str):
113
- manager.add_index_node(
114
- id=id,
115
- address="nohost",
116
- shard_count=0,
117
- available_disk=100,
118
- dummy=True,
119
- primary_id=primary_id,
120
- )
121
-
122
-
123
- def test_choose_node_with_two_primary_nodes():
124
- manager.INDEX_NODES.clear()
125
- add_index_node("node-0")
126
- add_index_node("node-1")
127
-
128
- node, _ = manager.choose_node(
129
- writer_pb2.ShardObject(
130
- replicas=[
131
- writer_pb2.ShardReplica(
132
- shard=writer_pb2.ShardCreated(id="123"), node="node-0"
133
- )
134
- ]
135
- )
136
- )
137
- assert node.id == "node-0"
138
- node, _ = manager.choose_node(
139
- writer_pb2.ShardObject(
140
- replicas=[
141
- writer_pb2.ShardReplica(
142
- shard=writer_pb2.ShardCreated(id="123"), node="node-1"
143
- )
144
- ]
145
- )
146
- )
147
- assert node.id == "node-1"
148
-
149
- manager.INDEX_NODES.clear()
150
-
151
-
152
- def test_choose_node_with_two_read_replicas():
153
- """Test choose_node with two replica nodes pointing to two different primary
154
- nodes.
155
-
156
- """
157
- manager.INDEX_NODES.clear()
158
- add_read_replica_node("node-replica-0", primary_id="node-0")
159
- add_read_replica_node("node-replica-1", primary_id="node-1")
160
-
161
- node, _ = manager.choose_node(
162
- writer_pb2.ShardObject(
163
- replicas=[
164
- writer_pb2.ShardReplica(
165
- shard=writer_pb2.ShardCreated(id="123"), node="node-0"
166
- )
167
- ]
168
- ),
169
- use_read_replica_nodes=True,
170
- )
171
- assert node.id == "node-replica-0"
172
- node, _ = manager.choose_node(
173
- writer_pb2.ShardObject(
174
- replicas=[
175
- writer_pb2.ShardReplica(
176
- shard=writer_pb2.ShardCreated(id="123"), node="node-1"
177
- )
178
- ]
179
- ),
180
- use_read_replica_nodes=True,
181
- )
182
- assert node.id == "node-replica-1"
183
-
184
- manager.INDEX_NODES.clear()
185
-
186
-
187
- def test_choose_node_no_healthy_node_available():
188
- """There's only one read replica for node-0 and we try to choose a node for
189
- a shard in node-1. We expect it to fail as there's no possible valid node to
190
- choose.
191
-
192
- """
193
- manager.INDEX_NODES.clear()
194
- add_read_replica_node("node-replica-0", primary_id="node-0")
195
-
196
- with pytest.raises(NoHealthyNodeAvailable):
197
- manager.choose_node(
198
- writer_pb2.ShardObject(
199
- replicas=[
200
- writer_pb2.ShardReplica(
201
- shard=writer_pb2.ShardCreated(id="123"), node="node-1"
202
- )
203
- ]
204
- ),
205
- use_read_replica_nodes=True,
206
- )
207
-
208
- manager.INDEX_NODES.clear()
209
-
210
-
211
- def repeated_choose_node(
212
- count: int, shard: writer_pb2.ShardObject, **kwargs
213
- ) -> tuple[list[str], list[str]]:
214
- shard_ids = []
215
- node_ids = []
216
-
217
- for _ in range(count):
218
- node, shard_id = manager.choose_node(shard, **kwargs)
219
- shard_ids.append(shard_id)
220
- node_ids.append(node.id)
221
-
222
- return shard_ids, node_ids
223
-
224
-
225
- def test_choose_node_with_nodes_and_replicas(standalone_mode_off):
226
- """Validate how choose node selects between different options depending on
227
- configuration.
228
-
229
- Choose_node is called multiple times per assert to ensure there
230
- is no randomness in the replica/node choice.
231
-
232
- """
233
- TRIES_PER_ASSERT = 10
234
-
235
- shard = writer_pb2.ShardObject(
236
- replicas=[
237
- writer_pb2.ShardReplica(
238
- shard=writer_pb2.ShardCreated(id="123"),
239
- node="node-0",
240
- ),
241
- writer_pb2.ShardReplica(
242
- shard=writer_pb2.ShardCreated(id="456"),
243
- node="node-1",
244
- ),
245
- ]
246
- )
247
-
248
- # Start with 2 nodes and 1 read replica each
249
- manager.INDEX_NODES.clear()
250
- add_index_node("node-0")
251
- add_index_node("node-1")
252
- add_read_replica_node("node-replica-0", primary_id="node-0")
253
- add_read_replica_node("node-replica-1", primary_id="node-1")
254
-
255
- # Without read replicas, we only choose primaries
256
- shard_ids, node_ids = repeated_choose_node(
257
- TRIES_PER_ASSERT, shard, use_read_replica_nodes=False
258
- )
259
- assert set(shard_ids) == {"123"}
260
- assert set(node_ids) == {"node-0"}
261
-
262
- # Secondaries are preferred
263
- shard_ids, node_ids = repeated_choose_node(
264
- TRIES_PER_ASSERT, shard, use_read_replica_nodes=True
265
- )
266
- assert set(shard_ids) == {"123"}
267
- assert set(node_ids) == {"node-replica-0"}
268
-
269
- # Target replicas take more preference
270
- shard_ids, node_ids = repeated_choose_node(
271
- TRIES_PER_ASSERT,
272
- shard,
273
- use_read_replica_nodes=False,
274
- target_shard_replicas=["456"],
275
- )
276
- assert set(shard_ids) == {"456"}
277
- assert set(node_ids) == {"node-1"}
278
-
279
- shard_ids, node_ids = repeated_choose_node(
280
- TRIES_PER_ASSERT,
281
- shard,
282
- use_read_replica_nodes=True,
283
- target_shard_replicas=["456"],
284
- )
285
- assert set(shard_ids) == {"456"}
286
- assert set(node_ids) == {"node-replica-1"}
287
-
288
- # Let's remove a node so it becomes unavailable, replica keeps working
289
- manager.INDEX_NODES.clear()
290
- add_index_node("node-0")
291
- add_read_replica_node("node-replica-0", primary_id="node-0")
292
- add_read_replica_node("node-replica-1", primary_id="node-1")
293
-
294
- shard_ids, node_ids = repeated_choose_node(
295
- TRIES_PER_ASSERT, shard, use_read_replica_nodes=False
296
- )
297
- assert set(shard_ids) == {"123"}
298
- assert set(node_ids) == {"node-0"}
299
-
300
- shard_ids, node_ids = repeated_choose_node(
301
- TRIES_PER_ASSERT, shard, use_read_replica_nodes=True
302
- )
303
- assert set(shard_ids) == {"123"}
304
- assert set(node_ids) == {"node-replica-0"}
305
-
306
- # target replicas is ignored but only primaries are used
307
- shard_ids, node_ids = repeated_choose_node(
308
- TRIES_PER_ASSERT,
309
- shard,
310
- use_read_replica_nodes=False,
311
- target_shard_replicas=["456"],
312
- )
313
- assert set(shard_ids) == {"123"}
314
- assert set(node_ids) == {"node-0"}
315
-
316
- shard_ids, node_ids = repeated_choose_node(
317
- TRIES_PER_ASSERT,
318
- shard,
319
- use_read_replica_nodes=True,
320
- target_shard_replicas=["456"],
321
- )
322
- assert set(shard_ids) == {"456"}
323
- assert set(node_ids) == {"node-replica-1"}
324
-
325
- # Now let's add again the node but remove the replica
326
- manager.INDEX_NODES.clear()
327
- add_index_node("node-0")
328
- add_index_node("node-1")
329
- add_read_replica_node("node-replica-0", primary_id="node-0")
330
-
331
- shard_ids, node_ids = repeated_choose_node(
332
- TRIES_PER_ASSERT, shard, use_read_replica_nodes=False
333
- )
334
- assert set(shard_ids) == {"123"}
335
- assert set(node_ids) == {"node-0"}
336
-
337
- shard_ids, node_ids = repeated_choose_node(
338
- TRIES_PER_ASSERT, shard, use_read_replica_nodes=True
339
- )
340
- assert set(shard_ids) == {"123"}
341
- assert set(node_ids) == {"node-replica-0"}
342
-
343
- shard_ids, node_ids = repeated_choose_node(
344
- TRIES_PER_ASSERT,
345
- shard,
346
- use_read_replica_nodes=False,
347
- target_shard_replicas=["456"],
348
- )
349
- assert set(shard_ids) == {"456"}
350
- assert set(node_ids) == {"node-1"}
351
-
352
- shard_ids, node_ids = repeated_choose_node(
353
- TRIES_PER_ASSERT,
354
- shard,
355
- use_read_replica_nodes=True,
356
- target_shard_replicas=["456"],
357
- )
358
- assert set(shard_ids) == {"456"}
359
- assert set(node_ids) == {"node-1"}
360
-
361
- manager.INDEX_NODES.clear()
362
-
363
-
364
- @pytest.fixture(scope="function")
365
- def standalone_mode_off():
366
- prev = settings.standalone_mode
367
- settings.standalone_mode = False
368
- yield
369
- settings.standalone_mode = prev
370
-
371
-
372
- @pytest.fixture(scope="function")
373
- def index_nodes():
374
- index_nodes = {}
375
- with mock.patch.object(manager, "INDEX_NODES", new=index_nodes):
376
- yield index_nodes
377
-
378
-
379
- def test_get_index_nodes(standalone_mode_off, index_nodes):
380
- # Add a primary node
381
- manager.add_index_node(
382
- id="node-0",
383
- address="nohost",
384
- shard_count=0,
385
- available_disk=100,
386
- dummy=True,
387
- )
388
- # Add a secondary replica of node-0
389
- manager.add_index_node(
390
- id="node-1",
391
- address="nohost",
392
- shard_count=0,
393
- available_disk=100,
394
- dummy=True,
395
- primary_id="node-0",
396
- )
397
-
398
- # By default, only primary nodes are returned
399
- nodes = manager.get_index_nodes()
400
- assert len(nodes) == 1
401
- assert nodes[0].id == "node-0"
402
-
403
- # If we ask for secondary, we get both
404
- nodes = manager.get_index_nodes(include_secondary=True)
405
- assert len(nodes) == 2
406
- sorted(nodes, key=lambda x: x.id)
407
- assert nodes[0].id == "node-0"
408
- assert nodes[1].id == "node-1"
@@ -1,173 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
- import asyncio
21
- import uuid
22
- from typing import Any, Optional
23
- from unittest.mock import MagicMock
24
-
25
- import pytest
26
-
27
- from nucliadb.common import datamanagers
28
- from nucliadb.common.cluster import manager
29
- from nucliadb.common.cluster.settings import settings
30
- from nucliadb.common.maindb.driver import Transaction
31
- from nucliadb_protos import writer_pb2
32
-
33
-
34
- def test_should_create_new_shard():
35
- sm = manager.KBShardManager()
36
- low_para_counter = {
37
- "num_paragraphs": settings.max_shard_paragraphs - 1,
38
- }
39
- high_para_counter = {
40
- "num_paragraphs": settings.max_shard_paragraphs + 1,
41
- }
42
- assert sm.should_create_new_shard(**low_para_counter) is False
43
- assert sm.should_create_new_shard(**high_para_counter) is True
44
-
45
-
46
- @pytest.fixture(scope="function")
47
- async def fake_node():
48
- manager.INDEX_NODES.clear()
49
- yield manager.add_index_node(
50
- id="node-0",
51
- address="nohost",
52
- shard_count=0,
53
- available_disk=100,
54
- dummy=True,
55
- )
56
- manager.INDEX_NODES.clear()
57
-
58
-
59
- async def test_standalone_node_garbage_collects(fake_node):
60
- mng = manager.StandaloneKBShardManager()
61
-
62
- mng.max_ops_before_checks = 0
63
-
64
- await mng.add_resource(
65
- writer_pb2.ShardObject(
66
- shard="123",
67
- replicas=[
68
- writer_pb2.ShardReplica(
69
- shard=writer_pb2.ShardCreated(id="123"), node="node-0"
70
- )
71
- ],
72
- ),
73
- resource=MagicMock(),
74
- txid=-1,
75
- partition=0,
76
- kb="kb",
77
- )
78
-
79
- await asyncio.sleep(0.05)
80
- assert len(fake_node.writer.calls["GC"]) == 1
81
-
82
-
83
- async def test_shard_creation(fake_index_nodes: list[str], txn: Transaction):
84
- """Given a cluster of index nodes, validate shard creation logic.
85
-
86
- Every logic shard should create a configured amount of indexing replicas and
87
- update the information about writable shards.
88
-
89
- """
90
- index_nodes = set(fake_index_nodes)
91
- kbid = f"kbid:{test_shard_creation.__name__}"
92
- sm = manager.KBShardManager()
93
-
94
- # Fake KB shards instead of creating a KB to generate it
95
- shards = await datamanagers.cluster.get_kb_shards(txn, kbid=kbid)
96
- await datamanagers.cluster.update_kb_shards(
97
- txn,
98
- kbid=kbid,
99
- shards=writer_pb2.Shards(
100
- kbid=kbid,
101
- ),
102
- )
103
-
104
- # create first shard
105
- await sm.create_shard_by_kbid(txn, kbid)
106
-
107
- shards = await datamanagers.cluster.get_kb_shards(txn, kbid=kbid)
108
- assert shards is not None
109
- assert len(shards.shards) == 1
110
- assert shards.shards[0].read_only is False
111
- # B/c with Shards.actual
112
- assert shards.actual == 0
113
- assert set((replica.node for replica in shards.shards[0].replicas)) == index_nodes
114
-
115
- # adding a second shard will mark the first as read only
116
- await sm.create_shard_by_kbid(txn, kbid)
117
-
118
- shards = await datamanagers.cluster.get_kb_shards(txn, kbid=kbid)
119
- assert shards is not None
120
- assert len(shards.shards) == 2
121
- assert shards.shards[0].read_only is True
122
- assert shards.shards[1].read_only is False
123
- # B/c with Shards.actual
124
- assert shards.actual == 1
125
- assert set((replica.node for replica in shards.shards[1].replicas)) == index_nodes
126
-
127
- # adding a third one will be equivalent
128
- await sm.create_shard_by_kbid(txn, kbid)
129
-
130
- shards = await datamanagers.cluster.get_kb_shards(txn, kbid=kbid)
131
- assert shards is not None
132
- assert len(shards.shards) == 3
133
- assert shards.shards[0].read_only is True
134
- assert shards.shards[1].read_only is True
135
- assert shards.shards[2].read_only is False
136
- # B/c with Shards.actual
137
- assert shards.actual == 2
138
- assert set((replica.node for replica in shards.shards[1].replicas)) == index_nodes
139
-
140
-
141
- @pytest.fixture
142
- def txn():
143
- class MockTransaction:
144
- def __init__(self):
145
- self.store = {}
146
-
147
- async def get(self, key: str) -> Optional[Any]:
148
- return self.store.get(key, None)
149
-
150
- async def set(self, key: str, value: Any):
151
- self.store[key] = value
152
-
153
- yield MockTransaction()
154
-
155
-
156
- @pytest.fixture(scope="function")
157
- def fake_index_nodes():
158
- assert len(manager.INDEX_NODES) == 0, "Some test isn't cleaning global state!"
159
-
160
- nodes = [f"node-{i}" for i in range(settings.node_replicas)]
161
- for node_id in nodes:
162
- manager.add_index_node(
163
- id=node_id,
164
- address=f"nohost-{str(uuid.uuid4())}:1234",
165
- shard_count=0,
166
- available_disk=100,
167
- dummy=True,
168
- )
169
-
170
- yield nodes
171
-
172
- for node_id in nodes:
173
- manager.remove_index_node(node_id)
@@ -1,38 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
- from unittest.mock import MagicMock, patch
21
-
22
- import pytest
23
-
24
- from nucliadb.common import locking
25
- from nucliadb.common.cluster.rebalance import run
26
-
27
-
28
- async def test_run_handles_locked_rebalance():
29
- context = MagicMock()
30
- with patch(
31
- "nucliadb.common.cluster.rebalance.locking.distributed_lock"
32
- ) as distributed_lock:
33
- distributed_lock.side_effect = locking.ResourceLocked("rebalance")
34
- await run(context)
35
-
36
- distributed_lock.side_effect = locking.ResourceLocked("other-key")
37
- with pytest.raises(locking.ResourceLocked):
38
- await run(context)