Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions .github/testing/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,65 @@ items:
request:
api: /GetSuites
method: POST
- name: createSuite
request:
api: /CreateTestSuite
method: POST
body: |
{"name": "{{randAlpha 6}}"}
- name: suite
request:
api: /GetTestSuite
method: POST
body: |
{"name": "test"}
{"name": "{{randAlpha 6}}"}
expect:
bodyFieldsExpect:
name: ""
api: ""
- name: get-testcase-not-found
- name: UpdateTestSuite
request:
api: /GetTestCase
api: /UpdateTestSuite
method: POST
body: |
{"name": "test"}
{
"name": "{{index (keys .suites.data) 0}}",
"api": "{{randAlpha 6}}"}
}
- name: DeleteTestSuiteNotFound
request:
api: /DeleteTestSuite
method: POST
body: |
{"name": "{{randAlpha 6}}"}
expect:
statusCode: 500

- name: ListTestCase
request:
api: /ListTestCase
method: POST
body: |
{"name": "{{index (keys .suites.data) (randInt 0 (len (keys .suites.data)))}}"}
- name: list-testcases-not-found
request:
api: /ListTestCase
method: POST
body: |
{"name": "{{randAlpha 6}}"}
expect:
bodyFieldsExpect:
code: 2
- name: list-testcases
name: ""
- name: GetSuggestedAPIs-no-testsuite-found
request:
api: /GetSuggestedAPIs
method: POST
body: |
{"name": "{{randAlpha 6}}"}
expect:
verify:
- len(data.data) == 0
- name: get-testcase-not-found
request:
api: /GetTestCase
method: POST
Expand Down Expand Up @@ -67,9 +105,16 @@ items:
request:
api: /GetVersion
method: POST
- name: secrets
- name: GetSecrets
request:
api: /GetSecrets
method: POST
expect:
statusCode: 500

- name: DeleteTestSuite
request:
api: /DeleteTestSuite
method: POST
body: |
{"name": "{{index (keys .suites.data) 0}}"}
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
sudo atest service install
sudo atest service restart
sudo atest service status
atest run -p .github/testing/core.yaml
atest run -p .github/testing/core.yaml --request-ignore-error
sudo atest service status

Build:
Expand Down
11 changes: 11 additions & 0 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,14 @@ make install-precheck
```shell
git ls-files | xargs cloc
```

## pprof

```
go tool pprof -http=:9999 http://localhost:8080/debug/pprof/heap
```

Other usage of this:
* `/debug/pprof/heap?gc=1`
* `/debug/pprof/heap?seconds=10`
* `/debug/pprof/goroutine/?debug=0`
5 changes: 3 additions & 2 deletions cmd/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestRunSuite(t *testing.T) {
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer gock.Clean()
defer gock.Off()
util.MakeSureNotNil(tt.prepare)()
ctx := getDefaultContext()
opt := newDiscardRunOption()
Expand Down Expand Up @@ -141,7 +141,8 @@ func TestRunCommand(t *testing.T) {
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer gock.Clean()
defer gock.Off()

buf := new(bytes.Buffer)
util.MakeSureNotNil(tt.prepare)()
root := &cobra.Command{Use: "root"}
Expand Down
21 changes: 21 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

_ "embed"
pprof "net/http/pprof"

"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
template "github.com/linuxsuren/api-testing/pkg/render"
Expand Down Expand Up @@ -124,6 +125,7 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
mux.HandlePath(http.MethodGet, "/", frontEndHandlerWithLocation(o.consolePath))
mux.HandlePath(http.MethodGet, "/assets/{asset}", frontEndHandlerWithLocation(o.consolePath))
mux.HandlePath(http.MethodGet, "/healthz", frontEndHandlerWithLocation(o.consolePath))
debugHandler(mux)
o.httpServer.WithHandler(mux)
log.Printf("HTTP server listening at %v", httplis.Addr())
err = o.httpServer.Serve(httplis)
Expand Down Expand Up @@ -165,6 +167,25 @@ func frontEndHandlerWithLocation(consolePath string) func(w http.ResponseWriter,
}
}

func debugHandler(mux *runtime.ServeMux) {
mux.HandlePath(http.MethodGet, "/debug/pprof/{sub}", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
switch sub := pathParams["sub"]; sub {
case "cmdline":
pprof.Cmdline(w, r)
case "profile":
pprof.Profile(w, r)
case "symbol":
pprof.Symbol(w, r)
case "trace":
pprof.Trace(w, r)
case "allocs", "block", "goroutine", "heap", "mutex", "threadcreate":
pprof.Index(w, r)
case "":
pprof.Index(w, r)
}
})
}

