Skip to content

Commit 3d2d449

Browse files
committed
feat: support to set the prefix of mock server (#402)
Co-authored-by: rick <[email protected]>
1 parent ffac34f commit 3d2d449

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1677
-1142
lines changed

.github/pre-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/bin/sh
22

3-
make fmt test-all
3+
make fmt test
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Qodana
2+
on:
3+
workflow_dispatch:
4+
pull_request:
5+
push:
6+
branches:
7+
- master
8+
- feat/mock-timer
9+
10+
jobs:
11+
qodana:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v3
15+
with:
16+
fetch-depth: 0
17+
- name: 'Qodana Scan'
18+
uses: JetBrains/[email protected]
19+
env:
20+
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}

.github/workflows/release.yaml

Lines changed: 30 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,28 @@ jobs:
7878
registry: ${{ env.REGISTRY }}
7979
username: ${{ github.actor }}
8080
password: ${{ secrets.GH_PUBLISH_SECRETS }}
81+
- name: Log into registry ${{ env.REGISTRY_DOCKERHUB }}
82+
if: github.event_name != 'pull_request'
83+
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
84+
with:
85+
registry: ${{ env.REGISTRY_DOCKERHUB }}
86+
username: linuxsuren
87+
password: ${{ secrets.DOCKER_HUB_PUBLISH_SECRETS }}
88+
- name: Log into registry ${{ env.REGISTRY_ALIYUN }}
89+
if: github.event_name != 'pull_request'
90+
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
91+
with:
92+
registry: ${{ env.REGISTRY_ALIYUN }}
93+
username: ${{ secrets.REGISTRY_ALIYUN_USER }}
94+
password: ${{ secrets.REGISTRY_ALIYUN_PUBLISH_SECRETS }}
8195
- name: Extract Docker metadata
8296
id: meta
8397
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
8498
with:
85-
images: ${{ env.REGISTRY }}/linuxsuren/api-testing
99+
images: |
100+
${{ env.REGISTRY }}/linuxsuren/api-testing
101+
${{ env.REGISTRY_DOCKERHUB }}/${{ env.IMAGE_NAME }}
102+
${{ env.REGISTRY_ALIYUN }}/${{ env.IMAGE_NAME }}
86103
- name: Build and push Docker image
87104
id: build-and-push
88105
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
@@ -91,10 +108,21 @@ jobs:
91108
push: ${{ github.event_name != 'pull_request' }}
92109
tags: ${{ steps.meta.outputs.tags }}
93110
labels: ${{ steps.meta.outputs.labels }}
94-
platforms: linux/amd64,linux/arm64
111+
platforms: linux/amd64,linux/arm64,darwin/amd64
95112
cache-from: type=gha
96113
cache-to: type=gha,mode=max
97114
build-args: VERSION=${{ steps.vars.outputs.tag }}
115+
- name: Release Helm
116+
run: |
117+
echo ${{ secrets.DOCKER_HUB_PUBLISH_SECRETS }} | helm registry login docker.io -u linuxsuren --password-stdin
118+
export APP_VERSION=${{ steps.vars.outputs.tag }}
119+
export HELM_VERSION=${{ steps.vars.outputs.tag }}
120+
if [[ ! "$line" =~ ^v ]]
121+
then
122+
unset APP_VERSION
123+
unset HELM_VERSION
124+
fi
125+
make helm-package helm-push
98126
99127
# image-operator:
100128
# runs-on: ubuntu-20.04
@@ -126,90 +154,3 @@ jobs:
126154
# platforms: linux/amd64,linux/arm64
127155
# cache-from: type=gha
128156
# cache-to: type=gha,mode=max
129-
130-
image-dockerhub:
131-
runs-on: ubuntu-20.04
132-
steps:
133-
- name: Checkout
134-
uses: actions/checkout@v4
135-
with:
136-
fetch-tags: true
137-
fetch-depth: 0
138-
- name: Set output
139-
id: vars
140-
run: echo "tag=$(git describe --tags)" >> $GITHUB_OUTPUT
141-
- name: Setup Docker buildx
142-
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf
143-
- name: Log into registry ${{ env.REGISTRY_DOCKERHUB }}
144-
if: github.event_name != 'pull_request'
145-
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
146-
with:
147-
registry: ${{ env.REGISTRY_DOCKERHUB }}
148-
username: linuxsuren
149-
password: ${{ secrets.DOCKER_HUB_PUBLISH_SECRETS }}
150-
- name: Extract Docker metadata
151-
id: meta
152-
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
153-
with:
154-
images: ${{ env.REGISTRY_DOCKERHUB }}/${{ env.IMAGE_NAME }}
155-
- name: Build and push Docker image
156-
id: build-and-push
157-
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
158-
with:
159-
context: .
160-
push: ${{ github.event_name != 'pull_request' }}
161-
tags: ${{ steps.meta.outputs.tags }}
162-
labels: ${{ steps.meta.outputs.labels }}
163-
platforms: linux/amd64,linux/arm64
164-
cache-from: type=gha
165-
cache-to: type=gha,mode=max
166-
build-args: VERSION=${{ steps.vars.outputs.tag }}
167-
- name: Release Helm
168-
run: |
169-
echo ${{ secrets.DOCKER_HUB_PUBLISH_SECRETS }} | helm registry login docker.io -u linuxsuren --password-stdin
170-
export APP_VERSION=${{ steps.vars.outputs.tag }}
171-
export HELM_VERSION=${{ steps.vars.outputs.tag }}
172-
if [[ ! "$line" =~ ^v ]]
173-
then
174-
unset APP_VERSION
175-
unset HELM_VERSION
176-
fi
177-
make helm-package helm-push
178-
179-
image-aliyuncs:
180-
runs-on: ubuntu-20.04
181-
steps:
182-
- name: Checkout
183-
uses: actions/checkout@v4
184-
with:
185-
fetch-tags: true
186-
fetch-depth: 0
187-
- name: Set output
188-
id: vars
189-
run: echo "tag=$(git describe --tags)" >> $GITHUB_OUTPUT
190-
- name: Setup Docker buildx
191-
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf
192-
- name: Log into registry ${{ env.REGISTRY_ALIYUN }}
193-
if: github.event_name != 'pull_request'
194-
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
195-
with:
196-
registry: ${{ env.REGISTRY_ALIYUN }}
197-
username: ${{ secrets.REGISTRY_ALIYUN_USER }}
198-
password: ${{ secrets.REGISTRY_ALIYUN_PUBLISH_SECRETS }}
199-
- name: Extract Docker metadata
200-
id: meta
201-
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
202-
with:
203-
images: ${{ env.REGISTRY_ALIYUN }}/${{ env.IMAGE_NAME }}
204-
- name: Build and push Docker image
205-
id: build-and-push
206-
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
207-
with:
208-
context: .
209-
push: ${{ github.event_name != 'pull_request' }}
210-
tags: ${{ steps.meta.outputs.tags }}
211-
labels: ${{ steps.meta.outputs.labels }}
212-
platforms: linux/amd64,linux/arm64
213-
cache-from: type=gha
214-
cache-to: type=gha,mode=max
215-
build-args: VERSION=${{ steps.vars.outputs.tag }}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ test-ui-e2e:
7777
test-operator:
7878
cd operator && make test # converage file path: operator/cover.out
7979
test-all-backend: test
80-
test-all: test-all-backend test-ui
80+
test-all: test-all-backend
8181
test-e2e:
8282
cd e2e && ./start.sh && ./start.sh compose-k8s.yaml && ./start.sh compose-external.yaml
8383
fuzz:

