Exemple #1
0
    def test_extract_error_message(self):
        from MySQLdb._exceptions import OperationalError

        message = "Unknown table 'BIRTH_NAMES1' in information_schema"
        exception = OperationalError(message)
        extracted_message = MySQLEngineSpec._extract_error_message(exception)
        assert extracted_message == message

        exception = OperationalError(123, message)
        extracted_message = MySQLEngineSpec._extract_error_message(exception)
        assert extracted_message == message
Exemple #2
0
    def test_convert_dttm(self):
        dttm = self.get_dttm()

        self.assertEqual(
            MySQLEngineSpec.convert_dttm("DATE", dttm),
            "STR_TO_DATE('2019-01-02', '%Y-%m-%d')",
        )

        self.assertEqual(
            MySQLEngineSpec.convert_dttm("DATETIME", dttm),
            "STR_TO_DATE('2019-01-02 03:04:05.678900', '%Y-%m-%d %H:%i:%s.%f')",
        )
Exemple #3
0
    def test_is_db_column_type_match(self):
        type_expectations = (
            # Numeric
            ("TINYINT", GenericDataType.NUMERIC),
            ("SMALLINT", GenericDataType.NUMERIC),
            ("MEDIUMINT", GenericDataType.NUMERIC),
            ("INT", GenericDataType.NUMERIC),
            ("BIGINT", GenericDataType.NUMERIC),
            ("DECIMAL", GenericDataType.NUMERIC),
            ("FLOAT", GenericDataType.NUMERIC),
            ("DOUBLE", GenericDataType.NUMERIC),
            ("BIT", GenericDataType.NUMERIC),
            # String
            ("CHAR", GenericDataType.STRING),
            ("VARCHAR", GenericDataType.STRING),
            ("TINYTEXT", GenericDataType.STRING),
            ("MEDIUMTEXT", GenericDataType.STRING),
            ("LONGTEXT", GenericDataType.STRING),
            # Temporal
            ("DATE", GenericDataType.TEMPORAL),
            ("DATETIME", GenericDataType.TEMPORAL),
            ("TIMESTAMP", GenericDataType.TEMPORAL),
            ("TIME", GenericDataType.TEMPORAL),
        )

        for type_str, col_type in type_expectations:
            column_spec = MySQLEngineSpec.get_column_spec(type_str)
            assert column_spec.generic_type == col_type
Exemple #4
0
    def test_is_db_column_type_match(self):
        type_expectations = (
            # Numeric
            ("TINYINT", DbColumnType.NUMERIC),
            ("SMALLINT", DbColumnType.NUMERIC),
            ("MEDIUMINT", DbColumnType.NUMERIC),
            ("INT", DbColumnType.NUMERIC),
            ("BIGINT", DbColumnType.NUMERIC),
            ("DECIMAL", DbColumnType.NUMERIC),
            ("FLOAT", DbColumnType.NUMERIC),
            ("DOUBLE", DbColumnType.NUMERIC),
            ("BIT", DbColumnType.NUMERIC),
            # String
            ("CHAR", DbColumnType.STRING),
            ("VARCHAR", DbColumnType.STRING),
            ("TINYTEXT", DbColumnType.STRING),
            ("MEDIUMTEXT", DbColumnType.STRING),
            ("LONGTEXT", DbColumnType.STRING),
            # Temporal
            ("DATE", DbColumnType.TEMPORAL),
            ("DATETIME", DbColumnType.TEMPORAL),
            ("TIMESTAMP", DbColumnType.TEMPORAL),
            ("TIME", DbColumnType.TEMPORAL),
        )

        for type_expectation in type_expectations:
            type_str = type_expectation[0]
            col_type = type_expectation[1]
            assert MySQLEngineSpec.is_db_column_type_match(
                type_str, DbColumnType.NUMERIC) is (col_type
                                                    == DbColumnType.NUMERIC)
            assert MySQLEngineSpec.is_db_column_type_match(
                type_str, DbColumnType.STRING) is (col_type
                                                   == DbColumnType.STRING)
            assert MySQLEngineSpec.is_db_column_type_match(
                type_str, DbColumnType.TEMPORAL) is (col_type
                                                     == DbColumnType.TEMPORAL)
 def test_get_time_grain_with_unkown_values(self):
     """ Should concatenate from configs and then sort in the proper order
     putting unknown patterns at the end """
     app.config["TIME_GRAIN_ADDON_EXPRESSIONS"] = {
         "mysql": {
             "PT2H": "foo",
             "weird": "foo",
             "PT12H": "foo",
         }
     }
     time_grains = MySQLEngineSpec.get_time_grain_expressions()
     self.assertEqual(
         list(time_grains)[-1],
         "weird",
     )
     app.config["TIME_GRAIN_ADDON_EXPRESSIONS"] = {}
    def test_column_datatype_to_string(self):
        test_cases = (
            (DATE(), "DATE"),
            (VARCHAR(length=255), "VARCHAR(255)"),
            (
                VARCHAR(length=255, charset="latin1", collation="utf8mb4_general_ci"),
                "VARCHAR(255)",
            ),
            (NVARCHAR(length=128), "NATIONAL VARCHAR(128)"),
            (TEXT(), "TEXT"),
        )

        for original, expected in test_cases:
            actual = MySQLEngineSpec.column_datatype_to_string(
                original, mysql.dialect()
            )
            self.assertEqual(actual, expected)
