Exemple #1
0
    def test_pools_are_not_shared(self):
        settings = tests.get_mysqlx_config()
        pooling_dict = {"max_size": 1, "max_idle_time": 0,}
        cnx_options = {"pooling": pooling_dict}
        uri = ("mysqlx://{user}:{pwd}@["
               " (address={host}:{port}, priority=50)]"
               "".format(user=self.user, pwd=self.password,
                         host=settings["host"], port=settings["port"]))
        client1 = mysqlx.get_client(uri, cnx_options)

        # Getting a session from client1
        session1 = client1.get_session()
        session1.sql("SELECT 1").execute()
        session1.get_schema(settings["schema"])

        # Getting a session from client2
        client2 = mysqlx.get_client(uri, cnx_options)
        # Getting a session must success, the higher priority will cause to a
        # valid address to be used
        session2 = client2.get_session()
        session2.sql("SELECT 2").execute()

        # Verify the server connections
        connections = get_current_connections(self.session)
        open_connections = connections.get(self.user, -1)
        self.assertEqual(len(open_connections), 2)

        # Closing pools in client1 must not close connections in client2
        client1.close()
        with self.assertRaises(mysqlx.errors.OperationalError):
            session1.sql("SELECT 1").execute()
        session2.sql("SELECT 2").execute()
        session2.get_schema(settings["schema"])

        client2.close()
    def test_pools_are_not_shared(self):
        settings = tests.get_mysqlx_config()
        pooling_dict = {"max_size": 1, "max_idle_time": 0,}
        cnx_options = {"pooling": pooling_dict}
        uri = ("mysqlx://{user}:{pwd}@["
               " (address={host}:{port}, priority=50)]"
               "".format(user=self.user, pwd=self.password,
                         host=settings["host"], port=settings["port"]))
        client1 = mysqlx.get_client(uri, cnx_options)

        # Getting a session from client1
        session1 = client1.get_session()
        session1.sql("SELECT 1").execute()
        session1.get_schema(settings["schema"])

        # Getting a session from client2
        client2 = mysqlx.get_client(uri, cnx_options)
        # Getting a session must success, the higher priority will cause to a
        # valid address to be used
        session2 = client2.get_session()
        session2.sql("SELECT 2").execute()

        # Verify the server connections
        connections = get_current_connections(self.session)
        open_connections = connections.get(self.user, -1)
        self.assertEqual(len(open_connections), 2)

        # Closing pools in client1 must not close connections in client2
        client1.close()
        with self.assertRaises(mysqlx.errors.OperationalError):
            session1.sql("SELECT 1").execute()
        session2.sql("SELECT 2").execute()
        session2.get_schema(settings["schema"])

        client2.close()
    def test_get_default_schema(self):
        pooling_dict = {
            "max_size": 1,
            "max_idle_time": 3000,
            "queue_timeout": 1000
        }
        # Test None value is returned if no schema name is specified
        settings = self.connect_kwargs.copy()
        settings.pop("schema")
        client = mysqlx.get_client(settings, pooling_dict)
        session = client.get_session()
        schema = session.get_default_schema()
        self.assertIsNone(
            schema, "None value was expected but got '{}'".format(schema))
        session.close()

        # Test SQL statements not fully qualified, which must not raise error:
        #     mysqlx.errors.OperationalError: No database selected
        self.session.sql('CREATE DATABASE my_test_schema').execute()
        self.session.sql(
            'CREATE TABLE my_test_schema.pets(name VARCHAR(20))').execute()
        settings = self.connect_kwargs.copy()
        settings["schema"] = "my_test_schema"

        client = mysqlx.get_client(settings, pooling_dict)
        session = client.get_session()
        schema = session.get_default_schema()
        self.assertTrue(schema, mysqlx.Schema)
        self.assertEqual(schema.get_name(), "my_test_schema")
        result = session.sql('SHOW TABLES').execute().fetch_all()
        self.assertEqual("pets", result[0][0])
        self.session.sql('DROP DATABASE my_test_schema').execute()
        self.assertFalse(schema.exists_in_database())
        self.assertRaises(mysqlx.ProgrammingError, session.get_default_schema)
        session.close()
        client.close()

        # Test without default schema configured at connect time (passing None)
        settings = self.connect_kwargs.copy()
        settings["schema"] = None
        client = mysqlx.get_client(settings, pooling_dict)
        session = client.get_session()
        schema = session.get_default_schema()
        self.assertIsNone(
            schema, "None value was expected but got '{}'".format(schema))
        session.close()
        client.close()

        # Test not existing default schema at get_session raise error
        settings = self.connect_kwargs.copy()
        settings["schema"] = "nonexistent"
        client = mysqlx.get_client(settings, pooling_dict)
        self.assertRaises(InterfaceError, client.get_session)
    def test_get_default_schema(self):
        pooling_dict = {"max_size": 1, "max_idle_time": 3000,
                        "queue_timeout": 1000}
        # Test None value is returned if no schema name is specified
        settings = self.connect_kwargs.copy()
        settings.pop("schema")
        client = mysqlx.get_client(settings, pooling_dict)
        session = client.get_session()
        schema = session.get_default_schema()
        self.assertIsNone(schema,
                          "None value was expected but got '{}'".format(schema))
        session.close()

        # Test SQL statements not fully qualified, which must not raise error:
        #     mysqlx.errors.OperationalError: No database selected
        self.session.sql('CREATE DATABASE my_test_schema').execute()
        self.session.sql('CREATE TABLE my_test_schema.pets(name VARCHAR(20))'
                         ).execute()
        settings = self.connect_kwargs.copy()
        settings["schema"] = "my_test_schema"

        client = mysqlx.get_client(settings, pooling_dict)
        session = client.get_session()
        schema = session.get_default_schema()
        self.assertTrue(schema, mysqlx.Schema)
        self.assertEqual(schema.get_name(),
                         "my_test_schema")
        result = session.sql('SHOW TABLES').execute().fetch_all()
        self.assertEqual("pets", result[0][0])
        self.session.sql('DROP DATABASE my_test_schema').execute()
        self.assertFalse(schema.exists_in_database())
        self.assertRaises(mysqlx.ProgrammingError, session.get_default_schema)
        session.close()
        client.close()

        # Test without default schema configured at connect time (passing None)
        settings = self.connect_kwargs.copy()
        settings["schema"] = None
        client = mysqlx.get_client(settings, pooling_dict)
        session = client.get_session()
        schema = session.get_default_schema()
        self.assertIsNone(schema,
                          "None value was expected but got '{}'".format(schema))
        session.close()
        client.close()

        # Test not existing default schema at get_session raise error
        settings = self.connect_kwargs.copy()
        settings["schema"] = "nonexistent"
        client = mysqlx.get_client(settings, pooling_dict)
        self.assertRaises(InterfaceError, client.get_session)
    def setUp(self):
        self.connect_kwargs = tests.get_mysqlx_config()
        self.schema_name = self.connect_kwargs["schema"]
        try:
            self.client = mysqlx.get_client(self.connect_kwargs, "{}")
            self.session = self.client.get_session()
        except mysqlx.Error as err:
            self.fail("{0}".format(err))

        if os.name == "nt":
            if "64" in platform.architecture()[0]:
                self.platform_arch = "x86_64"
            elif "32" in platform.architecture()[0]:
                self.platform_arch = "i386"
            else:
                self.platform_arch = platform.architecture()
            self.os_ver = "Windows-{}".format(platform.win32_ver()[1])
        else:
            self.platform_arch = platform.machine()
            if platform.system() == "Darwin":
                self.os_ver = "{}-{}".format("macOS", platform.mac_ver()[0])
            else:
                self.os_ver = "-".join(platform.linux_distribution()[0:2])

        license_chunks = LICENSE.split(" ")
        if license_chunks[0] == "GPLv2":
            self.client_license = "GPL-2.0"
        else:
            self.client_license = "Commercial"
