Merge branch '3.0' into doc/analysis

This commit is contained in:
Haojun Liao 2025-03-22 23:56:55 +08:00 committed by GitHub
commit 7336f11f17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 84 additions and 128 deletions

View File

@ -8,7 +8,7 @@
</a>
</p>
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/taosdata/tdengine/tdengine-test.yml)](https://github.com/taosdata/TDengine/actions/workflows/tdengine-test.yml)
[![TDengine Release Build](https://github.com/taosdata/TDengine/actions/workflows/tdengine-release-build.yml/badge.svg)](https://github.com/taosdata/TDengine/actions/workflows/tdengine-release-build.yml)
[![Coverage Status](https://coveralls.io/repos/github/taosdata/TDengine/badge.svg?branch=3.0)](https://coveralls.io/github/taosdata/TDengine?branch=3.0)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/taosdata/tdengine)](https://github.com/feici02/TDengine/commits/main/)
<br />
@ -82,7 +82,9 @@ For contributing/building/testing TDengine Connectors, please check the followin
# 3. Prerequisites
At the moment, TDengine server supports running on Linux/Windows/MacOS systems. Any application can also choose the RESTful interface provided by taosAdapter to connect the taosd service. TDengine supports X64/ARM64 CPU, and it will support MIPS64, Alpha64, ARM32, RISC-V and other CPU architectures in the future. Right now we don't support build with cross-compiling environment.
At the moment, TDengine server supports running on Linux/MacOS systems. Any application can also choose the RESTful interface provided by taosAdapter to connect the taosd service. TDengine supports X64/ARM64 CPU, and it will support MIPS64, Alpha64, ARM32, RISC-V and other CPU architectures in the future. Right now we don't support build with cross-compiling environment.
Starting from version 3.1.0.0, TDengine supports the Windows system exclusively in its Enterprise edition.
If you want to compile taosAdapter or taosKeeper, you need to install Go 1.18 or above.
@ -127,13 +129,7 @@ brew install argp-standalone gflags pkgconfig
## 3.3 Prerequisites on Windows
<details>
<summary>Install required tools on Windows</summary>
Work in Progress.
</details>
Not available for community edition.
## 3.4 Clone the repo
@ -212,40 +208,7 @@ If you want to compile taosKeeper, you need to add the `-DBUILD_KEEPER=true` opt
## 4.3 Build on Windows
<details>
<summary>Detailed steps to build on Windows</summary>
If you use the Visual Studio 2013, please open a command window by executing "cmd.exe".
Please specify "amd64" for 64 bits Windows or specify "x86" for 32 bits Windows when you execute vcvarsall.bat.
```cmd
mkdir debug && cd debug
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" < amd64 | x86 >
cmake .. -G "NMake Makefiles"
nmake
```
If you use the Visual Studio 2019 or 2017:
please open a command window by executing "cmd.exe".
Please specify "x64" for 64 bits Windows or specify "x86" for 32 bits Windows when you execute vcvarsall.bat.
```cmd
mkdir debug && cd debug
"c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" < x64 | x86 >
cmake .. -G "NMake Makefiles"
nmake
```
Or, you can simply open a command window by clicking Windows Start -> "Visual Studio < 2019 | 2017 >" folder -> "x64 Native Tools Command Prompt for VS < 2019 | 2017 >" or "x86 Native Tools Command Prompt for VS < 2019 | 2017 >" depends what architecture your Windows is, then execute commands as follows:
```cmd
mkdir debug && cd debug
cmake .. -G "NMake Makefiles"
nmake
```
</details>
Not available for community edition.
# 5. Packaging
@ -285,17 +248,7 @@ sudo make install
## 6.3 Install on Windows
<details>
<summary>Detailed steps to install on windows</summary>
After building successfully, TDengine can be installed by:
```cmd
nmake install
```
</details>
Not available for community edition.
# 7. Running
@ -360,25 +313,7 @@ If TDengine CLI connects the server successfully, welcome messages and version i
## 7.3 Run TDengine on Windows
<details>
<summary>Detailed steps to run on windows</summary>
You can start TDengine server on Windows platform with below commands:
```cmd
.\build\bin\taosd.exe -c test\cfg
```
In another terminal, use the TDengine CLI to connect the server:
```cmd
.\build\bin\taos.exe -c test\cfg
```
option "-c test/cfg" specifies the system configuration file directory.
</details>
Not available for community edition.
# 8. Testing

View File

@ -151,15 +151,22 @@ Using docker-compose, configure Grafana Provisioning for automated setup, and ex
services:
tdengine:
image: tdengine/tdengine:3.3.0.0
image: tdengine/tdengine:latest
container_name: tdengine
hostname: tdengine
environment:
TAOS_FQDN: tdengine
MONITOR_FQDN: tdengine
EXPLORER_CLUSTER: http://tdengine:6041
TAOS_KEEPER_TDENGINE_HOST: tdengine
volumes:
- tdengine-data:/var/lib/taos/
ports:
- 6060:6060
grafana:
image: grafana/grafana:9.3.6
image: grafana/grafana:latest
volumes:
- ./tdengine.yml/:/etc/grafana/provisioning/tdengine.yml
- ./tdengine.yml:/etc/grafana/provisioning/tdengine.yml
- grafana-data:/var/lib/grafana
environment:
# install tdengine plugin at start
@ -169,6 +176,7 @@ Using docker-compose, configure Grafana Provisioning for automated setup, and ex
TDENGINE_BASIC_AUTH: "cm9vdDp0YmFzZTEyNQ=="
ports:
- 3000:3000
volumes:
grafana-data:
tdengine-data:

View File

@ -79,9 +79,9 @@ toc_max_heading_level: 4
### 虚拟表
“一个设备一张表”的设计解决了工业和物联网等场景下的大多数时序数据管理和分析难题,但是在遇到更复杂的场景时,这种设计受到了设备复杂性的挑战。这种复杂性的根源在于一个设备无法简单的用一个或一组数据采集点来描述或管理,而业务分析往往需要综合多个或多组采集点的数据才能完成。以汽车或发电风机为例,整个设备(汽车或风机)中含有非常大量的传感器(数据采集点),这些传感器的输出和采集频率千差万别。一个超级表只能描述其中一种传感器,当需要综合多个传感器的数据进行分析计算时,只能通过多级关联查询的方式来进行,而这往往会导致易用性和性能方面的问题。
“一个设备一张表”的设计解决了工业和物联网等场景下的大多数时序数据管理和分析难题,但是在遇到更复杂的场景时,这种设计受到了设备复杂性的挑战。根源在于一个设备无法简单的用一个或一组数据采集点来描述或管理,而业务分析往往需要综合多个或多组采集点的数据才能完成。以汽车或发电风机为例,整个设备(汽车或风机)中含有非常大量的传感器(数据采集点),这些传感器的输出和采集频率千差万别。一个超级表只能描述其中一种传感器,当需要综合多个传感器的数据进行分析计算时,只能通过多级关联查询的方式来进行,而这往往会导致易用性和性能方面的问题。
为了解决这个问题TDengine 引入虚拟表Virtual Table简称为 VTable的概念。虚拟表是一种不存储实际数据而可以用于分析计算的表它的数据来源为其它真实存储数据的子表、普通表通过将不同列数据按照时间戳排序、对齐、合并的方式来生成虚拟表。同真实表类似虚拟表也可以分为虚拟超级表、虚拟子表、虚拟普通表。虚拟超级表可以是一个设备或一组分析计算所需数据的完整集合每个虚拟子表可以根据需要引用相同或不同的列因此可以灵活地根据业务需要进行定义最终可以达到千表千面的效果。虚拟表不能写入、删除数据,在查询使用上同真实表基本相同,支持虚拟超级表、虚拟子表、虚拟普通表上的任何查询。唯一的区别在于虚拟表的数据是每次查询计算时动态生成的,只有一个查询中引用的列才会被合并进虚拟表中,因此同一个虚拟表在不同的查询中所呈现的数据可能是不同的。
为了解决这个问题TDengine 引入虚拟表Virtual Table简称为 VTable的概念。虚拟表是一种不存储实际数据而可以用于分析计算的表它的数据来源为其它真实存储数据的子表、普通表通过将不同列数据按照时间戳排序、对齐、合并的方式来生成虚拟表。同真实表类似虚拟表也可以分为虚拟超级表、虚拟子表、虚拟普通表。虚拟超级表可以是一个设备或一组分析计算所需数据的完整集合每个虚拟子表可以根据需要引用相同或不同的列因此可以灵活地根据业务需要进行定义最终达到千表千面的效果。虚拟表不能写入、删除数据在查询使用上同真实表基本相同支持虚拟超级表、虚拟子表、虚拟普通表上的任何查询。唯一的区别在于虚拟表的数据是每次查询计算时动态生成的只有一个查询中引用的列才会被合并进虚拟表中因此同一个虚拟表在不同的查询中所呈现的数据可能是不同的。
虚拟超级表的主要功能特点包括:
1. 列选择与拼接 <br />
@ -91,7 +91,7 @@ toc_max_heading_level: 4
3. 动态更新 <br />
虚拟表根据原始表的数据变化自动更新,确保数据的实时性。虚拟表不需实际存储,计算在生成时动态完成。
通过引入虚拟表的概念,现在 TDengine 可以非常方便的管理更大更复杂的设备数据。无论每个采集点如何建模(单列 or 多列),无论这些采集点的数据是分布在一个或多个库中,我们现在都可以通过定义虚拟子表的方式跨库跨表任意指定数据源,通过虚拟超级表的方式进行跨设备、跨分析的聚合运算,从此“一个设备一张表”彻底成为现实。
通过引入虚拟表的概念TDengine 可以非常方便的管理更大更复杂的设备数据。无论每个采集点如何建模(单列 or 多列),无论这些采集点的数据是分布在一个或多个库中,都可以通过定义虚拟子表的方式跨库跨表任意指定数据源,通过虚拟超级表的方式进行跨设备、跨分析的聚合运算,从此“一个设备一张表”彻底成为现实。
### 库
@ -101,7 +101,7 @@ toc_max_heading_level: 4
### 时间戳
时间戳在时序数据处理中扮演着至关重要的角色,特别是在应用程序需要从多个不同时区访问数据库时,这一问题变得更加复杂。在深入了解 TDengine 如何处理时间戳与时区之前,我们先介绍以下几个基本概念。
时间戳在时序数据处理中扮演着至关重要的角色,特别是在应用程序需要从多个不同时区访问数据库时,这一问题变得更加复杂。在深入了解 TDengine 如何处理时间戳与时区之前,先介绍以下几个基本概念。
- 本地日期时间:指特定地区的当地时间,通常表示为 yyyy-MM-dd hh:mm:ss.SSS 格式的字符串。这种时间表示不包含任何时区信息,如 “2021-07-21 12:00:00.000”。
- 时区地球上不同地理位置的标准时间。协调世界时Universal Time CoordinatedUTC或格林尼治时间是国际时间标准其他时区通常表示为相对于 UTC 的偏移量,如 “UTC+8” 代表东八区时间。 UTC 时间戳:表示自 UNIX 纪元(即 UTC 时间 1970 年 1 月 1 日 0 点起经过的毫秒数。例如“1700000000000” 对应的日期时间是 “2023-11-14 22:13:20UTC+0”。 在 TDengine 中保存时序数据时,实际上保存的是 UTC 时间戳。TDengine 在写入数据时,时间戳的处理分为如下两种情况。
- RFC-3339 格式当使用这种格式时TDengine 能够正确解析带有时区信息的时间字符串为 UTC 时间戳。例如“2018-10-03T14:38:05.000+08:00” 会被转换为 UTC 时间戳。
@ -109,10 +109,9 @@ toc_max_heading_level: 4
在查询数据时TDengine 客户端会根据应用程序当前的时区设置,自动将保存的 UTC 时间戳转换成本地时间进行显示,确保用户在不同时区下都能看到正确的时间信息。
## 数据建模
本节用智能电表做例子,简要的介绍如何在 TDengine 里使用 SQL 创建数据库、超级表、表的基本操作。
本节以智能电表为例,介绍如何在 TDengine 里使用 SQL 创建数据库、超级表、表的基本操作。
### 创建数据库
@ -276,7 +275,7 @@ CREATE STABLE phase_stb (
);
```
假设分别有 d1001,d1002,d1003,d1004 四个设备,分别对四个设备的电流、电压、相位采集量创建子表SQL 如下:
假设有 d1001、d1002、d1003、d1004 四个设备,为四个设备的电流、电压、相位采集量分别创建子表SQL 如下:
```sql
create table current_d1001 using current_stb(deviceid, location, group_id) tags("d1001", "California.SanFrancisco", 2);
@ -295,7 +294,7 @@ create table phase_d1003 using phase_stb(deviceid, location, group_id) tags("d10
create table phase_d1004 using phase_stb(deviceid, location, group_id) tags("d1004", "California.LosAngeles", 2);
```
此时想要通过一张虚拟超级表来讲这三种采集量聚合到一张表中,创建虚拟超级表 SQL 如下:
可通过一张虚拟超级表来将这三种采集量聚合到一张表中,创建虚拟超级表 SQL 如下:
```sql
CREATE STABLE meters_v (
@ -309,51 +308,51 @@ CREATE STABLE meters_v (
) VIRTUAL 1;
```
并且对四个设备 d1001,d1002,d1003,d1004 分别创建虚拟子表SQL 如下:
并且对四个设备 d1001、d1002、d1003、d1004 分别创建虚拟子表SQL 如下:
```sql
CREATE VTABLE d1001_v (
current from current_d1001.current,
voltage from voltage_d1001.voltage,
phase from phase_d1001.phase
current from current_d1001.current,
voltage from voltage_d1001.voltage,
phase from phase_d1001.phase
)
USING meters_v
TAGS (
"California.SanFrancisco",
2
"California.SanFrancisco",
2
);
CREATE VTABLE d1002_v (
current from current_d1002.current,
voltage from voltage_d1002.voltage,
phase from phase_d1002.phase
current from current_d1002.current,
voltage from voltage_d1002.voltage,
phase from phase_d1002.phase
)
USING meters_v
TAGS (
"California.SanFrancisco",
3
"California.SanFrancisco",
3
);
CREATE VTABLE d1003_v (
current from current_d1003.current,
voltage from voltage_d1003.voltage,
phase from phase_d1003.phase
current from current_d1003.current,
voltage from voltage_d1003.voltage,
phase from phase_d1003.phase
)
USING meters_v
TAGS (
"California.LosAngeles",
3
"California.LosAngeles",
3
);
CREATE VTABLE d1004_v (
current from current_d1004.current,
voltage from voltage_d1004.voltage,
phase from phase_d1004.phase
current from current_d1004.current,
voltage from voltage_d1004.voltage,
phase from phase_d1004.phase
)
USING meters_v
TAGS (
"California.LosAngeles",
2
"California.LosAngeles",
2
);
```
@ -361,7 +360,7 @@ TAGS (
![data-model-origin-table.png](data-model-origin-table.png)
虚拟表 d1001_v 中的数据如下 :
虚拟表 d1001_v 中的数据如下:
| Timestamp | Current | Voltage | Phase |
|:--------------:|:-------:|:---------:|:-------:|
@ -378,15 +377,15 @@ TAGS (
在跨源采集量对比分析中,“跨源”指数据来自**不同数据采集点**。在不同数据采集点中提取具有可比语义的采集量,通过虚拟表将这些采集量按照时间戳进行对齐和合并,并进行对比分析。
例如,用户可以将来自不同设备的电流数据聚合到一张虚拟表中,以便进行电流数据的对比分析。
以分析 d1001, d1002, d1003, d1004 四个设备的电流数据为例,创建虚拟表的 SQL 如下:
以分析 d1001、d1002、d1003、d1004 四个设备的电流数据为例,创建虚拟表的 SQL 如下:
```sql
CREATE VTABLE current_v (
ts timestamp,
d1001_current float from current_d1001.current,
d1002_current float from current_d1002.current,
d1003_current float from current_d1003.current,
d1004_current float from current_d1004.current
ts timestamp,
d1001_current float from current_d1001.current,
d1002_current float from current_d1002.current,
d1003_current float from current_d1003.current,
d1004_current float from current_d1004.current
);
```

View File

@ -139,6 +139,7 @@ res_start_time = 1730000000000
gen_figure = true
```
对比程序执行完成以后,会自动生成名称为`fc_result.xlsx` 的文件,第一个卡片是算法运行结果(如下表所示),分别包含了算法名称、执行调用参数、均方误差、执行时间 4 个指标。
| algorithm | params | MSE | elapsed_time(ms.) |

View File

@ -101,6 +101,7 @@ lof={"algorithm":"auto", "n_neighbor": 3}
对比程序执行完成以后,会自动生成名称为`ad_result.xlsx` 的文件,第一个卡片是算法运行结果(如下表所示),分别包含了算法名称、执行调用参数、查全率、查准率、执行时间 5 个指标。
| algorithm | params | precision(%) | recall(%) | elapsed_time(ms.) |
| --------- | -------------------------------------- | ------------ | --------- | ----------------- |
| ksigma | `{"k":2}` | 100 | 100 | 0.453 |
@ -113,3 +114,4 @@ lof={"algorithm":"auto", "n_neighbor": 3}
<img src={ad_result} alt="异常检测标注图" style="width:360px !important;"/>

View File

@ -138,15 +138,22 @@ docker run -d \
services:
tdengine:
image: tdengine/tdengine:3.3.0.0
image: tdengine/tdengine:latest
container_name: tdengine
hostname: tdengine
environment:
TAOS_FQDN: tdengine
MONITOR_FQDN: tdengine
EXPLORER_CLUSTER: http://tdengine:6041
TAOS_KEEPER_TDENGINE_HOST: tdengine
volumes:
- tdengine-data:/var/lib/taos/
ports:
- 6060:6060
grafana:
image: grafana/grafana:9.3.6
image: grafana/grafana:latest
volumes:
- ./tdengine.yml/:/etc/grafana/provisioning/tdengine.yml
- ./tdengine.yml:/etc/grafana/provisioning/tdengine.yml
- grafana-data:/var/lib/grafana
environment:
# install tdengine plugin at start
@ -156,6 +163,7 @@ docker run -d \
TDENGINE_BASIC_AUTH: "cm9vdDp0YmFzZTEyNQ=="
ports:
- 3000:3000
volumes:
grafana-data:
tdengine-data:

View File

@ -17,10 +17,10 @@ CREATE VTABLE [IF NOT EXISTS] [db_name].vtb_name
ts_col_name timestamp,
(create_defination[ ,create_defination] ...)
create_definition:
create_definition:
vtb_col_name column_definition
column_definition:
column_definition:
type_name [FROM [db_name.]table_name.col_name]
```
@ -33,9 +33,9 @@ CREATE VTABLE [IF NOT EXISTS] [db_name].vtb_name
[(tag_name [, tag_name] ...)]
TAGS (tag_value [, tag_value] ...)
create_definition:
create_definition:
[stb_col_name FROM] [db_name.]table_name.col_name
tag_value:
tag_value:
const_value
```
@ -66,7 +66,7 @@ CREATE VTABLE [IF NOT EXISTS] [db_name].vtb_name
**示例**
假设有表 t1, t2, t3 结构和数据如下:
假设有表 t1、t2、t3 结构和数据如下:
![virtual-table-origin-table.png](pic/virtual-table-origin-table.png)
@ -101,7 +101,7 @@ select c1, c2 from v1;
![virtual-table-query-res-part.png](pic/virtual-table-query-res-part.png)
因为 c1, c2 列对应的原始表 t1, t2 中没有 0:00:03 这个时间戳,所以最后的结果也不会包含这个时间戳。
因为 c1、c2 列对应的原始表 t1、t2 中没有 0:00:03 这个时间戳,所以最后的结果也不会包含这个时间戳。
**使用限制**
@ -205,7 +205,7 @@ SHOW [NORMAL | CHILD] [db_name.]VTABLES [LIKE 'pattern'];
**使用说明**
1. 如果没有指定 db_name, 显示当前数据库下的所有虚拟普通表和虚拟子表的信息。若没有使用数据库并且没有指定 db_name, 则会报错 database not specified。可以使用 LIKE 对表名进行模糊匹配。NORMAL 指定只显示虚拟普通表信息, CHILD 指定只显示虚拟子表信息。
1. 如果没有指定 db_name显示当前数据库下的所有虚拟普通表和虚拟子表的信息。若没有使用数据库并且没有指定 db_name, 则会报错 database not specified。可以使用 LIKE 对表名进行模糊匹配。NORMAL 指定只显示虚拟普通表信息, CHILD 指定只显示虚拟子表信息。
### 显示虚拟表创建语句

View File

@ -38,7 +38,7 @@ TARGET_LINK_LIBRARIES(
ADD_EXECUTABLE(userOperTest ../../../tests/script/api/passwdTest.c)
TARGET_LINK_LIBRARIES(
userOperTest
PUBLIC ${TAOS_NATIVE_LIB}
PUBLIC ${TAOS_NATIVE_LIB_STATIC}
)
ADD_EXECUTABLE(stmt2Test stmt2Test.cpp)

View File

@ -153,7 +153,7 @@ int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STabl
return terrno;
}
pMetaRsp->pSchemaExt = taosMemoryMalloc(pSchema->nCols * sizeof(SSchemaExt));
pMetaRsp->pSchemaExt = taosMemoryCalloc(1, pSchema->nCols * sizeof(SSchemaExt));
if (pMetaRsp->pSchemaExt == NULL) {
taosMemoryFree(pMetaRsp->pSchemas);
return terrno;

View File

@ -692,13 +692,13 @@ static int32_t tsdbDoS3Migrate(SRTNer *rtner) {
int32_t r = taosStatFile(fobj->fname, &size, &mtime, NULL);
if (size > chunksize && mtime < rtner->now - tsS3UploadDelaySec) {
if (pCfg->s3Compact && lcn < 0) {
extern int32_t tsdbAsyncCompact(STsdb * tsdb, const STimeWindow *tw, bool sync);
extern int32_t tsdbAsyncCompact(STsdb * tsdb, const STimeWindow *tw, bool sync,bool s3Migrate);
STimeWindow win = {0};
tsdbFidKeyRange(fset->fid, rtner->tsdb->keepCfg.days, rtner->tsdb->keepCfg.precision, &win.skey, &win.ekey);
tsdbInfo("vgId:%d, async compact begin lcn: %d.", TD_VID(rtner->tsdb->pVnode), lcn);
code = tsdbAsyncCompact(rtner->tsdb, &win, pCfg->sttTrigger == 1);
code = tsdbAsyncCompact(rtner->tsdb, &win, pCfg->sttTrigger == 1, true);
tsdbInfo("vgId:%d, async compact end lcn: %d.", TD_VID(rtner->tsdb->pVnode), lcn);
goto _exit;
return code;

View File

@ -3134,7 +3134,7 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfKe
taosMemoryFree(err); \
code = TSDB_CODE_THIRDPARTY_ERROR; \
} else { \
stInfo("[InternalERR] write streamState str:%s succ to write to %s, rowValLen:%d, ttlValLen:%d, %p", toString, \
stDebug("[InternalERR] write streamState str:%s succ to write to %s, rowValLen:%d, ttlValLen:%d, %p", toString, \
funcname, vLen, ttlVLen, wrapper); \
} \
taosMemoryFree(ttlV); \
@ -4593,7 +4593,7 @@ int32_t streamStatePutBatchOptimize(SStreamState* pState, int32_t cfIdx, rocksdb
int32_t klen = ginitDict[cfIdx].enFunc((void*)key, buf);
ginitDict[cfIdx].toStrFunc((void*)key, toString);
qInfo("[InternalERR] write cfIdx:%d key:%s vlen:%d", cfIdx, toString, vlen);
stDebug("[InternalERR] write cfIdx:%d key:%s vlen:%d", cfIdx, toString, vlen);
char* ttlV = tmpBuf;
int32_t ttlVLen = ginitDict[cfIdx].enValueFunc(dst, size, ttl, &ttlV);

View File

@ -19,6 +19,9 @@ This manual is intended to give developers a comprehensive guidance to test TDen
> - The commands and scripts below are verified on Linux (Ubuntu 18.04/20.04/22.04).
> - [taos-connector-python](https://github.com/taosdata/taos-connector-python) is used by tests written in Python, which requires Python 3.7+.
> - The commands and steps described below are to run the tests on a single host.
> - The testing framework is currently compatible with Python versions 3.8 through 3.10.
> - Vitural Environment is advised when setting up the environment, pease refer to [venv](https://docs.python.org/3/library/venv.html) for details.
# 2. Prerequisites