Exemple #7
0
 def test_get_time_grain_expressions(self):
     time_grains = MySQLEngineSpec.get_time_grain_expressions()
     self.assertEqual(
         list(time_grains.keys()),
         [
             None,
             "PT1S",
             "PT1M",
             "PT1H",
             "P1D",
             "P1W",
             "P1M",
             "P3M",
             "P1Y",
             "1969-12-29T00:00:00Z/P1W",
         ],
     )
Exemple #8
0
def test_get_time_grain_with_unkown_values():
    """Should concatenate from configs and then sort in the proper order
    putting unknown patterns at the end"""
    config = app.config.copy()

    app.config["TIME_GRAIN_ADDON_EXPRESSIONS"] = {
        "mysql": {
            "PT2H": "foo",
            "weird": "foo",
            "PT12H": "foo",
        }
    }

    with app.app_context():
        time_grains = MySQLEngineSpec.get_time_grain_expressions()
        assert list(time_grains)[-1] == "weird"

    app.config = config
Exemple #9
0
def test_get_time_grain_with_config():
    """Should concatenate from configs and then sort in the proper order"""
    config = app.config.copy()

    app.config["TIME_GRAIN_ADDON_EXPRESSIONS"] = {
        "mysql": {
            "PT2H": "foo",
            "PT4H": "foo",
            "PT6H": "foo",
            "PT8H": "foo",
            "PT10H": "foo",
            "PT12H": "foo",
            "PT1S": "foo",
        }
    }

    with app.app_context():
        time_grains = MySQLEngineSpec.get_time_grain_expressions()
        assert set(time_grains.keys()) == {
            None,
            "PT1S",
            "PT1M",
            "PT1H",
            "PT2H",
            "PT4H",
            "PT6H",
            "PT8H",
            "PT10H",
            "PT12H",
            "P1D",
            "P1W",
            "P1M",
            "P3M",
            "P1Y",
            "1969-12-29T00:00:00Z/P1W",
        }

    app.config = config
 def test_get_time_grain_with_config(self):
     """ Should concatenate from configs and then sort in the proper order """
     app.config["TIME_GRAIN_ADDON_EXPRESSIONS"] = {
         "mysql": {
             "PT2H": "foo",
             "PT4H": "foo",
             "PT6H": "foo",
             "PT8H": "foo",
             "PT10H": "foo",
             "PT12H": "foo",
             "PT1S": "foo",
         }
     }
     time_grains = MySQLEngineSpec.get_time_grain_expressions()
     self.assertEqual(
         list(time_grains.keys()),
         [
             None,
             "PT1S",
             "PT1M",
             "PT1H",
             "PT2H",
             "PT4H",
             "PT6H",
             "PT8H",
             "PT10H",
             "PT12H",
             "P1D",
             "P1W",
             "P1M",
             "P0.25Y",
             "P1Y",
             "1969-12-29T00:00:00Z/P1W",
         ],
     )
     app.config["TIME_GRAIN_ADDON_EXPRESSIONS"] = {}
Exemple #11
0
 def test_get_datatype_mysql(self):
     """Tests related to datatype mapping for MySQL"""
     self.assertEqual("TINY", MySQLEngineSpec.get_datatype(1))
     self.assertEqual("VARCHAR", MySQLEngineSpec.get_datatype(15))