def get_finance_income_df(ts_code):

    config_path = join(abspath(dirname(__file__)), '../config.json')
    with open(config_path) as json_file:
        connection_string = json.load(json_file)

    x_client = mysqlx.get_client(connection_string, client_options)
    session = x_client.get_session()
    schema = session.get_schema('stock')
    col = schema.get_collection('stock_x_fin_income')
    query = "tsCode = :tscode"
    params = {"tscode": ts_code}

    docs = col.find(query) \
        .bind(params) \
        .execute()
    dailyDatas = docs.fetch_all()

    session.close()
    x_client.close()

    if len(dailyDatas) == 0:
        return None

    variables = dailyDatas[0].keys()
    names = []
    for v in variables:
        names.append(convert_to_underline(v))
    # print(names)
    df = pd.DataFrame([[getattr(i, j) for j in variables] for i in dailyDatas],
                      columns=names)
    return df
    def setUp(self):
        self.connect_kwargs = tests.get_mysqlx_config()
        self.schema_name = self.connect_kwargs["schema"]
        try:
            self.client = mysqlx.get_client(self.connect_kwargs, "{}")
            self.session = self.client.get_session()
        except mysqlx.Error as err:
            self.fail("{0}".format(err))

        if os.name == "nt":
            if "64" in platform.architecture()[0]:
                self.platform_arch = "x86_64"
            elif "32" in platform.architecture()[0]:
                self.platform_arch = "i386"
            else:
                self.platform_arch = platform.architecture()
            self.os_ver = "Windows-{}".format(platform.win32_ver()[1])
        else:
            self.platform_arch = platform.machine()
            if platform.system() == "Darwin":
                self.os_ver = "{}-{}".format("macOS", platform.mac_ver()[0])
            else:
                self.os_ver = "-".join(linux_distribution()[0:2])

        license_chunks = LICENSE.split(" ")
        if license_chunks[0] == "GPLv2":
            self.client_license = "GPL-2.0"
        else:
            self.client_license = "Commercial"
Exemple #8
0
    def __init__(self, db_name, conn_options=None):
        self._database_name = db_name

        self._client = mysqlx.get_client(
            {
                'host': environ['HOST'],
                'port': environ['PORT'],
                'user': environ['USER'],
                'password': environ['PASSWORD']
            }, conn_options if conn_options is not None else {})
    def test_get_session(self):
        """Test get_session() opens new connections."""
        # Auxiliary session to query server
        old_session = mysqlx.get_session(self.connect_kwargs.copy())
        # Setup a client to get sessions from
        settings = self.connect_kwargs.copy()
        pooling_dict = {"enabled": True, "max_idle_time": 3000}
        cnx_options = {"pooling": pooling_dict}
        settings["user"] = self.users[0][0]
        settings["password"] = self.users[0][1]
        settings["host"] = self.host
        settings.pop("socket")
        client = mysqlx.get_client(settings, cnx_options)

        # Get 10 sessions, client will start 10 connections
        total_connections = 10
        sessions = []
        for _ in range(0, total_connections):
            session = client.get_session()
            self.assertTrue(isinstance(session, mysqlx.connection.Session))
            sessions.append(session)
        sleep(0.5)
        # Verify the number of connections open in the server
        connections = get_current_connections(old_session)
        self.assertEqual(len(connections[self.users[0][0]]), total_connections)

        # Verify that clossing the session returns the connection
        # to the pool instead of being closed
        sessions[5].close()
        sessions[9].close()
        sleep(0.5)
        connections = get_current_connections(old_session)
        self.assertTrue(
            len(connections[self.users[0][0]]) >= (total_connections - 2))

        connections = get_current_connections(old_session)
        open_connections = connections.get("unauthenticated user", [])
        if tests.MYSQL_VERSION < (8, 0, 16):
            # Send reset message requires the user to re-authentificate
            # the connection user stays in unauthenticated user
            self.assertEqual(len(open_connections), 2)
        else:
            self.assertEqual(len(open_connections), 0)

        # Connections must be closed when client.close() is invoked
        # check len(pool) == total_connections
        client.close()
        sleep(3)
        # Verify the connections on the pool are closed
        connections = get_current_connections(old_session)
        open_connections = connections.get("self.users[0][0]", 0)
        self.assertEqual(open_connections, 0)
    def test_get_session(self):
        """Test get_session() opens new connections."""
        # Auxiliary session to query server
        old_session = mysqlx.get_session(self.connect_kwargs.copy())
        # Setup a client to get sessions from
        settings = self.connect_kwargs.copy()
        pooling_dict = {"enabled": True, "max_idle_time":3000}
        cnx_options = {"pooling": pooling_dict}
        settings["user"] = self.users[0][0]
        settings["password"] = self.users[0][1]
        settings["host"] = self.host
        settings.pop("socket")
        client = mysqlx.get_client(settings, cnx_options)

        # Get 10 sessions, client will start 10 connections
        total_connections = 10
        sessions = []
        for _ in range(0, total_connections):
            session = client.get_session()
            self.assertTrue(isinstance(session, mysqlx.connection.Session))
            sessions.append(session)
        sleep(0.5)
        # Verify the number of connections open in the server
        connections = get_current_connections(old_session)
        self.assertEqual(len(connections[self.users[0][0]]), total_connections)

        # Verify that clossing the session returns the connection
        # to the pool instead of being closed
        sessions[5].close()
        sessions[9].close()
        sleep(0.5)
        connections = get_current_connections(old_session)
        self.assertTrue(len(connections[self.users[0][0]]) >=
                        (total_connections - 2))

        connections = get_current_connections(old_session)
        open_connections = connections.get("unauthenticated user", [])
        if tests.MYSQL_VERSION < (8, 0, 16):
            # Send reset message requires the user to re-authentificate
            # the connection user stays in unauthenticated user
            self.assertEqual(len(open_connections), 2)
        else:
            self.assertEqual(len(open_connections), 0)

        # Connections must be closed when client.close() is invoked
        # check len(pool) == total_connections
        client.close()
        sleep(3)
        # Verify the connections on the pool are closed
        connections = get_current_connections(old_session)
        open_connections = connections.get("self.users[0][0]", 0)
        self.assertEqual(open_connections, 0)
