Example #1
0
    def test_load_explore_json_into_cache(self, mock_update_job):
        async_query_manager.init_app(app)
        table = self.get_table(name="birth_names")
        user = security_manager.find_user("gamma")
        form_data = {
            "datasource": f"{table.id}__table",
            "viz_type": "dist_bar",
            "time_range_endpoints": ["inclusive", "exclusive"],
            "granularity_sqla": "ds",
            "time_range": "No filter",
            "metrics": ["count"],
            "adhoc_filters": [],
            "groupby": ["gender"],
            "row_limit": 100,
        }
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": user.id,
            "status": "pending",
            "errors": [],
        }

        with mock.patch.object(
            async_queries, "ensure_user_is_set"
        ) as ensure_user_is_set:
            load_explore_json_into_cache(job_metadata, form_data)

        ensure_user_is_set.assert_called_once_with(user.id)
        mock_update_job.assert_called_once_with(
            job_metadata, "done", result_url=mock.ANY
        )
Example #2
0
    def test_load_explore_json_into_cache(self, mock_update_job):
        async_query_manager.init_app(app)
        table = get_table_by_name("birth_names")
        form_data = {
            "datasource": f"{table.id}__table",
            "viz_type": "dist_bar",
            "time_range_endpoints": ["inclusive", "exclusive"],
            "granularity_sqla": "ds",
            "time_range": "No filter",
            "metrics": ["count"],
            "adhoc_filters": [],
            "groupby": ["gender"],
            "row_limit": 100,
        }
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": 1,
            "status": "pending",
            "errors": [],
        }

        load_explore_json_into_cache(job_metadata, form_data)

        mock_update_job.assert_called_with(job_metadata,
                                           "done",
                                           result_url=mock.ANY)
Example #3
0
    def test_chart_data_async_cached_sync_response(self):
        """
        Chart data API: Test chart data query returns results synchronously
        when results are already cached.
        """
        async_query_manager.init_app(app)

        class QueryContext:
            result_format = ChartDataResultFormat.JSON
            result_type = ChartDataResultType.FULL

        cmd_run_val = {
            "query_context": QueryContext(),
            "queries": [{
                "query": "select * from foo"
            }],
        }

        with mock.patch.object(ChartDataCommand,
                               "run",
                               return_value=cmd_run_val) as patched_run:
            self.query_context_payload[
                "result_type"] = ChartDataResultType.FULL
            rv = self.post_assert_metric(CHART_DATA_URI,
                                         self.query_context_payload, "data")
            self.assertEqual(rv.status_code, 200)
            data = json.loads(rv.data.decode("utf-8"))
            patched_run.assert_called_once_with(force_cached=True)
            self.assertEqual(data,
                             {"result": [{
                                 "query": "select * from foo"
                             }]})
Example #4
0
    def test_explore_json_async(self):
        tbl_id = self.table_ids.get("birth_names")
        form_data = {
            "datasource": f"{tbl_id}__table",
            "viz_type": "dist_bar",
            "time_range_endpoints": ["inclusive", "exclusive"],
            "granularity_sqla": "ds",
            "time_range": "No filter",
            "metrics": ["count"],
            "adhoc_filters": [],
            "groupby": ["gender"],
            "row_limit": 100,
        }
        async_query_manager.init_app(app)
        self.login(username="******")
        rv = self.client.post(
            "/superset/explore_json/", data={"form_data": json.dumps(form_data)},
        )
        data = json.loads(rv.data.decode("utf-8"))
        keys = list(data.keys())

        self.assertEqual(rv.status_code, 202)
        self.assertCountEqual(
            keys, ["channel_id", "job_id", "user_id", "status", "errors", "result_url"]
        )
Example #5
0
 def test_chart_data_async_results_type(self):
     """
     Chart data API: Test chart data query non-JSON format (async)
     """
     async_query_manager.init_app(app)
     self.query_context_payload["result_type"] = "results"
     rv = self.post_assert_metric(CHART_DATA_URI, self.query_context_payload, "data")
     self.assertEqual(rv.status_code, 200)
