-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathstep_api.go
More file actions
139 lines (122 loc) · 4.06 KB
/
step_api.go
File metadata and controls
139 lines (122 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package hrp
import (
"fmt"
"github.com/jinzhu/copier"
"github.com/rs/zerolog/log"
)
// IAPI represents interface for api,
// includes API and APIPath.
type IAPI interface {
GetPath() string
ToAPI() (*API, error)
}
type API struct {
Name string `json:"name" yaml:"name"` // required
Request *Request `json:"request,omitempty" yaml:"request,omitempty"`
Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"`
SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"`
TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"`
Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"`
Validators []interface{} `json:"validate,omitempty" yaml:"validate,omitempty"`
Export []string `json:"export,omitempty" yaml:"export,omitempty"`
Path string
}
func (api *API) GetPath() string {
return api.Path
}
func (api *API) ToAPI() (*API, error) {
return api, nil
}
// APIPath implements IAPI interface.
type APIPath string
func (path *APIPath) GetPath() string {
return fmt.Sprintf("%v", *path)
}
func (path *APIPath) ToAPI() (*API, error) {
api := &API{}
apiPath := path.GetPath()
err := LoadFileObject(apiPath, api)
if err != nil {
return nil, err
}
// 1. deal with request body compatibility
convertCompatRequestBody(api.Request)
// 2. deal with validators compatibility
err = convertCompatValidator(api.Validators)
// 3. deal with extract expr including hyphen
convertExtract(api.Extract)
return api, err
}
// StepAPIWithOptionalArgs implements IStep interface.
type StepAPIWithOptionalArgs struct {
StepConfig
API interface{} `json:"api,omitempty" yaml:"api,omitempty"` // *APIPath or *API
}
// TeardownHook adds a teardown hook for current teststep.
func (s *StepAPIWithOptionalArgs) TeardownHook(hook string) *StepAPIWithOptionalArgs {
s.TeardownHooks = append(s.TeardownHooks, hook)
return s
}
// Export specifies variable names to export from referenced api for current step.
func (s *StepAPIWithOptionalArgs) Export(names ...string) *StepAPIWithOptionalArgs {
api, ok := s.API.(*API)
if ok {
s.StepExport = append(api.Export, names...)
}
return s
}
func (s *StepAPIWithOptionalArgs) Name() string {
if s.StepName != "" {
return s.StepName
}
api, ok := s.API.(*API)
if ok {
return api.Name
}
return ""
}
func (s *StepAPIWithOptionalArgs) Type() StepType {
return StepTypeAPI
}
func (s *StepAPIWithOptionalArgs) Config() *StepConfig {
return &s.StepConfig
}
func (s *StepAPIWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepResult, err error) {
defer func() {
stepResult.StepType = StepTypeAPI
}()
// extend request with referenced API
api, _ := s.API.(*API)
step := &StepRequestWithOptionalArgs{}
// deep copy step to avoid data racing
if err = copier.Copy(step, s.StepConfig); err != nil {
log.Error().Err(err).Msg("copy step failed")
return
}
extendWithAPI(step, api)
stepResult, err = runStepRequest(r, step)
return
}
// extend teststep with api, teststep will merge and override referenced api
func extendWithAPI(testStep *StepRequestWithOptionalArgs, overriddenStep *API) {
// override api name
if testStep.StepName == "" {
testStep.StepName = overriddenStep.Name
}
// merge & override request
testStep.Request = overriddenStep.Request
// init upload
if len(testStep.Request.Upload) != 0 {
initUpload(testStep)
}
// merge & override variables
testStep.Variables = mergeVariables(testStep.Variables, overriddenStep.Variables)
// merge & override extractors
testStep.StepConfig.Extract = mergeMap(testStep.StepConfig.Extract, overriddenStep.Extract)
// merge & override validators
testStep.Validators = mergeValidators(testStep.Validators, overriddenStep.Validators)
// merge & override setupHooks
testStep.SetupHooks = mergeSlices(testStep.SetupHooks, overriddenStep.SetupHooks)
// merge & override teardownHooks
testStep.TeardownHooks = mergeSlices(testStep.TeardownHooks, overriddenStep.TeardownHooks)
}