Skip to content

Commit 8c64611

Browse files
authored
Fix imposters search (#173)
* Fix imposters search
1 parent bca67fd commit 8c64611

File tree

4 files changed

+149
-19
lines changed

4 files changed

+149
-19
lines changed

internal/server/http/imposter.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ func NewImposterFS(path string) (ImposterFs, error) {
151151
}, nil
152152
}
153153

154-
func (i ImposterFs) FindImposters(impostersCh chan []Imposter) error {
155-
err := fs.WalkDir(i.fs, ".", func(path string, info fs.DirEntry, err error) error {
154+
func (ifs ImposterFs) FindImposters(impostersCh chan []Imposter) error {
155+
err := fs.WalkDir(ifs.fs, ".", func(path string, info fs.DirEntry, err error) error {
156156
if err != nil {
157157
return fmt.Errorf("%w: error finding imposters", err)
158158
}
@@ -168,19 +168,20 @@ func (i ImposterFs) FindImposters(impostersCh chan []Imposter) error {
168168
default:
169169
return nil
170170
}
171-
imposters, err := i.unmarshalImposters(cfg)
171+
imposters, err := ifs.unmarshalImposters(cfg)
172172
if err != nil {
173173
return err
174174
}
175175
impostersCh <- imposters
176176
}
177177
return nil
178178
})
179+
close(impostersCh)
179180
return err
180181
}
181182

182-
func (i ImposterFs) unmarshalImposters(imposterConfig ImposterConfig) ([]Imposter, error) {
183-
imposterFile, _ := i.fs.Open(imposterConfig.FilePath)
183+
func (ifs ImposterFs) unmarshalImposters(imposterConfig ImposterConfig) ([]Imposter, error) {
184+
imposterFile, _ := ifs.fs.Open(imposterConfig.FilePath)
184185
defer imposterFile.Close()
185186

186187
bytes, _ := io.ReadAll(imposterFile)
@@ -202,7 +203,7 @@ func (i ImposterFs) unmarshalImposters(imposterConfig ImposterConfig) ([]Imposte
202203
}
203204

204205
for i := range imposters {
205-
imposters[i].BasePath = filepath.Dir(imposterConfig.FilePath)
206+
imposters[i].BasePath = filepath.Dir(filepath.Join(ifs.path, imposterConfig.FilePath))
206207
imposters[i].Path = imposterConfig.FilePath
207208
}
208209

internal/server/http/imposter_test.go

+133-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package http
22

33
import (
4+
"encoding/json"
45
"testing"
56

6-
"encoding/json"
77
"github.com/stretchr/testify/assert"
88
"github.com/stretchr/testify/require"
99
"gopkg.in/yaml.v2"
@@ -22,6 +22,138 @@ func TestNewImposterFS(t *testing.T) {
2222
})
2323
}
2424

25+
func TestImposterFS_FindImposters(t *testing.T) {
26+
// Set up
27+
const expected = 7
28+
ifs, err := NewImposterFS("test/testdata/imposters")
29+
require.NoError(t, err)
30+
31+
// We trigger the imposters search.
32+
// We expect exactly [expected] imposters.
33+
ch := make(chan []Imposter, expected)
34+
err = ifs.FindImposters(ch)
35+
require.NoError(t, err)
36+
37+
// We collect all the imposters.
38+
received := make([]Imposter, 0, expected)
39+
for ii := range ch {
40+
received = append(received, ii...)
41+
}
42+
require.Len(t, received, expected)
43+
44+
// Imposter 1
45+
schemaFile := "schemas/create_gopher_request.json"
46+
bodyFile := "responses/create_gopher_response.json"
47+
assert.EqualValues(t, Imposter{
48+
BasePath: "test/testdata/imposters",
49+
Path: "create_gopher.imp.json",
50+
Request: Request{
51+
Method: "POST",
52+
Endpoint: "/gophers",
53+
SchemaFile: &schemaFile,
54+
Params: &map[string]string{
55+
"gopherColor": "{v:[a-z]+}",
56+
},
57+
Headers: &map[string]string{
58+
"Content-Type": "application/json",
59+
},
60+
},
61+
Response: Responses{{
62+
Status: 200,
63+
Headers: &map[string]string{
64+
"Content-Type": "application/json",
65+
},
66+
BodyFile: &bodyFile,
67+
}},
68+
}, received[0])
69+
70+
// Imposter 2
71+
assert.EqualValues(t, Imposter{
72+
BasePath: "test/testdata/imposters",
73+
Path: "create_gopher.imp.json",
74+
Request: Request{},
75+
}, received[1])
76+
77+
// Imposter 3
78+
assert.EqualValues(t, Imposter{
79+
BasePath: "test/testdata/imposters",
80+
Path: "test_request.imp.json",
81+
Request: Request{
82+
Method: "GET",
83+
Endpoint: "/testRequest",
84+
},
85+
Response: Responses{{
86+
Status: 200,
87+
Body: "Handled",
88+
}},
89+
}, received[2])
90+
91+
// Imposter 4
92+
assert.EqualValues(t, Imposter{
93+
BasePath: "test/testdata/imposters",
94+
Path: "test_request.imp.yaml",
95+
Request: Request{
96+
Method: "GET",
97+
Endpoint: "/yamlTestRequest",
98+
},
99+
Response: Responses{{
100+
Status: 200,
101+
Body: "Yaml Handled",
102+
}},
103+
}, received[3])
104+
105+
// Imposter 5
106+
assert.EqualValues(t, Imposter{
107+
BasePath: "test/testdata/imposters",
108+
Path: "test_request.imp.yml",
109+
Request: Request{
110+
Method: "GET",
111+
Endpoint: "/ymlTestRequest",
112+
},
113+
Response: Responses{{
114+
Status: 200,
115+
Body: "Yml Handled",
116+
Delay: ResponseDelay{
117+
delay: 1000000000,
118+
offset: 4000000000,
119+
},
120+
}},
121+
}, received[4])
122+
123+
// Imposter 6
124+
assert.EqualValues(t, Imposter{
125+
BasePath: "test/testdata/imposters",
126+
Path: "test_request.imp.yml",
127+
Request: Request{
128+
Method: "POST",
129+
Endpoint: "/yamlGophers",
130+
Headers: &map[string]string{
131+
"Content-Type": "application/json",
132+
},
133+
},
134+
Response: Responses{{
135+
Status: 201,
136+
Headers: &map[string]string{
137+
"Content-Type": "application/json",
138+
"X-Source": "YAML",
139+
},
140+
BodyFile: &bodyFile,
141+
}},
142+
}, received[5])
143+
144+
// Imposter 7
145+
assert.EqualValues(t, Imposter{
146+
BasePath: "test/testdata/imposters",
147+
Path: "test_request.imp.yml",
148+
Request: Request{},
149+
}, received[6])
150+
151+
// Finally, once the search is done,
152+
// the channel must be closed.
153+
_, open := <-ch
154+
require.False(t, open)
155+
}
156+
25157
func TestResponses_MarshalJSON(t *testing.T) {
26158
tcs := map[string]struct {
27159
rr *Responses

internal/server/http/route_matchers.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func validateSchema(imposter Imposter, req *http.Request) error {
5555
return fmt.Errorf("unexpected empty body request")
5656
}
5757

58-
schemaFilePath, _ := filepath.Abs(schemaFile)
58+
schemaFilePath, err := filepath.Abs(schemaFile)
5959
if err != nil {
6060
return fmt.Errorf("%w: impossible find the schema", err)
6161
}

internal/server/http/server.go

+8-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"crypto/tls"
66
_ "embed"
7+
"errors"
78
"log"
89
"net/http"
910

@@ -86,23 +87,19 @@ func (s *Server) Build() error {
8687
}
8788

8889
var impostersCh = make(chan []Imposter)
89-
var done = make(chan struct{})
9090

9191
go func() {
9292
s.imposterFs.FindImposters(impostersCh)
93-
done <- struct{}{}
9493
}()
9594
loop:
9695
for {
97-
select {
98-
case imposters := <-impostersCh:
99-
s.addImposterHandler(imposters)
100-
log.Printf("imposter %s loaded\n", imposters[0].Path)
101-
case <-done:
102-
close(impostersCh)
103-
close(done)
96+
imposters, ok := <-impostersCh
97+
if !ok {
10498
break loop
10599
}
100+
101+
s.addImposterHandler(imposters)
102+
log.Printf("imposter %s loaded\n", imposters[0].Path)
106103
}
107104
if s.proxy.mode == killgrave.ProxyMissing {
108105
s.router.NotFoundHandler = s.proxy.Handler()
@@ -120,7 +117,7 @@ func (s *Server) Run() {
120117
}
121118
log.Printf("The fake server is on tap now: %s%s\n", s.httpServer.Addr, tlsString)
122119
err := s.run(s.secure)
123-
if err != http.ErrServerClosed {
120+
if !errors.Is(err, http.ErrServerClosed) {
124121
log.Fatal(err)
125122
}
126123
}()
@@ -143,7 +140,7 @@ func (s *Server) run(secure bool) error {
143140
return s.httpServer.ListenAndServeTLS("", "")
144141
}
145142

146-
// Shutdown shutdown the current http server
143+
// Shutdown shutdowns the current http server
147144
func (s *Server) Shutdown() error {
148145
log.Println("stopping server...")
149146
if err := s.httpServer.Shutdown(context.TODO()); err != nil {

0 commit comments

Comments
 (0)