Repository: incubator-hawq Updated Branches: refs/heads/master c0dcb5d60 -> fb14dbd98
HAWQ-732. Workable test framework. Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/fb14dbd9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/fb14dbd9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/fb14dbd9 Branch: refs/heads/master Commit: fb14dbd981ed2ecc450ce27d1a9cfff0de8f51b7 Parents: c0dcb5d Author: ztao1987 <[email protected]> Authored: Fri May 13 07:47:07 2016 +0800 Committer: ztao1987 <[email protected]> Committed: Fri May 13 07:47:07 2016 +0800 ---------------------------------------------------------------------- src/test/feature/lib/Makefile | 2 +- src/test/feature/lib/data-gen.cpp | 144 +++++------ src/test/feature/lib/data-gen.h | 23 +- src/test/feature/lib/hawq-config.cpp | 35 ++- src/test/feature/lib/psql.cpp | 347 ++++++++++++--------------- src/test/feature/lib/psql.h | 154 ++++++------ src/test/feature/lib/sql-util.cpp | 131 ++++++++++ src/test/feature/lib/sql-util.h | 74 +++--- src/test/feature/testlib/ans/sample.ans | 7 + src/test/feature/testlib/sql/sample.sql | 1 + src/test/feature/testlib/test-lib.cpp | 9 +- 11 files changed, 518 insertions(+), 409 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/Makefile ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/Makefile b/src/test/feature/lib/Makefile index 411613a..204952c 100644 --- a/src/test/feature/lib/Makefile +++ b/src/test/feature/lib/Makefile @@ -8,7 +8,7 @@ override CPPFLAGS := -I/usr/include -I/usr/local/include -I/usr/include/libxml2 override LIBS := $(LIBS) -lpq -lxml2 override LDFLAGS += -L/usr/local/lib -L/usr/lib -PROG = string-util.cpp psql.cpp command.cpp xml-parser.cpp hawq-config.cpp data-gen.cpp +PROG = $(abspath string-util.cpp psql.cpp command.cpp xml-parser.cpp hawq-config.cpp sql-util.cpp data-gen.cpp) all: g++ $(CPPFLAGS) $(CXXFLAGS) $(PROG) http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/data-gen.cpp ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/data-gen.cpp b/src/test/feature/lib/data-gen.cpp index da58b32..e2e2f71 100644 --- a/src/test/feature/lib/data-gen.cpp +++ b/src/test/feature/lib/data-gen.cpp @@ -1,138 +1,140 @@ -#include <iostream> #include "data-gen.h" -void -DataGenerator::genSimpleTable(std::string tableName, - bool appendonly, - std::string orientation, - std::string compresstype, - int compresslevel) { +#include <iostream> + +void DataGenerator::genSimpleTable(std::string tableName, bool appendonly, + std::string orientation, + std::string compresstype, + int compresslevel) { std::string desc = genTableDesc(appendonly, orientation, compresstype, compresslevel); - std::string createSql = "create table " + tableName - + "(a int, b int) " + desc; - sqlUtil.execute(createSql); + std::string createSql = + "create table " + tableName + "(a int, b int) " + desc; + sqlUtil->execute(createSql); - std::string insertSql = "insert into " + tableName - + " values(51,62), (14,15), (1,3);"; - sqlUtil.execute(insertSql); + std::string insertSql = + "insert into " + tableName + " values(51,62), (14,15), (1,3);"; + sqlUtil->execute(insertSql); } -void -DataGenerator::genTableWithSeries(std::string tableName, - bool appendonly, - std::string orientation, - std::string compresstype, - int compresslevel) { +void DataGenerator::genTableWithSeries(std::string tableName, bool appendonly, + std::string orientation, + std::string compresstype, + int compresslevel) { std::string desc = - genTableDesc(appendonly, orientation, compresstype, compresslevel); - std::string createSql = "create table " + tableName - + "(a int, b varchar(20)) " + desc; - sqlUtil.execute(createSql); + genTableDesc(appendonly, orientation, compresstype, compresslevel); + std::string createSql = + "create table " + tableName + "(a int, b varchar(20)) " + desc; + sqlUtil->execute(createSql); - std::string insertSql = "insert into " + tableName - + " values(generate_series(1,10000), 'abc')"; - sqlUtil.execute(insertSql); + std::string insertSql = + "insert into " + tableName + " values(generate_series(1,10000), 'abc')"; + sqlUtil->execute(insertSql); } - -void -DataGenerator::genTableWithFullTypes(std::string tableName, - bool appendonly, - std::string orientation, - std::string compresstype, - int compresslevel) { +void DataGenerator::genTableWithFullTypes(std::string tableName, + bool appendonly, + std::string orientation, + std::string compresstype, + int compresslevel) { std::string desc = genTableDesc(appendonly, orientation, compresstype, compresslevel); - std::string createSql = "create table " + tableName + "(c0 int4, c1 polygon, " + std::string createSql = + "create table " + tableName + + "(c0 int4, c1 polygon, " "c2 text, c3 time, c4 timetz, c5 macaddr, c6 timestamptz, c7 char(10), " "c8 int2, c9 bool, c10 cidr, c11 circle, c12 lseg, c13 interval, " "c14 bit, c15 money, c16 box, c17 bytea, c18 xml, c19 bit(5), " "c20 varchar(10), c21 inet, c22 int8, c23 varbit, c24 serial, " - "c25 float4, c26 point, c27 date, c28 float8) " + desc; - sqlUtil.execute(createSql); + "c25 float4, c26 point, c27 date, c28 float8) " + + desc; + sqlUtil->execute(createSql); - std::string insertSql = "insert into " + tableName + + std::string insertSql = + "insert into " + tableName + " values (2147483647, null, null, '00:00:00', null, 'FF:89:71:45:AE:01'," " '2000-01-01 08:00:00+09', null, 32767, 'true', '192.168.1.255/32', " "'<(1,2),3>', '[(0,0),(6,6)]', '-178000000 years', '0', '-21474836.48', " "'((100,200),(200,400))', null, '<aa>bb</aa>', null, '123456789a', " "'2001:db8:85a3:8d3:1319:8a2e:370:7344/64', null, null, 1, 0, POINT(1,2)," " '4277-12-31 AD', 128);"; - sqlUtil.execute(insertSql); + sqlUtil->execute(insertSql); - std::string insertSql2 = "insert into " + tableName + + std::string insertSql2 = + "insert into " + tableName + " values (0, '((100,123),(5,10),(7,2),(4,5))', 'hello world', null, " "'04:45:05.0012+08:40', null, null, 'bbccddeeff', 128, null, " - "'2001:db8:85a3:8d3:1319:8a2e:370:7344/128', '<(1,2),3>', '[(0,0),(6,6)]'," + "'2001:db8:85a3:8d3:1319:8a2e:370:7344/128', '<(1,2),3>', " + "'[(0,0),(6,6)]'," " null, '1', '0', '((0,1),(2,3))', 'hello world', '<aa>bb</aa>', null, " "'aaaa', '2001:db8:85a3:8d3:1319:8a2e:370:7344/64', 0, null, 2147483647, " "'-Infinity', POINT(1,2), '4277-12-31 AD', 'Infinity');"; - sqlUtil.execute(insertSql2); + sqlUtil->execute(insertSql2); - std::string insertSql3 = "insert into " + tableName + + std::string insertSql3 = + "insert into " + tableName + " values (null, null, 'abcd', '15:01:03', null, null, " " '2000-01-01 08:00:00+09', null, null, 'true', null, " "null, '[(0,0),(6,6)]', '-178000000 years', '0', '-21474836.48', " "'((100,200),(200,400))', null, '<aa>bb</aa>', null, '123456789a', " "'2001:db8:85a3:8d3:1319:8a2e:370:7344/64', null, null, 1, 0, POINT(1,2)," " '4277-12-31 AD', 128);"; - sqlUtil.execute(insertSql3); + sqlUtil->execute(insertSql3); - std::string insertSql4 = "insert into " + tableName + + std::string insertSql4 = + "insert into " + tableName + " values (0, '((100,123),(5,10),(7,2),(4,5))', 'hello world', null, " "'04:45:05.0012+08:40', null, null, 'bbccddeeff', 128, null, " "'2001:db8:85a3:8d3:1319:8a2e:370:7344/128', '<(1,2),3>', null," " null, null, '0', null, 'hello world', null, null, " "'aaaa', '2001:db8:85a3:8d3:1319:8a2e:370:7344/64', 0, null, 2147483647, " "'-Infinity', POINT(1,2), '4277-12-31 AD', 'Infinity');"; - sqlUtil.execute(insertSql4); + sqlUtil->execute(insertSql4); - std::string insertSql5 = "insert into " + tableName + + std::string insertSql5 = + "insert into " + tableName + " values (0, '((100,123),(5,10),(7,2),(4,5))', 'hello world', null, " "'04:45:05.0012+08:40', null, null, 'bbccddeeff', 128, null, " "'2001:db8:85a3:8d3:1319:8a2e:370:7344/128', '<(1,2),3>', null," " null, null, '0', null, 'hello world', null, null, " "null, null, 0, null, 2147483647, " "'-Infinity', POINT(1,2), '4277-12-31 AD', 'Infinity');"; - sqlUtil.execute(insertSql5); + sqlUtil->execute(insertSql5); - std::string insertSql6 = "insert into " + tableName + + std::string insertSql6 = + "insert into " + tableName + " values (0, '((100,123),(5,10),(7,2),(4,5))', 'hello world', null, " "'04:45:05.0012+08:40', null, null, 'bbccddeeff', 128, null, " "'2001:db8:85a3:8d3:1319:8a2e:370:7344/128', '<(1,2),3>', null," " null, null, null, null, 'hello world', null, null, " "null, null, 0, null, 34, " "null, null, null, null);"; - sqlUtil.execute(insertSql6); + sqlUtil->execute(insertSql6); } -void -DataGenerator::genTableWithNull(std::string tableName, - bool appendonly, - std::string orientation, - std::string compresstype, - int compresslevel) { +void DataGenerator::genTableWithNull(std::string tableName, bool appendonly, + std::string orientation, + std::string compresstype, + int compresslevel) { std::string desc = - genTableDesc(appendonly, orientation, compresstype, compresslevel); - std::string createSql = "create table " + tableName + - " (a int, b float, c varchar(20)) " + desc; - sqlUtil.execute(createSql); + genTableDesc(appendonly, orientation, compresstype, compresslevel); + std::string createSql = + "create table " + tableName + " (a int, b float, c varchar(20)) " + desc; + sqlUtil->execute(createSql); - std::string insertSql = "insert into " + tableName + + std::string insertSql = + "insert into " + tableName + " values (15, null, 'aa'), (null, null, 'WET'), (null, 51, null);"; - sqlUtil.execute(insertSql); + sqlUtil->execute(insertSql); } - -std::string -DataGenerator::genTableDesc(bool appendonly, - std::string orientation, std::string compresstype, - int compresslevel) { - std::string desc = - (appendonly ? "with (appendonly = true, orientation = " - : "with (appendonly = false, orientation = ") - + orientation + ", compresstype = " + compresstype - + ", compresslevel = " + std::to_string(compresslevel) + ")"; +std::string DataGenerator::genTableDesc(bool appendonly, + std::string orientation, + std::string compresstype, + int compresslevel) { + std::string desc = (appendonly ? "with (appendonly = true, orientation = " + : "with (appendonly = false, orientation = ") + + orientation + ", compresstype = " + compresstype + + ", compresslevel = " + std::to_string(compresslevel) + ")"; return desc; } http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/data-gen.h ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/data-gen.h b/src/test/feature/lib/data-gen.h index 38bed69..25aac5a 100644 --- a/src/test/feature/lib/data-gen.h +++ b/src/test/feature/lib/data-gen.h @@ -15,30 +15,25 @@ class DataGenerator { public: - DataGenerator() {} + explicit DataGenerator(SQLUtility *sqlUtil) : sqlUtil(sqlUtil) {} ~DataGenerator() {} - void genSimpleTable(std::string tableName, - bool appendonly = true, + void genSimpleTable(std::string tableName, bool appendonly = true, std::string orientation = "row", - std::string compresstype = "none", - int compresslevel = 0); + std::string compresstype = "none", int compresslevel = 0); - void genTableWithFullTypes(std::string tableName, - bool appendonly = true, + void genTableWithFullTypes(std::string tableName, bool appendonly = true, std::string orientation = "row", std::string compresstype = "none", int compresslevel = 0); - void genTableWithSeries(std::string tableName, - bool appendonly = true, + void genTableWithSeries(std::string tableName, bool appendonly = true, std::string orientation = "row", std::string compresstype = "none", int compresslevel = 0); - void genTableWithNull(std::string tableName, - bool appendonly = true, + void genTableWithNull(std::string tableName, bool appendonly = true, std::string orientation = "row", std::string compresstype = "none", int compresslevel = 0); @@ -47,12 +42,8 @@ class DataGenerator { std::string genTableDesc(bool appendonly, std::string orientation, std::string compresstype, int compresslevel); - private: - SQLUtility sqlUtil; + SQLUtility *sqlUtil = nullptr; }; - - - #endif /* SRC_TEST_FEATURE_LIB_DATA_GEN_H_ */ http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/hawq-config.cpp ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/hawq-config.cpp b/src/test/feature/lib/hawq-config.cpp index 263e54a..a54bb51 100644 --- a/src/test/feature/lib/hawq-config.cpp +++ b/src/test/feature/lib/hawq-config.cpp @@ -28,7 +28,7 @@ bool HawqConfig::LoadFromConfigFile() { bool HawqConfig::getMaster(std::string &hostname, int &port) { bool ret = LoadFromConfigFile(); - if(!ret){ + if (!ret) { return false; } hostname = xmlconf->getString("hawq_master_address_host"); @@ -37,7 +37,7 @@ bool HawqConfig::getMaster(std::string &hostname, int &port) { } void HawqConfig::getStandbyMaster(std::string &hostname, int &port) { - PSQLQueryResult result = psql.getQueryResult( + const PSQLQueryResult &result = psql.getQueryResult( "select hostname, port from gp_segment_configuration where role ='s'"); std::vector<std::vector<std::string> > table = result.getRows(); if (table.size() > 0) { @@ -48,8 +48,8 @@ void HawqConfig::getStandbyMaster(std::string &hostname, int &port) { } void HawqConfig::getTotalSegments(std::vector<std::string> &hostname, - std::vector<int> &port) { - PSQLQueryResult result = psql.getQueryResult( + std::vector<int> &port) { + const PSQLQueryResult &result = psql.getQueryResult( "select hostname, port from gp_segment_configuration where role ='p'"); std::vector<std::vector<std::string> > table = result.getRows(); for (int i = 0; i < table.size(); i++) { @@ -60,9 +60,8 @@ void HawqConfig::getTotalSegments(std::vector<std::string> &hostname, } void HawqConfig::getSlaves(std::vector<std::string> &hostname) { - std::ifstream inFile; - char* GPHOME = getenv("GPHOME"); + char *GPHOME = getenv("GPHOME"); if (GPHOME == nullptr) { return; } @@ -77,10 +76,10 @@ void HawqConfig::getSlaves(std::vector<std::string> &hostname) { } void HawqConfig::getUpSegments(std::vector<std::string> &hostname, - std::vector<int> &port) { - PSQLQueryResult result = - psql.getQueryResult( - "select hostname, port from gp_segment_configuration where role = 'p' and status = 'u'"); + std::vector<int> &port) { + const PSQLQueryResult &result = psql.getQueryResult( + "select hostname, port from gp_segment_configuration where role = 'p' " + "and status = 'u'"); std::vector<std::vector<std::string> > table = result.getRows(); if (table.size() > 0) { @@ -91,10 +90,10 @@ void HawqConfig::getUpSegments(std::vector<std::string> &hostname, } void HawqConfig::getDownSegments(std::vector<std::string> &hostname, - std::vector<int> &port) { - PSQLQueryResult result = - psql.getQueryResult( - "select hostname, port from gp_segment_configuration where role = 'p' and status != 'u'"); + std::vector<int> &port) { + const PSQLQueryResult &result = psql.getQueryResult( + "select hostname, port from gp_segment_configuration where role = 'p' " + "and status != 'u'"); std::vector<std::vector<std::string> > table = result.getRows(); if (table.size() > 0) { @@ -132,8 +131,8 @@ std::string HawqConfig::setGucValue(std::string gucName, std::string gucValue) { } bool HawqConfig::isMasterMirrorSynchronized() { - PSQLQueryResult result = psql.getQueryResult( - "select summary_state from gp_master_mirroring"); + const PSQLQueryResult &result = + psql.getQueryResult("select summary_state from gp_master_mirroring"); if (result.getRows().size() > 0) { std::string syncInfo = result.getData(0, 0); syncInfo = StringUtil::trim(syncInfo); @@ -147,8 +146,8 @@ bool HawqConfig::isMasterMirrorSynchronized() { } bool HawqConfig::isMultinodeMode() { - PSQLQueryResult result = psql.getQueryResult( - "select hostname from gp_segment_configuration"); + const PSQLQueryResult &result = + psql.getQueryResult("select hostname from gp_segment_configuration"); std::vector<std::vector<std::string> > table = result.getRows(); std::set<std::string> hostnameMap; http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/psql.cpp ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/psql.cpp b/src/test/feature/lib/psql.cpp index bb936b0..b7978ac 100644 --- a/src/test/feature/lib/psql.cpp +++ b/src/test/feature/lib/psql.cpp @@ -3,250 +3,211 @@ #include "psql.h" #include "command.h" -#define PSQL_BASIC_DIFF_OPTS "-w -I NOTICE: -I HINT: -I CONTEXT: -I GP_IGNORE:" -#define PSQL_PRETTY_DIFF_OPTS "-w -I NOTICE: -I HINT: -I CONTEXT: -I GP_IGNORE: -C3" +#define PSQL_BASIC_DIFF_OPTS "-w -I NOTICE: -I HINT: -I CONTEXT: -I GP_IGNORE:" +#define PSQL_PRETTY_DIFF_OPTS \ + "-w -I NOTICE: -I HINT: -I CONTEXT: -I GP_IGNORE: -C3" -void PSQLQueryResult::setErrorMessage(const std::string errmsg) -{ - this->_errmsg = errmsg; +void PSQLQueryResult::setErrorMessage(const std::string errmsg) { + this->_errmsg = errmsg; } -const std::string& PSQLQueryResult::getErrorMessage() const -{ - return this->_errmsg; +const std::string& PSQLQueryResult::getErrorMessage() const { + return this->_errmsg; } -bool PSQLQueryResult::isError() const -{ - return this->_errmsg.length() > 0; +bool PSQLQueryResult::isError() const { return this->_errmsg.length() > 0; } + +const std::vector<std::vector<std::string> >& PSQLQueryResult::getRows() const { + return this->_rows; } -const std::vector<std::vector<std::string> >& PSQLQueryResult::getRows() const -{ - return this->_rows; +const std::vector<std::string>& PSQLQueryResult::getFields() const { + return this->_fields; } -const std::vector<std::string>& PSQLQueryResult::getFields() const -{ - return this->_fields; +const std::vector<std::string>& PSQLQueryResult::getRow(int ri) const { + return this->getRows()[ri]; } -const std::vector<std::string>& PSQLQueryResult::getRow(int ri) const -{ - return this->getRows()[ri]; +const std::string& PSQLQueryResult::getData(int ri, int ci) const { + return this->getRow(ri)[ci]; } -const std::string& PSQLQueryResult::getData(int ri, int ci) const -{ - return this->getRow(ri)[ci]; +std::string PSQLQueryResult::getData(int ri, const std::string& ck) const { + for (int ci = 0; ci < this->_fields.size(); ci++) { + if (ck == this->_fields[ci]) { + return this->getData(ri, ci); + } + } + return ""; } -std::string PSQLQueryResult::getData(int ri, const std::string& ck) const -{ - for (int ci=0;ci<this->_fields.size();ci++) - { - if (ck == this->_fields[ci]) - { - return this->getData(ri, ci); - } +const std::string& PSQLQueryResult::getFieldName(int ci) const { + return this->_fields[ci]; +} + +int PSQLQueryResult::rowCount() const { return this->_rows.size(); } + +int PSQLQueryResult::fieldCount() const { return this->_fields.size(); } + +void PSQLQueryResult::savePGResult(const PGresult* res) { + int i, j; + int nfields = PQnfields(res); + for (i = 0; i < nfields; i++) { + this->_fields.push_back(PQfname(res, i)); + } + + for (i = 0; i < PQntuples(res); i++) { + std::vector<std::string> row; + for (j = 0; j < nfields; j++) { + row.push_back(PQgetvalue(res, i, j)); } - return ""; + this->_rows.push_back(row); + } } -const std::string& PSQLQueryResult::getFieldName(int ci) const -{ - return this->_fields[ci]; +void PSQLQueryResult::reset() { + this->_errmsg.clear(); + this->_rows.clear(); + this->_fields.clear(); } -int PSQLQueryResult::rowCount() const -{ - return this->_rows.size(); +PSQL& PSQL::runSQLCommand(const std::string& sql_cmd) { + Command c(this->_getPSQLQueryCommand(sql_cmd)); + c.run(); + this->_last_status = c.getResultStatus(); + this->_last_result = c.getResultOutput(); + return *this; } -int PSQLQueryResult::fieldCount() const -{ - return this->_fields.size(); +PSQL& PSQL::runSQLFile(const std::string& sql_file) { + this->_last_status = + Command::getCommandStatus(this->_getPSQLFileCommand(sql_file)); + return *this; } -void PSQLQueryResult::savePGResult(const PGresult *res) -{ - int i, j; - int nfields = PQnfields(res); - for (i=0; i<nfields; i++) - { - this->_fields.push_back(PQfname(res, i)); - } - - for (i=0; i<PQntuples(res); i++) - { - std::vector<std::string> row; - for (j=0; j<nfields; j++) - { - row.push_back(PQgetvalue(res, i, j)); - } - this->_rows.push_back(row); - } -} - -void PSQLQueryResult::reset() -{ - this->_errmsg.clear(); - this->_rows.clear(); - this->_fields.clear(); -} - -PSQL& PSQL::runSQLCommand(const std::string& sql_cmd) -{ - Command c(this->_getPSQLQueryCommand(sql_cmd)); - c.run(); - this->_last_status = c.getResultStatus(); - this->_last_result = c.getResultOutput(); - return *this; -} - -PSQL& PSQL::runSQLFile(const std::string& sql_file) -{ - this->_last_status = Command::getCommandStatus(this->_getPSQLFileCommand(sql_file)); - return *this; -} - -const PSQLQueryResult& PSQL::getQueryResult(const std::string& sql) -{ - PGconn *conn = NULL; - PGresult *res = NULL; - - conn = PQconnectdb(this->getConnectionString().c_str()); - if (PQstatus(conn) != CONNECTION_OK) - { - this->_result.setErrorMessage(PQerrorMessage(conn)); - goto done; - } +const PSQLQueryResult& PSQL::getQueryResult(const std::string& sql) { + PGconn* conn = NULL; + PGresult* res = NULL; - res = PQexec(conn, sql.c_str()); - if (PQresultStatus(res) != PGRES_TUPLES_OK) - { - this->_result.setErrorMessage(PQerrorMessage(conn)); - goto done; - } + conn = PQconnectdb(this->getConnectionString().c_str()); + if (PQstatus(conn) != CONNECTION_OK) { + this->_result.setErrorMessage(PQerrorMessage(conn)); + goto done; + } - this->_result.reset(); - this->_result.savePGResult(res); + res = PQexec(conn, sql.c_str()); + if (PQresultStatus(res) != PGRES_TUPLES_OK) { + this->_result.setErrorMessage(PQerrorMessage(conn)); + goto done; + } + + this->_result.reset(); + this->_result.savePGResult(res); done: - if (res) - { - PQclear(res); - res = NULL; - } - - if (conn) - { - PQfinish(conn); - conn = NULL; - } - - return this->_result; -} + if (res) { + PQclear(res); + res = NULL; + } -PSQL& PSQL::setHost(const std::string& host) -{ - this->_host = host; - return *this; -} + if (conn) { + PQfinish(conn); + conn = NULL; + } -PSQL& PSQL::setPort(const std::string& port) -{ - this->_port = port; - return *this; + return this->_result; } -PSQL& PSQL::setUser(const std::string& username) -{ - this->_user = username; - return *this; +PSQL& PSQL::setHost(const std::string& host) { + this->_host = host; + return *this; } -PSQL& PSQL::setPassword(const std::string& password) -{ - this->_password = password; - return *this; +PSQL& PSQL::setPort(const std::string& port) { + this->_port = port; + return *this; } -PSQL& PSQL::setOutputFile(const std::string& out) -{ - this->_output_file = out; - return *this; +PSQL& PSQL::setUser(const std::string& username) { + this->_user = username; + return *this; } -std::string PSQL::getConnectionString() const -{ - // host=localhost port=5432 dbname=mydb - std::string command; - command.append("host=").append(this->_host) - .append(" port=").append(this->_port) - .append(" user=").append(this->_user) - .append(" dbname=").append(this->_dbname); - return command; +PSQL& PSQL::setPassword(const std::string& password) { + this->_password = password; + return *this; } -int PSQL::getLastStatus() const -{ - return this->_last_status; +PSQL& PSQL::setOutputFile(const std::string& out) { + this->_output_file = out; + return *this; } -const std::string& PSQL::getLastResult() const -{ - return this->_last_result; +void PSQL::resetOutput() { this->_output_file.clear(); } + +std::string PSQL::getConnectionString() const { + // host=localhost port=5432 dbname=mydb + std::string command; + command.append("host=") + .append(this->_host) + .append(" port=") + .append(this->_port) + .append(" user=") + .append(this->_user) + .append(" dbname=") + .append(this->_dbname); + return command; } +int PSQL::getLastStatus() const { return this->_last_status; } -const std::string PSQL::_getPSQLBaseCommand() const -{ - std::string command = "psql"; - command.append(" -p ").append(this->_port); - command.append(" -h ").append(this->_host); - command.append(" -U ").append(this->_user); - command.append(" -d ").append(this->_dbname); - if (this->_output_file.length() > 0) - { - command.append(" -o ").append(this->_output_file); - } - - return command; +const std::string& PSQL::getLastResult() const { return this->_last_result; } + +const std::string PSQL::_getPSQLBaseCommand() const { + std::string command = "psql"; + command.append(" -p ").append(this->_port); + command.append(" -h ").append(this->_host); + command.append(" -U ").append(this->_user); + command.append(" -d ").append(this->_dbname); + if (this->_output_file.length() > 0) { + command.append(" > ").append(this->_output_file); + } + + return command; } -const std::string PSQL::_getPSQLQueryCommand(const std::string& query) const -{ - std::string command = this->_getPSQLBaseCommand(); - return command.append(" -c \"").append(query).append("\""); +const std::string PSQL::_getPSQLQueryCommand(const std::string& query) const { + std::string command = this->_getPSQLBaseCommand(); + return command.append(" -c \"").append(query).append("\""); } -const std::string PSQL::_getPSQLFileCommand(const std::string& file) const -{ - std::string command = this->_getPSQLBaseCommand(); - return command.append(" -f ").append(file); +const std::string PSQL::_getPSQLFileCommand(const std::string& file) const { + std::string command = this->_getPSQLBaseCommand(); + return command.append(" -a -f ").append(file); } -bool PSQL::checkDiff(const std::string& expect_file, const std::string& result_file, bool save_diff) -{ - std::string diff_file = result_file + ".diff"; - std::string command; - command.append("gpdiff.pl ").append(PSQL_BASIC_DIFF_OPTS).append(" ") - .append(expect_file).append(" ") - .append(result_file).append(" ") - .append(" >").append(diff_file); +bool PSQL::checkDiff(const std::string& expect_file, + const std::string& result_file, bool save_diff) { + std::string diff_file = result_file + ".diff"; + std::string command; + command.append("gpdiff.pl ") + .append(PSQL_BASIC_DIFF_OPTS) + .append(" ") + .append(expect_file) + .append(" ") + .append(result_file) + .append(" ") + .append(" >") + .append(diff_file); - if (Command::getCommandStatus(command) == 0) - { - unlink(diff_file.c_str()); - return false; - } - else - { - if (!save_diff) - { - unlink(diff_file.c_str()); - } - return true; + if (Command::getCommandStatus(command) == 0) { + unlink(diff_file.c_str()); + return false; + } else { + if (!save_diff) { + unlink(diff_file.c_str()); } + return true; + } } http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/psql.h ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/psql.h b/src/test/feature/lib/psql.h index 575329e..4105d6e 100644 --- a/src/test/feature/lib/psql.h +++ b/src/test/feature/lib/psql.h @@ -1,88 +1,90 @@ #ifndef __PSQL_H__ #define __PSQL_H__ - #include <vector> #include "command.h" #include "libpq-fe.h" -class PSQLQueryResult -{ -public: - PSQLQueryResult() {} - - void savePGResult(const PGresult *res); - void setErrorMessage(const std::string errmsg); - const std::string& getErrorMessage() const; - bool isError() const; - - const std::vector<std::vector<std::string> >& getRows() const; - const std::vector<std::string>& getFields() const; - - const std::vector<std::string>& getRow(int ri) const; - const std::string& getData(int ri, int ci) const; - std::string getData(int ri, const std::string& ck) const; - const std::string& getFieldName(int ci) const; - - int rowCount() const; - int fieldCount() const; - - void reset(); - -private: - std::string _errmsg; - std::vector<std::vector<std::string> > _rows; - std::vector<std::string> _fields; +class PSQLQueryResult { + public: + PSQLQueryResult() {} + + void savePGResult(const PGresult* res); + void setErrorMessage(const std::string errmsg); + const std::string& getErrorMessage() const; + bool isError() const; + + const std::vector<std::vector<std::string> >& getRows() const; + const std::vector<std::string>& getFields() const; + + const std::vector<std::string>& getRow(int ri) const; + const std::string& getData(int ri, int ci) const; + std::string getData(int ri, const std::string& ck) const; + const std::string& getFieldName(int ci) const; + + int rowCount() const; + int fieldCount() const; + + void reset(); + + private: + PSQLQueryResult(const PSQLQueryResult&); + const PSQLQueryResult& operator=(const PSQLQueryResult&); + + std::string _errmsg; + std::vector<std::vector<std::string> > _rows; + std::vector<std::string> _fields; }; -class PSQL -{ -public: - PSQL(const std::string& db, - const std::string& host = "localhost", - const std::string& port = "5432", - const std::string& user = "gpadmin", - const std::string& password = "") : _dbname(db), - _host(host), - _port(port), - _user(user), - _password(password) {} - virtual ~PSQL() {}; - - PSQL& runSQLCommand(const std::string& sql_cmd); - PSQL& runSQLFile(const std::string& sql_file); - const PSQLQueryResult& getQueryResult(const std::string& sql); - - PSQL& setHost(const std::string& host); - PSQL& setPort(const std::string& port); - PSQL& setUser(const std::string& username); - PSQL& setPassword(const std::string& password); - PSQL& setOutputFile(const std::string& out); - std::string getConnectionString() const; - - int getLastStatus() const; - const std::string& getLastResult() const; - - static bool checkDiff(const std::string& expect_file, const std::string& result_file, bool save_diff = true); - -private: - PSQL(const PSQL&); - const PSQL& operator=(const PSQL&); - - const std::string _getPSQLBaseCommand() const; - const std::string _getPSQLQueryCommand(const std::string& query) const; - const std::string _getPSQLFileCommand(const std::string& file) const; - - std::string _dbname; - std::string _host; - std::string _port; - std::string _user; - std::string _password; - std::string _output_file; - PSQLQueryResult _result; - - int _last_status; - std::string _last_result; +class PSQL { + public: + PSQL(const std::string& db, const std::string& host = "localhost", + const std::string& port = "5432", const std::string& user = "gpadmin", + const std::string& password = "") + : _dbname(db), + _host(host), + _port(port), + _user(user), + _password(password) {} + virtual ~PSQL(){}; + + PSQL& runSQLCommand(const std::string& sql_cmd); + PSQL& runSQLFile(const std::string& sql_file); + const PSQLQueryResult& getQueryResult(const std::string& sql); + + PSQL& setHost(const std::string& host); + PSQL& setPort(const std::string& port); + PSQL& setUser(const std::string& username); + PSQL& setPassword(const std::string& password); + PSQL& setOutputFile(const std::string& out); + std::string getConnectionString() const; + + int getLastStatus() const; + const std::string& getLastResult() const; + + static bool checkDiff(const std::string& expect_file, + const std::string& result_file, bool save_diff = true); + + void resetOutput(); + + private: + PSQL(const PSQL&); + const PSQL& operator=(const PSQL&); + + const std::string _getPSQLBaseCommand() const; + const std::string _getPSQLQueryCommand(const std::string& query) const; + const std::string _getPSQLFileCommand(const std::string& file) const; + + std::string _dbname; + std::string _host; + std::string _port; + std::string _user; + std::string _password; + std::string _output_file; + PSQLQueryResult _result; + + int _last_status; + std::string _last_result; }; #endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/sql-util.cpp ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/sql-util.cpp b/src/test/feature/lib/sql-util.cpp new file mode 100644 index 0000000..08e0d09 --- /dev/null +++ b/src/test/feature/lib/sql-util.cpp @@ -0,0 +1,131 @@ +#include "sql-util.h" + +#include <unistd.h> + +#include <fstream> +#include <iostream> +#include <vector> + +#include "string-util.h" + +SQLUtility::SQLUtility() + : conn(getConnection()), + testRootPath(getTestRootPath()), + test_info(::testing::UnitTest::GetInstance()->current_test_info()) { + schemaName = + std::string(test_info->test_case_name()) + "_" + test_info->name(); + conn->runSQLCommand("DROP SCHEMA IF EXISTS " + schemaName + " CASCADE"); + conn->runSQLCommand("CREATE SCHEMA " + schemaName); +} + +SQLUtility::~SQLUtility() { + if (!test_info->result()->Failed()) + conn->runSQLCommand("DROP SCHEMA " + schemaName + " CASCADE"); +} + +void SQLUtility::execute(const std::string &sql) { + EXPECT_EQ((conn->runSQLCommand("SET SEARCH_PATH=" + schemaName + ";" + sql)) + .getLastStatus(), + 0) + << conn->getLastResult(); +} + +void SQLUtility::query(const std::string &sql, int expectNum) { + const PSQLQueryResult &result = executeQuery(sql); + ASSERT_FALSE(result.isError()) << result.getErrorMessage(); + EXPECT_EQ(expectNum, result.rowCount()); +} + +void SQLUtility::query(const std::string &sql, const std::string &expectStr) { + const PSQLQueryResult &result = executeQuery(sql); + ASSERT_FALSE(result.isError()) << result.getErrorMessage(); + std::vector<std::vector<std::string> > resultString = result.getRows(); + std::string resultStr; + for (auto row : result.getRows()) { + for (auto column : row) resultStr += column + "|"; + resultStr += "\n"; + } + EXPECT_EQ(expectStr, resultStr); +} + +void SQLUtility::execSQLFile(const std::string &sqlFile, + const std::string &ansFile) { + // do precheck for sqlFile & ansFile + if (StringUtil::StartWith(sqlFile, "/") || + StringUtil::StartWith(ansFile, "/")) + ASSERT_TRUE(false) << "For sqlFile and ansFile, relative path to feature " + "test root dir is needed"; + std::string ansFileAbsPath = testRootPath + "/" + ansFile; + if (!std::ifstream(ansFileAbsPath)) + ASSERT_TRUE(false) << ansFileAbsPath << " doesn't exist"; + FilePath fp = splitFilePath(ansFileAbsPath); + // double check to avoid empty fileBaseName + if (fp.fileBaseName.empty()) + ASSERT_TRUE(false) << ansFileAbsPath << " is invalid"; + + // generate new sql file with set search_path added at the begining + const std::string newSqlFile = generateSQLFile(sqlFile); + + // outFile is located in the same folder with ansFile + std::string outFile = fp.path + "/" + fp.fileBaseName + ".out"; + conn->setOutputFile(outFile); + EXPECT_EQ(conn->runSQLFile(newSqlFile).getLastStatus(), 0); + conn->resetOutput(); + if (remove(newSqlFile.c_str())) + ASSERT_TRUE(false) << "Error deleting file " << newSqlFile; + EXPECT_FALSE(conn->checkDiff(ansFile, outFile, true)); +} + +std::unique_ptr<PSQL> SQLUtility::getConnection() { + std::unique_ptr<PSQL> psql( + new PSQL(HAWQ_DB, HAWQ_HOST, HAWQ_PORT, HAWQ_USER, HAWQ_PASSWORD)); + return std::move(psql); +} + +const std::string SQLUtility::generateSQLFile(const std::string &sqlFile) { + const std::string originSqlFile = testRootPath + "/" + sqlFile; + const std::string newSqlFile = "/tmp/" + schemaName + ".sql"; + std::fstream in; + in.open(originSqlFile, std::ios::in); + if (!in.is_open()) { + EXPECT_TRUE(false) << "Error opening file " << originSqlFile; + } + std::fstream out; + out.open(newSqlFile, std::ios::out); + if (!out.is_open()) { + EXPECT_TRUE(false) << "Error opening file " << newSqlFile; + } + out << "-- start_ignore" << std::endl + << "SET SEARCH_PATH=" + schemaName + ";" << std::endl + << "-- end_ignore" << std::endl; + std::string line; + while (getline(in, line)) { + out << line; + } + in.close(); + out.close(); + return newSqlFile; +} + +const PSQLQueryResult &SQLUtility::executeQuery(const std::string &sql) { + const PSQLQueryResult &result = + conn->getQueryResult("SET SEARCH_PATH=" + schemaName + ";" + sql); + return result; +} + +PSQL *SQLUtility::getPSQL() const { return conn.get(); } + +std::string SQLUtility::getTestRootPath() const { + FilePath fp = splitFilePath(__FILE__); + return splitFilePath(__FILE__).path + "/.."; +} + +FilePath SQLUtility::splitFilePath(const std::string &filePath) const { + FilePath fp; + size_t found1 = filePath.find_last_of("/"); + size_t found2 = filePath.find_last_of("."); + fp.path = filePath.substr(0, found1); + fp.fileBaseName = filePath.substr(found1 + 1, found2 - found1 - 1); + fp.fileSuffix = filePath.substr(found2 + 1, filePath.length() - found2 - 1); + return fp; +} http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/lib/sql-util.h ---------------------------------------------------------------------- diff --git a/src/test/feature/lib/sql-util.h b/src/test/feature/lib/sql-util.h index 3ede55f..5c5a59d 100644 --- a/src/test/feature/lib/sql-util.h +++ b/src/test/feature/lib/sql-util.h @@ -2,53 +2,65 @@ #define SRC_TEST_FEATURE_LIB_SQL_UTIL_H_ #include <string> + #include "gtest/gtest.h" #include "psql.h" #define HAWQ_DB (getenv("PGDATABASE") ? getenv("PGDATABASE") : "postgres") #define HAWQ_HOST (getenv("PGHOST") ? getenv("PGHOST") : "localhost") #define HAWQ_PORT (getenv("PGPORT") ? getenv("PGPORT") : "5432") -#define HAWQ_USER (getenv("PGUSER") ? getenv("PGUSER") : "taoz") +#define HAWQ_USER (getenv("PGUSER") ? getenv("PGUSER") : "gpadmin") #define HAWQ_PASSWORD (getenv("PGPASSWORD") ? getenv("PGPASSWORD") : "") +struct FilePath { + std::string path; + std::string fileBaseName; + std::string fileSuffix; +}; + class SQLUtility { public: - SQLUtility() - : conn(getConnection()), - test_info(::testing::UnitTest::GetInstance()->current_test_info()) { - schemaName = - std::string(test_info->test_case_name()) + "_" + test_info->name(); - conn->runSQLCommand("DROP SCHEMA IF EXISTS " + schemaName + " CASCADE"); - conn->runSQLCommand("CREATE SCHEMA " + schemaName); - } - - ~SQLUtility() { - if (!test_info->result()->Failed()) - conn->runSQLCommand("DROP SCHEMA " + schemaName + " CASCADE"); - } - - void execute(const std::string &sql) { - EXPECT_EQ(conn->runSQLCommand("SET SEARCH_PATH= " + schemaName + ";" + sql) - .getLastStatus(), - 0); - } - - void query(const std::string &sql, int resultNum) { - PSQLQueryResult result = - conn->getQueryResult("SET SEARCH_PATH= " + schemaName + ";" + sql); - EXPECT_EQ(result.rowCount(), resultNum); - } + SQLUtility(); + ~SQLUtility(); + + // Execute sql command + // @param sql The given sql command + // @return void + void execute(const std::string &sql); + + // Execute query command and check the rowCount + // @param sql The given query command + // @expectNum The expected rowCount + // @return void + void query(const std::string &sql, int expectNum); + + // Execute query command and check query result + // @param sql The given query command + // @expectStr The given query result + // @return void + void query(const std::string &sql, const std::string &expectStr); + + // Execute sql file and diff with ans file + // @param sqlFile The given sqlFile which is relative path to test root dir + // @param ansFile The given ansFile which is relative path to test root dir + // @return void + void execSQLFile(const std::string &sqlFile, const std::string &ansFile); + + // Get PSQL connection + // @return PSQL raw pointer + PSQL *getPSQL() const; private: - std::unique_ptr<PSQL> getConnection() { - std::unique_ptr<PSQL> psql( - new PSQL(HAWQ_DB, HAWQ_HOST, HAWQ_PORT, HAWQ_USER, HAWQ_PASSWORD)); - return std::move(psql); - } + std::unique_ptr<PSQL> getConnection(); + const std::string generateSQLFile(const std::string &sqlFile); + const PSQLQueryResult &executeQuery(const std::string &sql); + std::string getTestRootPath() const; + FilePath splitFilePath(const std::string &filePath) const; private: std::string schemaName; std::unique_ptr<PSQL> conn; + std::string testRootPath; const ::testing::TestInfo *const test_info; }; http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/testlib/ans/sample.ans ---------------------------------------------------------------------- diff --git a/src/test/feature/testlib/ans/sample.ans b/src/test/feature/testlib/ans/sample.ans new file mode 100644 index 0000000..08df8b4 --- /dev/null +++ b/src/test/feature/testlib/ans/sample.ans @@ -0,0 +1,7 @@ +select * from test; + p | q +---+----- + 1 | 1.1 + 2 | 2.2 +(2 rows) + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/testlib/sql/sample.sql ---------------------------------------------------------------------- diff --git a/src/test/feature/testlib/sql/sample.sql b/src/test/feature/testlib/sql/sample.sql new file mode 100644 index 0000000..ca202d3 --- /dev/null +++ b/src/test/feature/testlib/sql/sample.sql @@ -0,0 +1 @@ +select * from test; http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/fb14dbd9/src/test/feature/testlib/test-lib.cpp ---------------------------------------------------------------------- diff --git a/src/test/feature/testlib/test-lib.cpp b/src/test/feature/testlib/test-lib.cpp index 6e283ca..4959f4a 100644 --- a/src/test/feature/testlib/test-lib.cpp +++ b/src/test/feature/testlib/test-lib.cpp @@ -71,13 +71,16 @@ TEST_F(TestCommonLib, TestCommand) { TEST_F(TestCommonLib, TestSqlUtil) { SQLUtility util; - util.execute("create table test(p int)"); - util.execute("insert into test values(1),(2)"); + util.execute("create table test(p int, q float)"); + util.execute("insert into test values(1,1.1),(2,2.2)"); util.query("select * from test", 2); + util.query("select * from test", "1|1.1|\n2|2.2|\n"); + util.execSQLFile("testlib/sql/sample.sql", "testlib/ans/sample.ans"); } TEST_F(TestCommonLib, TestDataGenerator) { - DataGenerator dGen; + SQLUtility util; + DataGenerator dGen(&util); dGen.genSimpleTable("simpleAO"); dGen.genSimpleTable("simpleParquet", true, "parquet");
