Skip to content

Commit 2fb4f80

Browse files
committed
feat: adding resource loader interface and default implement
1 parent 5a3b114 commit 2fb4f80

File tree

8 files changed

+231
-89
lines changed

8 files changed

+231
-89
lines changed

cmd/root_test.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,28 @@ import (
55

66
"github.com/stretchr/testify/assert"
77

8-
exec "github.com/linuxsuren/go-fake-runtime"
8+
fakeruntime "github.com/linuxsuren/go-fake-runtime"
99
)
1010

1111
func TestCreateRunCommand(t *testing.T) {
1212
cmd := createRunCommand()
1313
assert.Equal(t, "run", cmd.Use)
1414

15-
init := createInitCommand(exec.FakeExecer{})
15+
init := createInitCommand(fakeruntime.FakeExecer{})
1616
assert.Equal(t, "init", init.Use)
1717

1818
server := createServerCmd(&fakeGRPCServer{})
1919
assert.NotNil(t, server)
2020
assert.Equal(t, "server", server.Use)
2121

22-
root := NewRootCmd(exec.FakeExecer{}, NewFakeGRPCServer())
22+
root := NewRootCmd(fakeruntime.FakeExecer{}, NewFakeGRPCServer())
2323
root.SetArgs([]string{"init", "-k=demo.yaml", "--wait-namespace", "demo", "--wait-resource", "demo"})
2424
err := root.Execute()
2525
assert.Nil(t, err)
2626
}
27+
28+
func TestRootCmd(t *testing.T) {
29+
c := NewRootCmd(fakeruntime.FakeExecer{ExpectOS: "linux"}, NewFakeGRPCServer())
30+
assert.NotNil(t, c)
31+
assert.Equal(t, "atest", c.Use)
32+
}

