2019-03-14 08:51:30 +00:00
|
|
|
import mock
|
2019-06-10 19:39:26 +00:00
|
|
|
from mock import patch
|
2016-01-12 11:39:54 +00:00
|
|
|
from tests import BaseTestCase
|
2017-06-02 15:08:13 +00:00
|
|
|
|
|
|
|
from redash.models import DataSource, Query, QueryResult
|
2016-02-18 15:44:55 +00:00
|
|
|
from redash.utils.configuration import ConfigurationContainer
|
2016-01-12 11:39:54 +00:00
|
|
|
|
|
|
|
|
2017-06-02 15:08:13 +00:00
|
|
|
class DataSourceTest(BaseTestCase):
|
|
|
|
def test_get_schema(self):
|
2019-12-11 11:54:29 +00:00
|
|
|
return_value = [{"name": "table", "columns": []}]
|
2019-03-14 08:51:30 +00:00
|
|
|
|
2019-12-11 11:54:29 +00:00
|
|
|
with mock.patch(
|
|
|
|
"redash.query_runner.pg.PostgreSQL.get_schema"
|
|
|
|
) as patched_get_schema:
|
2019-03-14 08:51:30 +00:00
|
|
|
patched_get_schema.return_value = return_value
|
|
|
|
|
|
|
|
schema = self.factory.data_source.get_schema()
|
|
|
|
|
|
|
|
self.assertEqual(return_value, schema)
|
|
|
|
|
|
|
|
def test_get_schema_uses_cache(self):
|
2019-12-11 11:54:29 +00:00
|
|
|
return_value = [{"name": "table", "columns": []}]
|
|
|
|
with mock.patch(
|
|
|
|
"redash.query_runner.pg.PostgreSQL.get_schema"
|
|
|
|
) as patched_get_schema:
|
2019-03-14 08:51:30 +00:00
|
|
|
patched_get_schema.return_value = return_value
|
|
|
|
|
|
|
|
self.factory.data_source.get_schema()
|
|
|
|
schema = self.factory.data_source.get_schema()
|
|
|
|
|
|
|
|
self.assertEqual(return_value, schema)
|
|
|
|
self.assertEqual(patched_get_schema.call_count, 1)
|
|
|
|
|
|
|
|
def test_get_schema_skips_cache_with_refresh_true(self):
|
2019-12-11 11:54:29 +00:00
|
|
|
return_value = [{"name": "table", "columns": []}]
|
|
|
|
with mock.patch(
|
|
|
|
"redash.query_runner.pg.PostgreSQL.get_schema"
|
|
|
|
) as patched_get_schema:
|
2019-03-14 08:51:30 +00:00
|
|
|
patched_get_schema.return_value = return_value
|
|
|
|
|
|
|
|
self.factory.data_source.get_schema()
|
2019-12-11 11:54:29 +00:00
|
|
|
new_return_value = [{"name": "new_table", "columns": []}]
|
2019-03-14 08:51:30 +00:00
|
|
|
patched_get_schema.return_value = new_return_value
|
|
|
|
schema = self.factory.data_source.get_schema(refresh=True)
|
|
|
|
|
|
|
|
self.assertEqual(new_return_value, schema)
|
|
|
|
self.assertEqual(patched_get_schema.call_count, 2)
|
2017-06-02 15:08:13 +00:00
|
|
|
|
2020-02-09 10:40:47 +00:00
|
|
|
def test_schema_sorter(self):
|
|
|
|
input_data = [
|
|
|
|
{"name": "zoo", "columns": ["is_zebra", "is_snake", "is_cow"]},
|
|
|
|
{
|
|
|
|
"name": "all_terain_vehicle",
|
|
|
|
"columns": ["has_wheels", "has_engine", "has_all_wheel_drive"],
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
expected_output = [
|
|
|
|
{
|
|
|
|
"name": "all_terain_vehicle",
|
|
|
|
"columns": ["has_all_wheel_drive", "has_engine", "has_wheels"],
|
|
|
|
},
|
|
|
|
{"name": "zoo", "columns": ["is_cow", "is_snake", "is_zebra"]},
|
|
|
|
]
|
|
|
|
|
|
|
|
real_output = self.factory.data_source._sort_schema(input_data)
|
|
|
|
|
|
|
|
self.assertEqual(real_output, expected_output)
|
|
|
|
|
|
|
|
def test_model_uses_schema_sorter(self):
|
|
|
|
orig_schema = [
|
|
|
|
{"name": "zoo", "columns": ["is_zebra", "is_snake", "is_cow"]},
|
|
|
|
{
|
|
|
|
"name": "all_terain_vehicle",
|
|
|
|
"columns": ["has_wheels", "has_engine", "has_all_wheel_drive"],
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
sorted_schema = [
|
|
|
|
{
|
|
|
|
"name": "all_terain_vehicle",
|
|
|
|
"columns": ["has_all_wheel_drive", "has_engine", "has_wheels"],
|
|
|
|
},
|
|
|
|
{"name": "zoo", "columns": ["is_cow", "is_snake", "is_zebra"]},
|
|
|
|
]
|
|
|
|
|
|
|
|
with mock.patch(
|
|
|
|
"redash.query_runner.pg.PostgreSQL.get_schema"
|
|
|
|
) as patched_get_schema:
|
|
|
|
patched_get_schema.return_value = orig_schema
|
|
|
|
|
|
|
|
out_schema = self.factory.data_source.get_schema()
|
|
|
|
|
|
|
|
self.assertEqual(out_schema, sorted_schema)
|
|
|
|
|
2017-06-02 15:08:13 +00:00
|
|
|
|
2016-01-12 11:39:54 +00:00
|
|
|
class TestDataSourceCreate(BaseTestCase):
|
|
|
|
def test_adds_data_source_to_default_group(self):
|
2019-12-11 11:54:29 +00:00
|
|
|
data_source = DataSource.create_with_group(
|
|
|
|
org=self.factory.org,
|
|
|
|
name="test",
|
|
|
|
options=ConfigurationContainer.from_json('{"dbname": "test"}'),
|
|
|
|
type="pg",
|
|
|
|
)
|
2016-01-12 11:39:54 +00:00
|
|
|
self.assertIn(self.factory.org.default_group.id, data_source.groups)
|
2016-05-30 15:30:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TestDataSourceIsPaused(BaseTestCase):
|
|
|
|
def test_returns_false_by_default(self):
|
2016-05-30 19:44:09 +00:00
|
|
|
self.assertFalse(self.factory.data_source.paused)
|
2016-05-30 15:30:05 +00:00
|
|
|
|
|
|
|
def test_persists_selection(self):
|
|
|
|
self.factory.data_source.pause()
|
2016-05-30 19:44:09 +00:00
|
|
|
self.assertTrue(self.factory.data_source.paused)
|
2016-05-30 15:30:05 +00:00
|
|
|
|
|
|
|
self.factory.data_source.resume()
|
2016-05-30 19:44:09 +00:00
|
|
|
self.assertFalse(self.factory.data_source.paused)
|
2016-05-30 15:30:05 +00:00
|
|
|
|
|
|
|
def test_allows_setting_reason(self):
|
|
|
|
reason = "Some good reason."
|
|
|
|
self.factory.data_source.pause(reason)
|
2016-05-30 19:44:09 +00:00
|
|
|
self.assertTrue(self.factory.data_source.paused)
|
2016-05-30 15:30:05 +00:00
|
|
|
self.assertEqual(self.factory.data_source.pause_reason, reason)
|
|
|
|
|
|
|
|
def test_resume_clears_reason(self):
|
|
|
|
self.factory.data_source.pause("Reason")
|
|
|
|
self.factory.data_source.resume()
|
|
|
|
self.assertEqual(self.factory.data_source.pause_reason, None)
|
|
|
|
|
|
|
|
def test_reason_is_none_by_default(self):
|
|
|
|
self.assertEqual(self.factory.data_source.pause_reason, None)
|
2017-06-02 15:08:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TestDataSourceDelete(BaseTestCase):
|
|
|
|
def test_deletes_the_data_source(self):
|
|
|
|
data_source = self.factory.create_data_source()
|
|
|
|
data_source.delete()
|
|
|
|
|
|
|
|
self.assertIsNone(DataSource.query.get(data_source.id))
|
|
|
|
|
|
|
|
def test_sets_queries_data_source_to_null(self):
|
|
|
|
data_source = self.factory.create_data_source()
|
|
|
|
query = self.factory.create_query(data_source=data_source)
|
|
|
|
|
|
|
|
data_source.delete()
|
|
|
|
self.assertIsNone(DataSource.query.get(data_source.id))
|
|
|
|
self.assertIsNone(Query.query.get(query.id).data_source_id)
|
|
|
|
|
|
|
|
def test_deletes_child_models(self):
|
|
|
|
data_source = self.factory.create_data_source()
|
|
|
|
self.factory.create_query_result(data_source=data_source)
|
2019-12-11 11:54:29 +00:00
|
|
|
self.factory.create_query(
|
|
|
|
data_source=data_source,
|
|
|
|
latest_query_data=self.factory.create_query_result(data_source=data_source),
|
|
|
|
)
|
2017-06-02 15:08:13 +00:00
|
|
|
|
|
|
|
data_source.delete()
|
|
|
|
self.assertIsNone(DataSource.query.get(data_source.id))
|
2019-12-11 11:54:29 +00:00
|
|
|
self.assertEqual(
|
|
|
|
0, QueryResult.query.filter(QueryResult.data_source == data_source).count()
|
|
|
|
)
|
2019-06-10 19:39:26 +00:00
|
|
|
|
2019-12-11 11:54:29 +00:00
|
|
|
@patch("redash.redis_connection.delete")
|
2019-06-10 19:39:26 +00:00
|
|
|
def test_deletes_schema(self, mock_redis):
|
|
|
|
data_source = self.factory.create_data_source()
|
|
|
|
data_source.delete()
|
|
|
|
|
|
|
|
mock_redis.assert_called_with(data_source._schema_key)
|