Exemple #11
0
    def __init__(self):
        config_path = join(abspath(dirname(__file__)), '../config.json')
        with open(config_path) as json_file:
            conf_dict = json.load(json_file)
            conf_mysql = conf_dict['mysql']
            conf_tushare_token = conf_dict['tushareToken']

        ts.set_token(conf_tushare_token)
        self.pro = ts.pro_api()
        df = self.pro.stock_basic(exchange='', list_status='L')
        self.stock_df = df

        self.x_client = mysqlx.get_client(conf_mysql, client_options)
    def test_max_pool_size(self):
        """Test exausted pool behavior"""
        # Initial pool limit size
        pool_limit = 5
        # Setup a client to get sessions from.
        settings = self.connect_kwargs.copy()
        pooling_dict = {
            "enabled": True,
            "max_idle_time": 10000,
            "queue_timeout": 3000,
            "max_size": pool_limit,  # initial pool limit
        }
        cnx_options = {"pooling": pooling_dict}
        settings["user"] = self.users[1][0]
        settings["password"] = self.users[1][1]
        settings["host"] = self.host
        settings.pop("socket")
        client = mysqlx.get_client(settings, cnx_options)

        # Get sessions as in pool_limit
        sessions = []
        last_session = None
        for _ in range(0, pool_limit):
            session = client.get_session()
            self.assertTrue(isinstance(session, mysqlx.connection.Session))
            sessions.append(session)
            last_session = session
        self.assertEqual(len(sessions), pool_limit)

        # Verify the server has open sessions as in pool_limit
        connections = get_current_connections(self.session)
        open_connections = connections.get(self.users[1][0], -1)
        self.assertEqual(len(open_connections), pool_limit)

        # verify exception is raised if the pool is exausted
        with self.assertRaises(mysqlx.errors.PoolError):
            client.get_session()

        # Verify that closing the last open session is returned to the pool
        # so then can be retrieved again, which is only possibble after the
        # pool has become available one more time (timeout has been reached).
        last_session.close()
        sleep(3)
        _ = client.get_session()
        client.close()

        # verify all sessions are closed
        for session in sessions:
            with self.assertRaises(mysqlx.errors.OperationalError):
                session.sql("SELECT 1").execute()
            session.get_schema(settings["schema"])
 def test_context_manager(self):
     """Test mysqlx.get_client() context manager."""
     settings = self.connect_kwargs.copy()
     pooling_dict = {"enabled": True, "max_size": 5}
     cnx_options = {"pooling": pooling_dict}
     with mysqlx.get_client(settings, cnx_options) as client:
         with client.get_session() as session:
             self.assertIsInstance(session, mysqlx.Session)
             self.assertTrue(session.is_open())
         self.assertFalse(session.is_open())
         # Create one more session
         _ = client.get_session()
     for session in client.sessions:
         self.assertFalse(session.is_open())
    def test_max_pool_size(self):
        """Test exausted pool behavior"""
        # Initial pool limit size
        pool_limit = 5
        # Setup a client to get sessions from.
        settings = self.connect_kwargs.copy()
        pooling_dict = {
            "enabled": True,
            "max_idle_time": 2,
            "queue_timeout": 2000,
            "max_size": pool_limit,  # initial pool limit
        }
        cnx_options = {"pooling": pooling_dict}
        settings["user"] = self.users[1][0]
        settings["password"] = self.users[1][1]
        settings["host"] = self.host
        settings.pop("socket")
        client = mysqlx.get_client(settings, cnx_options)

        # Get sessions as in pool_limit
        sessions = []
        last_session = None
        for _ in range(0, pool_limit):
            session = client.get_session()
            self.assertTrue(isinstance(session, mysqlx.connection.Session))
            sessions.append(session)
            last_session = session
        self.assertEqual(len(sessions), pool_limit)

        # Verify the server has open sessions as in pool_limit
        connections = get_current_connections(self.session)
        open_connections = connections.get(self.users[1][0], -1)
        self.assertEqual(len(open_connections), pool_limit)

        # verify exception is raised if the pool is exausted
        with self.assertRaises(mysqlx.errors.PoolError):
            client.get_session()

        # Verify that closing the last open session is returned to the pool
        # so then can be retrieved again.
        last_session.close()
        _ = client.get_session()
        client.close()

        # verify all sessions are closed
        for session in sessions:
            with self.assertRaises(mysqlx.errors.OperationalError):
                session.sql("SELECT 1").execute()
            session.get_schema(settings["schema"])
 def test_routing(self):
     settings = tests.get_mysqlx_config()
     pooling_dict = {"enabled": True}
     cnx_options = {"pooling": pooling_dict}
     uri = ("mysqlx://{user}:{pwd}@[(address=1.0.0.2:{port}, priority=30),"
            " (address=1.0.0.1:{port}, priority=40),"
            " (address=127.0.0.1:{port}, priority=80),"
            " (address=localhost:{port}, priority=50)]"
            "".format(user=settings["user"], pwd=settings["password"],
                      port=settings["port"]))
     client = mysqlx.get_client(uri, cnx_options)
     # Getting a session must success, the higher priority will cause to a
     # valid address to be used
     client.get_session()
     client.close()
