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