strategy_tests.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. # Licensed to the Apache Software Foundation (ASF) under one
  2. # or more contributor license agreements. See the NOTICE file
  3. # distributed with this work for additional information
  4. # regarding copyright ownership. The ASF licenses this file
  5. # to you under the Apache License, Version 2.0 (the
  6. # "License"); you may not use this file except in compliance
  7. # with the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing,
  12. # software distributed under the License is distributed on an
  13. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. # KIND, either express or implied. See the License for the
  15. # specific language governing permissions and limitations
  16. # under the License.
  17. # isort:skip_file
  18. """Unit tests for Superset cache warmup"""
  19. import json
  20. from unittest.mock import MagicMock
  21. import tests.test_app
  22. from superset import db
  23. from superset.models.core import Log
  24. from superset.models.tags import get_tag, ObjectTypes, TaggedObject, TagTypes
  25. from superset.tasks.cache import (
  26. DashboardTagsStrategy,
  27. get_form_data,
  28. TopNDashboardsStrategy,
  29. )
  30. from .base_tests import SupersetTestCase
  31. URL_PREFIX = "http://0.0.0.0:8081"
  32. class CacheWarmUpTests(SupersetTestCase):
  33. def __init__(self, *args, **kwargs):
  34. super(CacheWarmUpTests, self).__init__(*args, **kwargs)
  35. def test_get_form_data_chart_only(self):
  36. chart_id = 1
  37. result = get_form_data(chart_id, None)
  38. expected = {"slice_id": chart_id}
  39. self.assertEqual(result, expected)
  40. def test_get_form_data_no_dashboard_metadata(self):
  41. chart_id = 1
  42. dashboard = MagicMock()
  43. dashboard.json_metadata = None
  44. result = get_form_data(chart_id, dashboard)
  45. expected = {"slice_id": chart_id}
  46. self.assertEqual(result, expected)
  47. def test_get_form_data_immune_slice(self):
  48. chart_id = 1
  49. filter_box_id = 2
  50. dashboard = MagicMock()
  51. dashboard.json_metadata = json.dumps(
  52. {
  53. "filter_immune_slices": [chart_id],
  54. "default_filters": json.dumps(
  55. {str(filter_box_id): {"name": ["Alice", "Bob"]}}
  56. ),
  57. }
  58. )
  59. result = get_form_data(chart_id, dashboard)
  60. expected = {"slice_id": chart_id}
  61. self.assertEqual(result, expected)
  62. def test_get_form_data_no_default_filters(self):
  63. chart_id = 1
  64. dashboard = MagicMock()
  65. dashboard.json_metadata = json.dumps({})
  66. result = get_form_data(chart_id, dashboard)
  67. expected = {"slice_id": chart_id}
  68. self.assertEqual(result, expected)
  69. def test_get_form_data_immune_fields(self):
  70. chart_id = 1
  71. filter_box_id = 2
  72. dashboard = MagicMock()
  73. dashboard.json_metadata = json.dumps(
  74. {
  75. "default_filters": json.dumps(
  76. {
  77. str(filter_box_id): {
  78. "name": ["Alice", "Bob"],
  79. "__time_range": "100 years ago : today",
  80. }
  81. }
  82. ),
  83. "filter_immune_slice_fields": {chart_id: ["__time_range"]},
  84. }
  85. )
  86. result = get_form_data(chart_id, dashboard)
  87. expected = {
  88. "slice_id": chart_id,
  89. "extra_filters": [{"col": "name", "op": "in", "val": ["Alice", "Bob"]}],
  90. }
  91. self.assertEqual(result, expected)
  92. def test_get_form_data_no_extra_filters(self):
  93. chart_id = 1
  94. filter_box_id = 2
  95. dashboard = MagicMock()
  96. dashboard.json_metadata = json.dumps(
  97. {
  98. "default_filters": json.dumps(
  99. {str(filter_box_id): {"__time_range": "100 years ago : today"}}
  100. ),
  101. "filter_immune_slice_fields": {chart_id: ["__time_range"]},
  102. }
  103. )
  104. result = get_form_data(chart_id, dashboard)
  105. expected = {"slice_id": chart_id}
  106. self.assertEqual(result, expected)
  107. def test_get_form_data(self):
  108. chart_id = 1
  109. filter_box_id = 2
  110. dashboard = MagicMock()
  111. dashboard.json_metadata = json.dumps(
  112. {
  113. "default_filters": json.dumps(
  114. {
  115. str(filter_box_id): {
  116. "name": ["Alice", "Bob"],
  117. "__time_range": "100 years ago : today",
  118. }
  119. }
  120. )
  121. }
  122. )
  123. result = get_form_data(chart_id, dashboard)
  124. expected = {
  125. "slice_id": chart_id,
  126. "extra_filters": [
  127. {"col": "name", "op": "in", "val": ["Alice", "Bob"]},
  128. {"col": "__time_range", "op": "in", "val": "100 years ago : today"},
  129. ],
  130. }
  131. self.assertEqual(result, expected)
  132. def test_top_n_dashboards_strategy(self):
  133. # create a top visited dashboard
  134. db.session.query(Log).delete()
  135. self.login(username="admin")
  136. dash = self.get_dash_by_slug("births")
  137. for _ in range(10):
  138. self.client.get(f"/superset/dashboard/{dash.id}/")
  139. strategy = TopNDashboardsStrategy(1)
  140. result = sorted(strategy.get_urls())
  141. expected = sorted([f"{URL_PREFIX}{slc.url}" for slc in dash.slices])
  142. self.assertEqual(result, expected)
  143. def reset_tag(self, tag):
  144. """Remove associated object from tag, used to reset tests"""
  145. if tag.objects:
  146. for o in tag.objects:
  147. db.session.delete(o)
  148. db.session.commit()
  149. def test_dashboard_tags(self):
  150. tag1 = get_tag("tag1", db.session, TagTypes.custom)
  151. # delete first to make test idempotent
  152. self.reset_tag(tag1)
  153. strategy = DashboardTagsStrategy(["tag1"])
  154. result = sorted(strategy.get_urls())
  155. expected = []
  156. self.assertEqual(result, expected)
  157. # tag dashboard 'births' with `tag1`
  158. tag1 = get_tag("tag1", db.session, TagTypes.custom)
  159. dash = self.get_dash_by_slug("births")
  160. tag1_urls = sorted([f"{URL_PREFIX}{slc.url}" for slc in dash.slices])
  161. tagged_object = TaggedObject(
  162. tag_id=tag1.id, object_id=dash.id, object_type=ObjectTypes.dashboard
  163. )
  164. db.session.add(tagged_object)
  165. db.session.commit()
  166. self.assertEqual(sorted(strategy.get_urls()), tag1_urls)
  167. strategy = DashboardTagsStrategy(["tag2"])
  168. tag2 = get_tag("tag2", db.session, TagTypes.custom)
  169. self.reset_tag(tag2)
  170. result = sorted(strategy.get_urls())
  171. expected = []
  172. self.assertEqual(result, expected)
  173. # tag first slice
  174. dash = self.get_dash_by_slug("unicode-test")
  175. slc = dash.slices[0]
  176. tag2_urls = [f"{URL_PREFIX}{slc.url}"]
  177. object_id = slc.id
  178. tagged_object = TaggedObject(
  179. tag_id=tag2.id, object_id=object_id, object_type=ObjectTypes.chart
  180. )
  181. db.session.add(tagged_object)
  182. db.session.commit()
  183. result = sorted(strategy.get_urls())
  184. self.assertEqual(result, tag2_urls)
  185. strategy = DashboardTagsStrategy(["tag1", "tag2"])
  186. result = sorted(strategy.get_urls())
  187. expected = sorted(tag1_urls + tag2_urls)
  188. self.assertEqual(result, expected)