Example #6
0
    def test_chart_data_cache_key_error(self):
        """
        Chart data cache API: Test chart data async cache request with invalid cache key
        """
        async_query_manager.init_app(app)
        rv = self.get_assert_metric(f"{CHART_DATA_URI}/test-cache-key",
                                    "data_from_cache")

        self.assertEqual(rv.status_code, 404)
Example #7
0
 def test_chart_data_async_invalid_token(self):
     """
     Chart data API: Test chart data query (async)
     """
     async_query_manager.init_app(app)
     test_client.set_cookie(
         "localhost", app.config["GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME"],
         "foo")
     rv = test_client.post(CHART_DATA_URI, json=self.query_context_payload)
     self.assertEqual(rv.status_code, 401)
Example #8
0
 def test_chart_data_async(self):
     self.logout()
     async_query_manager.init_app(app)
     self.login("admin")
     rv = self.post_assert_metric(CHART_DATA_URI, self.query_context_payload, "data")
     self.assertEqual(rv.status_code, 202)
     data = json.loads(rv.data.decode("utf-8"))
     keys = list(data.keys())
     self.assertCountEqual(
         keys, ["channel_id", "job_id", "user_id", "status", "errors", "result_url"]
     )
Example #9
0
    def test_events_last_id(self, mock_uuid4):
        async_query_manager.init_app(app)
        self.login(username="******")
        with mock.patch.object(async_query_manager._redis, "xrange") as mock_xrange:
            rv = self.fetch_events("1607471525180-0")
            response = json.loads(rv.data.decode("utf-8"))

        assert rv.status_code == 200
        channel_id = app.config["GLOBAL_ASYNC_QUERIES_REDIS_STREAM_PREFIX"] + self.UUID
        mock_xrange.assert_called_with(channel_id, "1607471525180-1", "+", 100)
        self.assertEqual(response, {"result": []})
Example #10
0
    def test_chart_data_cache_run_failed(self, cache_loader):
        """
        Chart data cache API: Test chart data async cache request with run failure
        """
        async_query_manager.init_app(app)
        cache_loader.load.return_value = self.query_context_payload
        rv = self.get_assert_metric(f"{CHART_DATA_URI}/test-cache-key",
                                    "data_from_cache")
        data = json.loads(rv.data.decode("utf-8"))

        self.assertEqual(rv.status_code, 422)
        self.assertEqual(data["message"], "Error loading data from cache")
Example #11
0
    def test_events_results(self, mock_uuid4):
        async_query_manager.init_app(app)
        self.login(username="******")
        with mock.patch.object(async_query_manager._redis,
                               "xrange") as mock_xrange:
            mock_xrange.return_value = [
                (
                    "1607477697866-0",
                    {
                        "data":
                        '{"channel_id": "1095c1c9-b6b1-444d-aa83-8e323b32831f", "job_id": "10a0bd9a-03c8-4737-9345-f4234ba86512", "user_id": "1", "status": "done", "errors": [], "result_url": "/api/v1/chart/data/qc-ecd766dd461f294e1bcdaa321e0e8463"}'
                    },
                ),
                (
                    "1607477697993-0",
                    {
                        "data":
                        '{"channel_id": "1095c1c9-b6b1-444d-aa83-8e323b32831f", "job_id": "027cbe49-26ce-4813-bb5a-0b95a626b84c", "user_id": "1", "status": "done", "errors": [], "result_url": "/api/v1/chart/data/qc-1bbc3a240e7039ba4791aefb3a7ee80d"}'
                    },
                ),
            ]
            rv = self.fetch_events()
            response = json.loads(rv.data.decode("utf-8"))

        assert rv.status_code == 200
        channel_id = app.config[
            "GLOBAL_ASYNC_QUERIES_REDIS_STREAM_PREFIX"] + self.UUID
        mock_xrange.assert_called_with(channel_id, "-", "+", 100)
        expected = {
            "result": [
                {
                    "channel_id": "1095c1c9-b6b1-444d-aa83-8e323b32831f",
                    "errors": [],
                    "id": "1607477697866-0",
                    "job_id": "10a0bd9a-03c8-4737-9345-f4234ba86512",
                    "result_url":
                    "/api/v1/chart/data/qc-ecd766dd461f294e1bcdaa321e0e8463",
                    "status": "done",
                    "user_id": "1",
                },
                {
                    "channel_id": "1095c1c9-b6b1-444d-aa83-8e323b32831f",
                    "errors": [],
                    "id": "1607477697993-0",
                    "job_id": "027cbe49-26ce-4813-bb5a-0b95a626b84c",
                    "result_url":
                    "/api/v1/chart/data/qc-1bbc3a240e7039ba4791aefb3a7ee80d",
                    "status": "done",
                    "user_id": "1",
                },
            ]
        }
        self.assertEqual(response, expected)
