Merge branch '3.0' of https://github.com/taosdata/TDengine into feat/TS-4243-3.0

This commit is contained in:
Hongze Cheng 2024-03-04 19:25:34 +08:00
commit 5103880397
6 changed files with 203 additions and 127 deletions

View File

@ -1199,6 +1199,18 @@ static int32_t createBlocksMergeSortInitialSources(SSortHandle* pHandle) {
return code; return code;
} }
static void freeSSortSource(SSortSource* source) {
if (NULL == source) return;
if (source->param && !source->onlyRef) {
taosMemoryFree(source->param);
}
if (!source->onlyRef && source->src.pBlock) {
blockDataDestroy(source->src.pBlock);
source->src.pBlock = NULL;
}
taosMemoryFree(source);
}
static int32_t createBlocksQuickSortInitialSources(SSortHandle* pHandle) { static int32_t createBlocksQuickSortInitialSources(SSortHandle* pHandle) {
int32_t code = 0; int32_t code = 0;
size_t sortBufSize = pHandle->numOfPages * pHandle->pageSize; size_t sortBufSize = pHandle->numOfPages * pHandle->pageSize;
@ -1231,14 +1243,7 @@ static int32_t createBlocksQuickSortInitialSources(SSortHandle* pHandle) {
code = blockDataMerge(pHandle->pDataBlock, pBlock); code = blockDataMerge(pHandle->pDataBlock, pBlock);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
if (source->param && !source->onlyRef) { freeSSortSource(source);
taosMemoryFree(source->param);
}
if (!source->onlyRef && source->src.pBlock) {
blockDataDestroy(source->src.pBlock);
source->src.pBlock = NULL;
}
taosMemoryFree(source);
return code; return code;
} }
@ -1248,15 +1253,7 @@ static int32_t createBlocksQuickSortInitialSources(SSortHandle* pHandle) {
int64_t p = taosGetTimestampUs(); int64_t p = taosGetTimestampUs();
code = blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo); code = blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
if (code != 0) { if (code != 0) {
if (source->param && !source->onlyRef) { freeSSortSource(source);
taosMemoryFree(source->param);
}
if (!source->onlyRef && source->src.pBlock) {
blockDataDestroy(source->src.pBlock);
source->src.pBlock = NULL;
}
taosMemoryFree(source);
return code; return code;
} }
@ -1265,16 +1262,13 @@ static int32_t createBlocksQuickSortInitialSources(SSortHandle* pHandle) {
if (pHandle->pqMaxRows > 0) blockDataKeepFirstNRows(pHandle->pDataBlock, pHandle->pqMaxRows); if (pHandle->pqMaxRows > 0) blockDataKeepFirstNRows(pHandle->pDataBlock, pHandle->pqMaxRows);
code = doAddToBuf(pHandle->pDataBlock, pHandle); code = doAddToBuf(pHandle->pDataBlock, pHandle);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
freeSSortSource(source);
return code; return code;
} }
} }
} }
if (source->param && !source->onlyRef) { freeSSortSource(source);
taosMemoryFree(source->param);
}
taosMemoryFree(source);
if (pHandle->pDataBlock != NULL && pHandle->pDataBlock->info.rows > 0) { if (pHandle->pDataBlock != NULL && pHandle->pDataBlock->info.rows > 0) {
size_t size = blockDataGetSize(pHandle->pDataBlock); size_t size = blockDataGetSize(pHandle->pDataBlock);

View File

@ -156,6 +156,7 @@ int32_t getSessionWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey,
(*pVal) = pPos; (*pVal) = pPos;
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey; SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
pPos->beUsed = true; pPos->beUsed = true;
pPos->beFlushed = false;
*pKey = *pDestWinKey; *pKey = *pDestWinKey;
goto _end; goto _end;
} }
@ -167,6 +168,7 @@ int32_t getSessionWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey,
(*pVal) = pPos; (*pVal) = pPos;
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey; SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
pPos->beUsed = true; pPos->beUsed = true;
pPos->beFlushed = false;
*pKey = *pDestWinKey; *pKey = *pDestWinKey;
goto _end; goto _end;
} }
@ -380,6 +382,14 @@ static SStreamStateCur* seekKeyCurrentPrev_buff(SStreamFileState* pFileState, co
(*pWins) = pWinStates; (*pWins) = pWinStates;
} }
if (size > 0 && index == -1) {
SRowBuffPos* pPos = taosArrayGetP(pWinStates, 0);
SSessionKey* pWin = (SSessionKey*)pPos->pKey;
if (pWinKey->win.skey == pWin->win.skey) {
index = 0;
}
}
if (index >= 0) { if (index >= 0) {
pCur = createSessionStateCursor(pFileState); pCur = createSessionStateCursor(pFileState);
pCur->buffIndex = index; pCur->buffIndex = index;
@ -387,6 +397,7 @@ static SStreamStateCur* seekKeyCurrentPrev_buff(SStreamFileState* pFileState, co
*pIndex = index; *pIndex = index;
} }
} }
return pCur; return pCur;
} }
@ -666,6 +677,7 @@ int32_t getStateWinResultBuff(SStreamFileState* pFileState, SSessionKey* key, ch
(*pVal) = pPos; (*pVal) = pPos;
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey; SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
pPos->beUsed = true; pPos->beUsed = true;
pPos->beFlushed = false;
*key = *pDestWinKey; *key = *pDestWinKey;
goto _end; goto _end;
} }
@ -679,6 +691,7 @@ int32_t getStateWinResultBuff(SStreamFileState* pFileState, SSessionKey* key, ch
(*pVal) = pPos; (*pVal) = pPos;
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey; SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
pPos->beUsed = true; pPos->beUsed = true;
pPos->beFlushed = false;
*key = *pDestWinKey; *key = *pDestWinKey;
goto _end; goto _end;
} }
@ -771,6 +784,7 @@ int32_t getCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, C
(*pVal) = pPos; (*pVal) = pPos;
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey; SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
pPos->beUsed = true; pPos->beUsed = true;
pPos->beFlushed = false;
*pWinKey = *pDestWinKey; *pWinKey = *pDestWinKey;
goto _end; goto _end;
} }
@ -799,6 +813,7 @@ int32_t getCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, C
(*pVal) = pPos; (*pVal) = pPos;
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey; SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
pPos->beUsed = true; pPos->beUsed = true;
pPos->beFlushed = false;
*pWinKey = *pDestWinKey; *pWinKey = *pDestWinKey;
goto _end; goto _end;
} }

