Skip to content

Commit bbaf91f

Browse files
feat: support to config mock server on ui (#552)
* doc: add document of atest extension * feat: support to config mock server on ui * add more document * Fix code scanning alert no. 61: Incorrect conversion between integer types Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Rick <[email protected]> --------- Signed-off-by: Rick <[email protected]> Co-authored-by: rick <[email protected]> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
1 parent 7d9a97f commit bbaf91f

File tree

17 files changed

+531
-359
lines changed

17 files changed

+531
-359
lines changed

cmd/server.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func createServerCmd(execer fakeruntime.Execer, httpServer server.HTTPServer) (c
102102
flags.StringArrayVarP(&opt.mockConfig, "mock-config", "", nil, "The mock config files")
103103
flags.StringVarP(&opt.mockPrefix, "mock-prefix", "", "/mock", "The mock server API prefix")
104104
flags.StringVarP(&opt.extensionRegistry, "extension-registry", "", "docker.io", "The extension registry URL")
105+
flags.DurationVarP(&opt.downloadTimeout, "download-timeout", "", time.Second*10, "The timeout of extension download")
105106

106107
// gc related flags
107108
flags.IntVarP(&opt.gcPercent, "gc-percent", "", 100, "The GC percent of Go")
@@ -129,6 +130,7 @@ type serverOption struct {
129130
configDir string
130131
skyWalking string
131132
extensionRegistry string
133+
downloadTimeout time.Duration
132134

133135
auth string
134136
oauthProvider string
@@ -251,6 +253,7 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
251253

252254
extDownloader := downloader.NewStoreDownloader()
253255
extDownloader.WithRegistry(o.extensionRegistry)
256+
extDownloader.WithTimeout(o.downloadTimeout)
254257
storeExtMgr := server.NewStoreExtManager(o.execer)
255258
storeExtMgr.WithDownloader(extDownloader)
256259
remoteServer := server.NewRemoteServer(loader, remote.NewGRPCloaderFromStore(), secretServer, storeExtMgr, o.configDir, o.grpcMaxRecvMsgSize)
@@ -264,9 +267,16 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
264267
}
265268

266269
// create mock server controller
267-
mockInMemoryReader := mock.NewInMemoryReader("")
270+
var mockWriter mock.ReaderAndWriter
271+
if len(o.mockConfig) > 0 {
272+
cmd.Println("currently only one mock config is supported, will take the first one")
273+
mockWriter = mock.NewLocalFileReader(o.mockConfig[0])
274+
} else {
275+
mockWriter = mock.NewInMemoryReader("")
276+
}
277+
268278
dynamicMockServer := mock.NewInMemoryServer(0)
269-
mockServerController := server.NewMockServerController(mockInMemoryReader, dynamicMockServer)
279+
mockServerController := server.NewMockServerController(mockWriter, dynamicMockServer, o.httpPort)
270280

271281
clean := make(chan os.Signal, 1)
272282
signal.Notify(clean, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
@@ -363,17 +373,7 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
363373
combineHandlers := server.NewDefaultCombineHandler()
364374
combineHandlers.PutHandler("", mux)
365375

366-
if len(o.mockConfig) > 0 {
367-
cmd.Println("currently only one mock config is supported, will take the first one")
368-
var mockServerHandler http.Handler
369-
if mockServerHandler, err = mock.NewInMemoryServer(0).
370-
SetupHandler(mock.NewLocalFileReader(o.mockConfig[0]), o.mockPrefix); err != nil {
371-
return
372-
}
373-
combineHandlers.PutHandler(o.mockPrefix, mockServerHandler)
374-
}
375-
376-
if handler, hErr := dynamicMockServer.SetupHandler(mockInMemoryReader, o.mockPrefix+"/server"); hErr != nil {
376+
if handler, hErr := dynamicMockServer.SetupHandler(mockWriter, o.mockPrefix+"/server"); hErr != nil {
377377
err = hErr
378378
return
379379
} else {

console/atest-ui/src/components/EditButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ElInput } from 'element-plus'
44
import type { InputInstance } from 'element-plus'
55
66
const props = defineProps({
7-
value: String,
7+
value: String || Number,
88
})
99
1010
const emit = defineEmits(['changed'])

console/atest-ui/src/views/MockManager.vue

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,30 @@ import { ref } from 'vue';
33
import { Codemirror } from 'vue-codemirror';
44
import { API } from './net';
55
import {useI18n} from "vue-i18n";
6+
import EditButton from '../components/EditButton.vue'
67
78
const { t } = useI18n()
89
9-
const mockConfig = ref('');
10+
interface MockConfig {
11+
Config: string
12+
Prefix: string
13+
Port: number
14+
}
15+
const mockConfig = ref({} as MockConfig);
1016
const link = ref('')
1117
API.GetMockConfig((d) => {
12-
mockConfig.value = d.Config
18+
mockConfig.value = d
1319
link.value = window.location.origin + d.Prefix + "/api.json"
1420
})
21+
const prefixChanged = (p: string) => {
22+
mockConfig.value.Prefix = p
23+
}
24+
const portChanged = (p: number) => {
25+
mockConfig.value.Port = p
26+
}
1527
const tabActive = ref('yaml')
1628
const insertSample = () => {
17-
mockConfig.value = `objects:
29+
mockConfig.value.Config = `objects:
1830
- name: projects
1931
initCount: 3
2032
sample: |
@@ -39,10 +51,14 @@ items:
3951
<el-divider direction="vertical" />
4052
<el-link target="_blank" :href="link">{{ link }}</el-link> <!-- Noncompliant -->
4153
</div>
54+
<div>
55+
API Prefix:<EditButton :value="mockConfig.Prefix" @changed="prefixChanged"/>
56+
Port:<EditButton :value="mockConfig.Port" @changed="portChanged"/>
57+
</div>
4258
<div>
4359
<el-tabs v-model="tabActive">
4460
<el-tab-pane label="YAML" name="yaml">
45-
<Codemirror v-model="mockConfig" />
61+
<Codemirror v-model="mockConfig.Config" />
4662
</el-tab-pane>
4763
</el-tabs>
4864
</div>

console/atest-ui/src/views/SecretManager.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { ElMessage } from 'element-plus'
33
import { reactive, ref } from 'vue'
44
import { Edit, Delete } from '@element-plus/icons-vue'
5-
import type { FormInstance, FormRules } from 'element-plus'
5+
import type { FormInstance } from 'element-plus'
66
import { API } from './net'
77
import type { Secret } from './net'
88
import { UIAPI } from './net-vue'

console/atest-ui/src/views/net.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -620,15 +620,13 @@ function GetSuggestedAPIs(name: string,
620620
.then(callback)
621621
}
622622

623-
function ReloadMockServer(config: string) {
623+
function ReloadMockServer(config: any) {
624624
const requestOptions = {
625625
method: 'POST',
626626
headers: {
627627
'X-Auth': getToken()
628628
},
629-
body: JSON.stringify({
630-
Config: config
631-
})
629+
body: JSON.stringify(config)
632630
}
633631
fetch(`/api/v1/mock/reload`, requestOptions)
634632
.then(DefaultResponseProcess)

docs/site/content/zh/latest/releases/v0.0.1.md

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
+++
2+
title = "插件"
3+
+++
4+
5+
`atest` 会把非核心、可扩展的功能以插件(extension)的形式实现。下面介绍有哪些插件,以及如何使用:
6+
7+
> 在不同的系统中,插件有着不同的表述,例如:extension、plugin 等。
8+
9+
| 类型 | 名称 | 描述 |
10+
|------|------|------|
11+
| 存储 | [orm](https://github.com/LinuxSuRen/atest-ext-store-orm) | 保存数据到关系型数据库中,例如:MySQL |
12+
| 存储 | [s3](https://github.com/LinuxSuRen/atest-ext-store-s3) | 保存数据到对象存储中 |
13+
| 存储 | [etcd](https://github.com/LinuxSuRen/atest-ext-store-etcd) | 保存数据到 Etcd 数据库中 |
14+
| 存储 | [git](https://github.com/LinuxSuRen/atest-ext-store-git) | 保存数据到 Git 仓库中 |
15+
| 存储 | [mongodb](https://github.com/LinuxSuRen/atest-ext-store-mongodb) | 保存数据到 MongDB 中 |
16+
17+
> `atest` 也是唯一支持如此丰富的存储的接口开发、测试的开源工具。
18+
19+
## 下载插件
20+
21+
我们建议通过如下的命令来下载插件:
22+
23+
```shell
24+
atest extension orm
25+
```
26+
27+
上面的命令,会识别当前的操作系统,自动下载最新版本的插件。当然,用户可以通过自行编译、手动下载的方式获取插件二进制文件。
28+
29+
`atest` 可以从任意支持 OCI 的镜像仓库中(命令参数说明中给出了支持的镜像服务地址)下载插件,也可以指定下载超时时间:
30+
31+
```shell
32+
atest extension orm --registry ghcr.io --timeout 2ms
33+
```
File renamed without changes.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
+++
2+
title = "Mock 服务"
3+
+++
4+
5+
Mock 服务在前后端并行开发、系统对接、设备对接场景下能起到非常好的作用,可以极大地降低团队之间、系统之间的耦合度。
6+
7+
用户可以通过命令行终端(CLI)、Web UI 的方式来使用 Mock 服务。
8+
9+
## 命令行
10+
11+
```shell
12+
atest mock --prefix / --port 9090 mock.yaml
13+
```
14+
15+
## Web
16+
17+
在 UI 上可以实现和命令行相同的功能,并可以通过页面编辑的方式修改、加载 Mock 服务配置。
18+
19+
## 语法
20+
21+
从整体上来看,我们的写法和 HTTP 的名称基本保持一致,用户无需再了解额外的名词。此外,提供两种描述 Mock 服务的方式:
22+
23+
* 针对某个数据对象的 CRUD
24+
* 任意 HTTP 服务
25+
26+
下面是一个具体的例子:
27+
28+
```yaml
29+
#!api-testing-mock
30+
# yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-mock-schema.json
31+
objects:
32+
- name: repo
33+
fields:
34+
- name: name
35+
kind: string
36+
- name: url
37+
kind: string
38+
- name: projects
39+
initCount: 3
40+
sample: |
41+
{
42+
"name": "api-testing",
43+
"color": "{{ randEnum "blue" "read" "pink" }}"
44+
}
45+
items:
46+
- name: base64
47+
request:
48+
path: /v1/base64
49+
response:
50+
body: aGVsbG8=
51+
encoder: base64
52+
- name: prList
53+
request:
54+
path: /v1/repos/{repo}/prs
55+
header:
56+
name: rick
57+
response:
58+
header:
59+
server: mock
60+
body: |
61+
{
62+
"count": 1,
63+
"items": [{
64+
"title": "fix: there is a bug on page {{ randEnum "one" }}",
65+
"number": 123,
66+
"message": "{{.Response.Header.server}}",
67+
"author": "someone",
68+
"status": "success"
69+
}]
70+
}
71+
```

docs/site/content/zh/latest/tasks/secure-zh.md renamed to docs/site/content/zh/latest/tasks/secure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ spec:
3131

3232
`ca`为 CA 证书的路径,`key`为与`cert`对应的私钥,这两项填写后代表启用 mTLS。(mTLS 尚未实现)
3333

34-
当`insecure`为`false`时,`cert`和`serverName`为必填项。
34+
当`insecure`为`false`时,`cert`和`serverName`为必填项。

0 commit comments

Comments
 (0)