blob: b447b73d065c9711cbbf957b471ded3c4b17b99e [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.
*/
/*
*
* This is control different sessions sequence issue
* The file format should be like
# This is basic transaction test demo //# is used for comment
Total:2 // indicate how sessions in total
0:DROP TABLE IF EXISTS TEST; // 0 indicate it is for prepare
0:CREATE TABLE TEST(A INT);
1:BEGIN;
2:BEGIN;
1:SELECT * FROM TEST;
2:INSERT INTO TEST VALUES(1);
2:COMMIT;
1:SELECT * FROM TEST;
1:COMMIT;
* There is another example for blocked test
# for blocked session. in below example,
# session 1 will lock whole table, session 2 will be blocked until session 1 commit
Total:2 // indicate how sessions in total
0:DROP TABLE IF EXISTS TEST; // 0 indicate it is for prepare
0:CREATE TABLE TEST(A INT);
1:BEGIN;
2:BEGIN;
1:TRUNCATE TEST;
2:1:SELECT * FROM TEST; //Here it indicates session 2 is blocked by session 1
1:COMMIT; //Here session 2 will not be blocked and output session 2 result.
2:COMMIT;
*
*/
#ifndef HAWQ_SRC_TEST_FEATURE_LIB_SQL_UTIL_PARALL_H_
#define HAWQ_SRC_TEST_FEATURE_LIB_SQL_UTIL_PARALL_H_
#include "sql_util.h"
#include <string>
#include <mutex>
namespace hawq {
namespace test {
enum MessageCommandType {
NULLCOMMAND,
NEXTLINE,
BLOCKEDSQL,
SQLSTRING,
EXITTHREAD,
PRINTRESULT,
BADSTATUS,
BLOCKOVER
};
class ThreadMessage{
public:
ThreadMessage(uint16_t tid = 0 );
~ThreadMessage();
int thread_id;
int vacuum ;
std::string messageinfo;
MessageCommandType command;
bool isrunning;
int32_t submit; // 1: commit ; 0: submit ; -1: rollback; -2 vacuum;
std::vector<int> waittids; //threadids which are blocked by this thread
std::vector<int> waitfortids; //threadids which this thread waiting for
};
class SQLUtilityParallel : public SQLUtility {
public:
SQLUtilityParallel();
~SQLUtilityParallel();
bool exclusive; // whether test access_exclusive lock;
// Execute sql file and diff with ans file.
// @param sqlFile The given sqlFile which is relative path to test root dir. This file control how the SQL is execute
// @param ansFile The given ansFile which is relative path to test root dir
// @param exclusive whether we can predict the order of transactions
// @return void
void execParallelControlSQLFile(const std::string &sqlFile, const std::string &ansFile,bool exclusive,
const std::string &initFile = "");
//int32_t getWaitNumber(const std::string &schemapath, const std::string &connstr);
// Run sql file and generate output file
bool runParallelControlFile(const std::string &sqlFile, const std::string &outputFile);
bool runParallelControlFile_exclusive(const std::string &sqlFile, const std::string &outputFile);
private:
// Handling SQL comand for every thread
// @param tid the thread id
// @param schemapath it is used that every case should have its own schema
// @param connstr the connection string
void thread_execute(uint16_t tid, const std::string &schemapath, const std::string &connstr);
// @param totalsession the number of totalsession
void thread_execute_exclusive(uint16_t tid, const std::string &schemapath, const std::string &connstr, const int32_t totalsession);
// Get total session number from input sql file
int32_t __getTotalSession(std::fstream &in);
//Process line to get session id, wait tid and running sql
// @param line input line
// @param totalsession the total session for this sql file
// @param(output) sessionid current execute thread id
// @param(output) waittid the thread which blocks current thread. 0 if it is not blocked.
// @param(output) message the sql will be executed
// @return whether it is executed successfully or not
bool __processLine(const std::string &line, const int32_t totalsession,
int32_t &sessionid, int32_t &waittid, std::string &message);
private:
std::vector<std::unique_ptr<ThreadMessage>> threadmessage;
std::mutex thread_mutex;
FILE* outputstream;
}; // class SQLUtilityParallel
} // namespace test
} // namespace hawq
#endif // SRC_TEST_FEATURE_LIB_SQL_UTIL_PARALL_H_