mirror of
https://github.com/taosdata/TDengine
synced 2026-05-24 10:09:01 +00:00
* migrate system-test/2-query * revert file * update case.task * resolve script migrate * run new test framework on new_testcases * migrate system-test/2-query * format docstring * fix test validation * fix test validation * fix error * migrate army case * migrate army case * fix error * migrate system-test/2-query * migrate system-test/2-query * migrate system-test/2-query * migrate system-test/2-query * test exe time * fix ci error * migrate system-test/1-insert * new common function * migrate system-test/1-insert * fix ci error * migrate system-test/1-insert * feat: add configuration and script for memory allocator settings * fix: correct HEAPPROFILE path and remove redundant metadata_thp setting in memory allocator script * fix ci error * migrate system-test/1-insert, 2-query * feat:insert into subquery (#31401) (#31710) * migrate system-test/99-TDcase * feat(gpt): add grant check for gpt. (#31708) * migrate system-test/99-TDcase * migrate system-test/99-TDcase * migrate system-test/99-TDcase * fix/send-heartbeat-statis (#31680) * migrate system-test/7-tmq * chore: support cmake option TAOSWS_GIT_TAG like taosadapter [skip ci] (#31486) * add system-test/6/cluster test * chore: move default branch from main to 3.3.6 for adapter/taosws * fix docstring validation * migrate system-test/7-tmq * migrate system-test/7-tmq * feat: add set_taos_malloc_env configuration and update related scripts * Update 03-kubernetes.md * enh: add log for snapshot (#31681) * simple test * more * migrate system-test/7-tmq * migrate system-test 0-others cases * migrate system-test/7-tmq * fix docstring validation * migrate system-test/7-tmq * fix docstring validation * fix: invalid queue * fix docstring validation * refactor: reorganize memory allocator script constants and improve mode descriptions * enh: TD-36324-improve-sync-heartbeat-log (#31727) * recover log level * fix: taosd crush in query when insufficient memory (#31746) Co-authored-by: Tony Zhang <tonyzhang@taosdata.com> * fix: overflow check in snprintf (#31780) * migrate system-test/7-tmq * migrate some cases * migrate system-test/7-tmq * fix failed cases * fix failed cases * migrate some cases * fix failed cases * fix failed cases * migrate testcases * fix: update environment file path in taosd.service and adjust set_taos_malloc.sh configuration * fix: set lcn before do s3 migrate. (#31782) * migrate testcases * fix failed cases * fix: add condition to set default malloc config for taosd service * fix: update usage message in set_taos_malloc.sh to include quiet mode option * fix: add quiet mode option to set malloc config in install script * fix: update set_taos_malloc.sh to improve output messages and adjust default malloc config invocation * recover log level * fix(tmq): [TS-6569]tdb error if write tmq meta data in multi thread (#31808) * fix: the calculation of dnode uptime (#31832) * migrate testcase * fix: correct timediff function bug and redress docs (#31798) * fix: enhance malloc configuration for taosd and taosadapter in install script * fix: TD-36442 show full condition (#31796) * enh/TD-36466-sync-heartbeat (#31805) * fix(plan) virtual table support BI moudle when use in select (#31787) * fix failed cases * enh: TS-5926-force-repair-wal (#31828) * migrate testcase * rename taos & taosd (#31855) * migrate testcase * migrate testcase * fix failed cases * fix: update environment file paths in taosd.service and set_taos_malloc.sh * feat: add performance tuning documentation for memory optimization and set_taos_malloc.sh usage * fix: update file paths in performance tuning documentation for consistency * feat: add performance tuning documentation for memory allocator configuration script * fix: add missing line breaks for improved readability in performance tuning documentation * fix: adjust heading levels for consistency in performance tuning documentation * fix cases * fix new_testcases * fix failed cases * fix(query): support show tags on virtual table (#31831) * fix failed cases * docs: replace mysql screenshot (#31888) * feat: use the new TDengine product name (#31859) * merge 3.0 * fix failed cases * fix failed cases * merge 3.0 * fix cases * fix cases * doc: Update 03-stream.md (#31675) * chore(deps): bump requests from 2.27.1 to 2.32.4 in /test (#31326) Bumps [requests](https://github.com/psf/requests) from 2.27.1 to 2.32.4. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.27.1...v2.32.4) --- updated-dependencies: - dependency-name: requests dependency-version: 2.32.4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix new cases * fix:Convert line endings from LF to CRLF for ans file * build(deps): bump golang.org/x/net in /tools/keeper (#30811) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.36.0 to 0.38.0. - [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.38.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump urllib3 from 1.26.20 to 2.5.0 in /test (#31414) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.20 to 2.5.0. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.20...2.5.0) --- updated-dependencies: - dependency-name: urllib3 dependency-version: 2.5.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump org.apache.tomcat.embed:tomcat-embed-core (#31392) Bumps org.apache.tomcat.embed:tomcat-embed-core from 9.0.104 to 9.0.106. --- updated-dependencies: - dependency-name: org.apache.tomcat.embed:tomcat-embed-core dependency-version: 9.0.106 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump org.apache.tomcat.embed:tomcat-embed-core (#31393) Bumps org.apache.tomcat.embed:tomcat-embed-core from 9.0.104 to 9.0.106. --- updated-dependencies: - dependency-name: org.apache.tomcat.embed:tomcat-embed-core dependency-version: 9.0.106 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump org.apache.kafka:kafka-clients (#31341) Bumps org.apache.kafka:kafka-clients from 3.9.0 to 3.9.1. --- updated-dependencies: - dependency-name: org.apache.kafka:kafka-clients dependency-version: 3.9.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: add lock when calculating log buffer start/end (#31883) * fix new cases * fix new cases * fix failed cases * feat: new stream (#31678) * fix: windows compile issue * test: add vtable cases (#31829) * fix: windows compile issues * test:add test cases * fix: windows compile issue * case: em-4 stream case submit * test: stream4_sub1 found bug2 * test: submit test_scene_meters_bug2.py * add stream parameters example * feat: [TS-6100] Do not translate const value as column. * Feat/ts 6100 3.0 zlv (#31747) * modify asan exampel * modify asan exampel * add example * add example * modify case example --------- Co-authored-by: zelv01 <1101510017@qq.com> * feat(stream): fix memory leak * modify sliding example * test: update test case. * feat(stream): fix conflicts * fix: add offset case 10a 10s 10m 10h 10d * feat(stream): fix conflicts * chore(stream): rename case name #TS-6100 * add case * modify example * fix: windows compile issues * fix: data null check * feat: [TS-6100] Forbid where when using %%trows (#31827) * feat: [TS-6100] Forbid where when using %%trows * test: update cases * feat: [TS-6100] Fix leaks. --------- Co-authored-by: Simon Guan <guanshengliang@qq.com> * test: reproduce bugs * test: update test case. * test: update test case. * feat: [TS-6100] Fix leaks. * test: add cases * Feat/ts 6100 3.0.pw10 (#31841) * enh: add operator reset func * fix: merge join reset issue * fix: memory issues * fix: add debug assert * fix: memory issues * fix: memory leak * fix: memory issues * fix taos log miss * fix: case issue * fix: case issue * fix: case issues * fix: drop dnode issue * fix: memory issues * fix: memory issues * fix: memory leak issues * fix: recalculate time range issue * fix: add debug log * fix: memory issues * fix: enable case asan * Update streamlist_for_ci.task * fix: case asan issue * fix: stream name issue * fix: external window compile issues * fix: deploy memory issue * fix: ahandle issue * fix: ahandle issue * fix: ahandle issue * fix: virtual table reader list issue * fix: log info * fix: msg error * fix: virtual table addr list issue * fix: memory issues * fix: memory leak issue * fix: memory issues * fix: memory free issues * fix: memory issues * fix: snode deploy issue * fix: mnode reader issue * fix: memory issues * fix: add debug test * enh: add ignore nodata trigger * fix: memory leaks * fix: configuration issue * fix: memory issue * fix: external window issue * fix: external window issues * fix: external window placeholder issue * fix: placeholder function init issues * fix: memory leak issue * fix: add debug log * fix: compile issues * fix: double free issue * fix: runner addr update issue * fix: msg rsp issue * fix: external window reset issue * fix: configuration issue * fix: deploy msg issue * fix: compile issue --------- Co-authored-by: huohong <sallyhuo@taosdata.com> * test: reproduce bugs * fix: add sliding interval combine case * test: add cases * test: add recalc test. * test: reproduce bugs * case : add vt ts is null check * modify case * bug: submit test_idmp_meters_bug3.py * test: add test for recalc. * test: add cases * fix: error code check * test: add cases * fix(stream): scan wal with schema in that version * add case * test: add cases * test: update test case. * fix: windows compile issues * add case * test: add cases (#31845) * modify case * fix: reset interpPrev * test: add test_idmp_meters bug4 and bug3 * add case * fix(stream): opti wal interface * fix: remove test_idmp_meters_bug5.py * test: add cases * fix(stream): fix ts data fetch for virtual tables * cancel asan case * test: update test case. * test: update test case. * add case * test: add cases * test: add cases * test: add case test_idmp_meters_bug5.py * test: update test case. * fix(stream): tmq error * test: add cases * feat: [TS-6100] Restore deleted code in mndSma.c since they are still in use. * fix(stream): optimize val scan logic * test: add test_recalc_expired_time.py to ci. * test: update test case. * test: update test case. * feat: [TS-6100] Fix fill range check * fix(stream): optimize val scan logic * add case * test: modify for partition by %%1 * test: add fun case stream4_sub7 * fix(stream): optimize val scan logic * add case * feat: [TS-6100] Rename OPTIONS to STREAM_OPTIONS. * test: add test for recalc. * test: use stream_options. * fix: some cases error. * test: remove recalc from ci. * fix: ci case issues (#31880) * enh: add operator reset func * fix: merge join reset issue * fix: memory issues * fix: add debug assert * fix: memory issues * fix: memory leak * fix: memory issues * fix taos log miss * fix: case issue * fix: case issue * fix: case issues * fix: drop dnode issue * fix: memory issues * fix: memory issues * fix: memory leak issues * fix: recalculate time range issue * fix: add debug log * fix: memory issues * fix: enable case asan * Update streamlist_for_ci.task * fix: case asan issue * fix: stream name issue * fix: external window compile issues * fix: deploy memory issue * fix: ahandle issue * fix: ahandle issue * fix: ahandle issue * fix: virtual table reader list issue * fix: log info * fix: msg error * fix: virtual table addr list issue * fix: memory issues * fix: memory leak issue * fix: memory issues * fix: memory free issues * fix: memory issues * fix: snode deploy issue * fix: mnode reader issue * fix: memory issues * fix: add debug test * enh: add ignore nodata trigger * fix: memory leaks * fix: configuration issue * fix: memory issue * fix: external window issue * fix: external window issues * fix: external window placeholder issue * fix: placeholder function init issues * fix: memory leak issue * fix: add debug log * fix: compile issues * fix: double free issue * fix: runner addr update issue * fix: msg rsp issue * fix: external window reset issue * fix: configuration issue * fix: deploy msg issue * fix: compile issue * fix: external window idx issue * fix: ci issues --------- Co-authored-by: huohong <sallyhuo@taosdata.com> * fix(stream): fix compilation error * fix(stream): optimize val scan logic * test:add test cases * test: modify case * fix: external agg error * test(stream): tobacco scene testing #TD-36514 * test: add stream cases (#31885) * fix: windows compile issue * fix: calc timerange * fix: windows compile issue * modify case * fix(stream): compile error * test: remove one debug test case file * test: modify * test: add test cases * test: reproduce bugs * test: reproduce bugs * feat: [TS-6100] Placeholder function should only appera in SELECT and… (#31868) * feat: [TS-6100] Placeholder function should only appera in SELECT and WHERE and FROM. * test: update case --------- Co-authored-by: Simon Guan <guanshengliang@qq.com> * add example * add example * modify case example * modify case * test:alter sql * test: add stream5 case * fix(stream): get schema error with version * test: add delete recalc test py. * test: remove bug cases * test: stream5 case test passed * test: add state cases (#31893) * fix(stream): compile error * test: modify case * test: add cases * test: add test. * test: update test case. * chore(test): fix case err * test: update test case. * fix: align data get * fix(stream): fix row index of datablock written into data cache * fix: put align data * test: update test case. * test: add test cases for virtual table * chore(test): fix case err #TD-36514 * add case * test: add test for water mark. * test: add meters bug6 for stream5 * test: add cases (#31903) * test: add test for recalc. * feat: [TS-6100] %%trows can only be used when event type is window close. * test: add precision of database for ms/us/ns * modify case * add case * add case * test: add test to ci. * modify case * fix: ci case issues (#31904) * enh: add operator reset func * fix: merge join reset issue * fix: memory issues * fix: add debug assert * fix: memory issues * fix: memory leak * fix: memory issues * fix taos log miss * fix: case issue * fix: case issue * fix: case issues * fix: drop dnode issue * fix: memory issues * fix: memory issues * fix: memory leak issues * fix: recalculate time range issue * fix: add debug log * fix: memory issues * fix: enable case asan * Update streamlist_for_ci.task * fix: case asan issue * fix: stream name issue * fix: external window compile issues * fix: deploy memory issue * fix: ahandle issue * fix: ahandle issue * fix: ahandle issue * fix: virtual table reader list issue * fix: log info * fix: msg error * fix: virtual table addr list issue * fix: memory issues * fix: memory leak issue * fix: memory issues * fix: memory free issues * fix: memory issues * fix: snode deploy issue * fix: mnode reader issue * fix: memory issues * fix: add debug test * enh: add ignore nodata trigger * fix: memory leaks * fix: configuration issue * fix: memory issue * fix: external window issue * fix: external window issues * fix: external window placeholder issue * fix: placeholder function init issues * fix: memory leak issue * fix: add debug log * fix: compile issues * fix: double free issue * fix: runner addr update issue * fix: msg rsp issue * fix: external window reset issue * fix: configuration issue * fix: deploy msg issue * fix: compile issue * fix: external window idx issue * fix: ci issues * fix: ci case issues * fix: drop dnode issue --------- Co-authored-by: huohong <sallyhuo@taosdata.com> * fix(stream): ci error * test: update test case. * feat: [TS-6100] Disable some failed UT. * feat: [TS-6100] Fix virtual table * test: add bug 5. * test: add test delete recalc to ci. * test: add bug 6. * test(stream): tobacco scene #TD-36514 * fix: reqCids,reqCols memory leak in SSTriggerRealtimeContext Co-authored-by: Tony Zhang <tonyzhang@taosdata.com> * test: add case stream6 * fix(stream): implement some pending features in trigger task * modify case * modify case * fix: case issues * modify case * test: add recalc for warter mark. * fix(stream): fix count window trigger of virtual tables * fix(stream): memory leak * test: fix run err. * test: add stream6 bug7 * fix: adjust format * test(stream): tobacco scene testing #TD-36514 * test: change bug7 with update window1 and 2 * test: add test bug 7. * case: restore write 3 window * fix: windows compile issue * fix: notify * test: add cases * modify case * test: update test case. * test(stream): toobacco scene testing #TD-36514 --------- Co-authored-by: Simon Guan <slguan@taosdata.com> Co-authored-by: plum-lihui <huili@taosdata.com> Co-authored-by: Alex Duan <417921451@qq.com> Co-authored-by: zelv01 <1101510017@qq.com> Co-authored-by: Jing Sima <simondominic9997@outlook.com> Co-authored-by: xiangyang guo <66111494+happyguoxy@users.noreply.github.com> Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: Haojun Liao <hjliao@taosdata.com> Co-authored-by: zyyang90 <zyyang@taosdata.com> Co-authored-by: Alex Duan <51781608+DuanKuanJun@users.noreply.github.com> Co-authored-by: facetosea <285808407@qq.com> Co-authored-by: Simon Guan <guanshengliang@qq.com> Co-authored-by: huohong <sallyhuo@taosdata.com> Co-authored-by: Li Hui <52318143+plum-lihui@users.noreply.github.com> Co-authored-by: Jinqing Kuang <kuangjinqingcn@gmail.com> Co-authored-by: xiao-77 <berylbao@taosdata.com> Co-authored-by: Zhixiao Bao <62235797+xiao-77@users.noreply.github.com> Co-authored-by: happyguoxy <happy_guoxy@163.com> Co-authored-by: Tony Zhang <34825804+Tony2h@users.noreply.github.com> Co-authored-by: Tony Zhang <tonyzhang@taosdata.com> * test: rename TSDB * docs: fix rust examples (#31908) * docs: modify rust native test case * docs: modify rust ws test case * docs: modify rust examples * docs: update rust pool docs * fix new cases * migrate test case * feat: support reading sub table names and tag values from CSV files to create sub tables (#31909) * feat: add obtaining table names from tag files * feat: add write data table control * feat: add table params to write * feat: delete log file * feat: modify test case csv path * feat: resolve memory leakage in the table building thread * feat: resolve compilation errors * feat: resolve table name copy len error * feat: modify create table log level * feat: modifying query configuration parameter array out of bounds * feat: support custom primary key names * feat: modify log level * feat: add set primary key name case * feat: add column keywords case * feat: add keywords case data * feat: modify primaryKeyName value len * feat: modify primaryKeyName value define * feat: modify primaryKeyName value size * fix: compile issue (#31943) Co-authored-by: taos-support <it@taosdata.com> * package: fix error * package: fix error * fix failed cases * merge 3.0 * rename create_table_keywords.py to test_create_table_keywords.py * fix failed cases * fix new cases * docs: update stream (#31957) * docs: update jdbc out-dated descripiton (#31959) * fix: TD-36560 refactor arbitrator group function name and log (#31852) * feat: support BLOB data type (#31704) * rename 0-others/mounts.py to 0-others/test_mounts.py * fix failed cases * docs: update gpt (#31975) * fix failed cases * fix failed cases * package: fix error * feat: add taosBenchmark command line parameters (#31967) * feat: add command line parameters * feat: add command line parameter test cases * fix: tableName len error * enh: set TD Release build in tdengine-build.yml * Update tdengine-build.yml * fix: add json file path log * fix: streamline TD_CONFIG export in build steps * fix: Restore the build configuration --------- Co-authored-by: haoranchen <haoran920c@163.com> * fix: tableName len error (#31977) * fix: tableName len error * fix: modify TD_CONFIG=Release * fix: code format * fix: Restore the build configuration * enh: set TD Release build in tdengine-build.yml (#31980) * enh: set TD Release build in tdengine-build.yml * Update tdengine-build.yml * fix: update cache key for externals to include debug build version * fix: remove verbose flag from build commands in tdengine-build.yml * skip memleak cases * fix failed case * fix failed cases * package: fix error * fix(stmt2):tbname error output (#31997) * fix: possible memory leak (#31972) * feat: create connect add dbname params (#32002) * feat: create connect add dbname params * fix: connect param error * skip failed cases * fix cases on windows * fix cases * support connect bi mode and fix log level * unique sql connect username and password * fix log level * enh: mounted vnode may have no tq (#31916) * fix: subquery memleak (#32024) * fix failed case * fix cases * rename 2-query/test_insert_select.py to 2-query/test_system_insert_select.py * skip memleak cases * enh: rename data forecast/detect to forecasting/anomaly detection (#32021) * package: unique product name * package: update for main * skip tsim cases * chore: update jdbc connection pool validation query sql (#32056) * refactor: quotes usage in bash scripts Signed-off-by: WANG Xu <feici02@outlook.com> * enhn(mqtt/rawblock): new format for msg payload (#31801) * fix: fix broken link in 14-stream.md * docs: 15-spark.md is missing end semicolon (#32068) * chore: bump dev version to 3.3.7.0.alpha (#32066) * fix: blob test (#32020) * fix blob query error * fix blob query error * fix blob query error * fix blob query error * fix blob query error * opt query * opt write * opt write * opt write * opt bse * opt write * opt write * opt write * opt write * opt write * opt write * opt write * opt write * opt write * opt write * opt write * opt write * opt write * add cache * opt query * opt query * opt bse * add data iter * add data iter * add more compress * add more compress * add more compress * add more compress * add more compress * add more compress * opt blob transfer * opt blob transfer * opt blob transfer * opt write * avoid unordered data write * avoid unordered data write * opt read * refactor log * fix invalid write * refactor code * fix merge error * fix merge error * add error code * support blob type len * support blob type len * support blob type len * support blob type len * support blob type len * support blob type len * support blob type len * support blob type len * support blob type len * support blob type len * Merge remote-tracking branch 'origin/3.0' into enh/blob * refactor code * support blob type len * refactor code * refactor code * benchmark support blob type * benchmark support blob type * add log * handle sort and merge row * change file set * change file set * change file set * change file set * change file set * change file set * change file set * opt code * opt read * add restart error and add unit test * add restart error and add unit test * add restart error and add unit test * add restart error and add unit test * add restart error and add unit test * refactor code * add restart error and add unit test * opt code * refactor code * fix invalid write * blob test * blob test * blob test * blob test * blob test * support blob * add str trim * add str trim * Merge remote-tracking branch 'origin/3.0' into feat/blob * Merge remote-tracking branch 'origin/3.0' into feat/blob * update test case * fix invalid read * fix invalid read * fix invalid read * add stmt2 * add stmt2 * add stmt2 * update parameter * refactor test case * refactor test case * support blob * support stmt2 * add sub * support blob * support blob * support sub * fix tmq crash * support windows/darwin * fix stmt2 bind row * fix blob crash * fix blob crash * fix blob query error * fix blob crash * fix merge error * refactor bse * add blob transfer * add blob transfer * add transfer snapshot * refactor code * change log level * change log level * add test case * refactor code * revert taosBenchmark * revert taosbench * fix: improve error handling and encoding for file reading in grep_asserts_in_file function * rm assert * fix mem leak * fix compile error * fix conflict * fix conflict * fix compile error * fix compile error * fix pre check error * fix pre check error * fix compile error on windows * fix error on window * fix error on windows * fix error on windows * opt no-blob sql * fix compile error on dawain * fix compile error on dawain * fix invalid read * fix mem leak * fix invalid read * fix invalid read * fix error on windows * remove unused code * refactor code * fix mem leak * fix mem leak * rm unused code * rm unused code * fix invalid copy * fix invalid copy * fix invalid copy * fix invalid copy * fix invalid copy * refactor code * make ci happy * refactor code * change make * update test case * update ignore code * update bse snapshot and test case * update bse snapshot and test case * refactor code * change unit test * update bse snapshot * update bse snapshot * fix test case * fix bse snapshot * fix bse snapshot * fix snapshot transfer * remove unused log * support func query * add test case * forbidden unsupport code * merge 3.0 * merge 3.0 * change test case * add forbidden code * add forbidden code * add code * support length func * support length func * taosBenchmark support blob * support blob raw block * support write raw block * support more query * Merge branch 'feat/blob' into feat/blob_test * SBlobRow2 * change bse commit change * refactor code * rm exe test * refactor code * checke return code * rename blob name * refactor code * refactor code * refactor code * refactor code * fix unordere write * fix unordere write * fix row merge error * fix row merge error * fix row merge error * fix row merge error * support ordered data * support ordered data * Merge remote-tracking branch 'origin/3.0' into feat/blob_test * fix stmt2 blob crash * add not support write type * add not support write type * add not support write type * rm exe * fix col-formate error * fix col-formate error * fix mem leak * refactor code * add error code for single blob column restriction and update error message * add error code for single blob column restriction and update error message * add error code for single blob column restriction and update error message * refactor code * change error code * make ci happy --------- Co-authored-by: yihaoDeng <yhdeng@taosdata.com> Co-authored-by: chenhaoran <haoran920c@163.com> * package: update for main (#32091) * fix compile error on windows (#32089) * fix: source code merge issues --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: WANG Xu <feici02@outlook.com> Co-authored-by: minhuinie <nminhui@163.com> Co-authored-by: huohong <sallyhuo@taosdata.com> Co-authored-by: chenhaoran <haoran920c@163.com> Co-authored-by: Nie Minhui <143420805+minhuinie@users.noreply.github.com> Co-authored-by: Mario Peng <48949600+Pengrongkun@users.noreply.github.com> Co-authored-by: Haojun Liao <hjxilinx@users.noreply.github.com> Co-authored-by: dongming chen <cademfly@hotmail.com> Co-authored-by: Linhe Huo <linhehuo@gmail.com> Co-authored-by: huohong <346479823@qq.com> Co-authored-by: Joel Brass <joel@jbrass.com> Co-authored-by: WANG Xu <feici02@outlook.com> Co-authored-by: Hongze Cheng <hzcheng@taosdata.com> Co-authored-by: Tony Zhang <34825804+Tony2h@users.noreply.github.com> Co-authored-by: Tony Zhang <tonyzhang@taosdata.com> Co-authored-by: Kaili Xu <klxu@taosdata.com> Co-authored-by: Zhixiao Bao <62235797+xiao-77@users.noreply.github.com> Co-authored-by: WANG MINGMING <wangmm0220@gmail.com> Co-authored-by: hongzhenliu <wluckyjob@gmail.com> Co-authored-by: Daniel Clow <106956386+danielclow@users.noreply.github.com> Co-authored-by: She Yanjie <57549981+sheyanjie-qq@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Simon Guan <slguan@taosdata.com> Co-authored-by: plum-lihui <huili@taosdata.com> Co-authored-by: Alex Duan <417921451@qq.com> Co-authored-by: zelv01 <1101510017@qq.com> Co-authored-by: Jing Sima <simondominic9997@outlook.com> Co-authored-by: xiangyang guo <66111494+happyguoxy@users.noreply.github.com> Co-authored-by: Haojun Liao <hjliao@taosdata.com> Co-authored-by: zyyang90 <zyyang@taosdata.com> Co-authored-by: Alex Duan <51781608+DuanKuanJun@users.noreply.github.com> Co-authored-by: facetosea <285808407@qq.com> Co-authored-by: Simon Guan <guanshengliang@qq.com> Co-authored-by: Li Hui <52318143+plum-lihui@users.noreply.github.com> Co-authored-by: Jinqing Kuang <kuangjinqingcn@gmail.com> Co-authored-by: xiao-77 <berylbao@taosdata.com> Co-authored-by: happyguoxy <happy_guoxy@163.com> Co-authored-by: guozhenwei <2227465945@qq.com> Co-authored-by: kevin men <men_shi_bin@163.com> Co-authored-by: taos-support <it@taosdata.com> Co-authored-by: Yihao Deng <luomoxyz@126.com> Co-authored-by: Minglei Jin <49711132+stephenkgu@users.noreply.github.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
1028 lines
39 KiB
Python
1028 lines
39 KiB
Python
import pytest
|
||
import os
|
||
import shutil
|
||
import time
|
||
import copy
|
||
import uuid
|
||
import json
|
||
import tempfile
|
||
import random
|
||
from new_test_framework.utils import tdSql, etool, tdLog, BeforeTest, eutil, eos
|
||
|
||
|
||
def pytest_addoption(parser):
|
||
parser.addoption("--yaml_file", action="store",
|
||
help="config YAML file in env directory")
|
||
parser.addoption("-N", action="store",
|
||
help="start dnodes numbers in clusters")
|
||
parser.addoption("-M", action="store",
|
||
help="create mnode numbers in clusters")
|
||
parser.addoption("-R", action="store_true",
|
||
help="restful realization form")
|
||
parser.addoption("-B", action="store_true",
|
||
help="start taosAdapter but not connect with taosrest")
|
||
parser.addoption("-Q", action="store",
|
||
help="set queryPolicy in one dnode")
|
||
parser.addoption("-D", action="store",
|
||
help="set disk number on each level. range 1 ~ 10")
|
||
parser.addoption("-K", action="store_true",
|
||
help="taoskeeper realization form")
|
||
parser.addoption("-L", action="store",
|
||
help="set multiple level number. range 1 ~ 3")
|
||
parser.addoption("-C", action="store",
|
||
help="create Dnode Numbers in one cluster")
|
||
parser.addoption("-I", action="store",
|
||
help="independentMnode Mnode")
|
||
parser.addoption("-A", action="store_true",
|
||
help="address sanitizer mode")
|
||
parser.addoption("--replica", action="store",
|
||
help="the number of replicas")
|
||
parser.addoption("--clean", action="store_true",
|
||
help="Clean test env processe and workdir before deploy")
|
||
parser.addoption("--tsim", action="store",
|
||
help="tsim test file")
|
||
parser.addoption("--skip_test", action="store_true",
|
||
help="Only do deploy or install without running test")
|
||
parser.addoption("--skip_deploy", action="store_true",
|
||
help="Only run test without start TDengine")
|
||
parser.addoption("--debug_log", action="store_true",
|
||
help="Enable debug log output.")
|
||
parser.addoption("--testlist", action="store",
|
||
help="Path to file containing list of test files to run")
|
||
parser.addoption("--skip_stop", action="store_true",
|
||
help="Do not destroy/stop the TDengine cluster after test class execution (for debugging or keeping environment alive)")
|
||
parser.addoption("--only_deploy", action="store_true",
|
||
help="Only deploy the environment without running any test cases")
|
||
#parser.addoption("--setup_all", action="store_true",
|
||
# help="Setup environment once before all tests running")
|
||
|
||
|
||
def pytest_configure(config):
|
||
#log_level = logging.DEBUG if config.getoption("--debug_log") else logging.INFO
|
||
#logging.basicConfig(level=log_level, format='%(asctime)s [%(levelname)s]: %(message)s')
|
||
|
||
config.addinivalue_line(
|
||
"markers",
|
||
"tsim: mark test to have its name dynamically modified based on --tsim file name"
|
||
)
|
||
|
||
|
||
@pytest.fixture(scope="session", autouse=True)
|
||
def before_test_session(request):
|
||
before_test = BeforeTest(request)
|
||
request.session.before_test = before_test
|
||
request.session.root_dir = request.config.rootdir
|
||
|
||
# 部署参数解析,存入session变量
|
||
if request.config.getoption("-M"):
|
||
request.session.mnodes_num = int(request.config.getoption("-M"))
|
||
else:
|
||
request.session.mnodes_num = 1
|
||
if request.config.getoption("--clean"):
|
||
request.session.clean = True
|
||
else:
|
||
request.session.clean = False
|
||
if request.config.getoption("--tsim"):
|
||
request.session.tsim_file = request.config.getoption("--tsim")
|
||
else:
|
||
request.session.tsim_file = None
|
||
if request.config.getoption("--replica"):
|
||
request.session.replicaVar = int(request.config.getoption("--replica"))
|
||
else:
|
||
request.session.replicaVar = 1
|
||
if request.config.getoption("--skip_deploy"):
|
||
request.session.skip_deploy = True
|
||
else:
|
||
request.session.skip_deploy = False
|
||
if request.config.getoption("--skip_test"):
|
||
request.session.skip_test = True
|
||
else:
|
||
request.session.skip_test = False
|
||
request.session.skip_stop = bool(request.config.getoption("--skip_stop"))
|
||
if request.config.getoption("-A"):
|
||
request.session.asan = True
|
||
else:
|
||
request.session.asan = False
|
||
|
||
# 读取环境变量并存入 session 变量
|
||
request.session.taos_bin_path = os.getenv('TAOS_BIN_PATH', None)
|
||
request.session.taos_bin_path = request.session.before_test.get_taos_bin_path(request.session.taos_bin_path)
|
||
|
||
request.session.work_dir = os.getenv('WORK_DIR', None)
|
||
request.session.work_dir = request.session.before_test.get_and_mkdir_workdir(request.session.work_dir)
|
||
if request.session.clean and os.path.exists(request.session.work_dir):
|
||
tdLog.info(f"rm {request.session.work_dir} before deploy")
|
||
shutil.rmtree(request.session.work_dir)
|
||
|
||
# 获取yaml文件,缓存到servers变量中,供cls使用
|
||
if request.config.getoption("--yaml_file"):
|
||
root_dir = request.config.rootdir
|
||
request.session.yaml_file = request.config.getoption("--yaml_file")
|
||
yaml_file = request.config.getoption("--yaml_file")
|
||
# 构建 env 目录下的 yaml_file 路径
|
||
yaml_file_path = os.path.join(root_dir, 'env', request.session.yaml_file)
|
||
|
||
# 检查文件是否存在
|
||
if not os.path.isfile(yaml_file_path):
|
||
raise pytest.UsageError(f"YAML file '{yaml_file_path}' does not exist.")
|
||
|
||
request.session.before_test.get_config_from_yaml(request, yaml_file_path)
|
||
tdLog.debug(f"taos_bin_path: {request.session.taos_bin_path}")
|
||
if request.session.taos_bin_path is None:
|
||
raise pytest.UsageError("TAOS_BIN_PATH is not set")
|
||
# 配置参数解析,存入session变量
|
||
else:
|
||
tdLog.debug(f"taos_bin_path: {request.session.taos_bin_path}")
|
||
if request.session.taos_bin_path is None:
|
||
raise pytest.UsageError("TAOS_BIN_PATH is not set")
|
||
if request.config.getoption("-N"):
|
||
request.session.denodes_num = int(request.config.getoption("-N"))
|
||
else:
|
||
request.session.denodes_num = 1
|
||
|
||
request.session.restful = False
|
||
request.session.start_taosadapter = False
|
||
if request.config.getoption("-R"):
|
||
request.session.restful = True
|
||
request.session.start_taosadapter = True
|
||
|
||
if request.config.getoption("-B"):
|
||
request.session.start_taosadapter = True
|
||
|
||
if request.config.getoption("-K"):
|
||
request.session.set_taoskeeper = True
|
||
else:
|
||
request.session.set_taoskeeper = False
|
||
if request.config.getoption("-Q"):
|
||
request.session.query_policy = int(request.config.getoption("-Q"))
|
||
else:
|
||
request.session.query_policy = 1
|
||
if request.config.getoption("-I"):
|
||
request.session.independentMnode = True if request.config.getoption("-I") in ["True", "true", "1"] else False
|
||
else:
|
||
request.session.independentMnode = False
|
||
if request.config.getoption("-D"):
|
||
request.session.disk = int(request.config.getoption("-D"))
|
||
else:
|
||
request.session.disk = 1
|
||
if request.config.getoption("-L"):
|
||
request.session.level = int(request.config.getoption("-L"))
|
||
else:
|
||
request.session.level = 1
|
||
if request.config.getoption("-C"):
|
||
request.session.create_dnode_num = int(request.config.getoption("-C"))
|
||
else:
|
||
request.session.create_dnode_num = request.session.denodes_num
|
||
|
||
request.session.before_test.get_config_from_param(request)
|
||
|
||
|
||
if request.session.work_dir is None:
|
||
raise pytest.UsageError("WORK_DIR is not set")
|
||
|
||
|
||
|
||
@pytest.fixture(scope="class", autouse=True)
|
||
def before_test_class(request):
|
||
'''
|
||
获取session中的配置,建立连接
|
||
测试结束后断开连接,清理环境
|
||
'''
|
||
tdLog.debug(f"Current class name: {request.cls.__name__}")
|
||
|
||
# 获取用例中可能需要用到的session变量
|
||
request.cls.yaml_file = request.session.yaml_file
|
||
request.cls.host = request.session.host
|
||
request.cls.port = request.session.port
|
||
request.cls.cfg_path = request.session.cfg_path
|
||
request.cls.dnode_nums = request.session.denodes_num
|
||
request.cls.mnode_nums = request.session.mnodes_num
|
||
request.cls.restful = request.session.restful
|
||
if request.session.restful:
|
||
request.cls.taosadapter = request.session.adapter
|
||
request.cls.set_taoskeeper = request.session.set_taoskeeper
|
||
if request.session.set_taoskeeper:
|
||
request.cls.taoskeeper = request.session.taoskeeper
|
||
request.cls.query_policy = request.session.query_policy
|
||
request.cls.replicaVar = request.session.replicaVar
|
||
request.cls.tsim_file = request.session.tsim_file
|
||
if request.session.tsim_file is not None:
|
||
request.cls.tsim_path = request.session.tsim_path
|
||
request.cls.taos_bin_path = request.session.taos_bin_path
|
||
request.cls.lib_path = request.session.lib_path
|
||
request.cls.work_dir = request.session.work_dir
|
||
|
||
# 如果用例中定义了updatecfgDict,则更新配置
|
||
if hasattr(request.cls, "updatecfgDict"):
|
||
tdLog.info(f"update cfg: {request.cls.updatecfgDict}")
|
||
request.session.before_test.update_cfg(request.cls.updatecfgDict)
|
||
|
||
# 部署taosd,包括启动dnode,mnode,adapter
|
||
if not request.session.skip_deploy:
|
||
request.session.before_test.deploy_taos(request.cls.yaml_file, request.session.mnodes_num, request.session.clean)
|
||
# 为老用例兼容,初始化老框架部分实例
|
||
request.session.before_test.init_dnode_cluster(request, dnode_nums=request.cls.dnode_nums, mnode_nums=request.cls.mnode_nums, independentMnode=True, level=request.session.level, disk=request.session.disk)
|
||
|
||
# 建立连接
|
||
request.cls.conn = request.session.before_test.get_taos_conn(request)
|
||
tdSql.init(request.cls.conn.cursor())
|
||
tdSql.replica = request.session.replicaVar
|
||
|
||
# 为兼容老用例,初始化原框架连接
|
||
#tdSql_pytest.init(request.cls.conn.cursor())
|
||
#tdSql_army.init(request.cls.conn.cursor())
|
||
|
||
# 处理 -C 参数,如果未设置 -C 参数,create_dnode_num 和 -N 参数相同
|
||
for i in range(1, request.session.create_dnode_num):
|
||
tdSql.execute(f"create dnode localhost port {6030+i*100}")
|
||
time.sleep(1)
|
||
tdLog.debug(tdSql.query(f"show dnodes", row_tag=True))
|
||
|
||
if request.session.mnodes_num:
|
||
for i in range(2, request.session.mnodes_num + 1):
|
||
tdSql.execute(f"create mnode on dnode {i}")
|
||
tdLog.debug(tdSql.query(f"show mnodes", row_tag=True))
|
||
|
||
# 处理-Q参数,如果-Q参数不等于1,则创建qnode,并设置queryPolicy
|
||
if request.session.query_policy != 1:
|
||
tdSql.execute("create qnode on dnode 1")
|
||
tdSql.execute(f'alter local "queryPolicy" "{request.session.query_policy}"')
|
||
tdSql.query("show local variables")
|
||
for i in range(len(tdSql.queryResult)):
|
||
if tdSql.queryResult[i][0] == "queryPolicy" :
|
||
if int(tdSql.queryResult[i][1]) == int(request.session.query_policy):
|
||
tdLog.info(f'alter queryPolicy to {request.session.query_policy} successfully')
|
||
else:
|
||
tdLog.debug(tdSql.queryResult)
|
||
tdLog.exit(f"alter queryPolicy to {request.session.query_policy} failed")
|
||
|
||
|
||
if request.session.skip_test:
|
||
pytest.skip("skip test")
|
||
# ============================
|
||
# 兼容army 初始化caseBase
|
||
request.cls.tmpdir = "tmp"
|
||
|
||
# record server information
|
||
request.cls.dnodeNum = request.session.denodes_num
|
||
request.cls.mnodeNum = request.session.mnodes_num
|
||
request.cls.mLevel = request.session.level
|
||
request.cls.mLevelDisk = request.session.disk
|
||
# test case information
|
||
request.cls.db = "db"
|
||
request.cls.stb = "stb"
|
||
request.cls.checkColName = "ic"
|
||
# sql
|
||
request.cls.sqlSum = f"select sum({request.cls.checkColName}) from {request.cls.stb}"
|
||
request.cls.sqlMax = f"select max({request.cls.checkColName}) from {request.cls.stb}"
|
||
request.cls.sqlMin = f"select min({request.cls.checkColName}) from {request.cls.stb}"
|
||
request.cls.sqlAvg = f"select avg({request.cls.checkColName}) from {request.cls.stb}"
|
||
request.cls.sqlFirst = f"select first(ts) from {request.cls.stb}"
|
||
request.cls.sqlLast = f"select last(ts) from {request.cls.stb}"
|
||
# ============================
|
||
|
||
yield
|
||
|
||
# 测试结束后断开连接,清理环境
|
||
if not request.session.skip_deploy:
|
||
#tdSql.close()
|
||
#tdSql_pytest.close()
|
||
#tdSql_army.close()
|
||
tdSql.close()
|
||
request.cls.conn.close()
|
||
if_success = True
|
||
tdLog.debug(f"{request.session.items}")
|
||
for item in request.session.items:
|
||
# 检查是否属于当前类
|
||
if item.cls is request.node.cls and (hasattr(item, "rep_call") or hasattr(item, "rep_setup") or hasattr(item, "rep_teardown")):
|
||
if hasattr(item, "rep_call") and item.rep_call.outcome == "failed":
|
||
tdLog.debug(f" 失败原因: {str(item.rep_call.longrepr)}")
|
||
if_success = False
|
||
if hasattr(item, "rep_setup") and item.rep_setup.outcome == "failed":
|
||
tdLog.debug(f" 失败原因: {str(item.rep_setup.longrepr)}")
|
||
if_success = False
|
||
if hasattr(item, "rep_teardown") and item.rep_teardown.outcome == "failed":
|
||
tdLog.debug(f" 失败原因: {str(item.rep_teardown.longrepr)}")
|
||
if_success = False
|
||
elif hasattr(item, "rep_call") and item.rep_call.outcome == "error":
|
||
tdLog.debug(f" 错误原因: {str(item.rep_call.longrepr)}")
|
||
if_success = False
|
||
if hasattr(item, "rep_teardown") and item.rep_teardown.outcome == "error":
|
||
tdLog.debug(f" 错误原因: {str(item.rep_teardown.longrepr)}")
|
||
if_success = False
|
||
if hasattr(item, "rep_setup") and item.rep_setup.outcome == "error":
|
||
tdLog.debug(f" 错误原因: {str(item.rep_setup.longrepr)}")
|
||
if_success = False
|
||
if if_success and not request.session.skip_stop:
|
||
tdLog.info(f"successfully executed")
|
||
request.session.before_test.destroy(request.cls.yaml_file)
|
||
|
||
@pytest.fixture(scope="class", autouse=True)
|
||
def add_common_methods(request):
|
||
# 兼容原老框架,添加CaseBase方法
|
||
def init(cls, replicaVar=1, db="db", stb="stb", checkColName="ic"):
|
||
|
||
# init
|
||
cls.childtable_count = 0
|
||
cls.insert_rows = 0
|
||
cls.timestamp_step = 0
|
||
|
||
# save param
|
||
cls.replicaVar = int(replicaVar)
|
||
cls.tmpdir = "tmp"
|
||
|
||
# record server information
|
||
cls.dnodeNum = 0
|
||
cls.mnodeNum = 0
|
||
cls.mLevel = 0
|
||
cls.mLevelDisk = 0
|
||
|
||
# test case information
|
||
cls.db = db
|
||
cls.stb = stb
|
||
|
||
# sql
|
||
cls.sqlSum = f"select sum({checkColName}) from {db}.{cls.stb}"
|
||
cls.sqlMax = f"select max({checkColName}) from {db}.{cls.stb}"
|
||
cls.sqlMin = f"select min({checkColName}) from {db}.{cls.stb}"
|
||
cls.sqlAvg = f"select avg({checkColName}) from {db}.{cls.stb}"
|
||
cls.sqlFirst = f"select first(ts) from {db}.{cls.stb}"
|
||
cls.sqlLast = f"select last(ts) from {db}.{cls.stb}"
|
||
request.cls.init = init
|
||
|
||
def stop(self):
|
||
tdSql.close()
|
||
|
||
request.cls.stop = stop
|
||
|
||
def createDb(self, options=""):
|
||
sql = f"create database {self.db} {options}"
|
||
tdSql.execute(sql, show=True)
|
||
|
||
request.cls.createDb = createDb
|
||
|
||
def trimDb(self, show = False):
|
||
tdSql.execute(f"trim database {self.db}", show = show)
|
||
|
||
request.cls.trimDb = trimDb
|
||
|
||
def compactDb(self, show = False):
|
||
tdSql.execute(f"compact database {self.db}", show = show)
|
||
|
||
request.cls.compactDb = compactDb
|
||
|
||
def flushDb(self, show = False):
|
||
tdSql.execute(f"flush database {self.db}", show = show)
|
||
|
||
request.cls.flushDb = flushDb
|
||
|
||
def dropDb(self, show = False):
|
||
tdSql.execute(f"drop database {self.db}", show = show)
|
||
|
||
request.cls.dropDb = dropDb
|
||
|
||
def dropStream(self, sname, show = False):
|
||
tdSql.execute(f"drop stream {sname}", show = show)
|
||
|
||
request.cls.dropStream = dropStream
|
||
|
||
def splitVGroups(self):
|
||
vgids = self.getVGroup(self.db)
|
||
selid = random.choice(vgids)
|
||
sql = f"split vgroup {selid}"
|
||
tdSql.execute(sql, show=True)
|
||
if self.waitTransactionZero() is False:
|
||
tdLog.exit(f"{sql} transaction not finished")
|
||
return False
|
||
return True
|
||
|
||
request.cls.splitVGroups = splitVGroups
|
||
|
||
def alterReplica(self, replica):
|
||
sql = f"alter database {self.db} replica {replica}"
|
||
tdSql.execute(sql, show=True)
|
||
if self.waitTransactionZero() is False:
|
||
tdLog.exit(f"{sql} transaction not finished")
|
||
return False
|
||
return True
|
||
|
||
request.cls.alterReplica = alterReplica
|
||
|
||
def balanceVGroup(self):
|
||
sql = f"balance vgroup"
|
||
tdSql.execute(sql, show=True)
|
||
if self.waitTransactionZero() is False:
|
||
tdLog.exit(f"{sql} transaction not finished")
|
||
return False
|
||
return True
|
||
|
||
request.cls.balanceVGroup = balanceVGroup
|
||
|
||
def balanceVGroupLeader(self):
|
||
sql = f"balance vgroup leader"
|
||
tdSql.execute(sql, show=True)
|
||
if self.waitTransactionZero() is False:
|
||
tdLog.exit(f"{sql} transaction not finished")
|
||
return False
|
||
return True
|
||
|
||
request.cls.balanceVGroupLeader = balanceVGroupLeader
|
||
def balanceVGroupLeaderOn(self, vgId):
|
||
sql = f"balance vgroup leader on {vgId}"
|
||
tdSql.execute(sql, show=True)
|
||
if self.waitTransactionZero() is False:
|
||
tdLog.exit(f"{sql} transaction not finished")
|
||
return False
|
||
return True
|
||
|
||
request.cls.balanceVGroupLeaderOn = balanceVGroupLeaderOn
|
||
|
||
def balanceVGroupLeaderOn(self, vgId):
|
||
sql = f"balance vgroup leader on {vgId}"
|
||
tdSql.execute(sql, show=True)
|
||
if self.waitTransactionZero() is False:
|
||
tdLog.exit(f"{sql} transaction not finished")
|
||
return False
|
||
|
||
request.cls.balanceVGroupLeaderOn = balanceVGroupLeaderOn
|
||
#
|
||
# check db correct
|
||
#
|
||
|
||
# basic
|
||
def checkInsertCorrect(self, difCnt = 0):
|
||
sql = f"select count(*) from {self.db}.{self.stb}"
|
||
tdSql.checkAgg(sql, self.childtable_count * self.insert_rows)
|
||
|
||
# check child table count
|
||
sql = f" select count(*) from (select count(*) as cnt , tbname from {self.db}.{self.stb} group by tbname) where cnt = {self.insert_rows} "
|
||
tdSql.checkAgg(sql, self.childtable_count)
|
||
|
||
# check step
|
||
sql = f"select count(*) from (select diff(ts) as dif from {self.db}.{self.stb} partition by tbname order by ts desc) where dif != {self.timestamp_step}"
|
||
tdSql.checkAgg(sql, difCnt)
|
||
|
||
request.cls.checkInsertCorrect = checkInsertCorrect
|
||
# save agg result
|
||
def snapshotAgg(self):
|
||
self.sum = tdSql.getFirstValue(self.sqlSum)
|
||
self.avg = tdSql.getFirstValue(self.sqlAvg)
|
||
self.min = tdSql.getFirstValue(self.sqlMin)
|
||
self.max = tdSql.getFirstValue(self.sqlMax)
|
||
self.first = tdSql.getFirstValue(self.sqlFirst)
|
||
self.last = tdSql.getFirstValue(self.sqlLast)
|
||
|
||
request.cls.snapshotAgg = snapshotAgg
|
||
# check agg
|
||
def checkAggCorrect(self):
|
||
tdSql.checkAgg(self.sqlSum, self.sum)
|
||
tdSql.checkAgg(self.sqlAvg, self.avg)
|
||
tdSql.checkAgg(self.sqlMin, self.min)
|
||
tdSql.checkAgg(self.sqlMax, self.max)
|
||
tdSql.checkAgg(self.sqlFirst, self.first)
|
||
tdSql.checkAgg(self.sqlLast, self.last)
|
||
|
||
request.cls.checkAggCorrect = checkAggCorrect
|
||
# self check
|
||
def checkConsistency(self, col):
|
||
# top with max
|
||
sql = f"select max({col}) from {self.stb}"
|
||
expect = tdSql.getFirstValue(sql)
|
||
sql = f"select top({col}, 5) from {self.stb}"
|
||
tdSql.checkFirstValue(sql, expect)
|
||
|
||
#bottom with min
|
||
sql = f"select min({col}) from {self.stb}"
|
||
expect = tdSql.getFirstValue(sql)
|
||
sql = f"select bottom({col}, 5) from {self.stb}"
|
||
tdSql.checkFirstValue(sql, expect)
|
||
|
||
# order by asc limit 1 with first
|
||
sql = f"select last({col}) from {self.stb}"
|
||
expect = tdSql.getFirstValue(sql)
|
||
sql = f"select {col} from {self.stb} order by _c0 desc limit 1"
|
||
tdSql.checkFirstValue(sql, expect)
|
||
|
||
# order by desc limit 1 with last
|
||
sql = f"select first({col}) from {self.stb}"
|
||
expect = tdSql.getFirstValue(sql)
|
||
sql = f"select {col} from {self.stb} order by _c0 asc limit 1"
|
||
tdSql.checkFirstValue(sql, expect)
|
||
|
||
request.cls.checkConsistency = checkConsistency
|
||
|
||
# check sql1 is same result with sql2
|
||
def checkSameResult(self, sql1, sql2):
|
||
tdLog.info(f"sql1={sql1}")
|
||
tdLog.info(f"sql2={sql2}")
|
||
tdLog.info("compare sql1 same with sql2 ...")
|
||
|
||
# sql
|
||
rows1 = tdSql.query(sql1,queryTimes=2)
|
||
res1 = copy.deepcopy(tdSql.queryResult)
|
||
|
||
tdSql.query(sql2,queryTimes=2)
|
||
res2 = tdSql.queryResult
|
||
|
||
rowlen1 = len(res1)
|
||
rowlen2 = len(res2)
|
||
errCnt = 0
|
||
|
||
if rowlen1 != rowlen2:
|
||
tdLog.error(f"both row count not equal. rowlen1={rowlen1} rowlen2={rowlen2} ")
|
||
return False
|
||
|
||
for i in range(rowlen1):
|
||
row1 = res1[i]
|
||
row2 = res2[i]
|
||
collen1 = len(row1)
|
||
collen2 = len(row2)
|
||
if collen1 != collen2:
|
||
tdLog.error(f"both col count not equal. collen1={collen1} collen2={collen2}")
|
||
return False
|
||
for j in range(collen1):
|
||
if row1[j] != row2[j]:
|
||
tdLog.info(f"error both column value not equal. row={i} col={j} col1={row1[j]} col2={row2[j]} .")
|
||
errCnt += 1
|
||
|
||
if errCnt > 0:
|
||
tdLog.error(f"sql2 column value different with sql1. different count ={errCnt} ")
|
||
|
||
tdLog.info("sql1 same result with sql2.")
|
||
|
||
request.cls.checkSameResult = checkSameResult
|
||
# check same value
|
||
def checkSame(self, real, expect, show = True):
|
||
if real == expect:
|
||
if show:
|
||
tdLog.info(f"check same succ. real={real} expect={expect}.")
|
||
else:
|
||
tdLog.exit(f"check same failed. real={real} expect={expect}.")
|
||
request.cls.checkSame = checkSame
|
||
# check except
|
||
def checkExcept(self, command):
|
||
try:
|
||
code = eos.exe(command)
|
||
if code == 0:
|
||
tdLog.exit(f"Failed, not report error cmd:{command}")
|
||
else:
|
||
tdLog.info(f"Passed, report error code={code} is expect, cmd:{command}")
|
||
except:
|
||
tdLog.info(f"Passed, catch expect report error for command {command}")
|
||
request.cls.checkExcept = checkExcept
|
||
#
|
||
# get db information
|
||
#
|
||
|
||
# get vgroups
|
||
def getVGroup(self, dbName):
|
||
vgidList = []
|
||
sql = f"select vgroup_id from information_schema.ins_vgroups where db_name='{dbName}'"
|
||
res = tdSql.getResult(sql)
|
||
rows = len(res)
|
||
for i in range(rows):
|
||
vgidList.append(res[i][0])
|
||
|
||
return vgidList
|
||
|
||
request.cls.getVGroup = getVGroup
|
||
|
||
# get distributed rows
|
||
def getDistributed(self, tbName):
|
||
sql = f"show table distributed {tbName}"
|
||
tdSql.query(sql)
|
||
dics = {}
|
||
i = 0
|
||
for i in range(tdSql.getRows()):
|
||
row = tdSql.getData(i, 0)
|
||
#print(row)
|
||
row = row.replace('[', '').replace(']', '')
|
||
#print(row)
|
||
items = row.split(' ')
|
||
#print(items)
|
||
for item in items:
|
||
#print(item)
|
||
v = item.split('=')
|
||
#print(v)
|
||
if len(v) == 2:
|
||
dics[v[0]] = v[1]
|
||
if i > 5:
|
||
break
|
||
print(dics)
|
||
return dics
|
||
|
||
request.cls.getDistributed = getDistributed
|
||
|
||
def taos(self, command, show = True, checkRun = False):
|
||
return etool.runBinFile("taos", command, show, checkRun)
|
||
request.cls.taos = taos
|
||
|
||
def taosdump(self, command, show = True, checkRun = True, retFail = True):
|
||
return etool.runBinFile("taosdump", command, show, checkRun, retFail)
|
||
request.cls.taosdump = taosdump
|
||
|
||
def benchmark(self, command, show = True, checkRun = True, retFail = True):
|
||
return etool.runBinFile("taosBenchmark", command, show, checkRun, retFail)
|
||
request.cls.benchmark = benchmark
|
||
|
||
#
|
||
# util
|
||
#
|
||
|
||
# wait transactions count to zero , return False is translation not finished
|
||
def waitTransactionZero(self, seconds = 300, interval = 1):
|
||
# wait end
|
||
for i in range(seconds):
|
||
sql ="show transactions;"
|
||
rows = tdSql.query(sql)
|
||
if rows == 0:
|
||
tdLog.info("transaction count became zero.")
|
||
return True
|
||
#tdLog.info(f"i={i} wait ...")
|
||
time.sleep(interval)
|
||
|
||
return False
|
||
|
||
request.cls.waitTransactionZero = waitTransactionZero
|
||
def waitCompactsZero(self, seconds = 300, interval = 1):
|
||
# wait end
|
||
for i in range(seconds):
|
||
sql ="show compacts;"
|
||
rows = tdSql.query(sql)
|
||
if rows == 0:
|
||
tdLog.info("compacts count became zero.")
|
||
return True
|
||
#tdLog.info(f"i={i} wait ...")
|
||
time.sleep(interval)
|
||
|
||
return False
|
||
|
||
request.cls.waitCompactsZero = waitCompactsZero
|
||
|
||
# check file exist
|
||
def checkFileExist(self, pathFile):
|
||
if os.path.exists(pathFile) == False:
|
||
tdLog.error(f"file not exist {pathFile}")
|
||
|
||
# check list not exist
|
||
def checkListNotEmpty(self, lists, tips=""):
|
||
if len(lists) == 0:
|
||
tdLog.error(f"list is empty {tips}")
|
||
|
||
request.cls.checkListNotEmpty = checkListNotEmpty
|
||
|
||
# check list have str
|
||
def checkListString(self, rlist, s):
|
||
if s is None:
|
||
return
|
||
for i in range(len(rlist)):
|
||
if rlist[i].find(s) != -1:
|
||
# found
|
||
tdLog.info(f'found "{s}" on index {i} , line={rlist[i]}')
|
||
return
|
||
|
||
# not found
|
||
|
||
i = 1
|
||
for x in rlist:
|
||
print(f"{i} {x}")
|
||
i += 1
|
||
tdLog.exit(f'faild, not found "{s}" on above')
|
||
request.cls.checkListString = checkListString
|
||
|
||
# check many string
|
||
def checkManyString(self, rlist, manys):
|
||
for s in manys:
|
||
self.checkListString(rlist, s)
|
||
request.cls.checkManyString = checkManyString
|
||
#
|
||
# str util
|
||
#
|
||
# covert list to sql format string
|
||
def listSql(self, lists, sepa = ","):
|
||
strs = ""
|
||
for ls in lists:
|
||
if strs != "":
|
||
strs += sepa
|
||
strs += f"'{ls}'"
|
||
return strs
|
||
|
||
request.cls.listSql = listSql
|
||
#
|
||
# taosBenchmark
|
||
#
|
||
|
||
# run taosBenchmark and check insert Result
|
||
def insertBenchJson(self, jsonFile, options="", checkStep=False):
|
||
# exe insert
|
||
cmd = f"{options} -f {jsonFile}"
|
||
etool.runBinFile("taosBenchmark", command = cmd)
|
||
|
||
#
|
||
# check insert result
|
||
#
|
||
with open(jsonFile, "r") as file:
|
||
data = json.load(file)
|
||
|
||
db = data["databases"][0]["dbinfo"]["name"]
|
||
stb = data["databases"][0]["super_tables"][0]["name"]
|
||
child_count = data["databases"][0]["super_tables"][0]["childtable_count"]
|
||
insert_rows = data["databases"][0]["super_tables"][0]["insert_rows"]
|
||
timestamp_step = data["databases"][0]["super_tables"][0]["timestamp_step"]
|
||
|
||
# drop
|
||
try:
|
||
drop = data["databases"][0]["dbinfo"]["drop"]
|
||
except:
|
||
drop = "yes"
|
||
|
||
# command is first
|
||
if options.find("-Q") != -1:
|
||
drop = "no"
|
||
|
||
# cachemodel
|
||
try:
|
||
cachemode = data["databases"][0]["dbinfo"]["cachemodel"]
|
||
except:
|
||
cachemode = None
|
||
|
||
# vgropus
|
||
try:
|
||
vgroups = data["databases"][0]["dbinfo"]["vgroups"]
|
||
except:
|
||
vgroups = None
|
||
|
||
tdLog.info(f"get json info: db={db} stb={stb} child_count={child_count} insert_rows={insert_rows} \n")
|
||
|
||
# all count insert_rows * child_table_count
|
||
sql = f"select * from {db}.{stb}"
|
||
tdSql.query(sql)
|
||
tdSql.checkRows(child_count * insert_rows)
|
||
|
||
# timestamp step
|
||
if checkStep:
|
||
sql = f"select * from (select diff(ts) as dif from {db}.{stb} partition by tbname) where dif != {timestamp_step};"
|
||
tdSql.query(sql)
|
||
tdSql.checkRows(0)
|
||
|
||
if drop.lower() == "yes":
|
||
# check database optins
|
||
sql = f"select `vgroups`,`cachemodel` from information_schema.ins_databases where name='{db}';"
|
||
tdSql.query(sql)
|
||
|
||
if cachemode != None:
|
||
|
||
value = eutil.removeQuota(cachemode)
|
||
tdLog.info(f" deal both origin={cachemode} after={value}")
|
||
tdSql.checkData(0, 1, value)
|
||
|
||
if vgroups != None:
|
||
tdSql.checkData(0, 0, vgroups)
|
||
|
||
return db, stb,child_count, insert_rows
|
||
|
||
request.cls.insertBenchJson = insertBenchJson
|
||
|
||
# insert & check
|
||
def benchInsert(self, jsonFile, options = "", results = None):
|
||
# exe insert
|
||
benchmark = etool.benchMarkFile()
|
||
cmd = f"{benchmark} {options} -f {jsonFile}"
|
||
rlist = eos.runRetList(cmd, True, True, True)
|
||
if results != None:
|
||
for result in results:
|
||
self.checkListString(rlist, result)
|
||
|
||
# open json
|
||
with open(jsonFile, "r") as file:
|
||
data = json.load(file)
|
||
|
||
# read json
|
||
dbs = data["databases"]
|
||
for db in dbs:
|
||
dbName = db["dbinfo"]["name"]
|
||
stbs = db["super_tables"]
|
||
for stb in stbs:
|
||
stbName = stb["name"]
|
||
child_count = stb["childtable_count"]
|
||
insert_rows = stb["insert_rows"]
|
||
timestamp_step = stb["timestamp_step"]
|
||
|
||
# check result
|
||
|
||
# count
|
||
sql = f"select count(*) from {dbName}.{stbName}"
|
||
tdSql.checkAgg(sql, child_count * insert_rows)
|
||
# diff
|
||
sql = f"select * from (select diff(ts) as dif from {dbName}.{stbName} partition by tbname) where dif != {timestamp_step};"
|
||
tdSql.query(sql)
|
||
tdSql.checkRows(0)
|
||
# show
|
||
tdLog.info(f"insert check passed. db:{dbName} stb:{stbName} child_count:{child_count} insert_rows:{insert_rows}\n")
|
||
request.cls.benchInsert = benchInsert
|
||
# tmq
|
||
def tmqBenchJson(self, jsonFile, options="", checkStep=False):
|
||
# exe insert
|
||
command = f"{options} -f {jsonFile}"
|
||
rlist = etool.runBinFile("taosBenchmark", command, checkRun = True)
|
||
|
||
#
|
||
# check insert result
|
||
#
|
||
print(rlist)
|
||
|
||
return rlist
|
||
request.cls.tmqBenchJson = tmqBenchJson
|
||
# cmd
|
||
def benchmarkCmd(self, options, childCnt, insertRows, timeStep, results):
|
||
# set
|
||
self.childtable_count = childCnt
|
||
self.insert_rows = insertRows
|
||
self.timestamp_step = timeStep
|
||
|
||
# run
|
||
cmd = f"{options} -t {childCnt} -n {insertRows} -S {timeStep} -y"
|
||
rlist = self.benchmark(cmd)
|
||
for result in results:
|
||
self.checkListString(rlist, result)
|
||
|
||
# check correct
|
||
self.checkInsertCorrect()
|
||
|
||
request.cls.benchmarkCmd = benchmarkCmd
|
||
# generate new json file
|
||
def genNewJson(self, jsonFile, modifyFunc=None):
|
||
try:
|
||
with open(jsonFile, 'r', encoding='utf-8') as f:
|
||
data = json.load(f)
|
||
except FileNotFoundError:
|
||
tdLog.info(f"the specified json file '{jsonFile}' was not found.")
|
||
return None
|
||
except Exception as e:
|
||
tdLog.info(f"error reading the json file: {e}")
|
||
return None
|
||
|
||
if callable(modifyFunc):
|
||
modifyFunc(data)
|
||
|
||
tempDir = os.path.join(tempfile.gettempdir(), 'json_templates')
|
||
try:
|
||
os.makedirs(tempDir, exist_ok=True)
|
||
except PermissionError:
|
||
tdLog.info(f"no sufficient permissions to create directory at '{tempDir}'.")
|
||
return None
|
||
except Exception as e:
|
||
tdLog.info(f"error creating temporary directory: {e}")
|
||
return None
|
||
|
||
tempPath = os.path.join(tempDir, f"temp_{uuid.uuid4().hex}.json")
|
||
|
||
try:
|
||
with open(tempPath, 'w', encoding='utf-8') as f:
|
||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||
except Exception as e:
|
||
tdLog.info(f"error writing to temporary json file: {e}")
|
||
return None
|
||
|
||
tdLog.info(f"create temporary json file successfully, file: {tempPath}")
|
||
return tempPath
|
||
request.cls.genNewJson = genNewJson
|
||
|
||
# delete file
|
||
def deleteFile(self, filename):
|
||
try:
|
||
if os.path.exists(filename):
|
||
os.remove(filename)
|
||
except Exception as err:
|
||
raise Exception(err)
|
||
request.cls.deleteFile = deleteFile
|
||
|
||
# read file to list
|
||
def readFileToList(self, filePath):
|
||
try:
|
||
with open(filePath, 'r', encoding='utf-8') as file:
|
||
lines = file.readlines()
|
||
# Strip trailing newline characters
|
||
return [line.rstrip('\n') for line in lines]
|
||
except FileNotFoundError:
|
||
tdLog.info(f"Error: File not found {filePath}")
|
||
return []
|
||
except Exception as e:
|
||
tdLog.info(f"Error reading file: {e}")
|
||
return []
|
||
request.cls.readFileToList = readFileToList
|
||
|
||
def pytest_collection_modifyitems(config, items):
|
||
if config.getoption("--only_deploy"):
|
||
dummy_items = [item for item in items if "cases/dummy/" in str(item.fspath)]
|
||
deselected = [item for item in items if item not in dummy_items]
|
||
config.hook.pytest_deselected(items=deselected)
|
||
items[:] = dummy_items
|
||
return
|
||
|
||
tsim_path = config.getoption("--tsim")
|
||
testlist_file = config.getoption("--testlist")
|
||
|
||
if testlist_file:
|
||
# 读取测试列表文件
|
||
try:
|
||
with open(testlist_file, 'r') as f:
|
||
test_files = set()
|
||
for line in f:
|
||
line = line.strip()
|
||
# 跳过空行和注释行
|
||
if not line or line.startswith('#'):
|
||
continue
|
||
# 确保路径格式正确
|
||
if line.endswith('.py'):
|
||
test_files.add(line)
|
||
else:
|
||
test_files.add(f"{line}.py")
|
||
except FileNotFoundError:
|
||
pytest.exit(f"Testlist file not found: {testlist_file}")
|
||
except Exception as e:
|
||
pytest.exit(f"Error reading testlist file: {str(e)}")
|
||
|
||
if tsim_path:
|
||
for item in items:
|
||
if item.get_closest_marker("tsim"):
|
||
tsim_name = f"{os.path.split(os.path.dirname(tsim_path))[-1]}_{os.path.splitext(os.path.basename(tsim_path))[0]}"
|
||
item.name = f"{tsim_name}" # 有效,名称可以修改
|
||
item._nodeid = "::".join(item._nodeid.split('::')[:-1]) + f"::{tsim_name}" # 有效,名称可以修改
|
||
tdLog.debug(item.name)
|
||
tdLog.debug(item._nodeid)
|
||
params = {'params': tsim_name} # 你的参数组合
|
||
param_ids = [tsim_name] # 自定义参数ID
|
||
|
||
# 创建参数化标记
|
||
marker = pytest.mark.parametrize(
|
||
argnames='params',
|
||
argvalues=[tsim_name],
|
||
ids=param_ids
|
||
)
|
||
item.add_marker(marker)
|
||
|
||
# 确保Allure能识别新参数
|
||
item.callspec = type('CallSpec', (), {'params': params, 'id': param_ids[0]})
|
||
else:
|
||
name_suffix = ""
|
||
if config.getoption('-N'):
|
||
name_suffix += f"_N{config.getoption('-N')}"
|
||
if config.getoption('-M'):
|
||
name_suffix += f"_M{config.getoption('-M')}"
|
||
if config.getoption('-R'):
|
||
name_suffix += f"_R"
|
||
if config.getoption('-Q'):
|
||
name_suffix += f"_Q"
|
||
if config.getoption('-D'):
|
||
name_suffix += f"_D{config.getoption('-D')}"
|
||
if config.getoption('-L'):
|
||
name_suffix += f"_L{config.getoption('-L')}"
|
||
if config.getoption('-C'):
|
||
name_suffix += f"_C{config.getoption('-C')}"
|
||
if config.getoption('-I'):
|
||
name_suffix += f"_I"
|
||
if config.getoption('--replica'):
|
||
name_suffix += f"_replica{config.getoption('--replica')}"
|
||
|
||
# 筛选测试项
|
||
selected = []
|
||
deselected = []
|
||
for item in items:
|
||
if name_suffix != "":
|
||
item.name = f"{item.name}{name_suffix}" # 有效,名称可以修改
|
||
item._nodeid = "::".join(item._nodeid.split('::')[:-1]) + f"::{item.name}" # 有效,名称可以修改
|
||
tdLog.debug(item.name)
|
||
tdLog.debug(item._nodeid)
|
||
params = {'params': name_suffix} # 你的参数组合
|
||
param_ids = [name_suffix] # 自定义参数ID
|
||
|
||
# 创建参数化标记
|
||
marker = pytest.mark.parametrize(
|
||
argnames='params',
|
||
argvalues=[name_suffix],
|
||
ids=param_ids
|
||
)
|
||
item.add_marker(marker)
|
||
|
||
# 确保Allure能识别新参数
|
||
item.callspec = type('CallSpec', (), {'params': params, 'id': param_ids[0]})
|
||
|
||
# 检查是否在测试列表中
|
||
if testlist_file:
|
||
if any(os.path.relpath(str(item.fspath)).endswith(test_file) for test_file in test_files):
|
||
selected.append(item)
|
||
else:
|
||
deselected.append(item)
|
||
|
||
if testlist_file:
|
||
# 更新测试项列表
|
||
items[:] = selected
|
||
config.hook.pytest_deselected(items=deselected)
|
||
|
||
|
||
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
|
||
def pytest_runtest_makereport(item, call):
|
||
outcome = yield
|
||
rep = outcome.get_result()
|
||
setattr(item, "rep_" + rep.when, rep)
|