1
1

pipeline_tests.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import uuid
  2. from flask import url_for
  3. from pathlib import Path
  4. from pycs.database.Model import Model
  5. from pycs.database.LabelProvider import LabelProvider
  6. from pycs.database.Project import Project
  7. from tests.base import BaseTestCase
  8. from tests.base import pаtch_tpool_execute
  9. class _BasePipelineTests(BaseTestCase):
  10. def setupModels(self):
  11. super().setupModels()
  12. Model.discover("tests/client/test_models")
  13. self.model = Model.query.one()
  14. self.project = self.new_project()
  15. root = Path(self.project.root_folder)
  16. data_root = Path(self.project.data_folder)
  17. for folder in [data_root, root / "temp"]:
  18. folder.mkdir(exist_ok=True, parents=True)
  19. file_uuid = str(uuid.uuid1())
  20. self.file, is_new = self.project.add_file(
  21. uuid=file_uuid,
  22. file_type="image",
  23. name="name",
  24. filename="image",
  25. extension=".jpg",
  26. size=32*1024,
  27. )
  28. self.assertTrue(is_new)
  29. with open(self.file.absolute_path, "wb") as f:
  30. f.write(b"some content")
  31. def new_project(self, **kwargs):
  32. return Project.new(
  33. name="test_project",
  34. description="Project for a test case",
  35. model=self.model,
  36. root_folder="project_folder",
  37. external_data=False,
  38. data_folder="project_folder/data",
  39. **kwargs
  40. )
  41. def tearDown(self):
  42. self.wait_for_bg_jobs(raise_errors=False)
  43. self.project.delete()
  44. super().tearDown()
  45. class ModelPipelineTests(_BasePipelineTests):
  46. _sleep_time: float = .2
  47. def test_predict_file_busy(self):
  48. url = url_for("predict_file", file_id=self.file.id)
  49. self.post(url, json=dict(predict=True))
  50. self.post(url, json=dict(predict=True), status_code=400)
  51. def test_predict_file_errors(self):
  52. self.post(url_for("predict_file", file_id=4242),
  53. status_code=404)
  54. url = url_for("predict_file", file_id=self.file.id)
  55. for data in [None, dict(), dict(predict=False)]:
  56. self.post(url, status_code=400, json=data)
  57. def test_predict_file(self):
  58. url = url_for("predict_file", file_id=self.file.id)
  59. self.assertEqual(0, self.file.results.count())
  60. self.post(url, json=dict(predict=True))
  61. self.wait_for_bg_jobs()
  62. self.assertEqual(1, self.file.results.count())
  63. def test_predict_file_multiple_times(self):
  64. url = url_for("predict_file", file_id=self.file.id)
  65. self.assertEqual(0, self.file.results.count())
  66. self.post(url, json=dict(predict=True))
  67. self.wait_for_bg_jobs()
  68. self.assertEqual(1, self.file.results.count())
  69. self.post(url, json=dict(predict=True))
  70. self.wait_for_bg_jobs()
  71. self.assertEqual(1, self.file.results.count())
  72. def test_predict_model_errors(self):
  73. self.post(url_for("predict_model", project_id=4242),
  74. status_code=404)
  75. url = url_for("predict_model", project_id=self.project.id)
  76. for data in [None, dict(), dict(predict=False), dict(predict=True), dict(predict="not new or all")]:
  77. self.post(url, status_code=400, json=data)
  78. def test_predict_model_busy(self):
  79. url = url_for("predict_model", project_id=self.project.id)
  80. self.post(url, json=dict(predict="new"))
  81. self.post(url, json=dict(predict="new"), status_code=400)
  82. def test_predict_model_for_new(self):
  83. url = url_for("predict_model", project_id=self.project.id)
  84. self.post(url, json=dict(predict="new"))
  85. def test_predict_model_for_all(self):
  86. url = url_for("predict_model", project_id=self.project.id)
  87. self.post(url, json=dict(predict="all"))
  88. def test_model_fit_errors(self):
  89. self.post(url_for("fit_model", project_id=4242),
  90. status_code=404)
  91. url = url_for("fit_model", project_id=self.project.id)
  92. for data in [None, dict(), dict(fit=False)]:
  93. self.post(url, status_code=400, json=data)
  94. def test_model_fit_busy(self):
  95. url = url_for("fit_model", project_id=self.project.id)
  96. self.post(url, json=dict(fit=True))
  97. self.post(url, json=dict(fit=True), status_code=400)
  98. def test_model_fit(self):
  99. url = url_for("fit_model", project_id=self.project.id)
  100. self.post(url, json=dict(fit=True))
  101. class LabelProviderPipelineTests:
  102. def new_project(self):
  103. LabelProvider.discover("tests/client/test_labels")
  104. return super().new_project(label_provider=self.label_provider)
  105. @property
  106. def url(self):
  107. return url_for("execute_label_provider", project_id=self.project.id)
  108. def test_label_provider_errors(self):
  109. url = url_for("execute_label_provider", project_id=4242)
  110. self.post(url, status_code=404)
  111. for data in [None, dict(), dict(execute=False)]:
  112. self.post(self.url, json=data, status_code=400)
  113. self.project.label_provider = None
  114. self.project.commit()
  115. self.post(self.url, json=dict(execute=True), status_code=400)
  116. def test_label_provider_busy(self):
  117. self.post(self.url, json=dict(execute=True))
  118. self.post(self.url, json=dict(execute=True), status_code=400)
  119. def test_label_loading(self):
  120. self.post(self.url, json=dict(execute=True))
  121. self.wait_for_bg_jobs()
  122. self.assertEqual(self.n_labels, self.project.labels.count())
  123. def test_label_loading_multiple(self):
  124. for i in range(3):
  125. self.post(self.url, json=dict(execute=True))
  126. self.wait_for_bg_jobs()
  127. self.assertEqual(self.n_labels, self.project.labels.count())
  128. class SimpleLabelProviderPipelineTests(LabelProviderPipelineTests, _BasePipelineTests):
  129. @property
  130. def n_labels(self):
  131. return 10
  132. @property
  133. def label_provider(self):
  134. name_filter = LabelProvider.name.contains("Simple")
  135. return LabelProvider.query.filter(name_filter).one()
  136. class HierarchicalLabelProviderPipelineTests(LabelProviderPipelineTests, _BasePipelineTests):
  137. @property
  138. def n_labels(self):
  139. leafs = 10 * 3 * 3
  140. intermediate = 10 * 3
  141. roots = 10
  142. return roots + intermediate + leafs
  143. @property
  144. def label_provider(self):
  145. name_filter = LabelProvider.name.contains("Hierarchical")
  146. return LabelProvider.query.filter(name_filter).one()