README-ZH.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
* 支持的协议: HTTP, gRPC, tRPC
1313
* 支持多种格式的测试结果导出: Markdown, HTML, PDF, Stdout
14-
* 通过简单配置模拟服务
14+
* 简单易用的 Mock 服务,支持 OpenAPI
1515
* 支持转换为 [JMeter](https://jmeter.apache.org/) 文件格式
1616
* 支持响应体字段检查或 [eval](https://expr.medv.io/)
1717
* 使用 [JSON schema] 校验响应参数(https://json-schema.org/)
@@ -133,6 +133,6 @@ docker run -p 1234:8080 -v /var/tmp:/var/tmp \
133133
134134
`[email protected]`, 欢迎通过此邮件列表讨论与 API Testing 相关的任何问题。
135135
136-
### Githbu Discussion
136+
### GitHub Discussion
137137
138-
[Github Discussion](https://github.com/LinuxSuRen/api-testing/discussions/new/choose)
138+
[GitHub Discussion](https://github.com/LinuxSuRen/api-testing/discussions/new/choose)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This is a API testing tool. 🚀
1111

1212
* Supported protocols: HTTP, gRPC, tRPC
1313
* Multiple test report formats: Markdown, HTML, PDF, Stdout
14-
* Mock Server in simple configuration
14+
* Mock Server in simple configuration, and Open API support
1515
* Support converting to [JMeter](https://jmeter.apache.org/) files
1616
* Response Body fields equation check or [eval](https://expr.medv.io/)
1717
* Validate the response body with [JSON schema](https://json-schema.org/)
@@ -132,6 +132,6 @@ Feel free to talk to us about any questions you may have about API Testing in th
132132
133133
`[email protected]`, Feel free to discuss everything related to API Testing via this mailing list.
134134
135-
### Githbu discussion
135+
### `GitHub` discussion
136136
137-
[Github Discussion](https://github.com/LinuxSuRen/api-testing/discussions/new/choose)
137+
[GitHub Discussion](https://github.com/LinuxSuRen/api-testing/discussions/new/choose)

cmd/mock.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ package cmd
1818

1919
import (
2020
"errors"
21+
"os"
22+
"os/signal"
23+
"syscall"
2124

2225
"github.com/linuxsuren/api-testing/pkg/mock"
2326
"github.com/spf13/cobra"
@@ -55,14 +58,19 @@ func (o *mockOption) preRunE(c *cobra.Command, args []string) (err error) {
5558

5659
func (o *mockOption) runE(c *cobra.Command, args []string) (err error) {
5760
reader := mock.NewLocalFileReader(o.files[0])
58-
5961
server := mock.NewInMemoryServer(o.port)
6062

6163
if err = server.Start(reader, o.prefix); err != nil {
6264
return
6365
}
6466

65-
<-c.Context().Done()
66-
server.Stop()
67+
clean := make(chan os.Signal, 1)
68+
signal.Notify(clean, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
69+
70+
select {
71+
case <-c.Context().Done():
72+
case <-clean:
73+
}
74+
err = server.Stop()
6775
return
6876
}

cmd/server.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/linuxsuren/api-testing/pkg/oauth"
4242
template "github.com/linuxsuren/api-testing/pkg/render"
4343
"github.com/linuxsuren/api-testing/pkg/server"
44+
"github.com/linuxsuren/api-testing/pkg/service"
4445
"github.com/linuxsuren/api-testing/pkg/testing"
4546
"github.com/linuxsuren/api-testing/pkg/testing/remote"
4647
"github.com/linuxsuren/api-testing/pkg/util"
@@ -233,6 +234,11 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
233234
}
234235
}
235236

237+
// create mock server controller
238+
mockInMemoryReader := mock.NewInMemoryReader("")
239+
dynamicMockServer := mock.NewInMemoryServer(0)
240+
mockServerController := server.NewMockServerController(mockInMemoryReader, dynamicMockServer)
241+
236242
clean := make(chan os.Signal, 1)
237243
signal.Notify(clean, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
238244

@@ -242,6 +248,7 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
242248
reflection.Register(gRPCServer)
243249
}
244250
server.RegisterRunnerServer(s, remoteServer)
251+
server.RegisterMockServer(s, mockServerController)
245252
serverLogger.Info("gRPC server listening at", "addr", lis.Addr())
246253
s.Serve(lis)
247254
}()
@@ -256,13 +263,16 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
256263
}()
257264

258265
mux := runtime.NewServeMux(runtime.WithMetadata(server.MetadataStoreFunc))
259-
err = server.RegisterRunnerHandlerFromEndpoint(ctx, mux, "127.0.0.1:7070", []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())})
266+
err = errors.Join(
267+
server.RegisterRunnerHandlerFromEndpoint(ctx, mux, "127.0.0.1:7070", []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}),
268+
server.RegisterMockHandlerFromEndpoint(ctx, mux, "127.0.0.1:7070", []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}))
260269
if err == nil {
261270
mux.HandlePath(http.MethodGet, "/", frontEndHandlerWithLocation(o.consolePath))
262271
mux.HandlePath(http.MethodGet, "/assets/{asset}", frontEndHandlerWithLocation(o.consolePath))
263272
mux.HandlePath(http.MethodGet, "/healthz", frontEndHandlerWithLocation(o.consolePath))
264273
mux.HandlePath(http.MethodGet, "/favicon.ico", frontEndHandlerWithLocation(o.consolePath))
265274
mux.HandlePath(http.MethodGet, "/get", o.getAtestBinary)
275+
mux.HandlePath(http.MethodPost, "/runner/{suite}/{case}", service.WebRunnerHandler)
266276

267277
postRequestProxyFunc := postRequestProxy(o.skyWalking)
268278
mux.HandlePath(http.MethodPost, "/browser/{app}", postRequestProxyFunc)
@@ -305,6 +315,13 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
305315
combineHandlers.PutHandler(o.mockPrefix, mockServerHandler)
306316
}
307317

318+
if handler, hErr := dynamicMockServer.SetupHandler(mockInMemoryReader, o.mockPrefix+"/server"); hErr != nil {
319+
err = hErr
320+
return
321+
} else {
322+
combineHandlers.PutHandler(o.mockPrefix+"/server", handler)
323+
}
324+
308325
debugHandler(mux, remoteServer)
309326
o.httpServer.WithHandler(combineHandlers.GetHandler())
310327
serverLogger.Info("HTTP server listening at", "addr", httplis.Addr())

0 commit comments

Comments
 (0)