Skip to content

Commit

Permalink
feat: support session scope store (#517)
Browse files Browse the repository at this point in the history
* chore: stop using the image from docker hub

* feat: support session scope store

* support to set the suggested api cout limit

* add more unit tests

---------

Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
  • Loading branch information
LinuxSuRen and LinuxSuRen authored Jul 21, 2024
1 parent 62383ba commit 6e0c70e
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 41 deletions.
2 changes: 1 addition & 1 deletion console/atest-ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ API.GetVersion((d) => {
})
const sideWidth = ref("width: 200px; display: flex;flex-direction: column;")
const isCollapse = ref(false)
const isCollapse = ref(true)
watch(isCollapse, (e) => {
if (e) {
sideWidth.value = "width: 80px; display: flex;flex-direction: column;"
Expand Down
2 changes: 1 addition & 1 deletion console/atest-ui/src/views/TestCase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ function formChange() {
}
}
const bodyType = ref(5)
const bodyType = ref(1)
function bodyTypeChange(e: number) {
let contentType = ""
switch (e) {
Expand Down
12 changes: 6 additions & 6 deletions e2e/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ services:
# - minio
- postgres
etcd:
image: "bitnami/etcd:3.5.10"
image: "ghcr.io/linuxsuren/bitnami/etcd:3.5.10"
expose:
- "2379"
environment:
Expand All @@ -45,7 +45,7 @@ services:
retries: 10
start_period: 3s
mysql:
image: mysql:8.2.0
image: ghcr.io/linuxsuren/library/mysql:8.2.0
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: root
Expand All @@ -57,7 +57,7 @@ services:
retries: 10
start_period: 3s
mariadb:
image: mariadb:11.0
image: ghcr.io/linuxsuren/library/mariadb:11.0
environment:
MARIADB_ROOT_PASSWORD: root
MARIADB_DATABASE: atest
Expand All @@ -68,14 +68,14 @@ services:
retries: 10
start_period: 3s
minio:
image: bitnami/minio:2023.11.6
image: ghcr.io/linuxsuren/bitnami/minio:2023.11.6
environment:
MINIO_ROOT_USER: root
MINIO_ROOT_PASSWORD: root
MINIO_SERVER_HOST: minio
MINIO_DEFAULT_BUCKETS: bucket
mongo:
image: mongo
image: ghcr.io/linuxsuren/library/mongo:7.0.12
healthcheck:
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/27017"]
interval: 3s
Expand All @@ -86,7 +86,7 @@ services:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root
postgres:
image: postgres:16.0
image: ghcr.io/linuxsuren/library/postgres:16.0
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: root
Expand Down
15 changes: 10 additions & 5 deletions pkg/runner/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ func (r ReportResultSlice) Swap(i, j int) {

type simpleTestCaseRunner struct {
UnimplementedRunner
simpleResponse SimpleResponse
cookies []*http.Cookie
simpleResponse SimpleResponse
cookies []*http.Cookie
apiSuggestLimit int
}

// NewSimpleTestCaseRunner creates the instance of the simple test case runner
Expand All @@ -82,6 +83,7 @@ func NewSimpleTestCaseRunner() TestCaseRunner {
UnimplementedRunner: NewDefaultUnimplementedRunner(),
simpleResponse: SimpleResponse{},
cookies: []*http.Cookie{},
apiSuggestLimit: 10,
}
return runner
}
Expand Down Expand Up @@ -234,7 +236,6 @@ func (r *simpleTestCaseRunner) GetSuggestedAPIs(suite *testing.TestSuite, api st

var swagger *spec.Swagger
if swagger, err = apispec.ParseURLToSwagger(suite.Spec.URL); err == nil && swagger != nil {
result = []*testing.TestCase{}
swaggerAPI := apispec.NewSwaggerAPI(swagger)
for api, methods := range swaggerAPI.ApiMap {
for _, method := range methods {
Expand Down Expand Up @@ -267,6 +268,9 @@ func (r *simpleTestCaseRunner) GetSuggestedAPIs(suite *testing.TestSuite, api st
testcase.Name = swagger.Paths.Paths[api].Patch.ID
}
result = append(result, testcase)
if len(result) >= r.apiSuggestLimit {
return
}
}
}
}
Expand Down Expand Up @@ -303,8 +307,9 @@ func (r *simpleTestCaseRunner) withResponseRecord(resp *http.Response) (response
func (r *simpleTestCaseRunner) GetResponseRecord() SimpleResponse {
return r.simpleResponse
}
func (s *simpleTestCaseRunner) WithSuite(suite *testing.TestSuite) {
// not need this parameter

func (r *simpleTestCaseRunner) WithAPISuggestLimit(limit int) {
r.apiSuggestLimit = limit
}

func expectInt(name string, expect, actual int) (err error) {
Expand Down
1 change: 1 addition & 0 deletions pkg/runner/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ func TestBodyFiledsVerify(t *testing.T) {
func TestGetSuggestedAPIs(t *testing.T) {
runner := NewSimpleTestCaseRunner()
runner.WithSuite(nil)
runner.WithAPISuggestLimit(6)
// not a swagger
result, err := runner.GetSuggestedAPIs(&atest.TestSuite{}, "")
assert.NoError(t, err, err)
Expand Down
9 changes: 9 additions & 0 deletions pkg/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type TestCaseRunner interface {
WithTestReporter(TestReporter)
WithExecer(fakeruntime.Execer)
WithSuite(*testing.TestSuite)
WithAPISuggestLimit(int)
}

// HTTPResponseRecord represents a http response record
Expand Down Expand Up @@ -107,3 +108,11 @@ func (r *UnimplementedRunner) GetSuggestedAPIs(suite *testing.TestSuite, api str
// empty implement
return
}

func (r *UnimplementedRunner) WithAPISuggestLimit(int) {
// empty implement
}

func (s *UnimplementedRunner) WithSuite(suite *testing.TestSuite) {
// empty implement
}
19 changes: 18 additions & 1 deletion pkg/runner/runner_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2023 API Testing Authors.
Copyright 2023-2024 API Testing Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -30,3 +30,20 @@ func TestRunnerFactory(t *testing.T) {
runner = GetTestSuiteRunner(&atest.TestSuite{Spec: atest.APISpec{Kind: "grpc", RPC: &atest.RPCDesc{}}})
assert.IsType(t, NewGRPCTestCaseRunner("", atest.RPCDesc{}), runner)
}

func TestUnimplementedRunner(t *testing.T) {
runner := NewDefaultUnimplementedRunner()
output, err := runner.RunTestCase(&atest.TestCase{}, nil, nil)
assert.Nil(t, output)
assert.Error(t, err)

runner.WithWriteLevel("debug")
runner.WithTestReporter(nil)

var results []*atest.TestCase
results, err = runner.GetSuggestedAPIs(nil, "")
assert.Nil(t, results)
assert.NoError(t, err)

runner.WithAPISuggestLimit(0)
}
6 changes: 6 additions & 0 deletions pkg/runner/testdata/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
"summary": "summary",
"operationId": "patchUser"
}
},
"/api/v1/groups/{group}": {
"get": {
"summary": "summary",
"operationId": "getGroup"
}
}
},
"components": {
Expand Down
2 changes: 2 additions & 0 deletions pkg/server/remote_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func (s *remoteRunnerAdapter) WithExecer(fakeruntime.Execer) {
func (s *remoteRunnerAdapter) WithSuite(suite *testing.TestSuite) {
s.suite = suite
}
func (s *remoteRunnerAdapter) WithAPISuggestLimit(limit int) {
}

func init() {
env := os.Environ()
Expand Down
14 changes: 14 additions & 0 deletions pkg/server/remote_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,20 @@ func TestFakeSecretServer(t *testing.T) {
assert.Error(t, err)
}

func TestRemoteRunnerAdapter(t *testing.T) {
runner := &remoteRunnerAdapter{}
runner.GetSuggestedAPIs(nil, "")
runner.WithSecure(nil)
runner.WithOutputWriter(nil)
runner.WithWriteLevel("debug")
runner.WithTestReporter(nil)
runner.WithExecer(nil)
runner.WithSuite(nil)
runner.WithAPISuggestLimit(0)
_, err := runner.RunTestCase(nil, nil, nil)
assert.Error(t, err)
}

func getRemoteServerInTempDir() (server RunnerServer, call func()) {
dir, _ := os.MkdirTemp(os.TempDir(), "remote-server-test")
call = func() { os.RemoveAll(dir) }
Expand Down
2 changes: 2 additions & 0 deletions pkg/testing/case.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ func (m SortedKeysStringMap) GetValue(key string) string {
case map[string]interface{}:
verifier := convertToVerifier(o)
return verifier.Value
case *Verifier:
return o.Value
}

return ""
Expand Down
33 changes: 32 additions & 1 deletion pkg/testing/case_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2023 API Testing Authors.
Copyright 2023-2024 API Testing Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -54,3 +54,34 @@ body:
assert.Nil(t, err)
assert.Equal(t, "plain", req.Body.String())
}

func TestResponse(t *testing.T) {
resp := &atesting.Response{
Body: "body",
BodyFieldsExpect: map[string]interface{}{
"name": "rick",
},
}
assert.Equal(t, "body", resp.GetBody())
assert.Equal(t, map[string]interface{}{"name": "rick"}, resp.GetBodyFieldsExpect())
}

func TestSortedKeysStringMap(t *testing.T) {
obj := atesting.SortedKeysStringMap{
"c": "d",
"f": map[string]interface{}{
"value": "f",
},
"e": &atesting.Verifier{
Value: "e",
},
"a": "b",
}
assert.Equal(t, []string{"a", "c", "e", "f"}, obj.Keys())
assert.Equal(t, "b", obj.GetValue("a"))
assert.Nil(t, obj.GetVerifier("b"))
assert.Equal(t, "e", obj.GetValue("e"))
assert.Equal(t, "f", obj.GetValue("f"))
assert.Equal(t, "f", obj.GetVerifier("f").Value)
assert.Empty(t,obj.GetValue("not-found"))
}
82 changes: 82 additions & 0 deletions pkg/testing/loader_non_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
Copyright 2024 API Testing Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package testing_test

import (
"testing"

atest "github.com/linuxsuren/api-testing/pkg/testing"
"github.com/stretchr/testify/assert"
)

func TestNonLoader(t *testing.T) {
loader := atest.NewNonWriter()
defer loader.Close()

assert.False(t, loader.HasMore())

data, err := loader.Load()
assert.NoError(t, err)
assert.Nil(t, data)

assert.NoError(t, loader.Put(""))
assert.Empty(t, loader.GetContext())
assert.Equal(t, 0, loader.GetCount())

loader.Reset()

var suites []atest.TestSuite
suites, err = loader.ListTestSuite()
assert.NoError(t, err)
assert.Empty(t, suites)

_, err = loader.GetTestSuite("test", false)
assert.NoError(t, err)

assert.NoError(t, loader.CreateSuite("", ""))

var suite *atest.TestSuite
var absPath string
suite, absPath, err = loader.GetSuite("test")
assert.NoError(t, err)
assert.Nil(t, suite)
assert.Empty(t, absPath)

assert.NoError(t, loader.UpdateSuite(atest.TestSuite{}))
assert.NoError(t, loader.DeleteSuite(""))

var testCases []atest.TestCase
testCases, err = loader.ListTestCase("")
assert.NoError(t, err)
assert.Empty(t, testCases)

data, err = loader.GetTestSuiteYaml("")
assert.NoError(t, err)
assert.Nil(t, data)

_, err = loader.GetTestCase("", "")
assert.NoError(t, err)
assert.NoError(t, loader.CreateTestCase("", atest.TestCase{}))
assert.NoError(t, loader.UpdateTestCase("", atest.TestCase{}))
assert.NoError(t, loader.DeleteTestCase("", ""))

var readonly bool
readonly, err = loader.Verify()
assert.NoError(t, err)
assert.False(t, readonly)
assert.Empty(t, loader.PProf(""))
}
3 changes: 0 additions & 3 deletions pkg/testing/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ func (s *storeFactory) GetStores() (stores []Store, err error) {
func (s *storeFactory) GetStoresByOwner(owner string) (stores []Store, err error) {
var all []Store
all, err = s.GetStores()
if owner == "" {
return all, err
}
if err == nil {
for _, item := range all {
if item.Owner != owner {
Expand Down
Loading

0 comments on commit 6e0c70e

Please sign in to comment.