type gRPCServer interface {
Serve(lis net.Listener) error
grpc.ServiceRegistrar
Expand Down
40 changes: 40 additions & 0 deletions cmd/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package cmd

import (
"bytes"
"fmt"
"net"
"net/http"
"strings"
"testing"

"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/linuxsuren/api-testing/pkg/server"
"github.com/linuxsuren/api-testing/pkg/util"
fakeruntime "github.com/linuxsuren/go-fake-runtime"
Expand Down Expand Up @@ -97,6 +100,43 @@ func TestFrontEndHandlerWithLocation(t *testing.T) {
handler(resp, req, map[string]string{})
assert.Equal(t, "ok", resp.GetBody().String())
})

t.Run("pprof", func(t *testing.T) {
apis := []string{"", "cmdline", "symbol",
"trace", "profile",
"allocs", "block", "goroutine", "heap", "mutex", "threadcreate"}

mu := runtime.NewServeMux()
debugHandler(mu)

ready := make(chan struct{})
var err error
var listen net.Listener
var port string
go func() {
listen, err = net.Listen("tcp", ":0")
assert.NoError(t, err)

addr := listen.Addr().String()
items := strings.Split(addr, ":")
port = items[len(items)-1]

ready <- struct{}{}
server := http.Server{Addr: addr, Handler: mu}
server.Serve(listen)
}()

<-ready
defer listen.Close()

for _, name := range apis {
// gock.Off()

resp, err := http.Get(fmt.Sprintf("http://localhost:%s/debug/pprof/%s?seconds=1", port, name))
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
})
}

type fakeResponseWriter struct {
Expand Down
39 changes: 39 additions & 0 deletions docs/manifests/podman.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Pod
metadata:
labels:
app: api-testing
name: api-testing
spec:
containers:
- image: ghcr.io/linuxsuren/api-testing:master
name: web
ports:
- containerPort: 8080
hostPort: 8080
protocol: TCP
volumeMounts:
- mountPath: /root/.config/atest/
name: config
tty: true
workingDir: /
- image: ghcr.io/linuxsuren/api-testing:master
name: extension-orm
command: [atest-store-orm]
tty: true
workingDir: /
- image: ghcr.io/linuxsuren/api-testing:master
name: extension-s3
command: [atest-store-s3]
tty: true
workingDir: /
- image: ghcr.io/linuxsuren/api-testing:master
name: extension-git
command: [atest-store-git]
tty: true
workingDir: /
volumes:
- name: config
hostPath:
path: /root/.config/atest/
type: DirectoryOrCreate
19 changes: 15 additions & 4 deletions pkg/testing/loader_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"path"
"path/filepath"
"sync"

"github.com/linuxsuren/api-testing/pkg/util"
)
Expand All @@ -13,15 +14,17 @@ type fileLoader struct {
paths []string
index int
parent string

lock *sync.RWMutex
}

// NewFileLoader creates the instance of file loader
func NewFileLoader() Loader {
return &fileLoader{index: -1}
return &fileLoader{index: -1, lock: &sync.RWMutex{}}
}

func NewFileWriter(parent string) Writer {
return &fileLoader{index: -1, parent: parent}
return &fileLoader{index: -1, parent: parent, lock: &sync.RWMutex{}}
}

// HasMore returns if there are more test cases
Expand All @@ -38,6 +41,9 @@ func (l *fileLoader) Load() (data []byte, err error) {

// Put adds the test case path
func (l *fileLoader) Put(item string) (err error) {
l.lock.Lock()
defer l.lock.Unlock()

if l.parent == "" {
l.parent = path.Dir(item)
}
Expand All @@ -47,9 +53,8 @@ func (l *fileLoader) Put(item string) (err error) {
if files, err = filepath.Glob(pattern); err == nil {
l.paths = append(l.paths, files...)
}
fmt.Println(pattern, "pattern", files)
fmt.Println(pattern, "pattern", len(files))
}
fmt.Println(l.paths, item, l.parent, err)
return
}

Expand Down Expand Up @@ -133,6 +138,9 @@ func (l *fileLoader) CreateSuite(name, api string) (err error) {
}

func (l *fileLoader) GetSuite(name string) (suite *TestSuite, absPath string, err error) {
l.lock.RLock()
defer l.lock.RUnlock()

for i := range l.paths {
suitePath := l.paths[i]
if absPath, err = filepath.Abs(suitePath); err != nil {
Expand Down Expand Up @@ -165,6 +173,9 @@ func (l *fileLoader) UpdateSuite(suite TestSuite) (err error) {
}

func (l *fileLoader) DeleteSuite(name string) (err error) {
l.lock.Lock()
defer l.lock.Unlock()

found := false
for i := range l.paths {
suitePath := l.paths[i]
Expand Down