Example #12
0
    def test_load_chart_data_into_cache(self, mock_update_job):
        async_query_manager.init_app(app)
        query_context = get_query_context("birth_names")
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": 1,
            "status": "pending",
            "errors": [],
        }

        load_chart_data_into_cache(job_metadata, query_context)

        mock_update_job.assert_called_with(job_metadata,
                                           "done",
                                           result_url=mock.ANY)
Example #13
0
    def test_chart_data_cache_no_login(self, cache_loader):
        """
        Chart data cache API: Test chart data async cache request (no login)
        """
        self.logout()
        async_query_manager.init_app(app)
        cache_loader.load.return_value = self.query_context_payload
        orig_run = ChartDataCommand.run

        def mock_run(self, **kwargs):
            assert kwargs["force_cached"] == True
            # override force_cached to get result from DB
            return orig_run(self, force_cached=False)

        with mock.patch.object(ChartDataCommand, "run", new=mock_run):
            rv = self.client.get(f"{CHART_DATA_URI}/test-cache-key", )

        self.assertEqual(rv.status_code, 401)
Example #14
0
    def test_load_explore_json_into_cache_error(self, mock_update_job):
        async_query_manager.init_app(app)
        form_data = {}
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": 1,
            "status": "pending",
            "errors": [],
        }

        with pytest.raises(SupersetException):
            load_explore_json_into_cache(job_metadata, form_data)

        errors = ["The dataset associated with this chart no longer exists"]
        mock_update_job.assert_called_with(job_metadata,
                                           "error",
                                           errors=errors)
Example #15
0
    def test_load_chart_data_into_cache_error(self, mock_update_job,
                                              mock_run_command):
        async_query_manager.init_app(app)
        query_context = get_query_context("birth_names")
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": 1,
            "status": "pending",
            "errors": [],
        }
        with pytest.raises(ChartDataQueryFailedError):
            load_chart_data_into_cache(job_metadata, query_context)

        mock_run_command.assert_called_with(cache=True)
        errors = [{"message": "Error: foo"}]
        mock_update_job.assert_called_with(job_metadata,
                                           "error",
                                           errors=errors)
Example #16
0
 def test_explore_json_async_results_format(self):
     tbl_id = self.table_ids.get("birth_names")
     form_data = {
         "datasource": f"{tbl_id}__table",
         "viz_type": "dist_bar",
         "time_range_endpoints": ["inclusive", "exclusive"],
         "granularity_sqla": "ds",
         "time_range": "No filter",
         "metrics": ["count"],
         "adhoc_filters": [],
         "groupby": ["gender"],
         "row_limit": 100,
     }
     async_query_manager.init_app(app)
     self.login(username="******")
     rv = self.client.post(
         "/superset/explore_json/?results=true",
         data={"form_data": json.dumps(form_data)},
     )
     self.assertEqual(rv.status_code, 200)
    def test_load_chart_data_into_cache(self, mock_update_job):
        async_query_manager.init_app(app)
        query_context = get_query_context("birth_names")
        user = security_manager.find_user("gamma")
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": user.id,
            "status": "pending",
            "errors": [],
        }

        with mock.patch.object(async_queries,
                               "ensure_user_is_set") as ensure_user_is_set:
            load_chart_data_into_cache(job_metadata, query_context)

        ensure_user_is_set.assert_called_once_with(user.id)
        mock_update_job.assert_called_once_with(job_metadata,
                                                "done",
                                                result_url=mock.ANY)
