-
Notifications
You must be signed in to change notification settings - Fork 0
/
service.go
124 lines (113 loc) · 3.15 KB
/
service.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
package httptest
import (
"context"
"io"
"net"
"net/http"
"time"
"github.com/andrescosta/goico/pkg/service"
httpsvc "github.com/andrescosta/goico/pkg/service/http"
"github.com/andrescosta/goico/pkg/test"
"github.com/gorilla/mux"
)
type HandlerFn func(rw http.ResponseWriter, r *http.Request)
type PathHandler struct {
Scheme string
Path string
Handler HandlerFn
}
type Service struct {
URL string
Client *http.Client
Servedone <-chan error
Cancel context.CancelFunc
}
func NewService(ctx context.Context, handlers []PathHandler, hfn httpsvc.HealthCheckFn, stackLevel httpsvc.StackLevel) (*Service, error) {
localhost := "127.0.0.1:0"
svc, err := httpsvc.New(
httpsvc.WithContext(ctx),
httpsvc.WithAddr(localhost),
httpsvc.WithName("listener-test"),
httpsvc.WithStackLevelOnError[*httpsvc.ServiceOptions](stackLevel),
httpsvc.WithHealthCheckFn[*httpsvc.ServiceOptions](hfn),
httpsvc.WithInitRoutesFn[*httpsvc.ServiceOptions](func(_ context.Context, r *mux.Router) error {
for _, h := range handlers {
r.HandleFunc(h.Path, h.Handler).Schemes(h.Scheme)
}
return nil
}),
)
if err != nil {
return nil, err
}
addr, servedone, err := start(localhost, svc)
if err != nil {
return nil, err
}
return &Service{
URL: "http://" + addr,
Client: &http.Client{Transport: &http.Transport{}},
Servedone: servedone,
}, nil
}
func SetHTTPServerTimeouts(t time.Duration) {
timeout := t.String()
test.SetargsV("http.timeout.write", timeout)
test.SetargsV("http.timeout.read", timeout)
test.SetargsV("http.timeout.idle", timeout)
test.SetargsV("http.timeout.handler", timeout)
}
func NewSidecar(ctx context.Context, hfn httpsvc.HealthCheckFn) (*Service, error) {
localhost := "127.0.0.1:0"
service, err := service.New(
service.WithName("sidecar-test"),
service.WithContext(ctx),
service.WithKind("headless"),
service.WithAddr(localhost),
)
if err != nil {
return nil, err
}
svc, err := httpsvc.NewSidecar(
httpsvc.WithHealthCheckFn[*httpsvc.SidecarOptions](hfn),
httpsvc.WithPrimaryService(service),
httpsvc.WithServiceStatusFn(func() (string, time.Time) { return service.Status() }),
)
if err != nil {
return nil, err
}
addr, servedone, err := start(localhost, svc)
if err != nil {
return nil, err
}
return &Service{
URL: "http://" + addr,
Client: &http.Client{Transport: &http.Transport{}},
Servedone: servedone,
}, nil
}
func start(addr string, svc *httpsvc.Service) (string, chan error, error) {
servedone := make(chan error, 1)
listener, err := net.Listen("tcp", addr)
if err != nil {
return "", nil, err
}
go func() {
servedone <- svc.DoServe(listener)
close(servedone)
}()
return listener.Addr().String(), servedone, nil
}
func (s *Service) Get(url string) (*http.Response, error) {
return s.Verb(url, http.MethodGet, nil)
}
func (s *Service) Post(url string) (*http.Response, error) {
return s.Verb(url, http.MethodPost, nil)
}
func (s *Service) Verb(url string, verb string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequestWithContext(context.Background(), verb, url, body)
if err != nil {
return nil, err
}
return http.DefaultClient.Do(req)
}