# Readme

## 添加权限

去 https://pch.pingcap.net/ 申请账号权限

```
# aws
Account ID: 676546228356
Account Name: qa-dbaas-dev
Role: Dbaas Dev User

# gcp
Project ID: gcp-qa-dbaas-dev
Project Name: qa-dbaas-dev
Role: Editor
```

s3 地址：https://s3.console.aws.amazon.com/s3/buckets/import-scene-test?region=ap-southeast-1&tab=objects
gs 地址：https://console.cloud.google.com/storage/browser/import-scene-test;tab=objects?hl=zh-cn&project=gcp-qa-dbaas-dev&prefix=&forceOnObjectsSortingFiltering=false

## code tree

```shell
↪ pwd
/root/code/tidbcloud/qa-PlatformAPIAuto/webScene
↪ tree
.
...
├── import
│   ├── base.go
│   ├── cases                       # 所有的测试样例实现
│   │   ├── basic_operation.go      # test case
│   │   └── source_format.go
│   ├── const.go
│   ├── readme.md
│   ├── retry.go
│   └── statement.go
├── import_test.go                  # import test case 入口
├── MainOrder_test.go               # 总入口
├── pkg
│   ├── cluster                     # cluster 有关的操作
│   │   ├── dedicated_cluster.go
│   │   ├── interface.go
│   │   └── serverless_cluster.go
│   ├── import                      # import 有关的操作
│   │   ├── base.go
│   │   ├── gs.go
│   │   ├── interface.go
│   │   └── s3.go
│   └── sql                         # 写 sql 有关的操作
│       └── statement.go
...
```

## MainOrder_test.go

这是所有 Import test case 的入口，从代码可以看出，我们的 test 函数都必须以 `ImportTest` 开头

```go
func TestImportMainOrder(t *testing.T) {
	t.Parallel()
	t.Run(fmt.Sprintf("test %s", "import"), func(t *testing.T) {
		for _, c := range ImportCaseList {
			l4g.Info("--------- %s, %s ---------", c, common.TestCaseMap[c])
			t.Run(c, common.TestCaseMap[c])
		}
	})
}

func Analysis() {
	caseListData := strings.Split(common.CaseList, " ")
	for _, casedata := range caseListData {
		if strings.HasPrefix(casedata, "ImportTest") {
			ImportCaseList = append(ImportCaseList, casedata)
			continue
		}
		...
	}
}
```

## import_test.go

函数命名为 `ImportTestXXXXXXXInXXXXXX`，实际的实现在 `github.com/tidbcloud/qa-PlatformAPIAuto/webScene/import/cases` 中。

```go
import (
	importCases "github.com/tidbcloud/qa-PlatformAPIAuto/webScene/import/cases"
)

...

func ImportTestBasicOperationInDedicatedAws(t *testing.T) {
	t.Parallel()
	importCases.RunImportTestBasicOperation(t, awsClusterId, imp.AwsProvider)
}

...
```

## test case

在 `github.com/tidbcloud/qa-PlatformAPIAuto/webScene/import/cases` 中，每一种测试样例创建一个文件。

以 `basic_operation.go` 为例

```go
type BasicOperationTest struct {
	imp.BaseImportScene
}

func (t *BasicOperationTest) Run() {
	allure.Test(
		t.T,
		allure.Epic("TestImportBasicOperation"),
		allure.Feature("CreateImport and CancelImport"),
		allure.Description("1. create import; 2. cancel import; 3. create import till completed"),
		allure.Action(func() {
			t.CreateClusterStep()
			t.CreateTargetTableStep(basicOperationTable)
			t.CreateImportCredentialStep()
			defer t.DeleteImportCredentialStep()
			t.CreateImportStep()
			t.CancelImportStep()
			t.TruncateTargetTableStep(basicOperationTable)
			t.CreateImportTillCompletedStep()
		}),
	)
}

// RunImportTestBasicOperationInDedicatedAws is a test case for
// basic import operations, like create import, cancel import, in dedicated aws.
func RunImportTestBasicOperation(t *testing.T, clusterId, provider string) {
	test := &BasicOperationTest{}

	test.Init(t, clusterId, provider)
	// each test should init data
	test.buildData()
	test.Run()
}

// the table used in this test case
var basicOperationTable = imp.Table{
	SchemaName:      "test",
	TableName:       "person",
	SchemaStatement: "CREATE TABLE IF NOT EXISTS `test`.`person` ( `id` int DEFAULT NULL, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `birthday` date DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
}

// buildData is used to build import data for different providers
// data should be created previously now, maybe generated by code is better later
func (t *BasicOperationTest) buildData() {
	if t.Provider == imp.AwsProvider {
		t.ImportData = &common.ImportData{
			SourceUrl:      "s3://import-scene-test/basic-operation/",
			DataSourceType: int(imp.ImportDataSourceTypeS3),
			Region:         "ap-southeast-1",
			DataFormat:     int(imp.ImportDataFormatSql),
			AwsRoleArn:     "xxxx",
		}
	} else {
		t.ImportData = &common.ImportData{
			SourceUrl:      "gs://import-scene-test/basic-operation/",
			DataSourceType: int(imp.ImportDataSourceTypeGcs),
			DataFormat:     int(imp.ImportDataFormatSql),
		}
	}
}
```

1. （必要）场景测试基本都要先创建集群 `CreateClusterStep`
2. （必要）提前在下游建表 `CreateTargetTableStep`。可以在 `github.com/tidbcloud/qa-PlatformAPIAuto/webScene/import/data.go` 中自定义 table
3. （必要）创建 Import 需要的鉴权信息 `CreateImportCredentialStep`
4. （必要）结束后销毁 Import 鉴权信息 `DeleteImportCredentialStep`
5. （必要）创建 Import `CreateImportStep`
6. 由于这个 test case 是 Import 的基本操作，所以需要
    1. `CancelImportStep`
    2. `TruncateTargetTableStep`
    3. `CreateImportTillCompletedStep`


`buildData` 是非常重要的函数，大概率每一个 test case 的测试数据都不一样，添加新 case 需要先创建好数据集，后续可能会用代码生成数据集已更方便地管理，但是现在先由手动创建。

如果在一个 case 中需要用到多个数据集，则需要在

```go
		allure.Action(func() {
			t.CreateClusterStep()
			t.CreateTargetTableStep(basicOperationTable)
			t.CreateImportCredentialStep()
			defer t.DeleteImportCredentialStep()
			t.CreateImportStep()
			t.CancelImportStep()
			t.TruncateTargetTableStep(basicOperationTable)
			t.CreateImportTillCompletedStep()
		}),
```

中相应的位置再 `buildXXXXData()`

## 如何本地运行测试样例

```shell
↪ pwd
/root/code/tidbcloud/qa-PlatformAPIAuto/webScene
↪ export ALLURE_RESULTS_PATH=xxxxx/qa-PlatformAPIAuto/
# 如果不指定 awsClusterId/gcpClusterId，代码会自动创建/销毁集群
# 本地测试建议使用自己的集群，因为集群创建时间太长了
↪ go test -env dev -awsClusterId xxxx -gcpClusterId xxxx -orgId xxxx -projectId xxxx -tenantEmail xxxx -CaseList ImportTestBasicOperationInDedicatedAws --timeout=180000s
```