/
testing.go
133 lines (119 loc) 路 4.05 KB
/
testing.go
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
// Copyright 2015-present, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// 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 esitesting
import (
"fmt"
"net/http"
"os"
"os/exec"
"strings"
"github.com/corestoreio/caddy-esi/esitag"
"github.com/corestoreio/errors"
ps "github.com/mitchellh/go-ps"
)
func init() {
esitag.RegisterResourceHandlerFactory("mockTimeout", func(opt *esitag.ResourceOptions) (esitag.ResourceHandler, error) {
return ResourceMock{
DoRequestFn: func(*esitag.ResourceArgs) (_ http.Header, content []byte, err error) {
// mockTimeout://duration
return nil, nil, errors.Timeout.Newf("[backend] Timeout after %q", opt.URL)
},
}, nil
})
}
const mockRequestMsg = "%s %q Timeout %s MaxBody %s"
// ResourceMock exported for testing
type ResourceMock struct {
DoRequestFn func(args *esitag.ResourceArgs) (http.Header, []byte, error)
CloseFn func() error
}
// DoRequest calls DoRequestFn
func (rm ResourceMock) DoRequest(a *esitag.ResourceArgs) (http.Header, []byte, error) {
return rm.DoRequestFn(a)
}
// Close returns nil if CloseFn is nil otherwise calls CloseFn
func (rm ResourceMock) Close() error {
if rm.CloseFn == nil {
return nil
}
return rm.CloseFn()
}
// MockRequestContent for testing purposes only.
func MockRequestContent(content string) esitag.ResourceHandler {
return ResourceMock{
DoRequestFn: func(args *esitag.ResourceArgs) (http.Header, []byte, error) {
if args.URL == "" && args.Tag.Key == "" {
panic(fmt.Sprintf("[esibackend] URL and Key cannot be empty: %#v\n", args))
}
return nil, []byte(fmt.Sprintf(mockRequestMsg, content, args.URL, args.Tag.Timeout, args.MaxBodySizeHumanized())), nil
},
}
}
// MockRequestContentCB for testing purposes only. Call back gets executed
// before the function returns.
func MockRequestContentCB(content string, callback func() error) esitag.ResourceHandler {
return ResourceMock{
DoRequestFn: func(args *esitag.ResourceArgs) (http.Header, []byte, error) {
if err := callback(); err != nil {
return nil, nil, errors.Wrapf(err, "MockRequestContentCB with URL %q", args.URL)
}
return nil, []byte(fmt.Sprintf(mockRequestMsg, content, args.URL, args.Tag.Timeout, args.MaxBodySizeHumanized())), nil
},
}
}
// MockRequestError for testing purposes only.
func MockRequestError(err error) esitag.ResourceHandler {
return ResourceMock{
DoRequestFn: func(_ *esitag.ResourceArgs) (http.Header, []byte, error) {
return nil, nil, err
},
}
}
// MockRequestPanic just panics
func MockRequestPanic(msg interface{}) esitag.ResourceHandler {
return ResourceMock{
DoRequestFn: func(_ *esitag.ResourceArgs) (http.Header, []byte, error) {
panic(msg)
},
}
}
// StartProcess starts a process and returns a cleanup function which kills the
// process. Panics on error.
func StartProcess(name string, arg ...string) *exec.Cmd {
cmd := exec.Command(name, arg...)
if err := cmd.Start(); err != nil {
panic(fmt.Sprintf("skipping test; couldn't find go binary: %v", err))
}
return cmd
}
// KillZombieProcess searches a running process by its name and kills it. Writes
// the success to Stderr. Panics on errors.
func KillZombieProcess(processName16 string) {
pses, err := ps.Processes()
if err != nil {
panic(err)
}
for _, p := range pses {
if strings.Contains(p.Executable(), processName16) { // max length 16
proc, err := os.FindProcess(p.Pid())
if err != nil {
panic(err)
}
if err := proc.Kill(); err != nil {
panic(err)
}
fmt.Fprintf(os.Stderr, "Killed previous running process %s with pid %d\n", p.Executable(), p.Pid())
}
}
}