Example #18
0
    def test_chart_data_cache(self, cache_loader):
        """
        Chart data cache API: Test chart data async cache request
        """
        async_query_manager.init_app(app)
        cache_loader.load.return_value = self.query_context_payload
        orig_run = ChartDataCommand.run

        def mock_run(self, **kwargs):
            assert kwargs["force_cached"] == True
            # override force_cached to get result from DB
            return orig_run(self, force_cached=False)

        with mock.patch.object(ChartDataCommand, "run", new=mock_run):
            rv = self.get_assert_metric(f"{CHART_DATA_URI}/test-cache-key",
                                        "data_from_cache")
            data = json.loads(rv.data.decode("utf-8"))

        expected_row_count = self.get_expected_row_count("client_id_3")
        self.assertEqual(rv.status_code, 200)
        self.assertEqual(data["result"][0]["rowcount"], expected_row_count)
Example #19
0
    def test_load_chart_data_into_cache_error(self, mock_update_job, mock_run_command):
        async_query_manager.init_app(app)
        query_context = get_query_context("birth_names")
        user = security_manager.find_user("gamma")
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": user.id,
            "status": "pending",
            "errors": [],
        }
        with pytest.raises(ChartDataQueryFailedError):
            with mock.patch.object(
                async_queries, "ensure_user_is_set"
            ) as ensure_user_is_set:
                load_chart_data_into_cache(job_metadata, query_context)
            ensure_user_is_set.assert_called_once_with(user.id)

        mock_run_command.assert_called_once_with(cache=True)
        errors = [{"message": "Error: foo"}]
        mock_update_job.assert_called_once_with(job_metadata, "error", errors=errors)
Example #20
0
    def test_load_explore_json_into_cache_error(self, mock_update_job):
        async_query_manager.init_app(app)
        user = security_manager.find_user("gamma")
        form_data = {}
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": user.id,
            "status": "pending",
            "errors": [],
        }

        with pytest.raises(SupersetException):
            with mock.patch.object(
                async_queries, "ensure_user_is_set"
            ) as ensure_user_is_set:
                load_explore_json_into_cache(job_metadata, form_data)
            ensure_user_is_set.assert_called_once_with(user.id)

        errors = ["The dataset associated with this chart no longer exists"]
        mock_update_job.assert_called_once_with(job_metadata, "error", errors=errors)
Example #21
0
    def test_soft_timeout_load_chart_data_into_cache(
        self, mock_update_job, mock_run_command
    ):
        async_query_manager.init_app(app)
        user = security_manager.find_user("gamma")
        form_data = {}
        job_metadata = {
            "channel_id": str(uuid4()),
            "job_id": str(uuid4()),
            "user_id": user.id,
            "status": "pending",
            "errors": [],
        }
        errors = ["A timeout occurred while loading chart data"]

        with pytest.raises(SoftTimeLimitExceeded):
            with mock.patch.object(
                async_queries, "ensure_user_is_set",
            ) as ensure_user_is_set:
                ensure_user_is_set.side_effect = SoftTimeLimitExceeded()
                load_chart_data_into_cache(job_metadata, form_data)
            ensure_user_is_set.assert_called_once_with(user.id, "error", errors=errors)
Example #22
0
 def configure_async_queries(self) -> None:
     if feature_flag_manager.is_feature_enabled("GLOBAL_ASYNC_QUERIES"):
         async_query_manager.init_app(self.superset_app)
Example #23
0
 def test_events_no_login(self):
     async_query_manager.init_app(app)
     rv = self.fetch_events()
     assert rv.status_code == 401