View File

@ -6,7 +6,7 @@ sql connect
print ======================== dnode1 start print ======================== dnode1 start
$db = testdb $db = testdb
sql drop database if exists $db sql drop database if exists $db
sql create database $db cachemodel 'both' minrows 10 stt_trigger 1 sql create database $db cachemodel 'none' minrows 10 stt_trigger 1
sql use $db sql use $db
sql create stable st2 (ts timestamp, f1 int, f2 double, f3 binary(10), f4 timestamp) tags (id int) sql create stable st2 (ts timestamp, f1 int, f2 double, f3 binary(10), f4 timestamp) tags (id int)

View File

@ -357,95 +357,95 @@ if $data45 != 5 then
return -1 return -1
endi endi
#sql select last_row(*), id from st2 group by id order by id sql select last_row(*), id from st2 group by id order by id
#print ===> $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09 print ===> $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09
#print ===> $data10 $data11 $data12 $data13 $data14 $data15 $data16 $data17 $data18 $data19 print ===> $data10 $data11 $data12 $data13 $data14 $data15 $data16 $data17 $data18 $data19
#print ===> $data20 $data21 $data22 $data23 $data24 $data25 $data26 $data27 $data28 $data29 print ===> $data20 $data21 $data22 $data23 $data24 $data25 $data26 $data27 $data28 $data29
#print ===> $data30 $data31 $data32 $data33 $data34 $data35 $data36 $data37 $data38 $data39 print ===> $data30 $data31 $data32 $data33 $data34 $data35 $data36 $data37 $data38 $data39
#print ===> $data40 $data41 $data42 $data43 $data44 $data45 $data46 $data47 $data48 $data49 print ===> $data40 $data41 $data42 $data43 $data44 $data45 $data46 $data47 $data48 $data49
#
#if $rows != 5 then if $rows != 5 then
# return -1 return -1
#endi endi
#if $data00 != @21-05-12 10:10:12.000@ then if $data00 != @21-05-12 10:10:12.000@ then
# return -1 return -1
#endi endi
#if $data01 != 6 then if $data01 != 6 then
# return -1 return -1
#endi endi
#if $data02 != NULL then if $data02 != NULL then
# print $data02 print $data02
# return -1 return -1
#endi endi
#if $data03 != NULL then if $data03 != NULL then
# return -1 return -1
#endi endi
#if $data04 != @70-01-01 07:59:57.000@ then if $data04 != @70-01-01 07:59:57.000@ then
# return -1 return -1
#endi endi
#if $data05 != 1 then if $data05 != 1 then
# return -1 return -1
#endi endi
#if $data10 != @21-05-11 10:12:23.000@ then if $data10 != @21-05-11 10:12:23.000@ then
# return -1 return -1
#endi endi
#if $data11 != 22 then if $data11 != 22 then
# return -1 return -1
#endi endi
#if $data12 != 23.000000000 then if $data12 != 23.000000000 then
# print $data02 print $data02
# return -1 return -1
#endi endi
#if $data13 != NULL then if $data13 != NULL then
# return -1 return -1
#endi endi
#if $data14 != @70-01-01 07:59:58.-04@ then if $data14 != @70-01-01 07:59:58.-04@ then
# return -1 return -1
#endi endi
#if $data15 != 2 then if $data15 != 2 then
# return -1 return -1
#endi endi
#if $data20 != @21-05-10 10:12:24.000@ then if $data20 != @21-05-10 10:12:24.000@ then
# return -1 return -1
#endi endi
#if $data21 != 24 then if $data21 != 24 then
# return -1 return -1
#endi endi
#if $data22 != NULL then if $data22 != NULL then
# print expect NULL actual: $data22 print expect NULL actual: $data22
# return -1 return -1
#endi endi
#if $data23 != 25 then if $data23 != 25 then
# return -1 return -1
#endi endi
#if $data24 != @70-01-01 07:59:57.-04@ then = if $data24 != @70-01-01 07:59:57.-04@ then =
# return -1 return -1
#endi endi
#if $data25 != 3 then if $data25 != 3 then
# return -1 return -1
#endi endi
#if $data30 != @21-05-11 10:12:25.000@ then if $data30 != @21-05-11 10:12:25.000@ then
# return -1 return -1
#endi endi
#if $data31 != 26 then if $data31 != 26 then
# return -1 return -1
#endi endi
#if $data32 != NULL then if $data32 != NULL then
# print $data02 print $data02
# return -1 return -1
#endi endi
#if $data33 != 27 then if $data33 != 27 then
# return -1 return -1
#endi endi
#if $data34 != @70-01-01 07:59:56.-04@ then if $data34 != @70-01-01 07:59:56.-04@ then
# return -1 return -1
#endi endi
#if $data35 != 4 then if $data35 != 4 then
# return -1 return -1
#endi endi
#if $data40 != @21-05-11 10:12:29.000@ then if $data40 != @21-05-11 10:12:29.000@ then
# return -1 return -1
#endi endi
#if $data41 != NULL then #if $data41 != NULL then
# return -1 # return -1
#endi #endi
@ -453,15 +453,15 @@ endi
# print $data02 # print $data02
# return -1 # return -1
#endi #endi
#if $data43 != NULL then if $data43 != NULL then
# return -1 return -1
#endi endi
#if $data44 != NULL then #if $data44 != NULL then
# return -1 # return -1
#endi #endi
#if $data45 != 5 then if $data45 != 5 then
# return -1 return -1
#endi endi
print "test tbn" print "test tbn"
sql create table if not exists tbn (ts timestamp, f1 int, f2 double, f3 binary(10), f4 timestamp) sql create table if not exists tbn (ts timestamp, f1 int, f2 double, f3 binary(10), f4 timestamp)

