Skip to content

Commit

Permalink
Capture response body in Results
Browse files Browse the repository at this point in the history
Fixes #279
  • Loading branch information
tsenart committed May 18, 2018
1 parent da7a2c6 commit 2da25b2
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
6 changes: 2 additions & 4 deletions lib/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package vegeta
import (
"crypto/tls"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
Expand Down Expand Up @@ -263,11 +262,10 @@ func (a *Attacker) hit(tr Targeter, tm time.Time) *Result {
}
defer r.Body.Close()

in, err := io.Copy(ioutil.Discard, r.Body)
if err != nil {
if res.Body, err = ioutil.ReadAll(r.Body); err != nil {
return &res
}
res.BytesIn = uint64(in)
res.BytesIn = uint64(len(res.Body))

if req.ContentLength != -1 {
res.BytesOut = uint64(req.ContentLength)
Expand Down
19 changes: 19 additions & 0 deletions lib/attack_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package vegeta

import (
"bytes"
"crypto/tls"
"fmt"
"io"
Expand Down Expand Up @@ -184,3 +185,21 @@ func TestBadTargeterError(t *testing.T) {
t.Fatalf("got: %v, want: %v", got, want)
}
}

func TestResponseBodyCapture(t *testing.T) {
t.Parallel()

want := []byte("VEGETA")
server := httptest.NewServer(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(want)
}),
)
defer server.Close()
atk := NewAttacker()
tr := NewStaticTargeter(Target{Method: "GET", URL: server.URL})
res := atk.hit(tr, time.Now())
if got := res.Body; !bytes.Equal(got, want) {
t.Fatalf("got: %v, want: %v", got, want)
}
}
8 changes: 7 additions & 1 deletion lib/results.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package vegeta

import (
"bytes"
"encoding/base64"
"encoding/csv"
"encoding/gob"
"encoding/json"
Expand All @@ -22,6 +24,7 @@ type Result struct {
BytesOut uint64 `json:"bytes_out"`
BytesIn uint64 `json:"bytes_in"`
Error string `json:"error"`
Body []byte `json:"body"`
}

// End returns the time at which a Result ended.
Expand All @@ -34,7 +37,8 @@ func (r Result) Equal(other Result) bool {
r.Latency == other.Latency &&
r.BytesIn == other.BytesIn &&
r.BytesOut == other.BytesOut &&
r.Error == other.Error
r.Error == other.Error &&
bytes.Equal(r.Body, other.Body)
}

// Results is a slice of Result type elements.
Expand Down Expand Up @@ -110,6 +114,7 @@ func NewCSVEncoder(w io.Writer) Encoder {
strconv.FormatUint(r.BytesOut, 10),
strconv.FormatUint(r.BytesIn, 10),
r.Error,
base64.StdEncoding.EncodeToString(r.Body),
})

if err != nil {
Expand Down Expand Up @@ -158,6 +163,7 @@ func NewCSVDecoder(rd io.Reader) Decoder {
}

r.Error = rec[5]
r.Body, err = base64.StdEncoding.DecodeString(rec[6])

return err
}
Expand Down
3 changes: 2 additions & 1 deletion lib/results_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,15 @@ func TestEncoding(t *testing.T) {
var buf bytes.Buffer
enc := tc.enc(&buf)
dec := tc.dec(&buf)
err := quick.Check(func(code uint16, ts uint32, latency time.Duration, bsIn, bsOut uint64, e string) bool {
err := quick.Check(func(code uint16, ts uint32, latency time.Duration, bsIn, bsOut uint64, body []byte, e string) bool {
want := Result{
Code: code,
Timestamp: time.Unix(int64(ts), 0),
Latency: latency,
BytesIn: bsIn,
BytesOut: bsOut,
Error: e,
Body: body,
}

if err := enc(&want); err != nil {
Expand Down

0 comments on commit 2da25b2

Please sign in to comment.