diff --git a/.gitignore b/.gitignore index f2c1cb75b3405954e97dcab3c0fade3772e968a3..e91d6739a540bfd88567381eb0dccc5462ba4918 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ tests/test/ tests/taoshebei/ tests/taoscsv/ tests/taosdalipu/ -tests/pytest/ tests/jenkins/ tests/hdfs/ *.iml diff --git a/.travis.yml b/.travis.yml index 63c62d1a8a9d0b2de53da02fa17520650049b6ab..221a1f1a300d265db1f8958feba6539a9b7b5b81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,15 @@ os: - linux # - osx +before_install: + - |- + case $TRAVIS_OS_NAME in + linux) + sudo apt -y update + sudo apt -y install python-pip python3-pip python-setuptools python3-setuptools + ;; + esac + addons: coverity_scan: @@ -50,6 +59,15 @@ script: - |- case $TRAVIS_OS_NAME in linux) + # Color setting + RED='\033[0;31m' + GREEN='\033[1;32m' + GREEN_DARK='\033[0;32m' + GREEN_UNDERLINE='\033[4;32m' + NC='\033[0m' + + sudo make install + cd ../tests/script sudo ./test.sh 2>&1 | grep 'success\|failed' | tee out.txt @@ -57,16 +75,32 @@ script: if [ "$total_success" -gt "0" ]; then total_success=`expr $total_success - 1` + echo -e "${GREEN} ### Total $total_success TSIM case(s) succeed! ### ${NC}" fi - echo "Total $total_success success" - total_failed=`grep failed out.txt | wc -l` - echo "Total $total_failed failed" - if [ "$total_failed" -ne "0" ]; then + echo -e "${RED} ### Total $total_failed TSIM case(s) failed! ### ${NC}" exit $total_failed fi + + pip install --user ../../src/connector/python/linux/python2/ + pip3 install --user ../../src/connector/python/linux/python3/ + + cd ../pytest + sudo ./simpletest.sh 2>&1 | grep 'successfully executed\|failed' | tee pytest-out.txt + total_py_success=`grep 'successfully executed' pytest-out.txt | wc -l` + + if [ "$total_py_success" -gt "0" ]; then + echo -e "${GREEN} ### Total $total_py_success python case(s) succeed! ### ${NC}" + fi + + total_py_failed=`grep 'failed' pytest-out.txt | wc -l` + if [ "$total_py_failed" -ne "0" ]; then + echo -e "${RED} ### Total $total_py_failed python case(s) failed! ### ${NC}" + exit $total_py_failed + fi + ;; esac @@ -81,6 +115,10 @@ matrix: - build-essential - cmake - net-tools + - python-pip + - python-setuptools + - python3-pip + - python3-setuptools # - os: osx # addons: diff --git a/tests/pytest/insert/__init__.py b/tests/pytest/insert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/pytest/insert/basic.py b/tests/pytest/insert/basic.py new file mode 100644 index 0000000000000000000000000000000000000000..c6dbd76de4c4699f2bde3c864a1ff43e6424cbb8 --- /dev/null +++ b/tests/pytest/insert/basic.py @@ -0,0 +1,53 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * + +class TDTestCase: + def init(self, conn): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + def run(self): + tdSql.prepare() + tdSql.execute('show databases') + tdSql.execute('drop database if exists db') + tdSql.execute('create database db') + tdSql.execute('use db') + tdSql.execute('create table tb (ts timestamp, speed int)') + + insertRows = 10 + tdLog.info("insert %d rows" % (insertRows)) + for i in range(0, insertRows): + tdSql.execute('insert into tb values (now + %dm, %d)' % (i, i)) + +# tdLog.info("insert earlier data") +# tdSql.execute('insert into tb values (now - 5m , 10)') +# tdSql.execute('insert into tb values (now - 6m , 10)') +# tdSql.execute('insert into tb values (now - 7m , 10)') +# tdSql.execute('insert into tb values (now - 8m , 10)') + +# tdSql.query("select * from tb") +# tdSql.checkRows(insertRows) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/simpletest.sh b/tests/pytest/simpletest.sh new file mode 100755 index 0000000000000000000000000000000000000000..aab36884f392923c2ab54ae88f73804a69414062 --- /dev/null +++ b/tests/pytest/simpletest.sh @@ -0,0 +1 @@ +sudo python2 ./test.py -f insert/basic.py diff --git a/tests/pytest/test.py b/tests/pytest/test.py new file mode 100644 index 0000000000000000000000000000000000000000..b88e4446653cc482e3a14c267961bbd6d12285a4 --- /dev/null +++ b/tests/pytest/test.py @@ -0,0 +1,87 @@ +#!/usr/bin/python +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### +# install pip +# pip install src/connector/python/linux/python2/ + +# -*- coding: utf-8 -*- +import sys +import getopt +from util.log import * +from util.dnodes import * +from util.cases import * + +import taos + +# add testcase here: +from insert.basic import * + +if __name__ == "__main__": + fileName = "all" + deployPath = "" + masterIp = "" + testCluster = False + opts, args = getopt.getopt(sys.argv[1:], 'f:p:m:sch', [ + 'file=', 'path=', 'master', 'stop', 'cluster', 'help']) + for key, value in opts: + if key in ['-h', '--help']: + tdLog.printNoPrefix( + 'A collection of test cases written using Python') + tdLog.printNoPrefix('-f Name of test case file written by Python') + tdLog.printNoPrefix('-p Deploy Path for Simulator') + tdLog.printNoPrefix('-m Master Ip for Simulator') + tdLog.printNoPrefix('-c Test Cluster Flag') + tdLog.printNoPrefix('-s stop All dnodes') + sys.exit(0) + if key in ['-f', '--file']: + fileName = value + if key in ['-p', '--path']: + deployPath = value + if key in ['-m', '--master']: + masterIp = value + if key in ['-c', '--cluster']: + testCluster = True + if key in ['-s', '--stop']: + cmd = "ps -ef|grep -w taosd | grep 'taosd' | grep -v grep | awk '{print $2}' && pkill -9 taosd" + os.system(cmd) + tdLog.exit('stop All dnodes') + + if masterIp == "": + tdDnodes.init(deployPath) + if testCluster: + tdLog.notice("Procedures for testing cluster") + if fileName == "all": + tdCases.runAllCluster() + else: + tdCases.runOneCluster(fileName) + else: + tdLog.notice("Procedures for testing self-deployment") + tdDnodes.stopAll() + tdDnodes.deploy(1) + tdDnodes.start(1) + conn = taos.connect( + host='192.168.0.1', + config=tdDnodes.getSimCfgPath()) + if fileName == "all": + tdCases.runAllLinux(conn) + else: + tdLog.info("CBD LN78: %s" % (fileName)) + tdCases.runOneLinux(conn, fileName) + conn.close() + else: + tdLog.notice("Procedures for tdengine deployed in %s" % (masterIp)) + conn = taos.connect(host=masterIp, config=tdDnodes.getSimCfgPath()) + if fileName == "all": + tdCases.runAllWindows(conn) + else: + tdCases.runOneWindows(conn, fileName) + conn.close() + diff --git a/tests/pytest/util/__init__.py b/tests/pytest/util/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/pytest/util/cases.py b/tests/pytest/util/cases.py new file mode 100644 index 0000000000000000000000000000000000000000..320c9d974f4253c2fe12951e208281d15b1010ed --- /dev/null +++ b/tests/pytest/util/cases.py @@ -0,0 +1,103 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import os +import time +import datetime +from util.log import * + + +class TDCase: + def __init__(self, name, case): + self.name = name + self.case = case + + +class TDCases: + def __init__(self): + self.linuxCases = [] + self.windowsCases = [] + self.clusterCases = [] + + def addWindows(self, name, case): + self.windowsCases.append(TDCase(name, case)) + + def addLinux(self, name, case): + self.linuxCases.append(TDCase(name, case)) + + def addCluster(self, name, case): + self.clusterCases.append(TDCase(name, case)) + + def runAllLinux(self, conn): + tdLog.notice("run total %d cases" % (len(self.linuxCases))) + for case in self.linuxCases: + case.case.init(conn) + case.case.run() + case.case.stop() + tdLog.notice("total %d cases executed" % (len(self.linuxCases))) + + def runOneLinux(self, conn, fileName): + tdLog.notice("run cases like %s" % (fileName)) + runNum = 0 + for case in self.linuxCases: + if case.name.find(fileName) != -1: + case.case.init(conn) + case.case.run() + case.case.stop() + time.sleep(5) + runNum += 1 + tdLog.notice("total %d cases executed" % (runNum)) + + def runAllWindows(self, conn): + tdLog.notice("run total %d cases" % (len(self.windowsCases))) + for case in self.windowsCases: + case.case.init(conn) + case.case.run() + case.case.stop() + tdLog.notice("total %d cases executed" % (len(self.windowsCases))) + + def runOneWindows(self, conn, fileName): + tdLog.notice("run cases like %s" % (fileName)) + runNum = 0 + for case in self.windowsCases: + if case.name.find(fileName) != -1: + case.case.init(conn) + case.case.run() + case.case.stop() + time.sleep(2) + runNum += 1 + tdLog.notice("total %d cases executed" % (runNum)) + + def runAllCluster(self): + tdLog.notice("run total %d cases" % (len(self.clusterCases))) + for case in self.clusterCases: + case.case.init() + case.case.run() + case.case.stop() + tdLog.notice("total %d cases executed" % (len(self.clusterCases))) + + def runOneCluster(self, fileName): + tdLog.notice("run cases like %s" % (fileName)) + runNum = 0 + for case in self.clusterCases: + if case.name.find(fileName) != -1: + case.case.init() + case.case.run() + case.case.stop() + time.sleep(2) + runNum += 1 + tdLog.notice("total %d cases executed" % (runNum)) + + +tdCases = TDCases() diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py new file mode 100644 index 0000000000000000000000000000000000000000..2be4f94802a2637f393d6471aa09f8ed0f2ea125 --- /dev/null +++ b/tests/pytest/util/dnodes.py @@ -0,0 +1,332 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import os +import os.path +from util.log import * + + +class TDSimClient: + def init(self, path): + self.path = path + + def getCfgDir(self): + return self.cfgDir + + def cfg(self, option, value): + cmd = "echo '%s %s' >> %s" % (option, value, self.cfgPath) + if os.system(cmd) != 0: + tdLog.exit(cmd) + + def deploy(self): + self.logDir = "%s/sim/psim/log" % (self.path,) + self.cfgDir = "%s/sim/psim/cfg" % (self.path) + self.cfgPath = "%s/sim/psim/cfg/taos.cfg" % (self.path) + + cmd = "rm -rf " + self.logDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "rm -rf " + self.cfgDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "mkdir -p " + self.logDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "mkdir -p " + self.cfgDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "touch " + self.cfgPath + if os.system(cmd) != 0: + tdLog.exit(cmd) + + self.cfg("masterIp", "192.168.0.1") + self.cfg("secondIp", "192.168.0.2") + self.cfg("logDir", self.logDir) + self.cfg("numOfLogLines", "100000000") + self.cfg("numOfThreadsPerCore", "2.0") + self.cfg("locale", "en_US.UTF-8") + self.cfg("charset", "GBK") + self.cfg("asyncLog", "0") + self.cfg("anyIp", "0") + self.cfg("sdbDebugFlag", "135") + self.cfg("rpcDebugFlag", "135") + self.cfg("tmrDebugFlag", "131") + self.cfg("cDebugFlag", "135") + self.cfg("udebugFlag", "135") + self.cfg("jnidebugFlag", "135") + self.cfg("qdebugFlag", "135") + tdLog.debug("psim is deployed and configured by %s" % (self.cfgPath)) + + +class TDDnode: + def __init__(self, index): + self.index = index + self.running = 0 + self.deployed = 0 + + def init(self, path): + self.path = path + + def deploy(self): + self.logDir = "%s/sim/dnode%d/log" % (self.path, self.index) + self.dataDir = "%s/sim/dnode%d/data" % (self.path, self.index) + self.cfgDir = "%s/sim/dnode%d/cfg" % (self.path, self.index) + self.cfgPath = "%s/sim/dnode%d/cfg/taos.cfg" % (self.path, self.index) + + cmd = "rm -rf " + self.dataDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "rm -rf " + self.logDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "rm -rf " + self.cfgDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "mkdir -p " + self.dataDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "mkdir -p " + self.logDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "mkdir -p " + self.cfgDir + if os.system(cmd) != 0: + tdLog.exit(cmd) + + cmd = "touch " + self.cfgPath + if os.system(cmd) != 0: + tdLog.exit(cmd) + + self.startIP() + self.cfg("masterIp", "192.168.0.1") + self.cfg("secondIp", "192.168.0.2") + self.cfg("publicIp", "192.168.0.%d" % (self.index)) + self.cfg("internalIp", "192.168.0.%d" % (self.index)) + self.cfg("privateIp", "192.168.0.%d" % (self.index)) + self.cfg("dataDir", self.dataDir) + self.cfg("logDir", self.logDir) + self.cfg("numOfLogLines", "100000000") + self.cfg("mgmtEqualVnodeNum", "0") + self.cfg("clog", "1") + self.cfg("statusInterval", "1") + self.cfg("numOfTotalVnodes", "64") + self.cfg("numOfMPeers", "3") + self.cfg("numOfThreadsPerCore", "2.0") + self.cfg("monitor", "0") + self.cfg("maxVnodeConnections", "30000") + self.cfg("maxMgmtConnections", "30000") + self.cfg("maxMeterConnections", "30000") + self.cfg("maxShellConns", "30000") + self.cfg("locale", "en_US.UTF-8") + self.cfg("charset", "UTF-8") + self.cfg("asyncLog", "0") + self.cfg("anyIp", "0") + self.cfg("dDebugFlag", "135") + self.cfg("mDebugFlag", "135") + self.cfg("sdbDebugFlag", "135") + self.cfg("rpcDebugFlag", "135") + self.cfg("tmrDebugFlag", "131") + self.cfg("cDebugFlag", "135") + self.cfg("httpDebugFlag", "135") + self.cfg("monitorDebugFlag", "135") + self.cfg("udebugFlag", "135") + self.cfg("jnidebugFlag", "135") + self.cfg("qdebugFlag", "135") + self.deployed = 1 + tdLog.debug( + "dnode:%d is deployed and configured by %s" % + (self.index, self.cfgPath)) + + def start(self): + binPath = os.path.dirname(os.path.realpath(__file__)) + binPath = binPath + "/../../../debug/" + binPath = os.path.realpath(binPath) + binPath += "/build/bin/" + + if self.deployed == 0: + tdLog.exit("dnode:%d is not deployed" % (self.index)) + cmd = "nohup %staosd -c %s > /dev/null 2>&1 & " % ( + binPath, self.cfgDir) + print(cmd) + if os.system(cmd) != 0: + tdLog.exit(cmd) + self.running = 1 + tdLog.debug("dnode:%d is running with %s " % (self.index, cmd)) + + tdLog.debug("wait 2 seconds for the dnode:%d to start." % (self.index)) + time.sleep(2) + + def stop(self): + if self.running != 0: + cmd = "ps -ef|grep -w taosd | grep '%s' | grep -v grep | awk '{print $2}' && pkill -sigint taosd" % ( + self.cfgDir) + if os.system(cmd) != 0: + tdLog.exit(cmd) + tdLog.debug("dnode:%d is stopped by kill -SIGINT" % (self.index)) + tdLog.debug( + "wait 2 seconds for the dnode:%d to stop." % + (self.index)) + time.sleep(2) + + def forcestop(self): + if self.running != 0: + cmd = "ps -ef|grep -w taosd | grep '%s' | grep -v grep | awk '{print $2}' && pkill -sigkill taosd" % ( + self.cfgDir) + if os.system(cmd) != 0: + tdLog.exit(cmd) + tdLog.debug("dnode:%d is stopped by kill -9" % (self.index)) + tdLog.debug( + "wait 2 seconds for the dnode:%d to stop." % + (self.index)) + time.sleep(2) + + def startIP(self): + cmd = "sudo ifconfig lo:%d 192.168.0.%d up" % (self.index, self.index) + if os.system(cmd) != 0: + tdLog.exit(cmd) + + def stopIP(self): + cmd = "sudo ifconfig lo:%d 192.168.0.%d down" % ( + self.index, self.index) + if os.system(cmd) != 0: + tdLog.exit(cmd) + + def cfg(self, option, value): + cmd = "echo '%s %s' >> %s" % (option, value, self.cfgPath) + if os.system(cmd) != 0: + tdLog.exit(cmd) + + def getDnodeRootDir(self, index): + dnodeRootDir = "%s/sim/psim/dnode%d" % (self.path, index) + return dnodeRootDir + + def getDnodesRootDir(self): + dnodesRootDir = "%s/sim/psim" % (self.path) + return dnodesRootDir + + +class TDDnodes: + def __init__(self): + self.dnodes = [] + self.dnodes.append(TDDnode(1)) + self.dnodes.append(TDDnode(2)) + self.dnodes.append(TDDnode(3)) + self.dnodes.append(TDDnode(4)) + self.dnodes.append(TDDnode(5)) + self.dnodes.append(TDDnode(6)) + self.dnodes.append(TDDnode(7)) + self.dnodes.append(TDDnode(8)) + self.dnodes.append(TDDnode(9)) + self.dnodes.append(TDDnode(10)) + + def init(self, path): + cmd = "ps -ef|grep -w taosd | grep 'taosd' | grep -v grep | awk '{print $2}' && pkill -sigkill taosd" + os.system(cmd) + + binPath = os.path.dirname(os.path.realpath(__file__)) + binPath = binPath + "/../../../debug/" + tdLog.debug("binPath %s" % (binPath)) + binPath = os.path.realpath(binPath) + tdLog.debug("binPath real path %s" % (binPath)) + + # cmd = "sudo cp %s/build/lib/libtaos.so /usr/local/lib/taos/" % (binPath) + # tdLog.debug(cmd) + # os.system(cmd) + + # cmd = "sudo cp %s/build/bin/taos /usr/local/bin/taos/" % (binPath) + # if os.system(cmd) != 0 : + # tdLog.exit(cmd) + # tdLog.debug("execute %s" % (cmd)) + + # cmd = "sudo cp %s/build/bin/taosd /usr/local/bin/taos/" % (binPath) + # if os.system(cmd) != 0 : + # tdLog.exit(cmd) + # tdLog.debug("execute %s" % (cmd)) + + if path == "": + # self.path = os.path.expanduser('~') + self.path = os.path.abspath(binPath + "../../") + else: + self.path = os.path.realpath(path) + + for i in range(len(self.dnodes)): + self.dnodes[i].init(self.path) + + self.sim = TDSimClient() + self.sim.init(self.path) + self.sim.deploy() + + def deploy(self, index): + self.check(index) + self.dnodes[index - 1].deploy() + + def cfg(self, index, option, value): + self.check(index) + self.dnodes[index - 1].cfg(option, value) + + def start(self, index): + self.check(index) + self.dnodes[index - 1].start() + + def stop(self, index): + self.check(index) + self.dnodes[index - 1].stop() + + def forcestop(self, index): + self.check(index) + self.dnodes[index - 1].forcestop() + + def startIP(self, index): + self.check(index) + self.dnodes[index - 1].startIP() + + def stopIP(self, index): + self.check(index) + self.dnodes[index - 1].stopIP() + + def check(self, index): + if index < 1 or index > 10: + tdLog.exit("index:%d should on a scale of [1, 10]" % (index)) + + def stopAll(self): + tdLog.debug("stop all dnodes") + for i in range(len(self.dnodes)): + self.dnodes[i].stop() + + cmd = "sudo systemctl stop taosd" + os.system(cmd) + # if os.system(cmd) != 0 : + # tdLog.exit(cmd) + cmd = "ps -ef | grep -w taosd | grep 'dnode' | grep -v grep | awk '{print $2}' && sudo pkill -sigkill taosd" + os.system(cmd) + # if os.system(cmd) != 0 : + # tdLog.exit(cmd) + + def getDnodesRootDir(self): + dnodesRootDir = "%s/sim" % (self.path) + return dnodesRootDir + + def getSimCfgPath(self): + return self.sim.getCfgDir() + + +tdDnodes = TDDnodes() diff --git a/tests/pytest/util/log.py b/tests/pytest/util/log.py new file mode 100644 index 0000000000000000000000000000000000000000..926e582448693eb7111ef79a9bc5b269e30f58bd --- /dev/null +++ b/tests/pytest/util/log.py @@ -0,0 +1,48 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import os +import time +import datetime + + +class TDLog: + def __init__(self): + self.path = "" + + def info(self, info): + print "%s %s" % (datetime.datetime.now(), info) + + def sleep(self, sec): + print "%s sleep %d seconds" % (datetime.datetime.now(), sec) + time.sleep(sec) + + def debug(self, err): + print "\033[1;36m%s %s\033[0m" % (datetime.datetime.now(), err) + + def success(self, info): + print "\033[1;32m%s %s\033[0m" % (datetime.datetime.now(), info) + + def notice(self, err): + print "\033[1;33m%s %s\033[0m" % (datetime.datetime.now(), err) + + def exit(self, err): + print "\033[1;31m%s %s\033[0m" % (datetime.datetime.now(), err) + sys.exit(1) + + def printNoPrefix(self, info): + print "\033[1;36m%s\033[0m" % (info) + + +tdLog = TDLog() diff --git a/tests/pytest/util/sql.py b/tests/pytest/util/sql.py new file mode 100644 index 0000000000000000000000000000000000000000..b4ac845bc899b575bcd8597d191cb8b6354fa4d7 --- /dev/null +++ b/tests/pytest/util/sql.py @@ -0,0 +1,135 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import os +import time +import datetime +from util.log import * + + +class TDSql: + def __init__(self): + self.queryRows = 0 + self.queryCols = 0 + self.affectedRows = 0 + + def init(self, cursor): + self.cursor = cursor + + def close(self): + self.cursor.close() + + def prepare(self): + tdLog.info("prepare database:db") + self.cursor.execute('reset query cache') + self.cursor.execute('drop database if exists db') + self.cursor.execute('create database db') + self.cursor.execute('use db') + + def error(self, sql): + expectErrNotOccured = True + try: + self.cursor.execute(sql) + except BaseException: + expectErrNotOccured = False + if expectErrNotOccured: + tdLog.exit("sql:%.40s, expect error not occured" % (sql)) + else: + tdLog.info("sql:%.40s, expect error occured" % (sql)) + + def query(self, sql): + self.sql = sql + self.cursor.execute(sql) + self.queryResult = self.cursor.fetchall() + self.queryRows = len(self.queryResult) + self.queryCols = len(self.cursor.description) + # if self.queryRows == 1 and self.queryCols == 1: + # tdLog.info("sql:%s, rows:%d cols:%d data:%s" % (self.sql, self.queryRows, self.queryCols, self.queryResult[0][0])) + # else: + # tdLog.info("sql:%s, rows:%d cols:%d" % (self.sql, self.queryRows, self.queryCols)) + return self.queryRows + + def checkRows(self, expectRows): + if self.queryRows != expectRows: + tdLog.exit( + "sql:%.40s, queryRows:%d != expect:%d" % + (self.sql, self.queryRows, expectRows)) + tdLog.info("sql:%.40s, queryRows:%d == expect:%d" % + (self.sql, self.queryRows, expectRows)) + + def checkData(self, row, col, data): + if row < 0: + tdLog.exit( + "sql:%.40s, row:%d is smaller than zero" % + (self.sql, row)) + if col < 0: + tdLog.exit( + "sql:%.40s, col:%d is smaller than zero" % + (self.sql, col)) + if row >= self.queryRows: + tdLog.exit( + "sql:%.40s, row:%d is larger than queryRows:%d" % + (self.sql, row, self.queryRows)) + if col >= self.queryCols: + tdLog.exit( + "sql:%.40s, col:%d is larger than queryRows:%d" % + (self.sql, col, self.queryCols)) + if self.queryResult[row][col] != data: + tdLog.exit( + "sql:%.40s row:%d col:%d data:%s != expect:%s" % + (self.sql, row, col, self.queryResult[row][col], data)) + tdLog.info("sql:%.40s, row:%d col:%d data:%s == expect:%d" % + (self.sql, row, col, self.queryResult[row][col], data)) + + def getData(self, row, col): + if row < 0: + tdLog.exit( + "sql:%.40s, row:%d is smaller than zero" % + (self.sql, row)) + if col < 0: + tdLog.exit( + "sql:%.40s, col:%d is smaller than zero" % + (self.sql, col)) + if row >= self.queryRows: + tdLog.exit( + "sql:%.40s, row:%d is larger than queryRows:%d" % + (self.sql, row, self.queryRows)) + if col >= self.queryCols: + tdLog.exit( + "sql:%.40s, col:%d is larger than queryRows:%d" % + (self.sql, col, self.queryCols)) + return self.queryResult[row][col] + + def executeTimes(self, sql, times): + for i in range(times): + try: + return self.cursor.execute(sql) + except BaseException: + time.sleep(1) + continue + + def execute(self, sql): + self.sql = sql + self.affectedRows = self.cursor.execute(sql) + return self.affectedRows + + def checkAffectedRows(self, expectAffectedRows): + if self.affectedRows != expectAffectedRows: + tdLog.exit("sql:%.40s, affectedRows:%d != expect:%d" % + (self.sql, self.affectedRows, expectAffectedRows)) + tdLog.info("sql:%.40s, affectedRows:%d == expect:%d" % + (self.sql, self.affectedRows, expectAffectedRows)) + + +tdSql = TDSql()