View File

@ -22,7 +22,7 @@
"vgroups": 2, "vgroups": 2,
"replica": 1, "replica": 1,
"precision": "ms", "precision": "ms",
"stt_trigger": 8, "stt_trigger": 1,
"minRows": 100, "minRows": 100,
"maxRows": 4096 "maxRows": 4096
}, },

View File

@ -1,11 +1,13 @@
from urllib.parse import uses_relative from urllib.parse import uses_relative
import taos import taos
import taosws
import sys import sys
import os import os
import time import time
import platform import platform
import inspect import inspect
from taos.tmq import Consumer from taos.tmq import Consumer
from taos.tmq import *
from pathlib import Path from pathlib import Path
from util.log import * from util.log import *
@ -17,7 +19,7 @@ from util.dnodes import TDDnode
from util.cluster import * from util.cluster import *
import subprocess import subprocess
BASEVERSION = "3.0.2.3" BASEVERSION = "3.2.0.0"
class TDTestCase: class TDTestCase:
def caseDescription(self): def caseDescription(self):
f''' f'''
@ -30,7 +32,7 @@ class TDTestCase:
self.replicaVar = int(replicaVar) self.replicaVar = int(replicaVar)
tdLog.debug(f"start to excute {__file__}") tdLog.debug(f"start to excute {__file__}")
tdSql.init(conn.cursor()) tdSql.init(conn.cursor())
self.deletedDataSql= '''drop database if exists deldata;create database deldata duration 300 stt_trigger 4; ;use deldata; self.deletedDataSql= '''drop database if exists deldata;create database deldata duration 300 stt_trigger 1; ;use deldata;
create table deldata.stb1 (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) tags (t1 int); create table deldata.stb1 (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) tags (t1 int);
create table deldata.ct1 using deldata.stb1 tags ( 1 ); create table deldata.ct1 using deldata.stb1 tags ( 1 );
insert into deldata.ct1 values ( now()-0s, 0, 0, 0, 0, 0.0, 0.0, 0, 'binary0', 'nchar0', now()+0a ) ( now()-10s, 1, 11111, 111, 11, 1.11, 11.11, 1, 'binary1', 'nchar1', now()+1a ) ( now()-20s, 2, 22222, 222, 22, 2.22, 22.22, 0, 'binary2', 'nchar2', now()+2a ) ( now()-30s, 3, 33333, 333, 33, 3.33, 33.33, 1, 'binary3', 'nchar3', now()+3a ); insert into deldata.ct1 values ( now()-0s, 0, 0, 0, 0, 0.0, 0.0, 0, 'binary0', 'nchar0', now()+0a ) ( now()-10s, 1, 11111, 111, 11, 1.11, 11.11, 1, 'binary1', 'nchar1', now()+1a ) ( now()-20s, 2, 22222, 222, 22, 2.22, 22.22, 0, 'binary2', 'nchar2', now()+2a ) ( now()-30s, 3, 33333, 333, 33, 3.33, 33.33, 1, 'binary3', 'nchar3', now()+3a );
@ -104,8 +106,19 @@ class TDTestCase:
print(f"{packageName} has been exists") print(f"{packageName} has been exists")
os.system(f" cd {packagePath} && tar xvf {packageName} && cd {packageTPath} && ./install.sh -e no " ) os.system(f" cd {packagePath} && tar xvf {packageName} && cd {packageTPath} && ./install.sh -e no " )
tdDnodes.stop(1) tdDnodes.stop(1)
print(f"start taosd: rm -rf {dataPath}/* && nohup taosd -c {cPath} & ") print(f"start taosd: rm -rf {dataPath}/* && nohup /usr/bin/taosd -c {cPath} & ")
os.system(f"rm -rf {dataPath}/* && nohup taosd -c {cPath} & " ) os.system(f"rm -rf {dataPath}/* && nohup /usr/bin/taosd -c {cPath} & " )
os.system(f"killall taosadapter" )
os.system(f"cp /etc/taos/taosadapter.toml {cPath}/taosadapter.toml " )
taosadapter_cfg = cPath + "/taosadapter.toml"
taosadapter_log_path = cPath + "/../log/"
print(f"taosadapter_cfg:{taosadapter_cfg},taosadapter_log_path:{taosadapter_log_path} ")
self.alter_string_in_file(taosadapter_cfg,"#path = \"/var/log/taos\"",f"path = \"{taosadapter_log_path}\"")
self.alter_string_in_file(taosadapter_cfg,"taosConfigDir = \"\"",f"taosConfigDir = \"{cPath}\"")
print("/usr/bin/taosadapter --version")
os.system(f" /usr/bin/taosadapter --version" )
print(f" LD_LIBRARY_PATH=/usr/lib -c {taosadapter_cfg} 2>&1 & ")
os.system(f" LD_LIBRARY_PATH=/usr/lib /usr/bin/taosadapter -c {taosadapter_cfg} 2>&1 & " )
sleep(5) sleep(5)
@ -116,7 +129,24 @@ class TDTestCase:
def is_list_same_as_ordered_list(self,unordered_list, ordered_list): def is_list_same_as_ordered_list(self,unordered_list, ordered_list):
sorted_list = sorted(unordered_list) sorted_list = sorted(unordered_list)
return sorted_list == ordered_list return sorted_list == ordered_list
def alter_string_in_file(self,file,old_str,new_str):
"""
replace str in file
:param file
:param old_str
:param new_str
:return:
"""
file_data = ""
with open(file, "r", encoding="utf-8") as f:
for line in f:
if old_str in line:
line = line.replace(old_str,new_str)
file_data += line
with open(file,"w",encoding="utf-8") as f:
f.write(file_data)
def run(self): def run(self):
scriptsPath = os.path.dirname(os.path.realpath(__file__)) scriptsPath = os.path.dirname(os.path.realpath(__file__))
distro_id = distro.id() distro_id = distro.id()
@ -131,7 +161,7 @@ class TDTestCase:
dbname = "test" dbname = "test"
stb = f"{dbname}.meters" stb = f"{dbname}.meters"
self.installTaosd(bPath,cPath) self.installTaosd(bPath,cPath)
os.system("echo 'debugFlag 143' > /etc/taos/taos.cfg ") # os.system(f"echo 'debugFlag 143' >> {cPath}/taos.cfg ")
tableNumbers=100 tableNumbers=100
recordNumbers1=100 recordNumbers1=100
recordNumbers2=1000 recordNumbers2=1000
@ -163,11 +193,46 @@ class TDTestCase:
# os.system(f"LD_LIBRARY_PATH=/usr/lib taos -s 'use test;create stream current_stream into current_stream_output_stb as select _wstart as `start`, _wend as wend, max(current) as max_current from meters where voltage <= 220 interval (5s);' ") # os.system(f"LD_LIBRARY_PATH=/usr/lib taos -s 'use test;create stream current_stream into current_stream_output_stb as select _wstart as `start`, _wend as wend, max(current) as max_current from meters where voltage <= 220 interval (5s);' ")
# os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;create stream power_stream into power_stream_output_stb as select ts, concat_ws(\\".\\", location, tbname) as meter_location, current*voltage*cos(phase) as active_power, current*voltage*sin(phase) as reactive_power from meters partition by tbname;" ') # os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;create stream power_stream into power_stream_output_stb as select ts, concat_ws(\\".\\", location, tbname) as meter_location, current*voltage*cos(phase) as active_power, current*voltage*sin(phase) as reactive_power from meters partition by tbname;" ')
# os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;show streams;" ') # os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;show streams;" ')
os.system(f"sed -i 's/\/etc\/taos/{cPath}/' 0-others/tmqBasic.json ") self.alter_string_in_file("0-others/tmqBasic.json", "/etc/taos/", cPath)
# os.system("LD_LIBRARY_PATH=/usr/lib taosBenchmark -f 0-others/tmqBasic.json -y ") # os.system("LD_LIBRARY_PATH=/usr/lib taosBenchmark -f 0-others/tmqBasic.json -y ")
os.system('LD_LIBRARY_PATH=/usr/lib taos -s "create topic if not exists tmq_test_topic as select current,voltage,phase from test.meters where voltage <= 106 and current <= 5;" ') os.system('LD_LIBRARY_PATH=/usr/lib taos -s "create topic if not exists tmq_test_topic as select current,voltage,phase from test.meters where voltage <= 106 and current <= 5;" ')
os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;show topics;" ') os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;show topics;" ')
os.system(f" /usr/bin/taosadapter --version " )
consumer_dict = {
"group.id": "g1",
"td.connect.user": "root",
"td.connect.pass": "taosdata",
"auto.offset.reset": "earliest",
}
consumer = taosws.Consumer(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
try:
consumer.subscribe(["tmq_test_topic"])
except TmqError:
tdLog.exit(f"subscribe error")
while True:
message = consumer.poll(timeout=1.0)
if message:
print("message")
id = message.vgroup()
topic = message.topic()
database = message.database()
for block in message:
nrows = block.nrows()
ncols = block.ncols()
for row in block:
print(row)
values = block.fetchall()
print(nrows, ncols)
consumer.commit(message)
else:
print("break")
break
consumer.close()
tdLog.info(" LD_LIBRARY_PATH=/usr/lib taosBenchmark -f 0-others/compa4096.json -y ") tdLog.info(" LD_LIBRARY_PATH=/usr/lib taosBenchmark -f 0-others/compa4096.json -y ")
os.system("LD_LIBRARY_PATH=/usr/lib taosBenchmark -f 0-others/compa4096.json -y") os.system("LD_LIBRARY_PATH=/usr/lib taosBenchmark -f 0-others/compa4096.json -y")
os.system("LD_LIBRARY_PATH=/usr/lib taos -s 'flush database db4096 '") os.system("LD_LIBRARY_PATH=/usr/lib taos -s 'flush database db4096 '")
@ -184,7 +249,8 @@ class TDTestCase:
os.system("pkill taosd") # make sure all the data are saved in disk. os.system("pkill taosd") # make sure all the data are saved in disk.
self.checkProcessPid("taosd") self.checkProcessPid("taosd")
os.system("pkill taosadapter") # make sure all the data are saved in disk.
self.checkProcessPid("taosadapter")
tdLog.printNoPrefix("==========step2:update new version ") tdLog.printNoPrefix("==========step2:update new version ")
self.buildTaosd(bPath) self.buildTaosd(bPath)
@ -193,6 +259,7 @@ class TDTestCase:
tdsql=tdCom.newTdSql() tdsql=tdCom.newTdSql()
print(tdsql) print(tdsql)
cmd = f" LD_LIBRARY_PATH=/usr/lib taos -h localhost ;" cmd = f" LD_LIBRARY_PATH=/usr/lib taos -h localhost ;"
print(os.system(cmd))
if os.system(cmd) == 0: if os.system(cmd) == 0:
raise Exception("failed to execute system command. cmd: %s" % cmd) raise Exception("failed to execute system command. cmd: %s" % cmd)