Skip to content

Commit 77dfc2f

Browse files
committed
Add string representation of Direction.
Allow to print Direction in human form. Extract Direction struct to a separate file. Add tests to cover Direction to string. Parse direction from string with a new method stream.ParseDirection. It returns direction or error if could not parse.
1 parent 29685f4 commit 77dfc2f

File tree

6 files changed

+107
-19
lines changed

6 files changed

+107
-19
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* Add TimeoutHandler for the HTTP API server. (#420, @miry)
88
* Set Write and Read timeouts for HTTP API server connections. (#423, @miry)
99
* Show uniq request id in API HTTP response. (#425, @miry)
10+
* Add method to parse `stream.Direction` from string.
11+
Allow to convert `stream.Direction` to string. (#430, @miry)
1012

1113
# [2.4.0] - 2022-03-07
1214

link.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,5 @@ func (link *ToxicLink) RemoveToxic(toxic *toxics.ToxicWrapper) {
241241

242242
// Direction returns the direction of the link (upstream or downstream).
243243
func (link *ToxicLink) Direction() string {
244-
if link.direction == stream.Upstream {
245-
return "upstream"
246-
}
247-
return "downstream"
244+
return link.direction.String()
248245
}

stream/direction.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package stream
2+
3+
import (
4+
"errors"
5+
"strings"
6+
)
7+
8+
type Direction uint8
9+
10+
var ErrInvalidDirectionParameter error = errors.New("stream: invalid direction")
11+
12+
const (
13+
Upstream Direction = iota
14+
Downstream
15+
NumDirections
16+
)
17+
18+
func (d Direction) String() string {
19+
if d >= NumDirections {
20+
return "num_directions"
21+
}
22+
return [...]string{"upstream", "downstream"}[d]
23+
}
24+
25+
func ParseDirection(value string) (Direction, error) {
26+
switch strings.ToLower(value) {
27+
case "downstream":
28+
return Downstream, nil
29+
case "upstream":
30+
return Upstream, nil
31+
}
32+
33+
return NumDirections, ErrInvalidDirectionParameter
34+
}

stream/direction_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package stream_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/Shopify/toxiproxy/v2/stream"
7+
)
8+
9+
func TestDirection_String(t *testing.T) {
10+
testCases := []struct {
11+
name string
12+
direction stream.Direction
13+
expected string
14+
}{
15+
{"Downstream to string", stream.Downstream, "downstream"},
16+
{"Upstream to string", stream.Upstream, "upstream"},
17+
{"NumDirections to string", stream.NumDirections, "num_directions"},
18+
{"Upstream via number direction to string", stream.Direction(0), "upstream"},
19+
{"Downstream via number direction to string", stream.Direction(1), "downstream"},
20+
{"High number direction to string", stream.Direction(5), "num_directions"},
21+
}
22+
23+
for _, tc := range testCases {
24+
tc := tc // capture range variable
25+
t.Run(tc.name, func(t *testing.T) {
26+
t.Parallel()
27+
28+
actual := tc.direction.String()
29+
if actual != tc.expected {
30+
t.Errorf("got \"%s\"; expected \"%s\"", actual, tc.expected)
31+
}
32+
})
33+
}
34+
}
35+
36+
func TestParseDirection(t *testing.T) {
37+
testCases := []struct {
38+
name string
39+
input string
40+
expected stream.Direction
41+
err error
42+
}{
43+
{"parse empty", "", stream.NumDirections, stream.ErrInvalidDirectionParameter},
44+
{"parse upstream", "upstream", stream.Upstream, nil},
45+
{"parse downstream", "downstream", stream.Downstream, nil},
46+
{"parse unknown", "unknown", stream.NumDirections, stream.ErrInvalidDirectionParameter},
47+
{"parse number", "-123", stream.NumDirections, stream.ErrInvalidDirectionParameter},
48+
{"parse upper case", "DOWNSTREAM", stream.Downstream, nil},
49+
{"parse camel case", "UpStream", stream.Upstream, nil},
50+
}
51+
52+
for _, tc := range testCases {
53+
tc := tc // capture range variable
54+
t.Run(tc.name, func(t *testing.T) {
55+
t.Parallel()
56+
57+
actual, err := stream.ParseDirection(tc.input)
58+
if actual != tc.expected {
59+
t.Errorf("got \"%s\"; expected \"%s\"", actual, tc.expected)
60+
}
61+
62+
if err != tc.err {
63+
t.Errorf("got \"%s\"; expected \"%s\"", err, tc.err)
64+
}
65+
})
66+
}
67+
}

stream/io_chan.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@ import (
66
"time"
77
)
88

9-
type Direction uint8
10-
11-
const (
12-
Upstream Direction = iota
13-
Downstream
14-
NumDirections
15-
)
16-
179
// Stores a slice of bytes with its receive timestamp.
1810
type StreamChunk struct {
1911
Data []byte

toxic_collection.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"encoding/json"
66
"fmt"
77
"io"
8-
"strings"
98
"sync"
109

1110
"github.com/rs/zerolog"
@@ -98,14 +97,11 @@ func (c *ToxicCollection) AddToxicJson(data io.Reader) (*toxics.ToxicWrapper, er
9897
return nil, joinError(err, ErrBadRequestBody)
9998
}
10099

101-
switch strings.ToLower(wrapper.Stream) {
102-
case "downstream":
103-
wrapper.Direction = stream.Downstream
104-
case "upstream":
105-
wrapper.Direction = stream.Upstream
106-
default:
100+
wrapper.Direction, err = stream.ParseDirection(wrapper.Stream)
101+
if err != nil {
107102
return nil, ErrInvalidStream
108103
}
104+
109105
if wrapper.Name == "" {
110106
wrapper.Name = fmt.Sprintf("%s_%s", wrapper.Type, wrapper.Stream)
111107
}

0 commit comments

Comments
 (0)