hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject [2/2] incubator-hawq git commit: HAWQ-768. Refactor c++ code for src/test/feature/lib.
Date Thu, 02 Jun 2016 02:05:23 GMT
HAWQ-768. Refactor c++ code for src/test/feature/lib.


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/ec098032
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/ec098032
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/ec098032

Branch: refs/heads/master
Commit: ec098032e95f26d9d8917ee55d172459e4d2268c
Parents: 2b33d93
Author: xunzhang <xunzhangthu@gmail.com>
Authored: Tue May 31 10:45:51 2016 +0800
Committer: yaoj2 <jyao@pivotal.io>
Committed: Thu Jun 2 10:04:38 2016 +0800

----------------------------------------------------------------------
 src/test/feature/Makefile                 |   2 +-
 src/test/feature/lib/command.cpp          | 178 ++++++++---------
 src/test/feature/lib/command.h            |  81 ++++----
 src/test/feature/lib/common.h             |  22 --
 src/test/feature/lib/data-gen.cpp         | 143 -------------
 src/test/feature/lib/data-gen.h           |  50 -----
 src/test/feature/lib/data_gen.cpp         | 149 ++++++++++++++
 src/test/feature/lib/data_gen.h           |  62 ++++++
 src/test/feature/lib/hawq-config.cpp      | 170 ----------------
 src/test/feature/lib/hawq-config.h        | 115 -----------
 src/test/feature/lib/hawq_config.cpp      | 170 ++++++++++++++++
 src/test/feature/lib/hawq_config.h        | 123 ++++++++++++
 src/test/feature/lib/psql.cpp             | 110 +++++-----
 src/test/feature/lib/psql.h               |  24 ++-
 src/test/feature/lib/sql-util.cpp         | 174 ----------------
 src/test/feature/lib/sql-util.h           |  73 -------
 src/test/feature/lib/sql_util.cpp         | 178 +++++++++++++++++
 src/test/feature/lib/sql_util.h           |  78 ++++++++
 src/test/feature/lib/string-util.cpp      |  95 ---------
 src/test/feature/lib/string-util.h        |  35 ----
 src/test/feature/lib/string_util.cpp      |  93 +++++++++
 src/test/feature/lib/string_util.h        |  33 +++
 src/test/feature/lib/xml-parser.cpp       | 267 -------------------------
 src/test/feature/lib/xml-parser.h         |  64 ------
 src/test/feature/lib/xml_parser.cpp       | 234 ++++++++++++++++++++++
 src/test/feature/lib/xml_parser.h         |  68 +++++++
 src/test/feature/parquet/test-parquet.cpp | 138 -------------
 src/test/feature/parquet/test_parquet.cpp | 140 +++++++++++++
 src/test/feature/query/test-prepare.cpp   |  72 -------
 src/test/feature/query/test-sequence.cpp  | 122 -----------
 src/test/feature/query/test_prepare.cpp   |  70 +++++++
 src/test/feature/query/test_sequence.cpp  | 120 +++++++++++
 src/test/feature/test-main.cpp            |   7 -
 src/test/feature/test_main.cpp            |   7 +
 src/test/feature/testlib/test-lib.cpp     |  87 --------
 src/test/feature/testlib/test_lib.cpp     |  86 ++++++++
 36 files changed, 1813 insertions(+), 1827 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/Makefile
----------------------------------------------------------------------
diff --git a/src/test/feature/Makefile b/src/test/feature/Makefile
index 1ed562a..82a3dc3 100644
--- a/src/test/feature/Makefile
+++ b/src/test/feature/Makefile
@@ -12,7 +12,7 @@ override CPPFLAGS := -I/usr/include -I/usr/local/include -I/usr/include/libxml2
 override LIBS := $(LIBS) -lgtest -lpq -lxml2 -ltest
 override LDFLAGS += -L/usr/local/lib -L/usr/lib -L$(abs_top_srcdir)/src/test/feature/ -L$(abs_top_srcdir)/src/test/feature/lib/ -L$(abs_top_srcdir)/src/interfaces/libpq -L$(gtest_lib_path) -L$(gmock_lib_path)
 
