blob: 97302383bf36f2ad94d7f3029854b457ee6340f3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <fstream>
#include "lib/command.h"
#include "lib/sql_util_parallel.h"
#include "lib/xml_parser.h"
#include "test_cloud.h"
#define CREATE_ROLE "CREATE ROLE"
#define ALTER_ROLE "ALTER ROLE"
#define DROP_ROLE "DROP ROLE"
using hawq::test::Command;
TEST_F(TestCloud, Permissions) {
ASSERT_TRUE(testLogin(getUserName(), HAWQ_PASSWORD))
<< "Connect Error: Can't login as " + getUserName();
execSql("drop role if exists lava;");
execSql("drop role if exists user1;");
execSql("drop role if exists user2;");
execSql(getHost2(), "drop role if exists user2;");
std::string result;
result = execSql("create role lava password \'lava00000000\';");
const std::string lava_pwd("lava00000000");
ASSERT_TRUE(checkOut(result, CREATE_ROLE))
<< "create role lava failure: " + result;
EXPECT_FALSE(testLogin("lava", lava_pwd))
<< "Error: lava can login before grant login permission";
result = execSql("alter role lava login;");
ASSERT_TRUE(checkOut(result, ALTER_ROLE))
<< "grant lava login permission failure: " + result;
ASSERT_TRUE(testLogin("lava", lava_pwd))
<< "Error: lava can't login after grant login permission";
result = execSql("alter role lava Superuser;");
ASSERT_TRUE(checkOut(result, ALTER_ROLE))
<< "grant lava Superuser permision failure: " + result;
result = execSql("alter role lava Createrole;");
ASSERT_TRUE(checkOut(result, ALTER_ROLE))
<< "grant lava Createrole permision failure: " + result;
result = execSql("lava", lava_pwd,
"create role user1 login password \'user100000000\';");
ASSERT_TRUE((checkOut(result, CREATE_ROLE)))
<< "lava create user1 failure: " + result;
ASSERT_TRUE(testLogin("user1", "user100000000")) << "login as user1 failure";
result = execSql("lava", lava_pwd,
"alter role user1 password \'newPwd00000000\';");
const std::string user_newPwd = "newPwd00000000";
ASSERT_TRUE(checkOut(result, ALTER_ROLE))
<< "lava reset user1's password failure";
EXPECT_FALSE(testLogin("user1", "user100000000"))
<< "user1 can login after reset password";
EXPECT_TRUE(testLogin("user1", user_newPwd))
<< "user1 user new password can't login after reset password";
result = execSql("user1", user_newPwd,
"create role user2 password \'user200000000\'");
EXPECT_FALSE(checkOut(result, CREATE_ROLE))
<< "user1 can create user2 before get creatrole permissions: " + result;
result = execSql("lava", lava_pwd, "alter role user1 createrole;");
ASSERT_TRUE(checkOut(result, ALTER_ROLE))
<< "lava grant user1 createrole permissions failure: " + result;
result = execSql("user1", user_newPwd,
"create role user2 password \'user200000000\'");
ASSERT_TRUE(checkOut(result, CREATE_ROLE))
<< "user1 can't create user2 after get creatrole permissions: " + result;
result = execSql("lava", lava_pwd, "alter role user1 nocreaterole;");
ASSERT_TRUE(checkOut(result, ALTER_ROLE))
<< "lava can't revoke createrole from user1:" << result;
result = execSql("user1", user_newPwd, "drop role user2;");
ASSERT_FALSE(checkOut(result, DROP_ROLE))
<< "user can drop user2 after revoked createrole permissions: " + result;
result = execSql("lava", lava_pwd, "drop role user2;");
ASSERT_TRUE(checkOut(result, DROP_ROLE)) << "lava can't drop user2";
result = execSql(getHost2(), "create role user2 password \'user200000000\';");
ASSERT_TRUE(checkOut(result, CREATE_ROLE))
<< "lavaIntern can't create user2 in cluster2: " + result;
result = execSql("lava", lava_pwd, "alter role user2 login;");
ASSERT_TRUE(checkOut(result, ALTER_ROLE))
<< "lava can't grant login permission in cluster1 to user2: " + result;
ASSERT_TRUE(testLogin("user2", "user200000000"))
<< "login as user2 in cluster1 failure";
result = execSql(getHost2(), "drop role user2;");
ASSERT_TRUE(checkOut(result, DROP_ROLE))
<< "drop user2 failure in cluster2: " + result;
ASSERT_FALSE(testLogin("user2", "user200000000"))
<< "user2 can login in cluster1 after drop user2 in cluster1";
}
TEST_F(TestCloud, Normal) {
Command::getCommandStatus("mkdir -p " + getTestRootPath() +
"/cloudtest/out/normal");
configConnection();
execSQLfile("cloudtest/sql/normal/before_normal.sql",
"cloudtest/out/normal/before_normal.out");
execSQLfileandCheck("cloudtest/sql/normal/all.sql",
"cloudtest/out/normal/all.out");
}
#define PROCESS_NUM 10
#define ITERATION_NUM 1
TEST_F(TestCloud, Parallel) {
std::string result;
Command::getCommandStatus("mkdir -p " + getTestRootPath() +
"/cloudtest/out/parallel");
Command::getCommandStatus("rm -rf " + getTestRootPath() +
"/cloudtest/out/parallel/round*");
configConnection();
execSQLfile("cloudtest/sql/parallel/before_parallel.sql",
"cloudtest/out/parallel/before_parallel.out");
for (int i = 0; i < ITERATION_NUM; i++) {
std::string outpath =
"cloudtest/out/parallel/round" + std::to_string(i) + "/";
Command::getCommandStatus("mkdir -p " + getTestRootPath() + "/" + outpath);
runParallelSQLFile("cloudtest/sql/parallel/parallel.sql",
outpath + "parallel.out", PROCESS_NUM);
}
std::string outputFile;
for (int i = 0; i < ITERATION_NUM; ++i)
for (int j = 0; j < PROCESS_NUM; ++j) {
outputFile = "cloudtest/out/parallel/round" + std::to_string(i) + "/" +
"parallel_process_" + std::to_string(j) + ".out";
bool result = hawq::test::SQLUtility::checkPatternInFile(
outputFile, ": ERROR:|FATAL|PANIC");
EXPECT_TRUE(result) << outputFile << " find : ERROR:|FATAL|PANIC";
}
}
TestCloud::TestCloud()
: testRootPath(hawq::test::SQLUtility::getTestRootPath()), usexml(false) {
setConfigXml("cloudtest/test_cloud.xml");
}
bool TestCloud::setConfigXml(const std::string &xmlfile) {
if (xmlfile.empty()) {
std::cout << "xml file should not be empty when you call setConfigXml";
return false;
} else {
std::string xmlabsfile = testRootPath + "/" + xmlfile;
if (!std::ifstream(xmlabsfile)) {
std::cout << xmlabsfile << " doesn't exist";
return false;
}
try {
std::unique_ptr<hawq::test::XmlConfig> xmlconf;
xmlconf.reset(new hawq::test::XmlConfig(xmlabsfile));
xmlconf->parse();
hostName = xmlconf->getString("cloud_host");
cluster2host = xmlconf->getString("cloud_host2");
port = xmlconf->getString("cloud_port", "5432");
databaseName = xmlconf->getString("cloud_database", "postgres");
userName = xmlconf->getString("cloud_user");
usexml = true;
xmlconf.release();
return true;
} catch (...) {
std::cout << "Parse Xml file" << xmlabsfile << "error";
return false;
}
}
}
void TestCloud::configConnection() {
conn.reset(new hawq::test::PSQL(databaseName, hostName, port, userName,
HAWQ_PASSWORD));
}
std::string TestCloud::getTestRootPath() const { return this->testRootPath; }
void TestCloud::execSQLfile(const std::string &sqlFile,
const std::string &outFile) {
std::string sqlFileAbsPath = testRootPath + "/" + sqlFile;
std::string outFileAbsPath = testRootPath + "/" + outFile;
conn->setOutputFile(outFileAbsPath);
EXPECT_EQ(0, conn->runSQLFile(sqlFileAbsPath, "").getLastStatus());
conn->resetOutput();
}
void TestCloud::execSQLfileandCheck(const std::string &sqlFile,
const std::string &outFile) {
execSQLfile(sqlFile, outFile);
bool result = hawq::test::SQLUtility::checkPatternInFile(
outFile, ": ERROR:|FATAL|PANIC");
EXPECT_TRUE(result) << outFile << " find ERROR|FATAL|PANIC";
}
bool TestCloud::testLogin(const std::string &host, const std::string &portStr,
const std::string &database, const std::string &user,
const std::string &pwd) const {
std::string loginCmd = "psql -h " + host + " -p " + portStr + " -d " +
database + " -U " + user + " --c '\\q'";
std::string result = Command::getCommandOutput("export PGPASSWORD=\'" + pwd +
"\' && " + loginCmd);
return result.empty();
}
bool TestCloud::testLogin(const std::string &user,
const std::string &pwd) const {
return testLogin(hostName, port, databaseName, user, pwd);
}
bool TestCloud::testLogin(const std::string &pwd) const {
return testLogin(hostName, port, databaseName, userName, pwd);
}
std::string TestCloud::execSql(const std::string &host,
const std::string &sql) {
return execSql(host, port, databaseName, userName, HAWQ_PASSWORD, sql);
}
std::string TestCloud::execSql(const std::string &sql) {
return execSql(userName, HAWQ_PASSWORD, sql);
}
std::string TestCloud::execSql(const std::string &user, const std::string &pwd,
const std::string &sql) {
return execSql(hostName, port, databaseName, user, pwd, sql);
}
std::string TestCloud::execSql(const std::string &host,
const std::string &portStr,
const std::string &database,
const std::string &user, const std::string &pwd,
const std::string &sql) {
std::string sqlCmd = "echo \"" + sql + "\" | psql -h " + host + " -p " +
portStr + " -d " + database + " -U " + user;
std::string result = Command::getCommandOutput("export PGPASSWORD=\'" + pwd +
"\' && " + sqlCmd);
return result;
}
bool TestCloud::checkOut(const std::string &out, const std::string &pattern) {
return (out.find("ERROR:") != std::string::npos)
? false
: (out.find(pattern) != std::string::npos);
}
void TestCloud::runParallelSQLFile(const std::string sqlFile,
const std::string outputFile, int processnum,
const std::string ansFile) {
hawq::test::SQLUtility sqlUtil(this->databaseName, this->hostName, this->port,
this->userName);
sqlUtil.runParallelSQLFile(sqlFile, outputFile, processnum, ansFile);
}