Exemple #16
0
 def test_routing(self):
     settings = tests.get_mysqlx_config()
     pooling_dict = {"enabled": True}
     cnx_options = {"pooling": pooling_dict}
     uri = ("mysqlx://{user}:{pwd}@[(address=1.0.0.2:{port}, priority=30),"
            " (address=1.0.0.1:{port}, priority=40),"
            " (address=127.0.0.1:{port}, priority=80),"
            " (address=localhost:{port}, priority=50)]"
            "".format(user=settings["user"], pwd=settings["password"],
                      port=settings["port"]))
     client = mysqlx.get_client(uri, cnx_options)
     # Getting a session must success, the higher priority will cause to a
     # valid address to be used
     client.get_session()
     client.close()
    def test_pools_recycle(self):
        settings = tests.get_mysqlx_config()
        pooling_dict = {
            "max_size": 1,
            "max_idle_time": 3000,
            "queue_timeout": 1000
        }
        cnx_options = {"pooling": pooling_dict}
        uri = ("mysqlx://{user}:{pwd}@["
               " (address={host}:{port}, priority=50)]?connect_timeout=20000"
               "".format(user=self.user,
                         pwd=self.password,
                         host=settings["host"],
                         port=settings["port"]))
        client = mysqlx.get_client(uri, cnx_options)

        def thread1(client):
            # Getting a session from client
            session1 = client.get_session()
            session1.sql("SELECT 1").execute()
            sleep(2)
            session1.close()

        def thread2(client):
            # Getting a session from client
            session2 = client.get_session()
            session2.sql("SELECT 2").execute()
            sleep(1)
            session2.close()

        worker1 = Thread(target=thread1, args=[client])
        worker1.start()
        worker1.join()
        sleep(0.5)
        worker2 = Thread(target=thread2, args=[client])
        worker2.start()
        worker2.join()
        # Verify the server connections
        connections = get_current_connections(self.session)
        open_connections = connections.get("unauthenticated user", [])
        if tests.MYSQL_VERSION < (8, 0, 16):
            # Send reset message requires the user to re-authentificate
            # the connection user stays in unauthenticated user
            self.assertTrue(len(open_connections) >= 1)
        else:
            self.assertEqual(len(open_connections), 0)

        client.close()
    def test_pooling(self):
        """Test pooled Session works as a normal Session."""
        settings = self.connect_kwargs.copy()
        pooling_dict = {"enabled": True}
        cnx_options = {"pooling": pooling_dict}
        client = mysqlx.get_client(settings, cnx_options)

        session = client.get_session()
        session.get_schema(settings["schema"])
        session.close()
        # Verify that clossing the session again does not raise eceptions
        session.close()
        # Verify that trying to use a closed session raises error
        with self.assertRaises(mysqlx.errors.OperationalError):
            session.sql("SELECT 1").execute()
        client.close()
        # Verify that clossing the client again does not raise eceptions
        client.close()
    def test_pooling(self):
        """Test pooled Session works as a normal Session."""
        settings = self.connect_kwargs.copy()
        pooling_dict = {"enabled": True}
        cnx_options = {"pooling": pooling_dict}
        client = mysqlx.get_client(settings, cnx_options)

        session = client.get_session()
        session.get_schema(settings["schema"])
        session.close()
        # Verify that clossing the session again does not raise eceptions
        session.close()
        # Verify that trying to use a closed session raises error
        with self.assertRaises(mysqlx.errors.OperationalError):
            session.sql("SELECT 1").execute()
        client.close()
        # Verify that clossing the client again does not raise eceptions
        client.close()
    def test_pools_recycle(self):
        settings = tests.get_mysqlx_config()
        pooling_dict = {"max_size": 1, "max_idle_time": 3000,
                        "queue_timeout": 1000}
        cnx_options = {"pooling": pooling_dict}
        uri = ("mysqlx://{user}:{pwd}@["
               " (address={host}:{port}, priority=50)]?connect_timeout=20000"
               "".format(user=self.user, pwd=self.password,
                         host=settings["host"], port=settings["port"]))
        client = mysqlx.get_client(uri, cnx_options)

        def thread1(client):
            # Getting a session from client
            session1 = client.get_session()
            session1.sql("SELECT 1").execute()
            sleep(2)
            session1.close()

        def thread2(client):
            # Getting a session from client
            session2 = client.get_session()
            session2.sql("SELECT 2").execute()
            sleep(1)
            session2.close()

        worker1 = Thread(target=thread1, args=[client])
        worker1.start()
        worker1.join()
        sleep(0.5)
        worker2 = Thread(target=thread2, args=[client])
        worker2.start()
        worker2.join()
        # Verify the server connections
        connections = get_current_connections(self.session)
        open_connections = connections.get("unauthenticated user", [])
        if tests.MYSQL_VERSION < (8, 0, 16):
            # Send reset message requires the user to re-authentificate
            # the connection user stays in unauthenticated user
            self.assertTrue(len(open_connections) >= 1)
        else:
            self.assertEqual(len(open_connections), 0)

        client.close()
    def test_reset_keeps_same_id(self):
        """Test pooled Session keeps the same session id."""
        settings = self.connect_kwargs.copy()
        pooling_dict = {"enabled": True, "max_size":1}
        cnx_options = {"pooling": pooling_dict}
        client = mysqlx.get_client(settings, cnx_options)

        session1 = client.get_session()
        conn_id1 = session1.sql("select connection_id()"
                               ).execute().fetch_all()[0][0]
        session1.close()
        # Verify that new session is has the same id from previous one
        session2 = client.get_session()
        conn_id2 = session2.sql("select connection_id()"
                               ).execute().fetch_all()[0][0]
        self.assertEqual(conn_id1, conn_id2,
                         "The connection id was not the same")
        session2.close()
        client.close()
    def test_reset_keeps_same_id(self):
        """Test pooled Session keeps the same session id."""
        settings = self.connect_kwargs.copy()
        pooling_dict = {"enabled": True, "max_size": 1}
        cnx_options = {"pooling": pooling_dict}
        client = mysqlx.get_client(settings, cnx_options)

        session1 = client.get_session()
        conn_id1 = session1.sql(
            "select connection_id()").execute().fetch_all()[0][0]
        session1.close()
        # Verify that new session is has the same id from previous one
        session2 = client.get_session()
        conn_id2 = session2.sql(
            "select connection_id()").execute().fetch_all()[0][0]
        self.assertEqual(conn_id1, conn_id2,
                         "The connection id was not the same")
        session2.close()
        client.close()
    def test_connection_attributes(self):
        # Validate an error is raised if URL user defined connection attributes
        # through a connection URL name is duplicate
        connection_attributes = {
            "foo": "bar",
            "repeated": "attribute",
            "baz": "zoom",
        }
        uri = build_uri(user=self.connect_kwargs["user"],
                        password=self.connect_kwargs["password"],
                        host=self.connect_kwargs["host"],
                        port=self.connect_kwargs["port"],
                        schema=self.connect_kwargs["schema"],
                        connection_attributes=connection_attributes)
        uri = "{},repeated=duplicate_attribute]".format(uri[0:-1])

        with self.assertRaises(InterfaceError) as context:
            my_client = mysqlx.get_client(uri, "{}")
            _ = my_client.get_session()

        self.assertTrue('Duplicate key ' in context.exception.msg,
                        "error found: {}".format(context.exception.msg))

        # Test error is raised for attribute name starting with '_'
        connection_attributes = [{
            "foo": "bar",
            "_baz": "zoom"
        }, {
            "_baz": "zoom"
        }, {
            "foo": "bar",
            "_baz": "zoom",
            "puuuuum": "kaplot"
        }]
        for conn_attr in connection_attributes:
            connect_kwargs = self.connect_kwargs.copy()
            connect_kwargs["connection_attributes"] = conn_attr
            with self.assertRaises(InterfaceError) as context:
                my_client = mysqlx.get_client(connect_kwargs, "{}")
                _ = my_client.get_session()

            self.assertTrue("connection-attributes" in context.exception.msg)
            self.assertTrue("cannot start with '_'" in context.exception.msg)

        # Test error is raised for attribute name size exceeds 32 characters
        connection_attributes = [{
            "foo": "bar",
            "p{}w".format("o" * 31): "kaplot"
        }, {
            "p{}w".format("o" * 31): "kaplot"
        }, {
            "baz": "zoom",
            "p{}w".format("o" * 31): "kaplot",
            "a": "b"
        }]
        for conn_attr in connection_attributes:
            connect_kwargs = self.connect_kwargs.copy()
            connect_kwargs["connection_attributes"] = conn_attr
            with self.assertRaises(InterfaceError) as context:
                my_client = mysqlx.get_client(connect_kwargs, "{}")
                _ = my_client.get_session()

            self.assertTrue(
                "exceeds 32 characters limit size" in context.exception.msg)

        # Test error is raised for attribute value size exceeds 1024 characters
        connection_attributes = [{
            "foo": "bar",
            "pum": "kr{}nk".format("u" * 1024)
        }, {
            "pum": "kr{}nk".format("u" * 1024)
        }, {
            "baz": "zoom",
            "pum": "kr{}nk".format("u" * 1024),
            "a": "b"
        }]
        for conn_attr in connection_attributes:
            connect_kwargs = self.connect_kwargs.copy()
            connect_kwargs["connection-attributes"] = conn_attr
            with self.assertRaises(InterfaceError) as context:
                my_client = mysqlx.get_client(connect_kwargs, "{}")
                _ = my_client.get_session()

            self.assertTrue(
                "exceeds 1024 characters limit size" in context.exception.msg)

        # Validate the user defined attributes are created in the server
        # Test user defined connection attributes through a connection URL
        connection_attributes = {
            "foo": "bar",
            "baz": "zoom",
            "quash": "",
            "puuuuum": "kaplot"
        }
        uri = build_uri(user=self.connect_kwargs["user"],
                        password=self.connect_kwargs["password"],
                        host=self.connect_kwargs["host"],
                        port=self.connect_kwargs["port"],
                        schema=self.connect_kwargs["schema"],
                        connection_attributes=connection_attributes)

        # Verify user defined session-connection-attributes are in the server
        my_session = mysqlx.get_session(uri)
        row = my_session.sql("SHOW VARIABLES LIKE \"pseudo_thread_id\"").\
            execute().fetch_all()[0]
        get_attrs = ("SELECT ATTR_NAME, ATTR_VALUE FROM "
                     "performance_schema.session_account_connect_attrs "
                     "where PROCESSLIST_ID = \"{}\"")
        rows = my_session.sql(get_attrs.format(row.get_string('Value'))).\
            execute().fetch_all()
        expected_attrs = connection_attributes.copy()
        expected_attrs.update({
            "_pid":
            str(os.getpid()),
            "_platform":
            self.platform_arch,
            "_source_host":
            socket.gethostname(),
            "_client_name":
            "mysql-connector-python",
            "_client_license":
            self.client_license,
            "_client_version":
            ".".join([str(x) for x in VERSION[0:3]]),
            "_os":
            self.os_ver
        })
        # Note that for an empty string "" value the server stores a Null value
        expected_attrs["quash"] = "None"
        for row in rows:
            self.assertEqual(
                expected_attrs[row.get_string('ATTR_NAME')],
                row.get_string('ATTR_VALUE'),
                "Attribute {} with value {} differs of {}".format(
                    row.get_string('ATTR_NAME'), row.get_string('ATTR_VALUE'),
                    expected_attrs[row.get_string('ATTR_NAME')]))
    def test_routing_random(self):
        settings = tests.get_mysqlx_config()
        pooling_dict = {"enabled": True, "max_size": 5, 'queue_timeout': 1000}
        cnx_options = {"pooling": pooling_dict}
        uri = ("mysqlx://{user}:{pwd}@["
               "(address=1.0.0.1:{port}, priority=20),"
               " (address=1.0.0.2:{port}, priority=20),"
               " (address=127.0.0.1:{port}, priority=30),"
               " (address=localhost:{port}, priority=30),"
               " (address=1.0.0.3:{port}, priority=60),"
               " (address=1.0.0.4:{port}, priority=60)]"
               "".format(user=settings["user"],
                         pwd=settings["password"],
                         port=settings["port"]))
        client = mysqlx.get_client(uri, cnx_options)
        # Getting a session must success, the higher priority will cause to a
        # valid address to be used
        sessions = []
        for _ in range(10):
            session = client.get_session()
            sessions.append(session)
        client.close()

        # Test routers without priority
        settings = tests.get_mysqlx_config()
        pooling_dict = {"enabled": True, "max_size": 5, 'queue_timeout': 1000}
        cnx_options = {"pooling": pooling_dict}
        uri = ("mysqlx://{user}:{pwd}@["
               "(address=1.0.0.2:{port}),"
               " (address=1.0.0.1:{port}),"
               " (address=127.0.0.1:{port}),"
               " (address=localhost:{port}),"
               " (address=127.0.0.1:{port}),"
               " (address=localhost:{port})]"
               "".format(user=settings["user"],
                         pwd=settings["password"],
                         port=settings["port"]))
        client = mysqlx.get_client(uri, cnx_options)
        # Getting the total of 10 sessions must success
        sessions = []
        for _ in range(10):
            session = client.get_session()
            sessions.append(session)

        # verify error is thrown when the total sum of the pool sizes is reached
        with self.assertRaises(mysqlx.errors.PoolError) as context:
            _ = client.get_session()
        self.assertTrue(
            ("pool max size has been reached" in context.exception.msg),
            "Unexpected exception message found: {}"
            "".format(context.exception.msg))
        client.close()

        # Verify "Unable to connect to any of the target hosts" error message
        settings = tests.get_mysqlx_config()
        pooling_dict = {"enabled": True, "max_size": 5, 'queue_timeout': 50}
        cnx_options = {"pooling": pooling_dict}
        uri = ("mysqlx://{user}:{pwd}@["
               "(address=1.0.0.1:{port}),"
               " (address=1.0.0.2:{port}),"
               " (address=1.0.0.3:{port}),"
               " (address=1.0.0.4:{port}),"
               " (address=1.0.0.5:{port}),"
               " (address=1.0.0.6:{port}),"
               " (address=1.0.0.7:{port}),"
               " (address=1.0.0.8:{port}),"
               " (address=1.0.0.9:{port}),"
               " (address=1.0.0.10:{port})]?connect-timeout=500"
               "".format(user=settings["user"],
                         pwd=settings["password"] + "$%^",
                         port=settings["port"]))
        client = mysqlx.get_client(uri, cnx_options)
        with self.assertRaises(mysqlx.errors.PoolError) as context:
            _ = client.get_session()
        self.assertTrue(("Unable to connect to any of the target hosts"
                         in context.exception.msg),
                        "Unexpected exception message found: {}"
                        "".format(context.exception.msg))

        try:
            client.close()
        except:
            # due to the small connect-timeout closing the client may fail.
            pass
        # Verify random order of the pools
        ip_orders = {}
        attempts = 10
        for _ in range(attempts):
            client = mysqlx.get_client(uri, cnx_options)
            with self.assertRaises(mysqlx.errors.PoolError) as context:
                _ = client.get_session()

            re_ip = re.compile("  pool: 1.0.0.(\d+).*")
            order_list = []
            for line in context.exception.msg.splitlines():
                if "pool:" not in line:
                    continue
                match = re_ip.match(line)
                if match:
                    order_list.append(match.group(1))
            # Verify the 10 pools were verified
            self.assertEqual(
                len(order_list), 10,
                "10 exception messages were expected but found: {}"
                "".format(context.exception.msg))
            key = ",".join(order_list)
            if not key in ip_orders:
                ip_orders[key] = 1
            else:
                ip_orders[key] = ip_orders[key] + 1
            try:
                client.close()
            except:
                # due to the small connect-timeout closing the client may fail.
                pass
        max_repeated = -1
        for ip_order in ip_orders:
            cur = ip_orders[ip_order]
            max_repeated = cur if cur > max_repeated else max_repeated
        # The possiblility of getting 2 times the same order is : ((1/(10!))^2)*9
        # Getting the same number of different orders than attempts ensures no repetitions.
        self.assertEqual(
            len(ip_orders), attempts, "Expected less repetions found: {}"
            "".format([
                "ip_order: {} reps: {}".format(ip_order, ip_orders[ip_order])
                for ip_order in ip_orders
            ]))