-PROG = test-main.cpp $(wildcard */*.cpp)
+PROG = test_main.cpp $(wildcard */*.cpp)
 RM = rm -rf
 
 .PHONY: all distclean clean doc

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/command.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/command.cpp b/src/test/feature/lib/command.cpp
index 1760971..d46aaf0 100644
--- a/src/test/feature/lib/command.cpp
+++ b/src/test/feature/lib/command.cpp
@@ -1,125 +1,109 @@
-#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;
+using std::string;
+
+namespace hawq {
+namespace test {
+
+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;
+  this->_result_status = -1;
+  return *this;
 }
 
-Command& Command::setCommand(const std::string& cmd)
-{
-    this->_cmd_string = cmd;
-    return *this;
+Command& Command::setCommand(const string& cmd) {
+  this->_cmd_string = cmd;
+  return *this;
 }
 
-Command& Command::setOutputFile(const std::string& out)
-{
-    this->_output_file = out;
-    return *this;
+Command& Command::setOutputFile(const string& out) {
+  this->_output_file = out;
+  return *this;
 }
 
-const std::string& Command::getCommand() const
-{
-    return this->_cmd_string;
+const string& Command::getCommand() const {
+  return this->_cmd_string;
 }
 
-const std::string& Command::getResultOutput() const
-{
-    return this->_result_output;
+const string& Command::getResultOutput() const {
+  return this->_result_output;
 }
 
-int Command::getResultStatus() const
-{
-    return this->_result_status;
+int Command::getResultStatus() const {
+  return this->_result_status;
 }
 
-bool Command::_isCommandValid() const
-{
-    if (this->_cmd_string.length() > 0)
-    {
-        return true;
-    } 
-    else
-    {
-        return false;
-    }
+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(); 
+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 string& Command::getCommandOutput(const 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();
+const string& Command::getCommandOutput(const string& cmd,
+                                        const 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 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();
+int Command::getCommandStatus(const string& cmd,
+                              const string& out) {
+  return Command()
+      .setCommand(cmd)
+      .setOutputFile(out)
+      .run()
+      .getResultStatus();
 }
+
+} // namespace test
+} // namespace hawq

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/command.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/command.h b/src/test/feature/lib/command.h
index 78da0aa..931b3bc 100644
--- a/src/test/feature/lib/command.h
+++ b/src/test/feature/lib/command.h
@@ -1,44 +1,49 @@
-#ifndef __COMMAND_H__
-#define __COMMAND_H__
+#ifndef HAWQ_SRC_TEST_FEATURE_LIB_COMMAND_H_
+#define HAWQ_SRC_TEST_FEATURE_LIB_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;
+namespace hawq {
+namespace test {
+
+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&);
+  Command& setOutputFile(const std::string&);
+  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();
+
+ private:
+  std::string _cmd_string;
+  std::string _output_file;
+  std::string _result_output;
+  int _result_status;
+
+  static const int MAX_BUFFER_SIZE = 1024;
 };
 
+} // namespace test
+} // namespace hawq
+
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/common.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/common.h b/src/test/feature/lib/common.h
deleted file mode 100644
index 34fc857..0000000
--- a/src/test/feature/lib/common.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef FILE_58f9fa9e_188f_5f43_d103_c16c3132fd24_HPP
-#define FILE_58f9fa9e_188f_5f43_d103_c16c3132fd24_HPP
-
-#include <vector>
-#include <gtest/gtest.h>
-
-namespace hawq {
-namespace test {
-
-template <class V>
-void EQUAL_CHECK(std::vector<V> a,
-                 std::vector<V> b) {
-  EXPECT_EQ(a.size(), b.size());
-  for(size_t i = 0; i < a.size(); ++i) {
-    EXPECT_EQ(a[i], b[i]);
-  }
-}
-
-} // namespace test
-} // namespace hawq
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
deleted file mode 100644
index 5ec806d..0000000
--- a/src/test/feature/lib/data-gen.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-#include "data-gen.h"
-
-#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 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) {
-  std::string desc =
-      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);
-}
-
-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, "
-      "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);
-
-  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);
-
-  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)]',"
-      " 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);
-
-  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);
-
-  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);
-
-  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);
-
-  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);
-}
-
-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);
-
-  std::string insertSql =
-      "insert into " + tableName +
-      " values (15, null, 'aa'), (null, null, 'WET'), (null, 51, null);";
-  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 != -1
-                          ? ", compresslevel = " + std::to_string(compresslevel)
-                          : "") +
-                     ")";
-  return desc;
-}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
deleted file mode 100644
index 3df0ac0..0000000
--- a/src/test/feature/lib/data-gen.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * data-gen.h
- *
- *  Created on: May 11, 2016
- *      Author: malili
- */
-
-#ifndef SRC_TEST_FEATURE_LIB_DATA_GEN_H_
-#define SRC_TEST_FEATURE_LIB_DATA_GEN_H_
-
-#include <string>
-
-#include "gtest/gtest.h"
-#include "sql-util.h"
-
-class DataGenerator {
- public:
-  explicit DataGenerator(SQLUtility *sqlUtil) : sqlUtil(sqlUtil) {}
-
-  ~DataGenerator() {}
-
-  void genSimpleTable(std::string tableName, bool appendonly = true,
-                      std::string orientation = "row",
-                      std::string compresstype = "none",
-                      int compresslevel = -1);
-
-  void genTableWithFullTypes(std::string tableName, bool appendonly = true,
-                             std::string orientation = "row",
-                             std::string compresstype = "none",
-                             int compresslevel = -1);
-
-  void genTableWithSeries(std::string tableName, bool appendonly = true,
-                          std::string orientation = "row",
-                          std::string compresstype = "none",
-                          int compresslevel = -1);
-
-  void genTableWithNull(std::string tableName, bool appendonly = true,
-                        std::string orientation = "row",
-                        std::string compresstype = "none",
-                        int compresslevel = -1);
-
- private:
-  std::string genTableDesc(bool appendonly, std::string orientation,
-                           std::string compresstype, int compresslevel);
-
- private:
-  SQLUtility *sqlUtil = nullptr;
-};
-
-#endif /* SRC_TEST_FEATURE_LIB_DATA_GEN_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
new file mode 100644
index 0000000..df19c09
--- /dev/null
+++ b/src/test/feature/lib/data_gen.cpp
@@ -0,0 +1,149 @@
+#include <string>
+#include "data_gen.h"
+using std::string;
+
+namespace hawq {
+namespace test {
+
+void DataGenerator::genSimpleTable(string tableName, bool appendonly,
+                                   string orientation,
+                                   string compresstype,
+                                   int compresslevel) {
+  string desc =
+      genTableDesc(appendonly, orientation, compresstype, compresslevel);
+  string createSql =
+      "create table " + tableName + "(a int, b int) " + desc;
+  sqlUtil->execute(createSql);
+
+  string insertSql =
+      "insert into " + tableName + " values(51,62), (14,15), (1,3);";
+  sqlUtil->execute(insertSql);
+}
+
+void DataGenerator::genTableWithSeries(string tableName, bool appendonly,
+                                       string orientation,
+                                       string compresstype,
+                                       int compresslevel) {
+  string desc =
+      genTableDesc(appendonly, orientation, compresstype, compresslevel);
+  string createSql =
+      "create table " + tableName + "(a int, b varchar(20)) " + desc;
+  sqlUtil->execute(createSql);
+
+  string insertSql =
+      "insert into " + tableName + " values(generate_series(1,10000), 'abc')";
+  sqlUtil->execute(insertSql);
+}
+
+void DataGenerator::genTableWithFullTypes(string tableName,
+                                          bool appendonly,
+                                          string orientation,
+                                          string compresstype,
+                                          int compresslevel) {
+  string desc =
+      genTableDesc(appendonly, orientation, compresstype, compresslevel);
+  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);
+
+  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);
+
+  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)]',"
+      " 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);
+
+  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);
+
+  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);
+
+  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);
+
+  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);
+}
+
+void DataGenerator::genTableWithNull(string tableName, bool appendonly,
+                                     string orientation,
+                                     string compresstype,
+                                     int compresslevel) {
+  string desc =
+      genTableDesc(appendonly, orientation, compresstype, compresslevel);
+  string createSql =
+      "create table " + tableName + " (a int, b float, c varchar(20)) " + desc;
+  sqlUtil->execute(createSql);
+
+  string insertSql =
+      "insert into " + tableName +
+      " values (15, null, 'aa'), (null, null, 'WET'), (null, 51, null);";
+  sqlUtil->execute(insertSql);
+}
+
+string DataGenerator::genTableDesc(bool appendonly,
+                                   string orientation,
+                                   string compresstype,
+                                   int compresslevel) {
+  string desc = (appendonly ? "with (appendonly = true, orientation = "
+                                 : "with (appendonly = false, orientation = ") +
+                     orientation + ", compresstype = " + compresstype +
+                     (compresslevel != -1
+                          ? ", compresslevel = " + std::to_string(compresslevel)
+                          : "") +
+                     ")";
+  return desc;
+}
+
+} // namespace test
+} // namespace hawq

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
new file mode 100644
index 0000000..5c2adae
--- /dev/null
+++ b/src/test/feature/lib/data_gen.h
@@ -0,0 +1,62 @@
+/*
+ * data_gen.h
+ *
+ *  Created on: May 11, 2016
+ *      Author: malili
+ */
+
+#ifndef HAWQ_SRC_TEST_FEATURE_LIB_DATA_GEN_H_
+#define HAWQ_SRC_TEST_FEATURE_LIB_DATA_GEN_H_
+
+#include <string>
+
+#include "gtest/gtest.h"
+#include "sql_util.h"
+
+namespace hawq {
+namespace test {
+
+class DataGenerator {
+ public:
+  explicit DataGenerator(hawq::test::SQLUtility *sqlUtil_) : sqlUtil(sqlUtil_) {}
+
+  ~DataGenerator() {}
+
+  void genSimpleTable(std::string tableName,
+                      bool appendonly = true,
+                      std::string orientation = "row",
+                      std::string compresstype = "none",
+                      int compresslevel = -1);
+
+  void genTableWithFullTypes(std::string tableName,
+                             bool appendonly = true,
+                             std::string orientation = "row",
+                             std::string compresstype = "none",
+                             int compresslevel = -1);
+
+  void genTableWithSeries(std::string tableName,
+                          bool appendonly = true,
+                          std::string orientation = "row",
+                          std::string compresstype = "none",
+                          int compresslevel = -1);
+
+  void genTableWithNull(std::string tableName,
+                        bool appendonly = true,
+                        std::string orientation = "row",
+                        std::string compresstype = "none",
+                        int compresslevel = -1);
+
+ private:
+  std::string genTableDesc(bool appendonly,
+                           std::string orientation,
+                           std::string compresstype,
+                           int compresslevel);
+
+ private:
+  hawq::test::SQLUtility *sqlUtil = nullptr;
+};
+
+} // namespace test
+} // namespace hawq
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
deleted file mode 100644
index a54bb51..0000000
--- a/src/test/feature/lib/hawq-config.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-#include "hawq-config.h"
-
-#include <fstream>
-#include <iostream>
-#include <set>
-#include <string>
-#include <vector>
-#include <unistd.h>
-
-#include "command.h"
-#include "psql.h"
-#include "string-util.h"
-#include "xml-parser.h"
-
-bool HawqConfig::LoadFromConfigFile() {
-  const char *env = getenv("GPHOME");
-  std::string confPath = env ? env : "";
-  if (!confPath.empty()) {
-    confPath.append("/etc/hawq-site.xml");
-  } else {
-    return false;
-  }
-
-  xmlconf.reset(new XmlConfig(confPath.c_str()));
-  xmlconf->parse();
-  return true;
-}
-
-bool HawqConfig::getMaster(std::string &hostname, int &port) {
-  bool ret = LoadFromConfigFile();
-  if (!ret) {
-    return false;
-  }
-  hostname = xmlconf->getString("hawq_master_address_host");
-  port = xmlconf->getInt32("hawq_master_address_port");
-  return true;
-}
-
-void HawqConfig::getStandbyMaster(std::string &hostname, int &port) {
-  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) {
-    hostname = table[0][0];
-    std::string portStr = table[0][1];
-    port = std::stoi(portStr);
-  }
-}
-
-void HawqConfig::getTotalSegments(std::vector<std::string> &hostname,
-                                  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++) {
-    hostname.push_back(table[i][0]);
-    std::string portStr = table[i][1];
-    port.push_back(std::stoi(portStr));
-  }
-}
-
-void HawqConfig::getSlaves(std::vector<std::string> &hostname) {
-  std::ifstream inFile;
-  char *GPHOME = getenv("GPHOME");
-  if (GPHOME == nullptr) {
-    return;
-  }
-  std::string slaveFile(GPHOME);
-  slaveFile.append("/etc/slaves");
-  inFile.open(slaveFile.c_str());
-  std::string line;
-  while (std::getline(inFile, line)) {
-    hostname.push_back(line);
-  }
-  inFile.close();
-}
-
-void HawqConfig::getUpSegments(std::vector<std::string> &hostname,
-                               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) {
-    hostname.push_back(table[0][0]);
-    std::string portStr = table[0][1];
-    port.push_back(std::stoi(portStr));
-  }
-}
-
-void HawqConfig::getDownSegments(std::vector<std::string> &hostname,
-                                 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) {
-    hostname.push_back(table[0][0]);
-    std::string portStr = table[0][1];
-    port.push_back(std::stoi(portStr));
-  }
-}
-
-std::string HawqConfig::getGucValue(std::string gucName) {
-  std::string cmd = "hawq config -s ";
-  cmd.append(gucName);
-  Command c(cmd);
-  std::string result = c.run().getResultOutput();
-  std::string gucValue = "";
-  std::vector<std::string> lines = StringUtil::split(result, '\n');
-  // second line is value output.
-  if (lines.size() >= 2) {
-    std::string valueLine = lines[1];
-    int pos = valueLine.find_first_of(':');
-    std::string value = valueLine.substr(pos + 1);
-    gucValue = StringUtil::trim(value);
-  }
-  return gucValue;
-}
-
-std::string HawqConfig::setGucValue(std::string gucName, std::string gucValue) {
-  std::string cmd = "hawq config -c ";
-  cmd.append(gucName);
-  cmd.append(" -v ");
-  cmd.append(gucValue);
-  Command c(cmd);
-  std::string ret = c.run().getResultOutput();
-  return ret;
-}
-
-bool HawqConfig::isMasterMirrorSynchronized() {
-  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);
-    if (syncInfo == "Synchronized") {
-      return true;
-    } else {
-      return false;
-    }
-  }
-  return false;
-}
-
-bool HawqConfig::isMultinodeMode() {
-  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;
-  for (int i = 0; i < table.size(); i++) {
-    std::string hostname2 = table[i][0];
-    if (hostname2 == "localhost") {
-      char hostnamestr[256];
-      gethostname(hostnamestr, 255);
-      hostname2.assign(hostnamestr);
-    }
-    if (hostnameMap.find(hostname2) == hostnameMap.end()) {
-      hostnameMap.insert(hostname2);
-    }
-  }
-  if (hostnameMap.size() <= 1) {
-    return false;
-  } else {
-    return true;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/hawq-config.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/hawq-config.h b/src/test/feature/lib/hawq-config.h
deleted file mode 100644
index e1135f8..0000000
--- a/src/test/feature/lib/hawq-config.h
+++ /dev/null
@@ -1,115 +0,0 @@
-#ifndef SRC_TEST_FEATURE_LIB_HAWQ_CONFIG_H_
-#define SRC_TEST_FEATURE_LIB_HAWQ_CONFIG_H_
-
-#include "psql.h"
-#include "sql-util.h"
-#include "xml-parser.h"
-
-/**
- *  HawqConfig common library. Get detailed infomation about HAWQ cluster
- *  including checking state of master and slaves, setting GUC and checking standby.
- *  @author hubert zhang
- */
-class HawqConfig {
-  public:
-    /**
-     * HawqConfig constructor
-     */
-    HawqConfig(): psql(HAWQ_DB, HAWQ_HOST, HAWQ_PORT, HAWQ_USER, HAWQ_PASSWORD) {
-    }
-
-    /**
-     * HawqConfig destructor
-     */
-    ~HawqConfig() {
-    }
-
-    /**
-     * get hawq master's hostname and port information
-     * @param hostname master hostname reference which will be set
-     * @param port master port number reference which will be set
-     * @return true if getMaster succeeded
-     */
-    bool getMaster(std::string &hostname, int &port);
-
-
-    /**
-     * get hawq standby master's hostname and port information
-     * @param hostname master hostname reference which will be set
-     * @param port master port number reference which will be set
-     * @return true if hawq getStandbyMaster succeeded
-     */
-    void getStandbyMaster(std::string &hostname, int &port);
-
-
-    /**
-     * get the list of all of the hawq segments
-     * @param hostname hostname list of all of the hawq segments
-     * @param port port list of all of the hawq segments
-     */
-    void getTotalSegments(std::vector<std::string> &hostname,
-        std::vector<int> &port);
-
-    /**
-     * get list of hostnames in slave file
-     * @param hostname list of hostnames in slave file.
-     */
-    void getSlaves(std::vector<std::string> &hostname);
-
-    /**
-     * get hawq segment list whose state is up(not down).
-     * @param hostname hostname list of all of the up segments
-     * @param port port list of all of the up segments
-     * @see getDownSegments
-     */
-    void getUpSegments(std::vector<std::string> &hostname,
-        std::vector<int> &port);
-
-    /**
-     * get hawq segment list whose state is down.
-     * @param hostname hostname list of all of the down segments
-     * @param port port list of all of the down segments
-     */
-    void getDownSegments(std::vector<std::string> &hostname,
-        std::vector<int> &port);
-
-    /**
-     * get the guc value by name
-     * @param gucName the guc name to be retrived
-     * @return guc value
-     */
-    std::string getGucValue(std::string gucName);
-
-    /**
-     * set guc value by hawq config
-     * @param gucName guc name to be set
-     * @param gucValue the value to be set
-     * @return hawq config return information
-     */
-    std::string setGucValue(std::string gucName, std::string gucValue);
-
-    /**
-     * whether hawq master and mirror is synchronized by checking gp_master_mirroring.
-     * @return true if Synchronized
-     */
-    bool isMasterMirrorSynchronized();
-
-    /**
-     * whether hawq is in multi-node mode.
-     * @return true if hawq is multi-node
-     */
-    bool isMultinodeMode();
-
-  private:
-    /**
-     * load key-value parameters in hawq-site.xml
-     * @return true if succeeded
-     */
-    bool LoadFromConfigFile();
-
-
-    std::unique_ptr<XmlConfig> xmlconf;
-    PSQL psql;
-};
-
-#endif /* SRC_TEST_FEATURE_LIB_HAWQ_CONFIG_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
new file mode 100644
index 0000000..287ca1b
--- /dev/null
+++ b/src/test/feature/lib/hawq_config.cpp
@@ -0,0 +1,170 @@
+#include <fstream>
+#include <string>
+#include <vector>
+#include <unordered_set>
+
+#include "hawq_config.h"
+#include "command.h"
+#include "psql.h"
+#include "xml_parser.h"
+#include "string_util.h"
+
+using std::string;
+
+namespace hawq {
+namespace test {
+
+bool HawqConfig::LoadFromConfigFile() {
+  const char *env = getenv("GPHOME");
+  string confPath = env ? env : "";
+  if (!confPath.empty()) {
+    confPath.append("/etc/hawq-site.xml");
+  } else {
+    return false;
+  }
+
+  xmlconf.reset(new XmlConfig(confPath));
+  xmlconf->parse();
+  return true;
+}
+
+bool HawqConfig::getMaster(string &hostname, int &port) {
+  bool ret = LoadFromConfigFile();
+  if (!ret) {
+    return false;
+  }
+  hostname = xmlconf->getString("hawq_master_address_host");
+  port = xmlconf->getInt32("hawq_master_address_port");
+  return true;
+}
+
+void HawqConfig::getStandbyMaster(string &hostname, int &port) {
+  const hawq::test::PSQLQueryResult &result = psql.getQueryResult(
+      "select hostname, port from gp_segment_configuration where role ='s'");
+  std::vector<std::vector<string> > table = result.getRows();
+  if (table.size() > 0) {
+    hostname = table[0][0];
+    port = std::stoi(table[0][1]);
+  }
+}
+
+void HawqConfig::getTotalSegments(std::vector<string> &hostname,
+                                  std::vector<int> &port) {
+  hostname.resize(0); port.resize(0);
+  const hawq::test::PSQLQueryResult &result = psql.getQueryResult(
+      "select hostname, port from gp_segment_configuration where role ='p'");
+  std::vector<std::vector<string> > table = result.getRows();
+  for (size_t i = 0; i < table.size(); ++i) {
+    hostname.push_back(table[i][0]);
+    port.push_back(std::stoi(table[i][1]));
+  }
+}
+
+void HawqConfig::getSlaves(std::vector<string> &hostname) {
+  hostname.resize(0);
+  std::ifstream inFile;
+  char *GPHOME = getenv("GPHOME");
+  if (GPHOME == nullptr) {
+    return;
+  }
+  string slaveFile(GPHOME);
+  slaveFile.append("/etc/slaves");
+  inFile.open(slaveFile.c_str());
+  string line;
+  while (std::getline(inFile, line)) {
+    hostname.push_back(line);
+  }
+  inFile.close();
+}
+
+void HawqConfig::getUpSegments(std::vector<string> &hostname,
+                               std::vector<int> &port) {
+  hostname.resize(0); port.resize(0);
+  const hawq::test::PSQLQueryResult &result = psql.getQueryResult(
+      "select hostname, port from gp_segment_configuration where role = 'p' "
+      "and status = 'u'");
+  std::vector<std::vector<string> > table = result.getRows();
+  for (size_t i = 0; i < table.size(); ++i) {
+    hostname.push_back(table[i][0]);
+    port.push_back(std::stoi(table[i][1]));
+  }
+}
+
+void HawqConfig::getDownSegments(std::vector<string> &hostname,
+                                 std::vector<int> &port) {
+  const hawq::test::PSQLQueryResult &result = psql.getQueryResult(
+      "select hostname, port from gp_segment_configuration where role = 'p' "
+      "and status != 'u'");
+  std::vector<std::vector<string> > table = result.getRows();
+
+  for (size_t i = 0; i < table.size(); ++i) {
+    hostname.push_back(table[i][0]);
+    port.push_back(std::stoi(table[i][1]));
+  }
+}
+
+string HawqConfig::getGucValue(const string & gucName) {
+  string cmd = "hawq config -s ";
+  cmd.append(gucName);
+  Command c(cmd);
+  string result = c.run().getResultOutput();
+  string gucValue = "";
+  auto lines = hawq::test::split(result, '\n');
+  // second line is value output.
+  if (lines.size() >= 2) {
+    string valueLine = lines[1];
+    int pos = valueLine.find_first_of(':');
+    string value = valueLine.substr(pos + 1);
+    gucValue = hawq::test::trim(value);
+  }
+  return gucValue;
+}
+
+string HawqConfig::setGucValue(const string &gucName,
+                               const string &gucValue) {
+  string cmd = "hawq config -c ";
+  cmd.append(gucName);
+  cmd.append(" -v ");
+  cmd.append(gucValue);
+  Command c(cmd);
+  string ret = c.run().getResultOutput();
+  return ret;
+}
+
+bool HawqConfig::isMasterMirrorSynchronized() {
+  const hawq::test::PSQLQueryResult &result =
+      psql.getQueryResult("select summary_state from gp_master_mirroring");
+  if (result.getRows().size() > 0) {
+    string syncInfo = result.getData(0, 0);
+    syncInfo = hawq::test::trim(syncInfo);
+    if (syncInfo == "Synchronized") {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  return false;
+}
+
+bool HawqConfig::isMultinodeMode() {
+  const hawq::test::PSQLQueryResult &result =
+      psql.getQueryResult("select hostname from gp_segment_configuration");
+  std::vector<std::vector<string> > table = result.getRows();
+  std::unordered_set<string> hostnameMap;
+  for (int i = 0; i < table.size(); i++) {
+    string hostname2 = table[i][0];
+    if (hostname2 == "localhost") {
+      char hostnamestr[256];
+      gethostname(hostnamestr, 255);
+      hostname2.assign(hostnamestr);
+    }
+    hostnameMap.insert(hostname2);
+  }
+  if (hostnameMap.size() <= 1) {
+    return false;
+  }
+  return true;
+}
+
+} // namespace test
+} // namespace hawq

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/hawq_config.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/hawq_config.h b/src/test/feature/lib/hawq_config.h
new file mode 100644
index 0000000..8094ad5
--- /dev/null
+++ b/src/test/feature/lib/hawq_config.h
@@ -0,0 +1,123 @@
+#ifndef HAWQ_SRC_TEST_FEATURE_LIB_HAWQ_CONFIG_H_
+#define HAWQ_SRC_TEST_FEATURE_LIB_HAWQ_CONFIG_H_
+
+#include <string>
+#include <vector>
+
+#include "psql.h"
+#include "sql_util.h"
+#include "xml_parser.h"
+
+namespace hawq {
+namespace test {
+
+/**
+ *  HawqConfig common library. Get detailed infomation about HAWQ cluster
+ *  including checking state of master and slaves, setting GUC and checking standby.
+ *  @author hubert zhang
+ */
+class HawqConfig {
+  public:
+    /**
+     * HawqConfig constructor
+     */
+    HawqConfig(): psql(HAWQ_DB, HAWQ_HOST, HAWQ_PORT, HAWQ_USER, HAWQ_PASSWORD) {}
+
+    /**
+     * HawqConfig destructor
+     */
+    ~HawqConfig() {}
+
+    /**
+     * get hawq master's hostname and port information
+     * @param hostname master hostname reference which will be set
+     * @param port master port number reference which will be set
+     * @return true if getMaster succeeded
+     */
+    bool getMaster(std::string &hostname, int &port);
+
+
+    /**
+     * get hawq standby master's hostname and port information
+     * @param hostname master hostname reference which will be set
+     * @param port master port number reference which will be set
+     * @return true if hawq getStandbyMaster succeeded
+     */
+    void getStandbyMaster(std::string &hostname, int &port);
+
+
+    /**
+     * get the list of all of the hawq segments
+     * @param hostname hostname list of all of the hawq segments
+     * @param port port list of all of the hawq segments
+     */
+    void getTotalSegments(std::vector<std::string> &hostname,
+                          std::vector<int> &port);
+
+    /**
+     * get list of hostnames in slave file
+     * @param hostname list of hostnames in slave file.
+     */
+    void getSlaves(std::vector<std::string> &hostname);
+
+    /**
+     * get hawq segment list whose state is up(not down).
+     * @param hostname hostname list of all of the up segments
+     * @param port port list of all of the up segments
+     * @see getDownSegments
+     */
+    void getUpSegments(std::vector<std::string> &hostname,
+                       std::vector<int> &port);
+
+    /**
+     * get hawq segment list whose state is down.
+     * @param hostname hostname list of all of the down segments
+     * @param port port list of all of the down segments
+     */
+    void getDownSegments(std::vector<std::string> &hostname,
+                         std::vector<int> &port);
+
+    /**
+     * get the guc value by name
+     * @param gucName the guc name to be retrived
+     * @return guc value
+     */
+    std::string getGucValue(const std::string & gucName);
+
+    /**
+     * set guc value by hawq config
+     * @param gucName guc name to be set
+     * @param gucValue the value to be set
+     * @return hawq config return information
+     */
+    std::string setGucValue(const std::string & gucName,
+                            const std::string & gucValue);
+
+    /**
+     * whether hawq master and mirror is synchronized by checking gp_master_mirroring.
+     * @return true if Synchronized
+     */
+    bool isMasterMirrorSynchronized();
+
+    /**
+     * whether hawq is in multi-node mode.
+     * @return true if hawq is multi-node
+     */
+    bool isMultinodeMode();
+
+  private:
+    /**
+     * load key-value parameters in hawq-site.xml
+     * @return true if succeeded
+     */
+    bool LoadFromConfigFile();
+
+  private:
+    std::unique_ptr<XmlConfig> xmlconf;
+    hawq::test::PSQL psql;
+};
+
+} // namespace test
+} // namespace hawq
+
+#endif /* SRC_TEST_FEATURE_LIB_HAWQ_CONFIG_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/psql.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/psql.cpp b/src/test/feature/lib/psql.cpp
index b7978ac..ecdd925 100644
--- a/src/test/feature/lib/psql.cpp
+++ b/src/test/feature/lib/psql.cpp
@@ -1,39 +1,45 @@
-#include <iostream>
 #include <unistd.h>
 #include "psql.h"
 #include "command.h"
 
+using std::string;
+
+namespace hawq {
+namespace test {
+
 #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) {
+void PSQLQueryResult::setErrorMessage(const string & errmsg) {
   this->_errmsg = errmsg;
 }
 
-const std::string& PSQLQueryResult::getErrorMessage() const {
+const 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 {
+const std::vector<std::vector<string> >& PSQLQueryResult::getRows() const {
   return this->_rows;
 }
 
-const std::vector<std::string>& PSQLQueryResult::getFields() const {
+const std::vector<string>& PSQLQueryResult::getFields() const {
   return this->_fields;
 }
 
-const std::vector<std::string>& PSQLQueryResult::getRow(int ri) const {
+const std::vector<string>& PSQLQueryResult::getRow(int ri) const {
   return this->getRows()[ri];
 }
 
-const std::string& PSQLQueryResult::getData(int ri, int ci) const {
+const string& PSQLQueryResult::getData(int ri, int ci) const {
   return this->getRow(ri)[ci];
 }
 
-std::string PSQLQueryResult::getData(int ri, const std::string& ck) const {
+string PSQLQueryResult::getData(int ri, const string& ck) const {
   for (int ci = 0; ci < this->_fields.size(); ci++) {
     if (ck == this->_fields[ci]) {
       return this->getData(ri, ci);
@@ -42,24 +48,26 @@ std::string PSQLQueryResult::getData(int ri, const std::string& ck) const {
   return "";
 }
 
-const std::string& PSQLQueryResult::getFieldName(int ci) const {
+const string& PSQLQueryResult::getFieldName(int ci) const {
   return this->_fields[ci];
 }
 
-int PSQLQueryResult::rowCount() const { return this->_rows.size(); }
+int PSQLQueryResult::rowCount() const {
+  return this->_rows.size();
+}
 
-int PSQLQueryResult::fieldCount() const { return this->_fields.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++) {
+  for (int 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++) {
+  for (int i = 0; i < PQntuples(res); i++) {
+    std::vector<string> row;
+    for (int j = 0; j < nfields; j++) {
       row.push_back(PQgetvalue(res, i, j));
     }
     this->_rows.push_back(row);
@@ -72,21 +80,21 @@ void PSQLQueryResult::reset() {
   this->_fields.clear();
 }
 
-PSQL& PSQL::runSQLCommand(const std::string& sql_cmd) {
-  Command c(this->_getPSQLQueryCommand(sql_cmd));
+PSQL& PSQL::runSQLCommand(const string& sql_cmd) {
+  hawq::test::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) {
+PSQL& PSQL::runSQLFile(const string& sql_file) {
   this->_last_status =
-      Command::getCommandStatus(this->_getPSQLFileCommand(sql_file));
+      hawq::test::Command::getCommandStatus(this->_getPSQLFileCommand(sql_file));
   return *this;
 }
 
-const PSQLQueryResult& PSQL::getQueryResult(const std::string& sql) {
+const PSQLQueryResult& PSQL::getQueryResult(const string& sql) {
   PGconn* conn = NULL;
   PGresult* res = NULL;
 
@@ -101,7 +109,6 @@ const PSQLQueryResult& PSQL::getQueryResult(const std::string& sql) {
     this->_result.setErrorMessage(PQerrorMessage(conn));
     goto done;
   }
-
   this->_result.reset();
   this->_result.savePGResult(res);
 
@@ -110,45 +117,45 @@ done:
     PQclear(res);
     res = NULL;
   }
-
   if (conn) {
     PQfinish(conn);
     conn = NULL;
   }
-
   return this->_result;
 }
 
-PSQL& PSQL::setHost(const std::string& host) {
+PSQL& PSQL::setHost(const string& host) {
   this->_host = host;
   return *this;
 }
 
-PSQL& PSQL::setPort(const std::string& port) {
+PSQL& PSQL::setPort(const string& port) {
   this->_port = port;
   return *this;
 }
 
-PSQL& PSQL::setUser(const std::string& username) {
+PSQL& PSQL::setUser(const string& username) {
   this->_user = username;
   return *this;
 }
 
-PSQL& PSQL::setPassword(const std::string& password) {
+PSQL& PSQL::setPassword(const string& password) {
   this->_password = password;
   return *this;
 }
 
-PSQL& PSQL::setOutputFile(const std::string& out) {
+PSQL& PSQL::setOutputFile(const string& out) {
   this->_output_file = out;
   return *this;
 }
 
-void PSQL::resetOutput() { this->_output_file.clear(); }
+void PSQL::resetOutput() {
+  this->_output_file.clear();
+}
 
-std::string PSQL::getConnectionString() const {
+string PSQL::getConnectionString() const {
   // host=localhost port=5432 dbname=mydb
-  std::string command;
+  string command;
   command.append("host=")
       .append(this->_host)
       .append(" port=")
@@ -160,12 +167,16 @@ std::string PSQL::getConnectionString() const {
   return command;
 }
 
-int PSQL::getLastStatus() const { return this->_last_status; }
+int PSQL::getLastStatus() const {
+  return this->_last_status;
+}
 
-const std::string& PSQL::getLastResult() const { return this->_last_result; }
+const string& PSQL::getLastResult() const {
+  return this->_last_result;
+}
 
-const std::string PSQL::_getPSQLBaseCommand() const {
-  std::string command = "psql";
+const string PSQL::_getPSQLBaseCommand() const {
+  string command = "psql";
   command.append(" -p ").append(this->_port);
   command.append(" -h ").append(this->_host);
   command.append(" -U ").append(this->_user);
@@ -173,24 +184,24 @@ const std::string PSQL::_getPSQLBaseCommand() const {
   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();
+const string PSQL::_getPSQLQueryCommand(const string& query) const {
+  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();
+const string PSQL::_getPSQLFileCommand(const string& file) const {
+  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;
+bool PSQL::checkDiff(const string& expect_file,
+                     const string& result_file,
+                     bool save_diff) {
+  string diff_file = result_file + ".diff";
+  string command;
   command.append("gpdiff.pl ")
       .append(PSQL_BASIC_DIFF_OPTS)
       .append(" ")
@@ -201,7 +212,7 @@ bool PSQL::checkDiff(const std::string& expect_file,
       .append(" >")
       .append(diff_file);
 
-  if (Command::getCommandStatus(command) == 0) {
+  if (hawq::test::Command::getCommandStatus(command) == 0) {
     unlink(diff_file.c_str());
     return false;
   } else {
@@ -211,3 +222,6 @@ bool PSQL::checkDiff(const std::string& expect_file,
     return true;
   }
 }
+
+} // namespace test
+} // namespace hawq

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/psql.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/psql.h b/src/test/feature/lib/psql.h
index 4105d6e..573b1a9 100644
--- a/src/test/feature/lib/psql.h
+++ b/src/test/feature/lib/psql.h
@@ -1,16 +1,21 @@
-#ifndef __PSQL_H__
-#define __PSQL_H__
+#ifndef HAWQ_SRC_TEST_FEATURE_PSQL_H_
+#define HAWQ_SRC_TEST_FEATURE_PSQL_H_
 
+#include <string>
 #include <vector>
 
 #include "command.h"
 #include "libpq-fe.h"
+
+namespace hawq {
+namespace test {
+
 class PSQLQueryResult {
  public:
   PSQLQueryResult() {}
 
   void savePGResult(const PGresult* res);
-  void setErrorMessage(const std::string errmsg);
+  void setErrorMessage(const std::string& errmsg);
   const std::string& getErrorMessage() const;
   bool isError() const;
 
@@ -41,11 +46,8 @@ class PSQL {
   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) {}
+      : _dbname(db), _host(host), _port(port),
+      _user(user), _password(password) {}
   virtual ~PSQL(){};
 
   PSQL& runSQLCommand(const std::string& sql_cmd);
@@ -63,7 +65,8 @@ class PSQL {
   const std::string& getLastResult() const;
 
   static bool checkDiff(const std::string& expect_file,
-                        const std::string& result_file, bool save_diff = true);
+                        const std::string& result_file,
+                        bool save_diff = true);
 
   void resetOutput();
 
@@ -87,4 +90,7 @@ class PSQL {
   std::string _last_result;
 };
 
+} // namespace test
+} // namespace hawq
+
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
deleted file mode 100644
index 6961983..0000000
--- a/src/test/feature/lib/sql-util.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "sql-util.h"
-
-#include <pwd.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <fstream>
-#include <iostream>
-#include <vector>
-
-#include "string-util.h"
-
-#ifdef __linux__
-#include <limits.h>
-#include <unistd.h>
-#elif __APPLE__
-#include <libproc.h>
-#endif
-
-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();
-  exec("DROP SCHEMA IF EXISTS " + schemaName + " CASCADE");
-  exec("CREATE SCHEMA " + schemaName);
-}
-
-SQLUtility::~SQLUtility() {
-  if (!test_info->result()->Failed())
-    exec("DROP SCHEMA " + schemaName + " CASCADE");
-}
-
-void SQLUtility::exec(const std::string &sql) {
-  EXPECT_EQ(0, (conn->runSQLCommand(sql)).getLastStatus())
-      << conn->getLastResult();
-}
-
-void SQLUtility::execute(const std::string &sql, bool check) {
-  conn->runSQLCommand("SET SEARCH_PATH=" + schemaName + ";" + sql);
-  EXPECT_NE(conn.get(), nullptr);
-  if (check) EXPECT_EQ(0, conn->getLastStatus()) << 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 outFileAbsPath = fp.path + "/" + fp.fileBaseName + ".out";
-  conn->setOutputFile(outFileAbsPath);
-  EXPECT_EQ(0, conn->runSQLFile(newSqlFile).getLastStatus());
-  conn->resetOutput();
-  EXPECT_FALSE(conn->checkDiff(ansFileAbsPath, outFileAbsPath, true));
-  if (conn->checkDiff(ansFileAbsPath, outFileAbsPath, true) == false) {
-    // no diff, continue to delete the generated sql file
-    if (remove(newSqlFile.c_str()))
-      ASSERT_TRUE(false) << "Error deleting file " << newSqlFile;
-  } else {
-    EXPECT_FALSE(true);
-  }
-}
-
-std::unique_ptr<PSQL> SQLUtility::getConnection() {
-  std::string user = HAWQ_USER;
-  if (user.empty()) {
-    struct passwd *pw;
-    uid_t uid = geteuid();
-    pw = getpwuid(uid);
-    user.assign(pw->pw_name);
-  }
-  std::unique_ptr<PSQL> psql(
-      new PSQL(HAWQ_DB, HAWQ_HOST, HAWQ_PORT, 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 << std::endl;
-  }
-  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;
-}
-
-const PSQL *SQLUtility::getPSQL() const { return conn.get(); }
-
-std::string SQLUtility::getTestRootPath() const {
-  std::string result;
-#ifdef __linux__
-  char pathbuf[PATH_MAX];
-  ssize_t count = readlink("/proc/self/exe", pathbuf, PATH_MAX);
-  if (count <= 0)
-    EXPECT_TRUE(false) << "readlink /proc/self/exe error: " << strerror(errno);
-  result = std::string(pathbuf, count);
-#elif __APPLE__
-  int ret;
-  pid_t pid;
-  char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
-
-  pid = getpid();
-  ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf));
-  if (ret <= 0)
-    EXPECT_TRUE(false) << "PID " << pid << ": proc_pidpath () "
-                       << strerror(errno);
-  result = std::string(pathbuf);
-#endif
-  return splitFilePath(result).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/ec098032/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
deleted file mode 100644
index 9fb8994..0000000
--- a/src/test/feature/lib/sql-util.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef SRC_TEST_FEATURE_LIB_SQL_UTIL_H_
-#define SRC_TEST_FEATURE_LIB_SQL_UTIL_H_
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#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") : "")
-#define HAWQ_PASSWORD (getenv("PGPASSWORD") ? getenv("PGPASSWORD") : "")
-
-struct FilePath {
-  std::string path;
-  std::string fileBaseName;
-  std::string fileSuffix;
-};
-
-class SQLUtility {
- public:
-  SQLUtility();
-  ~SQLUtility();
-
-  // Execute sql command
-  // @param sql The given sql command
-  // @return void
-  void execute(const std::string &sql, bool check = true);
-
-  // 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
-  const PSQL *getPSQL() const;
-
-  // Get test root dir abs path
-  // @return path string
-  std::string getTestRootPath() const;
-
- private:
-  std::unique_ptr<PSQL> getConnection();
-  const std::string generateSQLFile(const std::string &sqlFile);
-  const PSQLQueryResult &executeQuery(const std::string &sql);
-  FilePath splitFilePath(const std::string &filePath) const;
-  void exec(const std::string &sql);
-
- private:
-  std::string schemaName;
-  std::unique_ptr<PSQL> conn;
-  std::string testRootPath;
-  const ::testing::TestInfo *const test_info;
-};
-
-#endif  // SRC_TEST_FEATURE_LIB_SQL_UTIL_H_

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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..4f48664
--- /dev/null
+++ b/src/test/feature/lib/sql_util.cpp
@@ -0,0 +1,178 @@
+#include <pwd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <vector>
+
+#include "sql_util.h"
+#include "string_util.h"
+
+#ifdef __linux__
+#include <limits.h>
+#include <unistd.h>
+#elif __APPLE__
+#include <libproc.h>
+#endif
+
+using std::string;
+
+namespace hawq {
+namespace test {
+
+SQLUtility::SQLUtility()
+    : testRootPath(getTestRootPath()),
+      test_info(::testing::UnitTest::GetInstance()->current_test_info()) {
+  auto getConnection = [&] () {
+    string user = HAWQ_USER;
+    if(user.empty()) {
+      struct passwd *pw;
+      uid_t uid = geteuid();
+      pw = getpwuid(uid);
+      user.assign(pw->pw_name);
+    }
+    conn.reset(new hawq::test::PSQL(HAWQ_DB, HAWQ_HOST, HAWQ_PORT, user, HAWQ_PASSWORD));
+  };
+  getConnection();
+
+  schemaName =
+      string(test_info->test_case_name()) + "_" + test_info->name();
+  exec("DROP SCHEMA IF EXISTS " + schemaName + " CASCADE");
+  exec("CREATE SCHEMA " + schemaName);
+}
+
+SQLUtility::~SQLUtility() {
+  if (!test_info->result()->Failed())
+    exec("DROP SCHEMA " + schemaName + " CASCADE");
+}
+
+void SQLUtility::exec(const string &sql) {
+  EXPECT_EQ(0, (conn->runSQLCommand(sql)).getLastStatus())
+      << conn->getLastResult();
+}
+
+void SQLUtility::execute(const string &sql, bool check) {
+  conn->runSQLCommand("SET SEARCH_PATH=" + schemaName + ";" + sql);
+  EXPECT_NE(conn.get(), nullptr);
+  if (check) EXPECT_EQ(0, conn->getLastStatus()) << conn->getLastResult();
+}
+
+void SQLUtility::query(const string &sql, int expectNum) {
+  const hawq::test::PSQLQueryResult &result = executeQuery(sql);
+  ASSERT_FALSE(result.isError()) << result.getErrorMessage();
+  EXPECT_EQ(expectNum, result.rowCount());
+}
+
+void SQLUtility::query(const string &sql, const string &expectStr) {
+  const hawq::test::PSQLQueryResult &result = executeQuery(sql);
+  ASSERT_FALSE(result.isError()) << result.getErrorMessage();
+  std::vector<std::vector<string> > resultString = result.getRows();
+  string resultStr;
+  for (auto row : result.getRows()) {
+    for (auto column : row) resultStr += column + "|";
+    resultStr += "\n";
+  }
+  EXPECT_EQ(expectStr, resultStr);
+}
+
+void SQLUtility::execSQLFile(const string &sqlFile,
+                             const string &ansFile) {
+  // do precheck for sqlFile & ansFile
+  if (hawq::test::startsWith(sqlFile, "/") ||
+      hawq::test::startsWith(ansFile, "/"))
+    ASSERT_TRUE(false) << "For sqlFile and ansFile, relative path to feature "
+                          "test root dir is needed";
+  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 string newSqlFile = generateSQLFile(sqlFile);
+
+  // outFile is located in the same folder with ansFile
+  string outFileAbsPath = fp.path + "/" + fp.fileBaseName + ".out";
+  conn->setOutputFile(outFileAbsPath);
+  EXPECT_EQ(0, conn->runSQLFile(newSqlFile).getLastStatus());
+  conn->resetOutput();
+  EXPECT_FALSE(conn->checkDiff(ansFileAbsPath, outFileAbsPath, true));
+  if (conn->checkDiff(ansFileAbsPath, outFileAbsPath, true) == false) {
+    // no diff, continue to delete the generated sql file
+    if (remove(newSqlFile.c_str()))
+      ASSERT_TRUE(false) << "Error deleting file " << newSqlFile;
+  } else {
+    EXPECT_FALSE(true);
+  }
+}
+
+const string SQLUtility::generateSQLFile(const string &sqlFile) {
+  const string originSqlFile = testRootPath + "/" + sqlFile;
+  const 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;
+  string line;
+  while (getline(in, line)) {
+    out << line << std::endl;
+  }
+  in.close();
+  out.close();
+  return newSqlFile;
+}
+
+const hawq::test::PSQLQueryResult &SQLUtility::executeQuery(const string &sql) {
+  const hawq::test::PSQLQueryResult &result =
+      conn->getQueryResult("SET SEARCH_PATH=" + schemaName + ";" + sql);
+  return result;
+}
+
+const hawq::test::PSQL *SQLUtility::getPSQL() const { return conn.get(); }
+
+string SQLUtility::getTestRootPath() const {
+  string result;
+#ifdef __linux__
+  char pathbuf[PATH_MAX];
+  ssize_t count = readlink("/proc/self/exe", pathbuf, PATH_MAX);
+  if (count <= 0)
+    EXPECT_TRUE(false) << "readlink /proc/self/exe error: " << strerror(errno);
+  result = string(pathbuf, count);
+#elif __APPLE__
+  int ret;
+  pid_t pid;
+  char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
+
+  pid = getpid();
+  ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf));
+  if (ret <= 0)
+    EXPECT_TRUE(false) << "PID " << pid << ": proc_pidpath () "
+                       << strerror(errno);
+  result = string(pathbuf);
+#endif
+  return splitFilePath(result).path;
+}
+
+FilePath SQLUtility::splitFilePath(const 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;
+}
+
+} // namespace test
+} // namespace hawq

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/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
new file mode 100644
index 0000000..296108b
--- /dev/null
+++ b/src/test/feature/lib/sql_util.h
@@ -0,0 +1,78 @@
+#ifndef HAWQ_SRC_TEST_FEATURE_LIB_SQL_UTIL_H_
+#define HAWQ_SRC_TEST_FEATURE_LIB_SQL_UTIL_H_
+
+#include <memory>
+#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") : "")
+#define HAWQ_PASSWORD (getenv("PGPASSWORD") ? getenv("PGPASSWORD") : "")
+
+namespace hawq {
+namespace test {
+ 
+struct FilePath {
+  std::string path;
+  std::string fileBaseName;
+  std::string fileSuffix;
+};
+
+class SQLUtility {
+ public:
+  SQLUtility();
+  ~SQLUtility();
+
+  // Execute sql command
+  // @param sql The given sql command
+  // @return void
+  void execute(const std::string &sql, bool check = true);
+
+  // 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
+  const hawq::test::PSQL *getPSQL() const;
+
+  // Get test root dir abs path
+  // @return path string
+  std::string getTestRootPath() const;
+
+ private:
+  std::unique_ptr<hawq::test::PSQL> getConnection();
+  const std::string generateSQLFile(const std::string &sqlFile);
+  const hawq::test::PSQLQueryResult &executeQuery(const std::string &sql);
+  FilePath splitFilePath(const std::string &filePath) const;
+  void exec(const std::string &sql);
+
+ private:
+  std::string schemaName;
+  std::unique_ptr<hawq::test::PSQL> conn;
+  std::string testRootPath;
+  const ::testing::TestInfo *const test_info;
+}; // class SQLUtility
+
+} // namespace test
+} // namespace hawq
+
+#endif  // SRC_TEST_FEATURE_LIB_SQL_UTIL_H_

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/string-util.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/string-util.cpp b/src/test/feature/lib/string-util.cpp
deleted file mode 100644
index e4bb7f5..0000000
--- a/src/test/feature/lib/string-util.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-#include "string-util.h"
-
-#include <algorithm>
-#include <cassert>
-#include <regex>
-#include <string>
-
-bool StringUtil::iequals(const std::string &str1, const std::string &str2) {
-  if (str1.size() != str2.size()) {
-    return false;
-  }
-  for (std::string::const_iterator c1 = str1.begin(), c2 = str2.begin();
-       c1 != str1.end(); ++c1, ++c2) {
-    if (tolower(*c1) != tolower(*c2)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-void StringUtil::replace(std::string *subject, const std::string &search,
-                         const std::string &replace) {
-  size_t pos = 0;
-  while ((pos = subject->find(search, pos)) != std::string::npos) {
-    subject->replace(pos, search.length(), replace);
-    pos += replace.length();
-  }
-}
-
-void StringUtil::toLower(std::string *str) {
-  assert(str != nullptr);
-
-  std::transform(str->begin(), str->end(), str->begin(), ::tolower);
-}
-
-std::string StringUtil::lower(const std::string &str) {
-  std::string result;
-
-  for (std::string::const_iterator iter = str.begin(); iter != str.end();
-       iter++) {
-    char c = tolower(*iter);
-    result.append(&c, sizeof(char));
-  }
-
-  return result;
-}
-
-std::string &StringUtil::trim(std::string &s) {  // NOLINT
-  if (s.empty()) {
-    return s;
-  }
-  s.erase(0, s.find_first_not_of(" "));
-  s.erase(s.find_last_not_of(" ") + 1);
-  return s;
-}
-
-std::string &StringUtil::trimNewLine(std::string &s) {  // NOLINT
-  s.erase(std::remove(s.begin(), s.end(), '\n'), s.end());
-  return s;
-}
-
-std::vector<std::string> StringUtil::split(const std::string &s,
-                                           char delimiter) {
-  std::vector<std::string> v;
-
-  std::string::size_type i = 0;
-  std::string::size_type j = s.find(delimiter);
-  if (j == std::string::npos) {
-    v.push_back(s);
-  }
-  while (j != std::string::npos) {
-    v.push_back(s.substr(i, j - i));
-    i = ++j;
-    j = s.find(delimiter, j);
-
-    if (j == std::string::npos) v.push_back(s.substr(i, s.length()));
-  }
-  return v;
-}
-
-std::string StringUtil::regexReplace(std::string *subject,
-                                     const std::string &pattern,
-                                     const std::string &replace) {
-  const std::regex regPattern(pattern);
-  return std::regex_replace(*subject, regPattern, replace);
-}
-
-bool StringUtil::StartWith(const std::string &str,
-                           const std::string &strStart) {
-  if (str.empty() || strStart.empty()) {
-    return false;
-  }
-  return str.compare(0, strStart.size(), strStart) == 0 ? true : false;
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/string-util.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/string-util.h b/src/test/feature/lib/string-util.h
deleted file mode 100644
index f593a8c..0000000
--- a/src/test/feature/lib/string-util.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef SRC_TEST_FEATURE_LIB_STRING_UTIL_H_
-#define SRC_TEST_FEATURE_LIB_STRING_UTIL_H_
-
-
-#include <iomanip>
-#include <sstream>
-#include <string>
-#include <vector>
-
-class StringUtil {
- public:
-  StringUtil() {}
-  ~StringUtil() {}
-
-  static bool iequals(const std::string &str1, const std::string &str2);
-  static void replace(std::string *subject, const std::string &search,
-                      const std::string &replace);
-  static std::string regexReplace(std::string *subject,
-                                  const std::string &pattern,
-                                  const std::string &replace);
-  static void toLower(std::string *str);
-  static std::string lower(const std::string &str);
-  static std::string &trim(std::string &s);         // NOLINT
-  static std::string &trimNewLine(std::string &s);  // NOLINT
-  static std::vector<std::string> split(const std::string &s, char delimiter);
-  static bool StartWith(const std::string &str, const std::string &strStart);
-
-  template <typename T>
-  static std::string toStringWithPrecision(const T value, const int n) {
-    std::ostringstream out;
-    out << std::setiosflags(std::ios::fixed) << std::setprecision(n) << value;
-    return out.str();
-  }
-};
-#endif /* SRC_TEST_FEATURE_LIB_STRING_UTIL_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/string_util.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/string_util.cpp b/src/test/feature/lib/string_util.cpp
new file mode 100644
index 0000000..c26c0c8
--- /dev/null
+++ b/src/test/feature/lib/string_util.cpp
@@ -0,0 +1,93 @@
+#include <cassert>
+#include <vector>
+#include <string>
+#include <regex>
+#include <algorithm>
+
+#include "string_util.h"
+
+using std::vector;
+using std::string;
+
+namespace hawq {
+namespace test {
+
+bool iequals(const string & str1, const string & str2) {
+  if (str1.size() != str2.size()) {
+    return false;
+  }
+  for(size_t k = 0; k < str1.size(); ++k) {
+    if (tolower(str1[k]) != tolower(str2[k])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void replace(string & str,
+             const string & search,
+             const string & substitute) {
+  size_t pos = 0;
+  while ((pos = str.find(search, pos)) != string::npos) {
+    str.replace(pos, search.size(), substitute);
+    pos += substitute.size();
+  }
+}
+
+void toLower(string & str) {
+  std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+}
+
+string lower(const string & str) {
+  string ss(str);
+  std::transform(ss.begin(), ss.end(), ss.begin(), ::tolower);
+  return ss;
+}
+
+string &trim(string & str) { // NOLINT
+  if (str.empty()) {
+    return str;
+  }
+  str.erase(0, str.find_first_not_of(" "));
+  str.erase(str.find_last_not_of(" ") + 1);
+  return str;
+}
+
+string &trimNewLine(string & str) { // NOLINT
+  str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());
+  return str;
+}
+
+vector<string> split(const string & str, char delimiter) {
+  vector<string> res;
+  size_t st = 0, en = 0;
+  while(1) {
+    en = str.find(delimiter, st);
+    auto s = str.substr(st, en - st);
+    if(s.size()) res.push_back(std::move(s));
+    if(en == string::npos) break;
+    st = en + 1;
+  }
+  return res;
+}
+
+string regexReplace(string & str,
+                    const string & re,
+                    const string & fmt) {
+  const std::regex rexp(re);
+  return std::regex_replace(str, rexp, fmt);
+}
+
+bool startsWith(const string & str, const string & key) {
+  return str.find(key) == 0;
+}
+
+bool endsWith(const string & str, const string & key) {
+  if(str.size() < key.size()) {
+    return false;
+  }
+  return str.rfind(key) == (str.size() - key.size());
+}
+
+}
+} // namespace hawq

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ec098032/src/test/feature/lib/string_util.h
----------------------------------------------------------------------
diff --git a/src/test/feature/lib/string_util.h b/src/test/feature/lib/string_util.h
new file mode 100644
index 0000000..5aa6246
--- /dev/null
+++ b/src/test/feature/lib/string_util.h
@@ -0,0 +1,33 @@
+#ifndef HAWQ_SRC_TEST_FEATURE_LIB_STRING_UTIL_H_
+#define HAWQ_SRC_TEST_FEATURE_LIB_STRING_UTIL_H_
+
+#include <string>
+#include <vector>
+
+namespace hawq {
+namespace test {
+
+bool iequals(const std::string &, const std::string &);
+
+void replace(std::string &, const std::string &, const std::string &);
+
+void toLower(std::string &);
+
+std::string lower(const std::string &);
+
+std::string &trim(std::string &);
+
+std::string &trimNewLine(std::string &);
+
+std::vector<std::string> split(const std::string &, char);
+
+std::string regexReplace(std::string &, const std::string &, const std::string &);
+
+bool startsWith(const std::string &, const std::string &);
+
+bool endsWith(const std::string &, const std::string &);
+
+} // namespace test
+} // namespace hawq 
+
+#endif


Mime
View raw message