cmd/run.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import (
55
"fmt"
66
"io"
77
"os"
8-
"path"
9-
"path/filepath"
108
"strings"
119
"sync"
1210
"time"
@@ -16,7 +14,6 @@ import (
1614
"github.com/linuxsuren/api-testing/pkg/render"
1715
"github.com/linuxsuren/api-testing/pkg/runner"
1816
"github.com/linuxsuren/api-testing/pkg/testing"
19-
"github.com/linuxsuren/api-testing/pkg/util"
2017
"github.com/spf13/cobra"
2118
"golang.org/x/sync/semaphore"
2219
)
@@ -40,12 +37,16 @@ type runOption struct {
4037
swaggerURL string
4138
level string
4239
caseItems []string
40+
41+
// for internal use
42+
loader testing.Loader
4343
}
4444

4545
func newDefaultRunOption() *runOption {
4646
return &runOption{
4747
reporter: runner.NewMemoryTestReporter(),
4848
reportWriter: runner.NewResultWriter(os.Stdout),
49+
loader: testing.NewFileLoader(),
4950
}
5051
}
5152

@@ -134,19 +135,13 @@ func (o *runOption) runE(cmd *cobra.Command, args []string) (err error) {
134135
o.limiter.Stop()
135136
}()
136137

137-
var suites []string
138-
for _, pattern := range util.Expand(o.pattern) {
139-
var files []string
140-
if files, err = filepath.Glob(pattern); err == nil {
141-
suites = append(suites, files...)
142-
}
138+
if err = o.loader.Put(o.pattern); err != nil {
139+
return
143140
}
144141

145-
cmd.Println("found suites:", len(suites))
146-
for i := range suites {
147-
item := suites[i]
148-
cmd.Println("run suite:", item)
149-
if err = o.runSuiteWithDuration(item); err != nil {
142+
cmd.Println("found suites:", o.loader.GetCount())
143+
for o.loader.HasMore() {
144+
if err = o.runSuiteWithDuration(o.loader); err != nil {
150145
break
151146
}
152147
}
@@ -166,7 +161,7 @@ func (o *runOption) runE(cmd *cobra.Command, args []string) (err error) {
166161
return
167162
}
168163

169-
func (o *runOption) runSuiteWithDuration(suite string) (err error) {
164+
func (o *runOption) runSuiteWithDuration(loader testing.Loader) (err error) {
170165
sem := semaphore.NewWeighted(o.thread)
171166
stop := false
172167
var timeout *time.Ticker
@@ -204,7 +199,7 @@ func (o *runOption) runSuiteWithDuration(suite string) (err error) {
204199
}()
205200

206201
dataContext := getDefaultContext()
207-
ch <- o.runSuite(suite, dataContext, o.context, stopSingal)
202+
ch <- o.runSuite(loader, dataContext, o.context, stopSingal)
208203
}(errChannel, sem)
209204
if o.duration <= 0 {
210205
stop = true
@@ -221,9 +216,14 @@ func (o *runOption) runSuiteWithDuration(suite string) (err error) {
221216
return
222217
}
223218

224-
func (o *runOption) runSuite(suite string, dataContext map[string]interface{}, ctx context.Context, stopSingal chan struct{}) (err error) {
219+
func (o *runOption) runSuite(loader testing.Loader, dataContext map[string]interface{}, ctx context.Context, stopSingal chan struct{}) (err error) {
220+
var data []byte
221+
if data, err = loader.Load(); err != nil {
222+
return
223+
}
224+
225225
var testSuite *testing.TestSuite
226-
if testSuite, err = testing.Parse(suite); err != nil {
226+
if testSuite, err = testing.Parse(data); err != nil {
227227
return
228228
}
229229

@@ -253,7 +253,7 @@ func (o *runOption) runSuite(suite string, dataContext map[string]interface{}, c
253253
o.limiter.Accept()
254254

255255
ctxWithTimeout, _ := context.WithTimeout(ctx, o.requestTimeout)
256-
ctxWithTimeout = context.WithValue(ctxWithTimeout, runner.ContextKey("").ParentDir(), path.Dir(suite))
256+
ctxWithTimeout = context.WithValue(ctxWithTimeout, runner.ContextKey("").ParentDir(), loader.GetContext())
257257

258258
simpleRunner := runner.NewSimpleTestCaseRunner()
259259
simpleRunner.WithTestReporter(o.reporter)

cmd/run_test.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212

1313
"github.com/h2non/gock"
1414
"github.com/linuxsuren/api-testing/pkg/limit"
15+
atest "github.com/linuxsuren/api-testing/pkg/testing"
1516
"github.com/linuxsuren/api-testing/pkg/util"
16-
fakeruntime "github.com/linuxsuren/go-fake-runtime"
1717
"github.com/spf13/cobra"
1818
"github.com/stretchr/testify/assert"
1919
)
@@ -58,8 +58,13 @@ func TestRunSuite(t *testing.T) {
5858
opt.limiter = limit.NewDefaultRateLimiter(0, 0)
5959
stopSingal := make(chan struct{}, 1)
6060

61-
err := opt.runSuite(tt.suiteFile, ctx, context.TODO(), stopSingal)
62-
assert.Equal(t, tt.hasError, err != nil, err)
61+
loader := atest.NewFileLoader()
62+
err := loader.Put(tt.suiteFile)
63+
assert.NoError(t, err)
64+
if loader.HasMore() {
65+
err = opt.runSuite(loader, ctx, context.TODO(), stopSingal)
66+
assert.Equal(t, tt.hasError, err != nil, err)
67+
}
6368
})
6469
}
6570
}
@@ -128,6 +133,11 @@ func TestRunCommand(t *testing.T) {
128133
prepare: fooPrepare,
129134
args: []string{"-p", simpleSuite, "--report", "md", "--report-file", path.Join(tmpFile.Name(), "fake")},
130135
hasErr: true,
136+
}, {
137+
name: "malformed report file path",
138+
prepare: fooPrepare,
139+
args: []string{"-p", "[]]$#%*^&()"},
140+
hasErr: true,
131141
}}
132142
for _, tt := range tests {
133143
t.Run(tt.name, func(t *testing.T) {
@@ -146,12 +156,6 @@ func TestRunCommand(t *testing.T) {
146156
}
147157
}
148158

149-
func TestRootCmd(t *testing.T) {
150-
c := NewRootCmd(fakeruntime.FakeExecer{ExpectOS: "linux"}, NewFakeGRPCServer())
151-
assert.NotNil(t, c)
152-
assert.Equal(t, "atest", c.Use)
153-
}
154-
155159
func TestPreRunE(t *testing.T) {
156160
tests := []struct {
157161
name string

pkg/testing/loader.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package testing
2+
3+
// Loader is an interface for test cases loader
4+
type Loader interface {
5+
HasMore() bool
6+
Load() ([]byte, error)
7+
Put(string) (err error)
8+
GetContext() string
9+
GetCount() int
10+
}

pkg/testing/loader_file.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package testing
2+
3+
import (
4+
"os"
5+
"path"
6+
"path/filepath"
7+
8+
"github.com/linuxsuren/api-testing/pkg/util"
9+
)
10+
11+
type fileLoader struct {
12+
paths []string
13+
index int
14+
}
15+
16+
// NewFileLoader creates the instance of file loader
17+
func NewFileLoader() Loader {
18+
return &fileLoader{index: -1}
19+
}
20+
21+
// HasMore returns if there are more test cases
22+
func (l *fileLoader) HasMore() bool {
23+
l.index++
24+
return l.index < len(l.paths)
25+
}
26+
27+
// Load returns the test case content
28+
func (l *fileLoader) Load() (data []byte, err error) {
29+
data, err = os.ReadFile(l.paths[l.index])
30+
return
31+
}
32+
33+
// Put adds the test case path
34+
func (l *fileLoader) Put(item string) (err error) {
35+
for _, pattern := range util.Expand(item) {
36+
var files []string
37+
if files, err = filepath.Glob(pattern); err == nil {
38+
l.paths = append(l.paths, files...)
39+
}
40+
}
41+
return
42+
}
43+
44+
// GetContext returns the context of current test case
45+
func (l *fileLoader) GetContext() string {
46+
return path.Dir(l.paths[l.index])
47+
}
48+
49+
// GetCount returns the count of test cases
50+
func (l *fileLoader) GetCount() int {
51+
return len(l.paths)
52+
}

pkg/testing/loader_file_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package testing_test
2+
3+
import (
4+
"testing"
5+
6+
atest "github.com/linuxsuren/api-testing/pkg/testing"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestFileLoader(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
items []string
14+
verify func(t *testing.T, loader atest.Loader)
15+
}{{
16+
name: "empty",
17+
items: []string{},
18+
verify: func(t *testing.T, loader atest.Loader) {
19+
assert.False(t, loader.HasMore())
20+
assert.Empty(t, loader.GetCount())
21+
},
22+
}, {
23+
name: "brace expansion path",
24+
items: []string{"testdata/{invalid-,}testcase.yaml"},
25+
verify: defaultVerify,
26+
}, {
27+
name: "glob path",
28+
items: []string{"testdata/*testcase.yaml"},
29+
verify: defaultVerify,
30+
}}
31+
for _, tt := range tests {
32+
t.Run(tt.name, func(t *testing.T) {
33+
loader := atest.NewFileLoader()
34+
for _, item := range tt.items {
35+
loader.Put(item)
36+
}
37+
tt.verify(t, loader)
38+
})
39+
}
40+
}
41+
42+
func defaultVerify(t *testing.T, loader atest.Loader) {
43+
assert.True(t, loader.HasMore())
44+
data, err := loader.Load()
45+
assert.Nil(t, err)
46+
assert.Equal(t, invalidTestCaseContent, string(data))
47+
assert.Equal(t, "testdata", loader.GetContext())
48+
49+
assert.True(t, loader.HasMore())
50+
data, err = loader.Load()
51+
assert.Nil(t, err)
52+
assert.Equal(t, testCaseContent, string(data))
53+
assert.Equal(t, "testdata", loader.GetContext())
54+
55+
assert.False(t, loader.HasMore())
56+
}

pkg/testing/parser.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,8 @@ import (
1919
)
2020

2121
// Parse parses a file and returns the test suite
22-
func Parse(configFile string) (testSuite *TestSuite, err error) {
23-
var data []byte
24-
if data, err = os.ReadFile(configFile); err == nil {
25-
testSuite, err = ParseFromData(data)
26-
}
22+
func Parse(data []byte) (testSuite *TestSuite, err error) {
23+
testSuite, err = ParseFromData(data)
2724

2825
// schema validation
2926
if err == nil {
@@ -116,7 +113,7 @@ func (r *Request) Render(ctx interface{}, dataDir string) (err error) {
116113
}
117114

118115
// setting default values
119-
r.Method = emptyThenDefault(r.Method, http.MethodGet)
116+
r.Method = EmptyThenDefault(r.Method, http.MethodGet)
120117
return
121118
}
122119

@@ -153,18 +150,20 @@ func (r *Request) GetBody() (reader io.Reader, err error) {
153150

154151
// Render renders the response
155152
func (r *Response) Render(ctx interface{}) (err error) {
156-
r.StatusCode = zeroThenDefault(r.StatusCode, http.StatusOK)
153+
r.StatusCode = ZeroThenDefault(r.StatusCode, http.StatusOK)
157154
return
158155
}
159156

160-
func zeroThenDefault(val, defVal int) int {
157+
// ZeroThenDefault return the default value if the val is zero
158+
func ZeroThenDefault(val, defVal int) int {
161159
if val == 0 {
162160
val = defVal
163161
}
164162
return val
165163
}
166164

167-
func emptyThenDefault(val, defVal string) string {
165+
// EmptyThenDefault return the default value if the val is empty
166+
func EmptyThenDefault(val, defVal string) string {
168167
if strings.TrimSpace(val) == "" {
169168
val = defVal
170169
}

0 commit comments

Comments
 (0)