This is an automated email from the ASF dual-hosted git repository.

hugh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 904b60e  chore: added BasicParametersMixin to Redshift (#14752)
904b60e is described below

commit 904b60e420bc5088d981d404c31055eb9c39c3c2
Author: AAfghahi <[email protected]>
AuthorDate: Mon May 24 17:32:53 2021 -0400

    chore: added BasicParametersMixin to Redshift (#14752)
    
    * redshift basic mixin and tests
    
    * rebased
    
    * forgot prefix
---
 superset/db_engine_specs/redshift.py    | 19 ++++---
 tests/databases/api_tests.py            | 95 +++++++++++++++++++++------------
 tests/db_engine_specs/redshift_tests.py |  6 +++
 3 files changed, 80 insertions(+), 40 deletions(-)

diff --git a/superset/db_engine_specs/redshift.py 
b/superset/db_engine_specs/redshift.py
index f2d2652..beff1f6 100644
--- a/superset/db_engine_specs/redshift.py
+++ b/superset/db_engine_specs/redshift.py
@@ -19,6 +19,7 @@ from typing import Any, Dict, Pattern, Tuple
 
 from flask_babel import gettext as __
 
+from superset.db_engine_specs.base import BasicParametersMixin
 from superset.db_engine_specs.postgres import PostgresBaseEngineSpec
 from superset.errors import SupersetErrorType
 
@@ -45,26 +46,32 @@ CONNECTION_UNKNOWN_DATABASE_REGEX = re.compile(
 )
 
 
-class RedshiftEngineSpec(PostgresBaseEngineSpec):
+class RedshiftEngineSpec(PostgresBaseEngineSpec, BasicParametersMixin):
     engine = "redshift"
     engine_name = "Amazon Redshift"
     max_column_name_length = 127
 
+    sqlalchemy_uri_placeholder = (
+        
"redshift+psycopg2://user:password@host:port/dbname[?key=value&key=value...]"
+    )
+
+    encryption_parameters = {"sslmode": "verify-ca"}
+
     custom_errors: Dict[Pattern[str], Tuple[str, SupersetErrorType, Dict[str, 
Any]]] = {
         CONNECTION_ACCESS_DENIED_REGEX: (
             __('Either the username "%(username)s" or the password is 
incorrect.'),
             SupersetErrorType.CONNECTION_ACCESS_DENIED_ERROR,
-            {},
+            {"invalid": ["username", "password"]},
         ),
         CONNECTION_INVALID_HOSTNAME_REGEX: (
             __('The hostname "%(hostname)s" cannot be resolved.'),
             SupersetErrorType.CONNECTION_INVALID_HOSTNAME_ERROR,
-            {},
+            {"invalid": ["host"]},
         ),
         CONNECTION_PORT_CLOSED_REGEX: (
             __('Port %(port)s on hostname "%(hostname)s" refused the 
connection.'),
             SupersetErrorType.CONNECTION_PORT_CLOSED_ERROR,
-            {},
+            {"invalid": ["host", "port"]},
         ),
         CONNECTION_HOST_DOWN_REGEX: (
             __(
@@ -72,7 +79,7 @@ class RedshiftEngineSpec(PostgresBaseEngineSpec):
                 "reached on port %(port)s."
             ),
             SupersetErrorType.CONNECTION_HOST_DOWN_ERROR,
-            {},
+            {"invalid": ["host", "port"]},
         ),
         CONNECTION_UNKNOWN_DATABASE_REGEX: (
             __(
@@ -80,7 +87,7 @@ class RedshiftEngineSpec(PostgresBaseEngineSpec):
                 " Please verify your database name and try again."
             ),
             SupersetErrorType.CONNECTION_UNKNOWN_DATABASE_ERROR,
-            {},
+            {"invalid": ["database"]},
         ),
     }
 
diff --git a/tests/databases/api_tests.py b/tests/databases/api_tests.py
index 1868f95..9ad0b19 100644
--- a/tests/databases/api_tests.py
+++ b/tests/databases/api_tests.py
@@ -36,6 +36,7 @@ from superset import db, security_manager
 from superset.connectors.sqla.models import SqlaTable
 from superset.db_engine_specs.mysql import MySQLEngineSpec
 from superset.db_engine_specs.postgres import PostgresEngineSpec
+from superset.db_engine_specs.redshift import RedshiftEngineSpec
 from superset.db_engine_specs.bigquery import BigQueryEngineSpec
 from superset.db_engine_specs.hana import HanaEngineSpec
 from superset.errors import SupersetError
@@ -1371,10 +1372,14 @@ class TestDatabaseApi(SupersetTestCase):
     @mock.patch("superset.databases.api.get_available_engine_specs")
     @mock.patch("superset.databases.api.app")
     def test_available(self, app, get_available_engine_specs):
-        app.config = {"PREFERRED_DATABASES": ["postgresql"]}
+        app.config = {
+            "PREFERRED_DATABASES": ["postgresql", "biqquery", "mysql", 
"redshift"]
+        }
         get_available_engine_specs.return_value = [
             PostgresEngineSpec,
             BigQueryEngineSpec,
+            MySQLEngineSpec,
+            RedshiftEngineSpec,
             HanaEngineSpec,
         ]
 
@@ -1431,46 +1436,52 @@ class TestDatabaseApi(SupersetTestCase):
                     "sqlalchemy_uri_placeholder": 
"postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]",
                 },
                 {
-                    "engine": "bigquery",
-                    "name": "Google BigQuery",
+                    "engine": "mysql",
+                    "name": "MySQL",
                     "parameters": {
                         "properties": {
-                            "credentials_info": {
-                                "description": "Contents of BigQuery JSON 
credentials.",
+                            "database": {
+                                "description": "Database name",
                                 "type": "string",
-                                "x-encrypted-extra": True,
-                            }
+                            },
+                            "encryption": {
+                                "description": "Use an encrypted connection to 
the database",
+                                "type": "boolean",
+                            },
+                            "host": {
+                                "description": "Hostname or IP address",
+                                "type": "string",
+                            },
+                            "password": {
+                                "description": "Password",
+                                "nullable": True,
+                                "type": "string",
+                            },
+                            "port": {
+                                "description": "Database port",
+                                "format": "int32",
+                                "type": "integer",
+                            },
+                            "query": {
+                                "additionalProperties": {},
+                                "description": "Additional parameters",
+                                "type": "object",
+                            },
+                            "username": {
+                                "description": "Username",
+                                "nullable": True,
+                                "type": "string",
+                            },
                         },
+                        "required": ["database", "host", "port", "username"],
                         "type": "object",
                     },
-                    "preferred": False,
-                    "sqlalchemy_uri_placeholder": "bigquery://{project_id}",
+                    "preferred": True,
+                    "sqlalchemy_uri_placeholder": 
"mysql://user:password@host:port/dbname[?key=value&key=value...]",
                 },
-                {"engine": "hana", "name": "SAP HANA", "preferred": False},
-            ]
-        }
-
-    @mock.patch("superset.databases.api.get_available_engine_specs")
-    @mock.patch("superset.databases.api.app")
-    def test_available_with_mysql(self, app, get_available_engine_specs):
-        app.config = {"PREFERRED_DATABASES": ["mysql"]}
-        get_available_engine_specs.return_value = [
-            MySQLEngineSpec,
-            HanaEngineSpec,
-        ]
-
-        self.login(username="admin")
-        uri = "api/v1/database/available/"
-
-        rv = self.client.get(uri)
-        response = json.loads(rv.data.decode("utf-8"))
-        print(response)
-        assert rv.status_code == 200
-        assert response == {
-            "databases": [
                 {
-                    "engine": "mysql",
-                    "name": "MySQL",
+                    "engine": "redshift",
+                    "name": "Amazon Redshift",
                     "parameters": {
                         "properties": {
                             "database": {
@@ -1510,7 +1521,23 @@ class TestDatabaseApi(SupersetTestCase):
                         "type": "object",
                     },
                     "preferred": True,
-                    "sqlalchemy_uri_placeholder": 
"mysql://user:password@host:port/dbname[?key=value&key=value...]",
+                    "sqlalchemy_uri_placeholder": 
"redshift+psycopg2://user:password@host:port/dbname[?key=value&key=value...]",
+                },
+                {
+                    "engine": "bigquery",
+                    "name": "Google BigQuery",
+                    "parameters": {
+                        "properties": {
+                            "credentials_info": {
+                                "description": "Contents of BigQuery JSON 
credentials.",
+                                "type": "string",
+                                "x-encrypted-extra": True,
+                            }
+                        },
+                        "type": "object",
+                    },
+                    "preferred": False,
+                    "sqlalchemy_uri_placeholder": "bigquery://{project_id}",
                 },
                 {"engine": "hana", "name": "SAP HANA", "preferred": False},
             ]
diff --git a/tests/db_engine_specs/redshift_tests.py 
b/tests/db_engine_specs/redshift_tests.py
index 483fbe5..49e34b1 100644
--- a/tests/db_engine_specs/redshift_tests.py
+++ b/tests/db_engine_specs/redshift_tests.py
@@ -34,6 +34,7 @@ class TestRedshiftDbEngineSpec(TestDbEngineSpec):
                 message='Either the username "wronguser" or the password is 
incorrect.',
                 level=ErrorLevel.ERROR,
                 extra={
+                    "invalid": ["username", "password"],
                     "engine_name": "Amazon Redshift",
                     "issue_codes": [
                         {
@@ -62,6 +63,7 @@ class TestRedshiftDbEngineSpec(TestDbEngineSpec):
                 message='The hostname "badhost" cannot be resolved.',
                 level=ErrorLevel.ERROR,
                 extra={
+                    "invalid": ["host"],
                     "engine_name": "Amazon Redshift",
                     "issue_codes": [
                         {
@@ -90,6 +92,7 @@ could not connect to server: Connection refused
                 message='Port 12345 on hostname "localhost" refused the 
connection.',
                 level=ErrorLevel.ERROR,
                 extra={
+                    "invalid": ["host", "port"],
                     "engine_name": "Amazon Redshift",
                     "issue_codes": [
                         {"code": 1008, "message": "Issue 1008 - The port is 
closed."}
@@ -123,6 +126,7 @@ psql: error: could not connect to server: Operation timed 
out
                             "and can't be reached on the provided port.",
                         }
                     ],
+                    "invalid": ["host", "port"],
                 },
             )
         ]
@@ -153,6 +157,7 @@ psql: error: could not connect to server: Operation timed 
out
                             "and can't be reached on the provided port.",
                         }
                     ],
+                    "invalid": ["host", "port"],
                 },
             )
         ]
@@ -174,6 +179,7 @@ psql: error: could not connect to server: Operation timed 
out
                             "spelled incorrectly or does not exist.",
                         }
                     ],
+                    "invalid": ["database"],
                 },
             )
         ]

Reply via email to