You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by iw...@apache.org on 2016/05/10 02:23:33 UTC
incubator-hawq git commit: HAWQ-723. New Command & PSQL test libraries
Repository: incubator-hawq
Updated Branches:
refs/heads/master a1f47072f -> f8fd15e37
HAWQ-723. New Command & PSQL test libraries
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/f8fd15e3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/f8fd15e3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/f8fd15e3
Branch: refs/heads/master
Commit: f8fd15e3726f7b19c776393b5aef398702ee7680
Parents: a1f4707
Author: ivan <iw...@pivotal.io>
Authored: Tue May 10 10:20:32 2016 +0800
Committer: ivan <iw...@pivotal.io>
Committed: Tue May 10 10:20:32 2016 +0800
----------------------------------------------------------------------
src/test/feature/lib/command.cpp | 125 ++++++++++++++++++
src/test/feature/lib/command.h | 44 +++++++
src/test/feature/lib/psql.cpp | 238 ++++++++++++++++++++++++++++++++++
src/test/feature/lib/psql.h | 81 ++++++++++++
4 files changed, 488 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/f8fd15e3/src/test/feature/lib/command.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/command.cpp b/src/test/feature/lib/command.cpp
new file mode 100644
index 0000000..1760971
--- /dev/null
+++ b/src/test/feature/lib/command.cpp
@@ -0,0 +1,125 @@
+#include <unistd.h>
+#include <iostream>
+#include <fstream>
+#include "command.h"
+
+Command& Command::run()
+{
+ FILE *fp = NULL;
+ char result[MAX_BUFFER_SIZE] = {0};
+
+ if (!this->_isCommandValid())
+ {
+ goto error;
+ }
+
+ fp = popen(this->_cmd_string.append(" 2>&1").c_str(), "r");
+ if (NULL == fp)
+ {
+ goto error;
+ }
+
+ this->_result_output.clear();
+ while(fgets(result, sizeof(result), fp) != NULL)
+ {
+ this->_result_output.append(result);
+ }
+
+ this->_result_status = pclose(fp);
+ if (-1 == this->_result_status)
+ {
+ goto error;
+ }
+ this->_result_status = WEXITSTATUS(this->_result_status);
+
+ if (this->_output_file.length() > 0)
+ {
+ this->_saveToFile();
+ }
+
+ return *this;
+
+error:
+ this->_result_status = -1;
+ return *this;
+}
+
+Command& Command::setCommand(const std::string& cmd)
+{
+ this->_cmd_string = cmd;
+ return *this;
+}
+
+Command& Command::setOutputFile(const std::string& out)
+{
+ this->_output_file = out;
+ return *this;
+}
+
+const std::string& Command::getCommand() const
+{
+ return this->_cmd_string;
+}
+
+const std::string& Command::getResultOutput() const
+{
+ return this->_result_output;
+}
+
+int Command::getResultStatus() const
+{
+ return this->_result_status;
+}
+
+bool Command::_isCommandValid() const
+{
+ if (this->_cmd_string.length() > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void Command::_saveToFile()
+{
+ std::ofstream out(this->_output_file, std::ofstream::out);
+ out << this->_result_output;
+ out.close();
+}
+
+const std::string& Command::getCommandOutput(const std::string& cmd)
+{
+ return Command()
+ .setCommand(cmd)
+ .run()
+ .getResultOutput();
+}
+
+const std::string& Command::getCommandOutput(const std::string& cmd, const std::string& out)
+{
+ return Command()
+ .setCommand(cmd)
+ .setOutputFile(out)
+ .run()
+ .getResultOutput();
+}
+
+int Command::getCommandStatus(const std::string& cmd)
+{
+ return Command()
+ .setCommand(cmd)
+ .run()
+ .getResultStatus();
+}
+
+int Command::getCommandStatus(const std::string& cmd, const std::string& out)
+{
+ return Command()
+ .setCommand(cmd)
+ .setOutputFile(out)
+ .run()
+ .getResultStatus();
+}
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/f8fd15e3/src/test/feature/lib/command.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/command.h b/src/test/feature/lib/command.h
new file mode 100644
index 0000000..78da0aa
--- /dev/null
+++ b/src/test/feature/lib/command.h
@@ -0,0 +1,44 @@
+#ifndef __COMMAND_H__
+#define __COMMAND_H__
+
+#include <string>
+
+class Command
+{
+public:
+ Command() : _result_status(-1) {}
+ explicit Command(const std::string& cmd) : _cmd_string(cmd),
+ _result_status(-1) {}
+ Command(const std::string& cmd, const std::string& out) : _cmd_string(cmd),
+ _output_file(out),
+ _result_status(-1) {}
+ virtual ~Command() {}
+
+ Command& run();
+ Command& setCommand(const std::string& cmd);
+ Command& setOutputFile(const std::string& out);
+ const std::string& getCommand() const;
+ const std::string& getResultOutput() const;
+ int getResultStatus() const;
+
+ static const std::string& getCommandOutput(const std::string& cmd);
+ static const std::string& getCommandOutput(const std::string& cmd, const std::string& out);
+ static int getCommandStatus(const std::string& cmd);
+ static int getCommandStatus(const std::string& cmd, const std::string& out);
+
+private:
+ Command(const Command&);
+ const Command& operator=(const Command&);
+
+ bool _isCommandValid() const;
+ void _saveToFile();
+
+ std::string _cmd_string;
+ std::string _output_file;
+ std::string _result_output;
+ int _result_status;
+
+ static const int MAX_BUFFER_SIZE = 1024;
+};
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/f8fd15e3/src/test/feature/lib/psql.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/psql.cpp b/src/test/feature/lib/psql.cpp
new file mode 100644
index 0000000..b9b7acf
--- /dev/null
+++ b/src/test/feature/lib/psql.cpp
@@ -0,0 +1,238 @@
+#include <iostream>
+#include <unistd.h>
+#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"
+
+void PSQLQueryResult::setErrorMessage(const std::string errmsg)
+{
+ this->_errmsg = errmsg;
+}
+
+const std::string& PSQLQueryResult::getErrorMessage() const
+{
+ return this->_errmsg;
+}
+
+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::string>& PSQLQueryResult::getFields() const
+{
+ return this->_fields;
+}
+
+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];
+}
+
+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 "";
+}
+
+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));
+ }
+ 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::getCommandStatus(this->_getPSQLQueryCommand(sql_cmd));
+ return *this;
+}
+
+PSQL& PSQL::runSQLFile(const std::string& sql_file)
+{
+ 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;
+ }
+
+ 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;
+}
+
+PSQL& PSQL::setHost(const std::string& host)
+{
+ this->_host = host;
+ return *this;
+}
+
+PSQL& PSQL::setPort(const std::string& port)
+{
+ this->_port = port;
+ return *this;
+}
+
+PSQL& PSQL::setUser(const std::string& username)
+{
+ this->_user = username;
+ return *this;
+}
+
+PSQL& PSQL::setPassword(const std::string& password)
+{
+ this->_password = password;
+ return *this;
+}
+
+PSQL& PSQL::setOutputFile(const std::string& out)
+{
+ this->_output_file = out;
+ 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;
+}
+
+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::_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);
+}
+
+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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/f8fd15e3/src/test/feature/lib/psql.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/psql.h b/src/test/feature/lib/psql.h
new file mode 100644
index 0000000..fb6d64c
--- /dev/null
+++ b/src/test/feature/lib/psql.h
@@ -0,0 +1,81 @@
+#ifndef __PSQL_H__
+#define __PSQL_H__
+
+#include "libpq-fe.h"
+#include <vector>
+#include "command.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 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;
+
+ 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;
+};
+
+#endif