Exemple #25
0
import mysqlx

# https://dev.mysql.com/doc/dev/connector-python/8.0/tutorials/getting_started.

connection_dict = {
    'host': 'localhost',
    'port': 2000,
    'user': '******',
    'password': '******'
}
options_dict = {}

client = mysqlx.get_client(connection_dict, options_dict)
mySession = client.get_session()

# mySession.sql("USE test").execute()
try:
    schemaList = mySession.get_schemas()

    mySession.sql("USE staging").execute()
    myResult = mySession.sql(
        "SELECT  id,sku_id,create_date FROM staging.orderProperties as op limit 10"
    ).execute()
    rows = myResult.fetch_all()
    for row in rows:
        print(list(row))

except Exception as e:
    print(e, "something went wrong")

finally:
    def test_get_client_with_tls_version(self):
        # Test None value is returned if no schema name is specified
        settings = self.connect_kwargs.copy()
        settings.pop("schema")
        settings.pop("socket")

        pooling_dict = {
            "enabled": True,
            "max_idle_time": 2000,
            "max_size": 3,
            "queue_timeout": 1000
        }
        cnx_options = {"pooling": pooling_dict}

        # Dictionary connection settings tests
        # Empty tls_version list
        settings["tls-ciphersuites"] = ["DHE-RSA-AES256-SHA"]
        settings["tls-versions"] = []
        with self.assertRaises(InterfaceError) as context:
            _ = mysqlx.get_client(settings, cnx_options)
        self.assertTrue(("At least one" in context.exception.msg),
                        "Unexpected "
                        "exception message found: {}"
                        "".format(context.exception.msg))

        # Empty tls_ciphersuites list
        settings["tls-ciphersuites"] = []
        settings["tls-versions"] = ["TLSv1"]
        with self.assertRaises(InterfaceError) as context:
            _ = mysqlx.get_client(settings, cnx_options)
        self.assertTrue(("No valid cipher" in context.exception.msg),
                        "Unexpected exception message found: {}"
                        "".format(context.exception.msg))

        # URI string connection settings tests
        # Empty tls_version list
        settings["tls-ciphersuites"] = ["DHE-RSA-AES256-SHA"]
        settings["tls-versions"] = []
        uri_settings = build_uri(**settings)
        with self.assertRaises(InterfaceError) as context:
            _ = mysqlx.get_client(uri_settings, cnx_options)
        self.assertTrue(("At least one" in context.exception.msg),
                        "Unexpected "
                        "exception message found: {}"
                        "".format(context.exception.msg))

        # Empty tls_ciphersuites list
        settings["tls-ciphersuites"] = []
        settings["tls-versions"] = ["TLSv1"]
        uri_settings = build_uri(**settings)
        with self.assertRaises(InterfaceError) as context:
            _ = mysqlx.get_client(uri_settings, cnx_options)
        self.assertTrue(("No valid cipher" in context.exception.msg),
                        "Unexpected exception message found: {}"
                        "".format(context.exception.msg))

        # Verify InterfaceError exception is raised With invalid TLS version
        settings["tls-ciphersuites"] = ["DHE-RSA-AES256-SHA"]
        settings["tls-versions"] = ["TLSv8"]
        uri_settings = build_uri(**settings)

        with self.assertRaises(InterfaceError) as context:
            _ = mysqlx.get_client(uri_settings, cnx_options)
        self.assertTrue(("not recognized" in context.exception.msg),
                        "Unexpected exception message found: {}"
                        "".format(context.exception.msg))

        # Verify unkown cipher suite case
        settings["tls-ciphersuites"] = ["NOT-KNOWN"]
        settings["tls-versions"] = ["TLSv1.2"]
        uri_settings = build_uri(**settings)
        with self.assertRaises(InterfaceError) as context:
            _ = mysqlx.get_client(uri_settings, cnx_options)

        # Verify unsupported TLSv1.3 version is ignored (connection success)
        # when is not supported, TLSv1.2 is used
        settings["tls-ciphersuites"] = ["DHE-RSA-AES256-SHA"]
        settings["tls-versions"] = ["TLSv1.3", "TLSv1.2"]
        uri_settings = build_uri(**settings)
        client = mysqlx.get_client(uri_settings, cnx_options)
        session = client.get_session()
        session.close()
        client.close()

        supported_tls = check_tls_versions_support(
            ["TLSv1.2", "TLSv1.1", "TLSv1"])
        if not supported_tls:
            self.fail("No TLS version to test: {}".format(supported_tls))
        if len(supported_tls) > 1:
            # Verify given TLS version is used
            settings["tls-ciphersuites"] = ["DHE-RSA-AES256-SHA"]
            for tes_ver in supported_tls:
                settings["tls-versions"] = [tes_ver]
                uri_settings = build_uri(**settings)
                client = mysqlx.get_client(uri_settings, cnx_options)
                session = client.get_session()
                res = session.sql("SHOW STATUS").execute().fetch_all()
                for row in res:
                    if row.get_string("Variable_name") == 'Mysqlx_ssl_version':
                        self.assertEqual(
                            row.get_string("Value"), tes_ver,
                            "Unexpected TLS version found: {} for: {}"
                            "".format(row.get_string("Value"), tes_ver))
                session.close()
                client.close()

        # Following tests requires TLSv1.2
        if tests.MYSQL_VERSION < (8, 0, 17):
            return

        if "TLSv1.1" in supported_tls:
            # Verify the newest TLS version is used from the given list
            exp_res = ["TLSv1.2", "TLSv1.1", "TLSv1.2"]
            test_vers = [["TLSv1", "TLSv1.2", "TLSv1.1"], ["TLSv1", "TLSv1.1"],
                         ["TLSv1.2", "TLSv1"]]
            for tes_ver, exp_ver in zip(test_vers, exp_res):
                settings["tls-versions"] = tes_ver
                uri_settings = build_uri(**settings)
                client = mysqlx.get_client(uri_settings, cnx_options)
                session = client.get_session()
                res = session.sql("SHOW STATUS").execute().fetch_all()
                for row in res:
                    if row.get_string('Variable_name') == 'Mysqlx_ssl_version':
                        self.assertEqual(
                            row.get_string('Value'), exp_ver,
                            "Unexpected TLS version found: {}"
                            "".format(row.get_string('Value')))
                session.close()
                client.close()

        # Verify given TLS cipher suite is used
        exp_res = [
            "DHE-RSA-AES256-SHA256", "DHE-RSA-AES256-SHA256",
            "DHE-RSA-AES128-GCM-SHA256"
        ]
        test_ciphers = [["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
                        ["DHE-RSA-AES256-SHA256"],
                        ["TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"]]
        settings["tls-versions"] = "TLSv1.2"
        for test_cipher, exp_ver in zip(test_ciphers, exp_res):
            settings["tls-ciphersuites"] = test_cipher
            uri_settings = build_uri(**settings)
            client = mysqlx.get_client(uri_settings, cnx_options)
            session = client.get_session()
            res = session.sql("SHOW STATUS").execute().fetch_all()
            for row in res:
                if row.get_string("Variable_name") == "Mysqlx_ssl_cipher":
                    self.assertEqual(
                        row.get_string("Value"), exp_ver,
                        "Unexpected TLS version found: {} for: {}"
                        "".format(row.get_string("Value"), test_cipher))
            session.close()
            client.close()

        # Verify one of TLS cipher suite is used from the given list
        exp_res = [
            "DHE-RSA-AES256-SHA256", "DHE-RSA-AES256-SHA256",
            "DHE-RSA-AES128-GCM-SHA256"
        ]
        test_ciphers = [
            "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "DHE-RSA-AES256-SHA256",
            "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
        ]
        settings["tls_ciphersuites"] = test_ciphers
        settings["tls_versions"] = "TLSv1.2"
        uri_settings = build_uri(**settings)
        client = mysqlx.get_client(uri_settings, cnx_options)
        session = client.get_session()
        res = session.sql("SHOW STATUS").execute().fetch_all()
        for row in res:
            if row.get_string("Variable_name") == "Mysqlx_ssl_cipher":
                self.assertIn(
                    row.get_string("Value"), exp_res,
                    "Unexpected TLS version found: {} not in {}"
                    "".format(row.get_string('Value'), exp_res))
        session.close()
        client.close()
    def test_reset_get_new_connection(self):
        """Test connection is closed by max idle time."""
        # Verify max_idle_time closses an idle session and so for the
        # connection id must increase due to the pool which has created a
        # new connection to the server to return a new session.
        settings = self.connect_kwargs.copy()
        pooling_dict = {
            "enabled": True,
            "max_idle_time": 2000,
            "max_size": 3,
            "queue_timeout": 1000,
        }
        cnx_options = {"pooling": pooling_dict}
        client = mysqlx.get_client(settings, cnx_options)

        # Getting session 0
        session0 = client.get_session()
        conn_id0 = session0.sql(
            "select connection_id()").execute().fetch_all()[0][0]
        # Closing session 0
        session0.close()

        # Getting session 1
        session1 = client.get_session()
        conn_id1 = session1.sql(
            "select connection_id()").execute().fetch_all()[0][0]
        # Closing session 1
        self.assertEqual(conn_id1, conn_id0,
                         "The connection id was not greater")

        session1.close()
        # Verify that new session does not has the same id from previous one
        # goint to sleep 2 sec just above the max idle time
        sleep(4)
        # Getting session 2
        session2 = client.get_session()
        conn_id2 = session2.sql(
            "select connection_id()").execute().fetch_all()[0][0]
        self.assertNotEqual(conn_id0, conn_id2,
                            "The connection id was the same from the old")
        self.assertNotEqual(conn_id1, conn_id2,
                            "The connection id was the same from the old")

        # Verify pool integrity
        # Open the 4th connection in client life time, when max size is 3
        # Getting the max allowed connections
        # Getting session 3
        session3 = client.get_session()
        conn_id3 = session3.sql(
            "select connection_id()").execute().fetch_all()[0][0]
        self.assertGreater(conn_id3, conn_id2,
                           "The connection id was not greater")

        # Getting session 4
        session4 = client.get_session()
        # Verify exception is raised if the pool is exausted
        with self.assertRaises(mysqlx.errors.PoolError):
            client.get_session()

        # closing all connections
        session2.close()
        session3.close()
        session4.close()
        # No errors should raise by closing it again
        session4.close()
        # No errors should raise from closing client.
        client.close()
    def test_reset_get_new_connection(self):
        """Test connection is closed by max idle time."""
        # Verify max_idle_time closses an idle session and so for the
        # connection id must increase due to the pool which has created a
        # new connection to the server to return a new session.
        settings = self.connect_kwargs.copy()
        pooling_dict = {"enabled": True, "max_idle_time": 2000, "max_size":3,
                        "queue_timeout": 1000,}
        cnx_options = {"pooling": pooling_dict}
        client = mysqlx.get_client(settings, cnx_options)

        # Getting session 0
        session0 = client.get_session()
        conn_id0 = session0.sql("select connection_id()"
                               ).execute().fetch_all()[0][0]
        # Closing session 0
        session0.close()

        # Getting session 1
        session1 = client.get_session()
        conn_id1 = session1.sql("select connection_id()"
                               ).execute().fetch_all()[0][0]
        # Closing session 1
        self.assertEqual(conn_id1, conn_id0,
                         "The connection id was not greater")

        session1.close()
        # Verify that new session does not has the same id from previous one
        # goint to sleep 2 sec just above the max idle time
        sleep(4)
        # Getting session 2
        session2 = client.get_session()
        conn_id2 = session2.sql("select connection_id()"
                               ).execute().fetch_all()[0][0]
        self.assertNotEqual(conn_id0, conn_id2,
                            "The connection id was the same from the old")
        self.assertNotEqual(conn_id1, conn_id2,
                            "The connection id was the same from the old")

        # Verify pool integrity
        # Open the 4th connection in client life time, when max size is 3
        # Getting the max allowed connections
        # Getting session 3
        session3 = client.get_session()
        conn_id3 = session3.sql("select connection_id()"
                               ).execute().fetch_all()[0][0]
        self.assertGreater(conn_id3, conn_id2,
                           "The connection id was not greater")

        # Getting session 4
        session4 = client.get_session()
        # Verify exception is raised if the pool is exausted
        with self.assertRaises(mysqlx.errors.PoolError):
            client.get_session()

        # closing all connections
        session2.close()
        session3.close()
        session4.close()
        # No errors should raise by closing it again
        session4.close()
        # No errors should raise from closing client.
        client.close()
    def test_get_client(self):
        """Test valid and invalid parameters of get_client()."""
        # Test invalid settings
        invalid_params = [(), (""), ({}), ("1", "2", "3"), ({}, {}, {})]
        for params in invalid_params:
            with self.assertRaises(TypeError,
                                   msg="with params {}".format(params)):
                mysqlx.get_client(*params)

        invalid_params = [
            ("", ""),
            ({}, {}),
        ]
        for params in invalid_params:
            with self.assertRaises(InterfaceError,
                                   msg="with params {}".format(params)):
                mysqlx.get_client(*params)

        settings = self.connect_kwargs.copy()
        # Raise error for invalid values for pooling option
        invalid_values = [
            False, True, "False", "true", "", -1, 0, 1, "1", None
        ]
        for value in invalid_values:
            cnx_options = {"pooling": value}
            with self.assertRaises(InterfaceError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Raise error for unrecognized settings for pooling option
        invalid_values = [{"max_pool_size": 100}, {"min_pool_size": "10"}]
        for value in invalid_values:
            pooling_dict = value
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(InterfaceError):
                mysqlx.get_client(settings, cnx_options)

        # Raise error for invalid values for max_size option
        invalid_values = [
            False, True, "False", "true", "", -1, 0, "1", None, {}, ()
        ]
        for value in invalid_values:
            pooling_dict = {"max_size": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for max_size option
        valid_values = [1, 100]
        for value in valid_values:
            pooling_dict = {"max_size": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.max_size, value)
            client.close()

        # Raise error for invalid values for max_idle_time option
        invalid_values = [
            False, True, "False", "true", "", -1, "1", None, {}, ()
        ]
        for value in invalid_values:
            pooling_dict = {"max_idle_time": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for max_idle_time option
        valid_values = [0, 1000, 10000]
        exp_values = [0, 1000, 10000]
        for indx_value in range(len(valid_values)):
            value = valid_values[indx_value]
            pooling_dict = {"max_idle_time": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.max_idle_time, exp_values[indx_value])
            client.close()

        # Raise error for invalid values for queue_timeout option
        invalid_values = [
            False, True, "False", "true", "", -1, "1", None, {}, ()
        ]
        for value in invalid_values:
            pooling_dict = {"queue_timeout": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for queue_timeout option
        valid_values = [0, 1000, 10000]
        exp_values = [0, 1000, 10000]
        for indx_value in range(len(valid_values)):
            value = valid_values[indx_value]
            pooling_dict = {"queue_timeout": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.queue_timeout, exp_values[indx_value])
            client.close()

        # Raise error for invalid values for enabled option
        invalid_values = ["False", "true", "", -1, 1.5, "0", "1", 0, 1, None]
        for value in invalid_values:
            pooling_dict = {"enabled": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for enabled option
        valid_values = [True, False]
        for value in valid_values:
            pooling_dict = {"enabled": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.pooling_enabled, value)
            client.close()

        # Test default values for pooling option
        for value in valid_values:
            pooling_dict = {}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.max_idle_time, 0)
            self.assertEqual(client.queue_timeout, 0)
            self.assertEqual(client.pooling_enabled, True)
            self.assertEqual(client.max_size, 25)
            client.close()
Exemple #30
0
 def createSessionPool(self, connection_str, options_str):
     self.clients = mysqlx.get_client(connection_str, options_str)
    def test_get_client(self):
        """Test valid and invalid parameters of get_client()."""
        # Test invalid settings
        invalid_params = [(), (""), ({}), ("1", "2", "3"), ({}, {}, {})]
        for params in invalid_params:
            with self.assertRaises(TypeError,
                                   msg="with params {}".format(params)):
                mysqlx.get_client(*params)

        invalid_params = [("", ""), ({}, {}),]
        for params in invalid_params:
            with self.assertRaises(InterfaceError,
                                   msg="with params {}".format(params)):
                mysqlx.get_client(*params)

        settings = self.connect_kwargs.copy()
        # Raise error for invalid values for pooling option
        invalid_values = [False, True, "False", "true", "", -1, 0, 1, "1", None]
        for value in invalid_values:
            cnx_options = {"pooling": value}
            with self.assertRaises(InterfaceError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Raise error for unrecognized settings for pooling option
        invalid_values = [{"max_pool_size": 100}, {"min_pool_size": "10"}]
        for value in invalid_values:
            pooling_dict = value
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(InterfaceError):
                mysqlx.get_client(settings, cnx_options)

        # Raise error for invalid values for max_size option
        invalid_values = [False, True, "False", "true", "", -1, 0, "1", None,
                          {}, ()]
        for value in invalid_values:
            pooling_dict = {"max_size": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for max_size option
        valid_values = [1, 100]
        for value in valid_values:
            pooling_dict = {"max_size": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.max_size, value)
            client.close()

        # Raise error for invalid values for max_idle_time option
        invalid_values = [False, True, "False", "true", "", -1, "1", None, {},
                          ()]
        for value in invalid_values:
            pooling_dict = {"max_idle_time": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for max_idle_time option
        valid_values = [0, 1000, 10000]
        exp_values = [0, 1000, 10000]
        for indx_value in range(len(valid_values)):
            value = valid_values[indx_value]
            pooling_dict = {"max_idle_time": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.max_idle_time, exp_values[indx_value])
            client.close()

        # Raise error for invalid values for queue_timeout option
        invalid_values = [False, True, "False", "true", "", -1, "1", None, {},
                          ()]
        for value in invalid_values:
            pooling_dict = {"queue_timeout": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for queue_timeout option
        valid_values = [0, 1000, 10000]
        exp_values = [0, 1000, 10000]
        for indx_value in range(len(valid_values)):
            value = valid_values[indx_value]
            pooling_dict = {"queue_timeout": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.queue_timeout, exp_values[indx_value])
            client.close()

        # Raise error for invalid values for enabled option
        invalid_values = ["False", "true", "", -1, 1.5, "0", "1", 0, 1, None]
        for value in invalid_values:
            pooling_dict = {"enabled": value}
            cnx_options = {"pooling": pooling_dict}
            with self.assertRaises(AttributeError,
                                   msg="with value {}".format(value)):
                mysqlx.get_client(settings, cnx_options)

        # Test valid values for enabled option
        valid_values = [True, False]
        for value in valid_values:
            pooling_dict = {"enabled": value}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.pooling_enabled, value)
            client.close()

        # Test default values for pooling option
        for value in valid_values:
            pooling_dict = {}
            cnx_options = {"pooling": pooling_dict}
            client = mysqlx.get_client(settings, cnx_options)
            self.assertEqual(client.max_idle_time, 0)
            self.assertEqual(client.queue_timeout, 0)
            self.assertEqual(client.pooling_enabled, True)
            self.assertEqual(client.max_size, 25)
            client.close()
    def test_connection_attributes(self):
        # Validate an error is raised if URL user defined connection attributes
        # through a connection URL name is duplicate
        connection_attributes = {
            "foo": "bar",
            "repeated": "attribute",
            "baz": "zoom",
        }
        uri = build_uri(user=self.connect_kwargs["user"],
                        password=self.connect_kwargs["password"],
                        host=self.connect_kwargs["host"],
                        port=self.connect_kwargs["port"],
                        schema=self.connect_kwargs["schema"],
                        connection_attributes=connection_attributes)
        uri = "{},repeated=duplicate_attribute]".format(uri[0:-1])

        with self.assertRaises(InterfaceError) as context:
            my_client = mysqlx.get_client(uri, "{}")
            _ = my_client.get_session()

        self.assertTrue('Duplicate key ' in context.exception.msg,
                        "error found: {}".format(context.exception.msg))

        # Test error is raised for attribute name starting with '_'
        connection_attributes = [
            {"foo": "bar", "_baz": "zoom"},
            {"_baz": "zoom"},
            {"foo": "bar", "_baz": "zoom", "puuuuum": "kaplot"}
        ]
        for conn_attr in connection_attributes:
            connect_kwargs = self.connect_kwargs.copy()
            connect_kwargs["connection_attributes"] = conn_attr
            with self.assertRaises(InterfaceError) as context:
                my_client = mysqlx.get_client(connect_kwargs, "{}")
                _ = my_client.get_session()

            self.assertTrue("connection-attributes" in
                            context.exception.msg)
            self.assertTrue("cannot start with '_'" in context.exception.msg)

        # Test error is raised for attribute name size exceeds 32 characters
        connection_attributes = [
            {"foo": "bar", "p{}w".format("o"*31): "kaplot"},
            {"p{}w".format("o"*31): "kaplot"},
            {"baz": "zoom", "p{}w".format("o"*31): "kaplot", "a": "b"}
        ]
        for conn_attr in connection_attributes:
            connect_kwargs = self.connect_kwargs.copy()
            connect_kwargs["connection_attributes"] = conn_attr
            with self.assertRaises(InterfaceError) as context:
                my_client = mysqlx.get_client(connect_kwargs, "{}")
                _ = my_client.get_session()

            self.assertTrue("exceeds 32 characters limit size" in
                            context.exception.msg)

        # Test error is raised for attribute value size exceeds 1024 characters
        connection_attributes = [
            {"foo": "bar", "pum": "kr{}nk".format("u"*1024)},
            {"pum": "kr{}nk".format("u"*1024)},
            {"baz": "zoom", "pum": "kr{}nk".format("u"*1024), "a": "b"}
        ]
        for conn_attr in connection_attributes:
            connect_kwargs = self.connect_kwargs.copy()
            connect_kwargs["connection-attributes"] = conn_attr
            with self.assertRaises(InterfaceError) as context:
                my_client = mysqlx.get_client(connect_kwargs, "{}")
                _ = my_client.get_session()

            self.assertTrue("exceeds 1024 characters limit size" in
                            context.exception.msg)

        # Validate the user defined attributes are created in the server
        # Test user defined connection attributes through a connection URL
        connection_attributes = {
            "foo": "bar",
            "baz": "zoom",
            "quash": "",
            "puuuuum": "kaplot"
        }
        uri = build_uri(user=self.connect_kwargs["user"],
                        password=self.connect_kwargs["password"],
                        host=self.connect_kwargs["host"],
                        port=self.connect_kwargs["port"],
                        schema=self.connect_kwargs["schema"],
                        connection_attributes=connection_attributes)

        # Verify user defined session-connection-attributes are in the server
        my_session = mysqlx.get_session(uri)
        row = my_session.sql("SHOW VARIABLES LIKE \"pseudo_thread_id\"").\
            execute().fetch_all()[0]
        get_attrs = ("SELECT ATTR_NAME, ATTR_VALUE FROM "
                    "performance_schema.session_account_connect_attrs "
                    "where PROCESSLIST_ID = \"{}\"")
        rows = my_session.sql(get_attrs.format(row.get_string('Value'))).\
            execute().fetch_all()
        expected_attrs = connection_attributes.copy()
        expected_attrs.update({
            "_pid": str(os.getpid()),
            "_platform": self.platform_arch,
            "_source_host": socket.gethostname(),
            "_client_name": "mysql-connector-python",
            "_client_license": self.client_license,
            "_client_version": ".".join([str(x) for x in VERSION[0:3]]),
            "_os": self.os_ver
        })
        # Note that for an empty string "" value the server stores a Null value
        expected_attrs["quash"] = "None"
        for row in rows:
            self.assertEqual(expected_attrs[row.get_string('ATTR_NAME')],
                             row.get_string('ATTR_VALUE'),
                             "Attribute {} with value {} differs of {}".format(
                                 row.get_string('ATTR_NAME'),
                                 row.get_string('ATTR_VALUE'),
                                 expected_attrs[row.get_string('ATTR_NAME')]))