mirror of
https://github.com/getredash/redash.git
synced 2025-12-19 17:37:19 -05:00
245 lines
9.2 KiB
Python
245 lines
9.2 KiB
Python
from mock import ANY, call, patch
|
|
|
|
from redash.models import Query
|
|
from redash.tasks.queries.maintenance import refresh_queries
|
|
from tests import BaseTestCase
|
|
|
|
ENQUEUE_QUERY = "redash.tasks.queries.maintenance.enqueue_query"
|
|
|
|
|
|
class TestRefreshQuery(BaseTestCase):
|
|
def test_enqueues_outdated_queries_for_sqlquery(self):
|
|
"""
|
|
refresh_queries() launches an execution task for each query returned
|
|
from Query.outdated_queries().
|
|
"""
|
|
query1 = self.factory.create_query(options={"apply_auto_limit": True})
|
|
query2 = self.factory.create_query(
|
|
query_text="select 42;",
|
|
data_source=self.factory.create_data_source(),
|
|
options={"apply_auto_limit": True},
|
|
)
|
|
oq = staticmethod(lambda: [query1, query2])
|
|
with patch(ENQUEUE_QUERY) as add_job_mock, patch.object(Query, "outdated_queries", oq):
|
|
refresh_queries()
|
|
self.assertEqual(add_job_mock.call_count, 2)
|
|
add_job_mock.assert_has_calls(
|
|
[
|
|
call(
|
|
query1.query_text + " LIMIT 1000",
|
|
query1.data_source,
|
|
query1.user_id,
|
|
scheduled_query=query1,
|
|
metadata={"query_id": query1.id, "Username": query1.user.get_actual_user()},
|
|
),
|
|
call(
|
|
"select 42 LIMIT 1000",
|
|
query2.data_source,
|
|
query2.user_id,
|
|
scheduled_query=query2,
|
|
metadata={"query_id": query2.id, "Username": query2.user.get_actual_user()},
|
|
),
|
|
],
|
|
any_order=True,
|
|
)
|
|
|
|
def test_enqueues_outdated_queries_for_non_sqlquery(self):
|
|
"""
|
|
refresh_queries() launches an execution task for each query returned
|
|
from Query.outdated_queries().
|
|
"""
|
|
ds = self.factory.create_data_source(group=self.factory.org.default_group, type="prometheus")
|
|
query1 = self.factory.create_query(data_source=ds, options={"apply_auto_limit": True})
|
|
query2 = self.factory.create_query(query_text="select 42;", data_source=ds, options={"apply_auto_limit": True})
|
|
oq = staticmethod(lambda: [query1, query2])
|
|
with patch(ENQUEUE_QUERY) as add_job_mock, patch.object(Query, "outdated_queries", oq):
|
|
refresh_queries()
|
|
self.assertEqual(add_job_mock.call_count, 2)
|
|
add_job_mock.assert_has_calls(
|
|
[
|
|
call(
|
|
query1.query_text,
|
|
query1.data_source,
|
|
query1.user_id,
|
|
scheduled_query=query1,
|
|
metadata={"query_id": query1.id, "Username": query1.user.get_actual_user()},
|
|
),
|
|
call(
|
|
query2.query_text,
|
|
query2.data_source,
|
|
query2.user_id,
|
|
scheduled_query=query2,
|
|
metadata={"query_id": query2.id, "Username": query2.user.get_actual_user()},
|
|
),
|
|
],
|
|
any_order=True,
|
|
)
|
|
|
|
def test_doesnt_enqueue_outdated_queries_for_paused_data_source_for_sqlquery(self):
|
|
"""
|
|
refresh_queries() does not launch execution tasks for queries whose
|
|
data source is paused.
|
|
"""
|
|
query = self.factory.create_query(options={"apply_auto_limit": True})
|
|
oq = staticmethod(lambda: [query])
|
|
query.data_source.pause()
|
|
with patch.object(Query, "outdated_queries", oq):
|
|
with patch(ENQUEUE_QUERY) as add_job_mock:
|
|
refresh_queries()
|
|
add_job_mock.assert_not_called()
|
|
|
|
query.data_source.resume()
|
|
|
|
with patch(ENQUEUE_QUERY) as add_job_mock:
|
|
refresh_queries()
|
|
add_job_mock.assert_called_with(
|
|
query.query_text + " LIMIT 1000",
|
|
query.data_source,
|
|
query.user_id,
|
|
scheduled_query=query,
|
|
metadata=ANY,
|
|
)
|
|
|
|
def test_doesnt_enqueue_outdated_queries_for_paused_data_source_for_non_sqlquery(
|
|
self,
|
|
):
|
|
"""
|
|
refresh_queries() does not launch execution tasks for queries whose
|
|
data source is paused.
|
|
"""
|
|
ds = self.factory.create_data_source(group=self.factory.org.default_group, type="prometheus")
|
|
query = self.factory.create_query(data_source=ds, options={"apply_auto_limit": True})
|
|
oq = staticmethod(lambda: [query])
|
|
query.data_source.pause()
|
|
with patch.object(Query, "outdated_queries", oq):
|
|
with patch(ENQUEUE_QUERY) as add_job_mock:
|
|
refresh_queries()
|
|
add_job_mock.assert_not_called()
|
|
|
|
query.data_source.resume()
|
|
|
|
with patch(ENQUEUE_QUERY) as add_job_mock:
|
|
refresh_queries()
|
|
add_job_mock.assert_called_with(
|
|
query.query_text,
|
|
query.data_source,
|
|
query.user_id,
|
|
scheduled_query=query,
|
|
metadata=ANY,
|
|
)
|
|
|
|
def test_enqueues_parameterized_queries_for_sqlquery(self):
|
|
"""
|
|
Scheduled queries with parameters use saved values.
|
|
"""
|
|
query = self.factory.create_query(
|
|
query_text="select {{n}}",
|
|
options={
|
|
"parameters": [
|
|
{
|
|
"global": False,
|
|
"type": "text",
|
|
"name": "n",
|
|
"value": "42",
|
|
"title": "n",
|
|
}
|
|
],
|
|
"apply_auto_limit": True,
|
|
},
|
|
)
|
|
oq = staticmethod(lambda: [query])
|
|
with patch(ENQUEUE_QUERY) as add_job_mock, patch.object(Query, "outdated_queries", oq):
|
|
refresh_queries()
|
|
add_job_mock.assert_called_with(
|
|
"select 42 LIMIT 1000",
|
|
query.data_source,
|
|
query.user_id,
|
|
scheduled_query=query,
|
|
metadata=ANY,
|
|
)
|
|
|
|
def test_enqueues_parameterized_queries_for_non_sqlquery(self):
|
|
"""
|
|
Scheduled queries with parameters use saved values.
|
|
"""
|
|
ds = self.factory.create_data_source(group=self.factory.org.default_group, type="prometheus")
|
|
query = self.factory.create_query(
|
|
query_text="select {{n}}",
|
|
options={
|
|
"parameters": [
|
|
{
|
|
"global": False,
|
|
"type": "text",
|
|
"name": "n",
|
|
"value": "42",
|
|
"title": "n",
|
|
}
|
|
],
|
|
"apply_auto_limit": True,
|
|
},
|
|
data_source=ds,
|
|
)
|
|
oq = staticmethod(lambda: [query])
|
|
with patch(ENQUEUE_QUERY) as add_job_mock, patch.object(Query, "outdated_queries", oq):
|
|
refresh_queries()
|
|
add_job_mock.assert_called_with(
|
|
"select 42",
|
|
query.data_source,
|
|
query.user_id,
|
|
scheduled_query=query,
|
|
metadata=ANY,
|
|
)
|
|
|
|
def test_doesnt_enqueue_parameterized_queries_with_invalid_parameters(self):
|
|
"""
|
|
Scheduled queries with invalid parameters are skipped.
|
|
"""
|
|
query = self.factory.create_query(
|
|
query_text="select {{n}}",
|
|
options={
|
|
"parameters": [
|
|
{
|
|
"global": False,
|
|
"type": "text",
|
|
"name": "n",
|
|
"value": 42, # <-- should be text!
|
|
"title": "n",
|
|
}
|
|
],
|
|
"apply_auto_limit": True,
|
|
},
|
|
)
|
|
oq = staticmethod(lambda: [query])
|
|
with patch(ENQUEUE_QUERY) as add_job_mock, patch.object(Query, "outdated_queries", oq):
|
|
refresh_queries()
|
|
add_job_mock.assert_not_called()
|
|
|
|
def test_doesnt_enqueue_parameterized_queries_with_dropdown_queries_that_are_detached_from_data_source(
|
|
self,
|
|
):
|
|
"""
|
|
Scheduled queries with a dropdown parameter which points to a query that is detached from its data source are skipped.
|
|
"""
|
|
query = self.factory.create_query(
|
|
query_text="select {{n}}",
|
|
options={
|
|
"parameters": [
|
|
{
|
|
"global": False,
|
|
"type": "query",
|
|
"name": "n",
|
|
"queryId": 100,
|
|
"title": "n",
|
|
}
|
|
],
|
|
"apply_auto_limit": True,
|
|
},
|
|
)
|
|
|
|
self.factory.create_query(id=100, data_source=None)
|
|
|
|
oq = staticmethod(lambda: [query])
|
|
with patch(ENQUEUE_QUERY) as add_job_mock, patch.object(Query, "outdated_queries", oq):
|
|
refresh_queries()
|
|
add_job_mock.assert_not_called()
|