Exemple #12
0
    def test_extract_errors(self):
        """
        Test that custom error messages are extracted correctly.
        """
        msg = "mysql: Access denied for user 'test'@'testuser.com'"
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.CONNECTION_ACCESS_DENIED_ERROR,
                message=
                'Either the username "test" or the password is incorrect.',
                level=ErrorLevel.ERROR,
                extra={
                    "invalid": ["username", "password"],
                    "engine_name":
                    "MySQL",
                    "issue_codes": [
                        {
                            "code":
                            1014,
                            "message":
                            "Issue 1014 - Either the"
                            " username or the password is wrong.",
                        },
                        {
                            "code":
                            1015,
                            "message":
                            "Issue 1015 - Either the database is "
                            "spelled incorrectly or does not exist.",
                        },
                    ],
                },
            )
        ]

        msg = "mysql: Unknown MySQL server host 'badhostname.com'"
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.CONNECTION_INVALID_HOSTNAME_ERROR,
                message='Unknown MySQL server host "badhostname.com".',
                level=ErrorLevel.ERROR,
                extra={
                    "invalid": ["host"],
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        1007,
                        "message":
                        "Issue 1007 - The hostname"
                        " provided can't be resolved.",
                    }],
                },
            )
        ]

        msg = "mysql: Can't connect to MySQL server on 'badconnection.com'"
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.CONNECTION_HOST_DOWN_ERROR,
                message='The host "badconnection.com" might be '
                "down and can't be reached.",
                level=ErrorLevel.ERROR,
                extra={
                    "invalid": ["host", "port"],
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        1007,
                        "message":
                        "Issue 1007 - The hostname provided"
                        " can't be resolved.",
                    }],
                },
            )
        ]

        msg = "mysql: Can't connect to MySQL server on '93.184.216.34'"
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.CONNECTION_HOST_DOWN_ERROR,
                message=
                'The host "93.184.216.34" might be down and can\'t be reached.',
                level=ErrorLevel.ERROR,
                extra={
                    "invalid": ["host", "port"],
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        10007,
                        "message":
                        "Issue 1007 - The hostname provided "
                        "can't be resolved.",
                    }],
                },
            )
        ]

        msg = "mysql: Unknown database 'badDB'"
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        print(result)
        assert result == [
            SupersetError(
                message='Unable to connect to database "badDB".',
                error_type=SupersetErrorType.CONNECTION_UNKNOWN_DATABASE_ERROR,
                level=ErrorLevel.ERROR,
                extra={
                    "invalid": ["database"],
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        1015,
                        "message":
                        "Issue 1015 - Either the database is spelled incorrectly or does not exist.",
                    }],
                },
            )
        ]
Exemple #13
0
 def test_cancel_query(self, engine_mock):
     query = Query()
     cursor_mock = engine_mock.return_value.__enter__.return_value
     assert MySQLEngineSpec.cancel_query(cursor_mock, query, 123) is True
Exemple #14
0
    def test_extract_errors(self):
        """
        Test that custom error messages are extracted correctly.
        """
        msg = "mysql: Access denied for user 'test'@'testuser.com'. "
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.
                TEST_CONNECTION_ACCESS_DENIED_ERROR,
                message=
                'Either the username "test" or the password is incorrect.',
                level=ErrorLevel.ERROR,
                extra={
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        1014,
                        "message":
                        "Issue 1014 - Either the username or the password is wrong.",
                    }],
                },
            )
        ]

        msg = "mysql: Unknown MySQL server host 'badhostname.com'. "
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.
                TEST_CONNECTION_INVALID_HOSTNAME_ERROR,
                message='Unknown MySQL server host "badhostname.com".',
                level=ErrorLevel.ERROR,
                extra={
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        1007,
                        "message":
                        "Issue 1007 - The hostname provided can't be resolved.",
                    }],
                },
            )
        ]

        msg = "mysql: Can't connect to MySQL server on 'badconnection.com'."
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.TEST_CONNECTION_HOST_DOWN_ERROR,
                message=
                'The host "badconnection.com" might be down and can\'t be reached.',
                level=ErrorLevel.ERROR,
                extra={
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        1007,
                        "message":
                        "Issue 1007 - The hostname provided can't be resolved.",
                    }],
                },
            )
        ]

        msg = "mysql: Can't connect to MySQL server on '93.184.216.34'."
        result = MySQLEngineSpec.extract_errors(Exception(msg))
        assert result == [
            SupersetError(
                error_type=SupersetErrorType.TEST_CONNECTION_HOST_DOWN_ERROR,
                message=
                'The host "93.184.216.34" might be down and can\'t be reached.',
                level=ErrorLevel.ERROR,
                extra={
                    "engine_name":
                    "MySQL",
                    "issue_codes": [{
                        "code":
                        10007,
                        "message":
                        "Issue 1007 - The hostname provided can't be resolved.",
                    }],
                },
            )
        ]
Exemple #15
0
 def test_get_datatype(self):
     self.assertEquals('STRING', PrestoEngineSpec.get_datatype('string'))
     self.assertEquals('TINY', MySQLEngineSpec.get_datatype(1))
     self.assertEquals('VARCHAR', MySQLEngineSpec.get_datatype(15))
     self.assertEquals('VARCHAR', BaseEngineSpec.get_datatype('VARCHAR'))
Exemple #16
0
 def test_cancel_query_failed(self, engine_mock):
     query = Query()
     cursor_mock = engine_mock.raiseError.side_effect = Exception()
     assert MySQLEngineSpec.cancel_query(cursor_mock, query, 123) is False
 def test_get_datatype_mysql(self):
     self.assertEquals("TINY", MySQLEngineSpec.get_datatype(1))
     self.assertEquals("VARCHAR", MySQLEngineSpec.get_datatype(15))
Exemple #18
0
 def test_get_cancel_query_id(self, engine_mock):
     query = Query()
     cursor_mock = engine_mock.return_value.__enter__.return_value
     cursor_mock.fetchone.return_value = [123]
     assert MySQLEngineSpec.get_cancel_query_id(cursor_mock, query) == 123