## 目录结构

```
.
├── core
│   └── context.go
├── docs
│   └── project.md
└── resource                                 # 资源层
    ├── impl                                 # 各个 provider 实现(k8s, dbaas, aws ec2 etc)
    │       └── k8s                          # k8s 实现
    │           ├── testbed.go               # testbed k8s 的实现
    │           ├── testbed_client.go        # testbed client k8s 的实现
    │           ├── tidbcluster.go           # tidbcluster k8s 的实现
    │           ├── tidbcluster_client.go    # tidbcluster client k8s 的实现
    │           ├── tidb_lightning.go        # tidb-lightning k8s 的实现
    │           ├── tidb_lightning_client.go # tidb-lightning client k8s 的实现
    │           ├── workloadnode.go          # workloadnode k8s 的实现
    │           ├── workloadnode_client.go   # workloadnode client k8s 的实现
    ├── testbed.go                           # testbed 资源抽象
    ├── tidbcluster.go                       # tidbcluster 资源抽象
    └── types.go                             # client 定义
```

## 资源层

1. 对于每一类测试资源(例如 tidbcluster), 需要先在 resource 目录下声明一个资源抽象(如 tidbcluster.go). 资源抽象定义了该类资源提供出的 API 操作, 例如 tidbcluster.go 的定义如下:

    ```go
    // TiDBCluster is the tidb cluster interface
    type TiDBCluster interface {
    	core.Resource
    	ServiceURL(typ TiDBAddrType) (*url.URL, error)
    	PeerURLs(typ TiDBAddrType) ([]*url.URL, error)
    	Exec(opts TiDBClusterExecOptions) (stdout string, stderr string, err error)
    	Upgrade(opts TiDBClusterUpgradeOptions) error
    	Scale(opts TiDBClusterScaleOptions) error
    }
    ```

2. 然后在对应的 impl/`provider` 目录下添加资源的实现以及资源 client 的实现(如 impl/k8s/tidbcluster.go 以及 impl/k8s/tidbcluster_client.go)

   其中 client 定义如下, 用于创建, 获取以及删除测试资源。

    ```go
    // Client defines apis every resources need to impl
    type Client interface {
        Create(spec json.RawMessage) (core.Resource, error)
        Get(handle apiresource.ResourceHandle) (core.Resource, error)
        Delete(handle apiresource.ResourceHandle) error
        FQDN() string
    }
    ```

### 运行测试

```bash
cd e2etest && make test KUBECONFIG=PATH_TO_KUBECONFIG
```
