From e04e7a7214450fc6dff2571ecda65f7b7ea0d168 Mon Sep 17 00:00:00 2001 From: Tamas Bunth Date: Mon, 22 Oct 2018 11:27:55 +0200 Subject: Add unit test for mysqlc connector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can be used to test the mysqlc connector whenever there is an external mysql or mariadb server running. The test runs only when CONNECTIVITY_TEST_MYSQL_DRIVER environment variable is set. This variable should contain the URL of the database, including the port number and the host name. The URL should also contain a user name password pair which can be used to connect to the external database. The URL format is the following: [user]/[passwd]@sdbc:mysql:mysqlc:[host]:[port]/[db_name] README is updated and contains detailed information about the test. Change-Id: I1bbc9369ff193a29c06de63a0f6cc975877c8da3 Reviewed-on: https://gerrit.libreoffice.org/62171 Tested-by: Jenkins Reviewed-by: Tamás Bunth --- connectivity/qa/connectivity/mysql/mysql.cxx | 182 +++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 connectivity/qa/connectivity/mysql/mysql.cxx (limited to 'connectivity/qa') diff --git a/connectivity/qa/connectivity/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx new file mode 100644 index 000000000000..f5057dce1519 --- /dev/null +++ b/connectivity/qa/connectivity/mysql/mysql.cxx @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; + +class MysqlTestDriver : public test::BootstrapFixture +{ +private: + OUString m_sUrl; + Reference m_xMysqlcComponent; + Reference m_xDriver; + Sequence m_infos; + +public: + MysqlTestDriver() + : test::BootstrapFixture(false, false) + { + } + virtual void setUp() override; + void testDBConnection(); + void testCreateAndDropTable(); + void testIntegerInsertAndQuery(); + + CPPUNIT_TEST_SUITE(MysqlTestDriver); + CPPUNIT_TEST(testDBConnection); + CPPUNIT_TEST(testCreateAndDropTable); + CPPUNIT_TEST(testIntegerInsertAndQuery); + CPPUNIT_TEST_SUITE_END(); +}; + +void MysqlTestDriver::setUp() +{ + test::BootstrapFixture::setUp(); + + /* Get URL from environment variable. This test suite should run only when + * there is an URL given. This is because it can be used for testing connection to + * external databases as well. + * + * Example URL: + * username/password@sdbc:mysql:mysqlc:localhost:3306/testdatabase + */ + osl_getEnvironment(OUString("CONNECTIVITY_TEST_MYSQL_DRIVER").pData, &m_sUrl.pData); + m_xMysqlcComponent + = getMultiServiceFactory()->createInstance("com.sun.star.comp.sdbc.mysqlc.MysqlCDriver"); + CPPUNIT_ASSERT_MESSAGE("no mysqlc component!", m_xMysqlcComponent.is()); + + // set user name and password + m_infos = Sequence{ 2 }; + m_infos[0].Name = OUString{ "user" }; + sal_Int32 nPer = m_sUrl.indexOf("/"); + m_infos[0].Value = makeAny(m_sUrl.copy(0, nPer)); + m_sUrl = m_sUrl.copy(nPer + 1); + m_infos[1].Name = OUString{ "password" }; + sal_Int32 nAt = m_sUrl.indexOf("@"); + m_infos[1].Value = makeAny(m_sUrl.copy(0, nAt)); + m_sUrl = m_sUrl.copy(nAt + 1); + + m_xDriver.set(m_xMysqlcComponent, UNO_QUERY); + if (!m_xDriver.is()) + { + CPPUNIT_ASSERT_MESSAGE("cannot connect to mysqlc driver!", m_xDriver.is()); + } +} + +/** + * Test database connection. It is assumed that the given URL is correct and + * there is a server running at the location. + */ +void MysqlTestDriver::testDBConnection() +{ + Reference xConnection = m_xDriver->connect(m_sUrl, m_infos); + if (!xConnection.is()) + { + CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is()); + } + + uno::Reference xStatement = xConnection->createStatement(); + CPPUNIT_ASSERT(xStatement.is()); + + Reference xResultSet = xStatement->executeQuery("SELECT 1"); + CPPUNIT_ASSERT(xResultSet.is()); + Reference xRow(xResultSet, UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is()); + + sal_Bool result = xResultSet->first(); + CPPUNIT_ASSERT_MESSAGE("fetch first row failed!", result); +} + +/** + * Test creation and removal of a table + */ +void MysqlTestDriver::testCreateAndDropTable() +{ + Reference xConnection = m_xDriver->connect(m_sUrl, m_infos); + if (!xConnection.is()) + { + CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is()); + } + + uno::Reference xStatement = xConnection->createStatement(); + CPPUNIT_ASSERT(xStatement.is()); + + auto nUpdateCount + = xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)"); + CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement + + // we can use the same xStatement instance here + nUpdateCount = xStatement->executeUpdate("DROP TABLE myTestTable"); + CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement +} + +void MysqlTestDriver::testIntegerInsertAndQuery() +{ + Reference xConnection = m_xDriver->connect(m_sUrl, m_infos); + if (!xConnection.is()) + { + CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is()); + } + + Reference xStatement = xConnection->createStatement(); + CPPUNIT_ASSERT(xStatement.is()); + + auto nUpdateCount + = xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)"); + CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement + + Reference xPrepared + = xConnection->prepareStatement(OUString{ "INSERT INTO myTestTable VALUES (?)" }); + Reference xParams(xPrepared, UNO_QUERY); + constexpr int ROW_COUNT = 3; + for (int i = 0; i < ROW_COUNT; ++i) + { + xParams->setLong(1, i); // first and only column + nUpdateCount = xPrepared->executeUpdate(); + CPPUNIT_ASSERT_EQUAL(1, nUpdateCount); // one row is inserted at a time + } + + // now let's query the existing data + Reference xResultSet = xStatement->executeQuery("SELECT id from myTestTable"); + CPPUNIT_ASSERT_MESSAGE("result set cannot be instantiated after query", xResultSet.is()); + Reference xRow(xResultSet, UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is()); + + for (long i = 0; i < ROW_COUNT; ++i) + { + bool hasRow = xResultSet->next(); + CPPUNIT_ASSERT_MESSAGE("not enough result after query", hasRow); + CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(1)); // first and only column + } + + nUpdateCount = xStatement->executeUpdate("DROP TABLE myTestTable"); + CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement +} + +CPPUNIT_TEST_SUITE_REGISTRATION(MysqlTestDriver); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit