Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle slicer Toxic with zero SizeVariation #359

Merged
merged 8 commits into from
Jan 26, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Fix MacOS 12 tests for go17 with -race flag (#351, @strech)
* Rename `testing/` and `bin/` folders (#354, @strech)
* Added verbose error on proxy upstream dialing (#355, @f-dg)
* Fixed bugs in slicer toxic `SizeVariation` behavior (#359, @areveny)

# [2.3.0] - 2021-12-23

Expand Down
5 changes: 4 additions & 1 deletion toxics/slicer.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ func (t *SlicerToxic) chunk(start int, end int) []int {
return []int{start, end}
}

mid := start + (end-start)/2
// +1 in the size variation to offset favoring of smaller
// numbers by integer division
//#nosec
areveny marked this conversation as resolved.
Show resolved Hide resolved
areveny marked this conversation as resolved.
Show resolved Hide resolved
mid := start + (end-start)/2 + (rand.Intn(t.SizeVariation*2) - t.SizeVariation) + rand.Intn(1)
if t.SizeVariation > 0 {
mid = mid + (rand.Intn(t.SizeVariation*2) - t.SizeVariation) + rand.Intn(2)
areveny marked this conversation as resolved.
Show resolved Hide resolved
}
left := t.chunk(start, mid)
right := t.chunk(mid, end)

Expand Down
48 changes: 48 additions & 0 deletions toxics/slicer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,51 @@ L:
t.Errorf("Server did not read correct buffer from client!")
}
}

func TestSlicerToxicZeroSizeVariation(t *testing.T) {
data := []byte(strings.Repeat("hello world ", 2)) // 24 bytes
// SizeVariation: 0 by default
slicer := &toxics.SlicerToxic{AverageSize: 1, Delay: 10}

input := make(chan *stream.StreamChunk)
output := make(chan *stream.StreamChunk)
stub := toxics.NewToxicStub(input, output)

done := make(chan bool)
go func() {
slicer.Pipe(stub)
done <- true
}()
defer func() {
close(input)
for {
select {
case <-done:
return
case <-output:
}
}
}()

input <- &stream.StreamChunk{Data: data}

buf := make([]byte, 0, len(data))
reads := 0
L:
areveny marked this conversation as resolved.
Show resolved Hide resolved
for {
select {
case c := <-output:
reads++
buf = append(buf, c.Data...)
case <-time.After(10 * time.Millisecond):
break L
}
}

if reads != 24 {
t.Errorf("Expected to read 24 times, but read %d times.", reads)
}
if !bytes.Equal(buf, data) {
t.Errorf("Server did not read correct buffer from client!")
}
}