From 126957c599484be7f25dfb9b62854093ffcd918a Mon Sep 17 00:00:00 2001 From: Jakub Holy Date: Thu, 30 Jul 2015 10:15:56 +0200 Subject: [PATCH 01/13] Readme: Explain when `--stats` needs to be included It isn't intuitive that when I specify e.g. `--output-http-stats`, it isn't enough and I need to explicitly enable also `--stats` (and that `--stats` on its own does not do anything, you need other flags to specify what to output) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3ffb38d..f4a1316 100644 --- a/README.md +++ b/README.md @@ -303,14 +303,14 @@ https://github.com/buger/gor/releases -output-http-elasticsearch="": Send request and response stats to ElasticSearch: gor --input-raw :8080 --output-http staging.com --output-http-elasticsearch 'es_host:api_port/index_name' -output-http-header-filter=[]: WARNING: `--output-http-header-filter` DEPRECATED, use `--http-allow-header` instead -output-http-redirects=0: Enable how often redirects should be followed. - -output-http-stats=false: Report http output queue stats to console every 5 seconds. + -output-http-stats=false: Report http output queue stats to console every 5 seconds. Remember to include also `--stats` -output-http-workers=0: Gor uses dynamic worker scaling by default. Enter a number to run a set number of workers. -output-tcp=[]: Used for internal communication between Gor instances. Example: # Listen for requests on 80 port and forward them to other Gor instance on 28020 port gor --input-raw :80 --output-tcp replay.local:28020 - -output-tcp-stats=false: Report TCP output queue stats to console every 5 seconds. + -output-tcp-stats=false: Report TCP output queue stats to console every 5 seconds. Remember to include also `--stats` -split-output=false: By default each output gets same traffic. If set to `true` it splits traffic equally among all outputs. - -stats=false: Turn on queue stats output + -stats=false: Turn on queue stats output. Use in combination with the other *-stats flags. -verbose=false: Turn on verbose/debug output ``` From 27f83a6c0cecfcb814a78da4dcce8a1c8b4d19fb Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Fri, 31 Jul 2015 21:08:35 +0300 Subject: [PATCH 02/13] Improve debugging --- .gitignore | 2 ++ Makefile | 10 ++++++++-- settings.go | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 9d54abc..c59f5ba 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *.gor *.out + +*.bin diff --git a/Makefile b/Makefile index 4e4a814..3450a9b 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,13 @@ dbench: # Used mainly for debugging, because docker container do not have access to parent machine ports drun: - docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-dummy=0 --output-http="http://localhost:9000" --verbose -h + docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-dummy=0 --output-http="http://localhost:9000" --verbose -dbash: +drecord: + docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-dummy=0 --output-file=requests.bin --verbose + +dreplay: + docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-file=requests.bin --output-tcp=:9000 --verbose -h + +dbash: docker run -v `pwd`:$(SOURCE_PATH) -t -i gor /bin/bash \ No newline at end of file diff --git a/settings.go b/settings.go index dbf7146..8bcc7c9 100644 --- a/settings.go +++ b/settings.go @@ -122,7 +122,7 @@ func init() { // Debug gets called only if --verbose flag specified func Debug(args ...interface{}) { if Settings.verbose { - fmt.Print("[DEBUG] ") + fmt.Printf("[DEBUG][PID %d] ", os.Getpid()) log.Println(args...) } } From a79e54c5f11c099ddc15550a56c35a615109bc10 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Fri, 31 Jul 2015 21:41:06 +0300 Subject: [PATCH 03/13] Do not set http header if it explicitly set --- Makefile | 2 +- http_client.go | 5 ++++- output_file.go | 1 - output_http.go | 3 +++ output_http_test.go | 34 +++++++++++++++++++++++++++++++++ plugins.go | 9 +++++++++ raw_socket_listener/listener.go | 4 ++-- 7 files changed, 53 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 3450a9b..d951930 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ drace: docker run -v `pwd`:$(SOURCE_PATH) -t -i --env GORACE="halt_on_error=1" gor go test ./... $(ARGS) -v -race -timeout 15s dtest: - docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go test ./... $(ARGS) -v -timeout 5s + docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go test ./... $(ARGS) -v -timeout 10s dcover: docker run -v `pwd`:$(SOURCE_PATH) -t -i --env GORACE="halt_on_error=1" gor go test $(ARGS) -race -v -timeout 15s -coverprofile=coverage.out diff --git a/http_client.go b/http_client.go index f9ad04d..ea89811 100644 --- a/http_client.go +++ b/http_client.go @@ -20,6 +20,7 @@ var defaultPorts = map[string]string{ type HTTPClientConfig struct { FollowRedirects int Debug bool + OriginalHost bool } type HTTPClient struct { @@ -115,7 +116,9 @@ func (c *HTTPClient) Send(data []byte) (response []byte, err error) { c.conn.SetWriteDeadline(timeout) - data = proto.SetHost(data, []byte(c.baseURL), []byte(c.host)) + if !c.config.OriginalHost { + data = proto.SetHost(data, []byte(c.baseURL), []byte(c.host)) + } if c.config.Debug { Debug("[HTTPClient] Sending:", string(data)) diff --git a/output_file.go b/output_file.go index 4f5be15..f6a81ae 100644 --- a/output_file.go +++ b/output_file.go @@ -21,7 +21,6 @@ type FileOutput struct { file *os.File } - // NewFileOutput constructor for FileOutput, accepts path func NewFileOutput(path string) io.Writer { o := new(FileOutput) diff --git a/output_http.go b/output_http.go index eb3e925..907fc28 100644 --- a/output_http.go +++ b/output_http.go @@ -18,6 +18,8 @@ type HTTPOutputConfig struct { elasticSearch string + OriginalHost bool + Debug bool } @@ -94,6 +96,7 @@ func (o *HTTPOutput) startWorker() { client := NewHTTPClient(o.address, &HTTPClientConfig{ FollowRedirects: o.config.redirectLimit, Debug: o.config.Debug, + OriginalHost: o.config.OriginalHost, }) deathCount := 0 diff --git a/output_http_test.go b/output_http_test.go index 16f8422..3d32734 100644 --- a/output_http_test.go +++ b/output_http_test.go @@ -76,6 +76,40 @@ func TestHTTPOutput(t *testing.T) { Settings.modifierConfig = HTTPModifierConfig{} } +func TestHTTPOutputKeepOriginalHost(t *testing.T) { + wg := new(sync.WaitGroup) + quit := make(chan int) + + input := NewTestInput() + + listener := startHTTP(func(req *http.Request) { + if req.Host != "custom-host.com" { + t.Error("Wrong header", req.Host) + } + + wg.Done() + }) + + headers := HTTPHeaders{HTTPHeader{"Host", "custom-host.com"}} + Settings.modifierConfig = HTTPModifierConfig{headers: headers} + + output := NewHTTPOutput(listener.Addr().String(), &HTTPOutputConfig{Debug: false, OriginalHost: true}) + + Plugins.Inputs = []io.Reader{input} + Plugins.Outputs = []io.Writer{output} + + go Start(quit) + + wg.Add(1) + input.EmitGET() + + wg.Wait() + + close(quit) + + Settings.modifierConfig = HTTPModifierConfig{} +} + func TestOutputHTTPSSL(t *testing.T) { wg := new(sync.WaitGroup) quit := make(chan int) diff --git a/plugins.go b/plugins.go index d47012b..cb189a4 100644 --- a/plugins.go +++ b/plugins.go @@ -98,6 +98,15 @@ func InitPlugins() { registerPlugin(NewHTTPInput, options) } + // If we explicitly set Host header http output should not rewrite it + // Fix: https://github.com/buger/gor/issues/174 + for _, header := range Settings.modifierConfig.headers { + if header.Name == "Host" { + Settings.outputHTTPConfig.OriginalHost = true + break + } + } + for _, options := range Settings.outputHTTP { registerPlugin(NewHTTPOutput, options, &Settings.outputHTTPConfig) } diff --git a/raw_socket_listener/listener.go b/raw_socket_listener/listener.go index 280e288..f82ae6f 100644 --- a/raw_socket_listener/listener.go +++ b/raw_socket_listener/listener.go @@ -27,12 +27,12 @@ type Listener struct { // Expect: 100-continue request is send in 2 tcp messages // We store ACK aliases to merge this packets together - ackAliases map[uint32]uint32 + ackAliases map[uint32]uint32 // To get ACK of second message we need to compute its Seq and wait for them message seqWithData map[uint32]uint32 // Messages ready to be send to client - packetsChan chan *TCPPacket + packetsChan chan *TCPPacket // Messages ready to be send to client messagesChan chan *TCPMessage From 083c97a9c407d4235d784c9925ce5f027ee027f4 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Fri, 31 Jul 2015 22:39:01 +0300 Subject: [PATCH 04/13] Option to configure timeout --- http_client.go | 7 ++++++- output_http.go | 2 ++ settings.go | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/http_client.go b/http_client.go index ea89811..f9ab412 100644 --- a/http_client.go +++ b/http_client.go @@ -21,6 +21,7 @@ type HTTPClientConfig struct { FollowRedirects int Debug bool OriginalHost bool + Timeout time.Duration } type HTTPClient struct { @@ -43,6 +44,10 @@ func NewHTTPClient(baseURL string, config *HTTPClientConfig) *HTTPClient { u.Host += ":" + defaultPorts[u.Scheme] } + if config.Timeout.Nanoseconds() == 0 { + config.Timeout = 5 * time.Second + } + client := new(HTTPClient) client.baseURL = u.String() client.host = u.Host @@ -112,7 +117,7 @@ func (c *HTTPClient) Send(data []byte) (response []byte, err error) { } } - timeout := time.Now().Add(5 * time.Second) + timeout := time.Now().Add(c.config.Timeout) c.conn.SetWriteDeadline(timeout) diff --git a/output_http.go b/output_http.go index 907fc28..2908b2e 100644 --- a/output_http.go +++ b/output_http.go @@ -18,6 +18,7 @@ type HTTPOutputConfig struct { elasticSearch string + Timeout time.Duration OriginalHost bool Debug bool @@ -97,6 +98,7 @@ func (o *HTTPOutput) startWorker() { FollowRedirects: o.config.redirectLimit, Debug: o.config.Debug, OriginalHost: o.config.OriginalHost, + Timeout: o.config.Timeout, }) deathCount := 0 diff --git a/settings.go b/settings.go index 8bcc7c9..dd2a000 100644 --- a/settings.go +++ b/settings.go @@ -87,6 +87,7 @@ func init() { flag.Var(&Settings.outputHTTP, "output-http", "Forwards incoming requests to given http address.\n\t# Redirect all incoming requests to staging.com address \n\tgor --input-raw :80 --output-http http://staging.com") flag.IntVar(&Settings.outputHTTPConfig.workers, "output-http-workers", 0, "Gor uses dynamic worker scaling by default. Enter a number to run a set number of workers.") flag.IntVar(&Settings.outputHTTPConfig.redirectLimit, "output-http-redirects", 0, "Enable how often redirects should be followed.") + flag.DurationVar(&Settings.outputHTTPConfig.Timeout, "output-http-timeout", 0, "Specify HTTP request/response timeout. By default 5s. Example: --output-http-timeout 30s") flag.BoolVar(&Settings.outputHTTPConfig.stats, "output-http-stats", false, "Report http output queue stats to console every 5 seconds.") From 587b9ad2d55ed88a0eeb4f09ba992e313a7aacc3 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Fri, 31 Jul 2015 22:41:32 +0300 Subject: [PATCH 05/13] Update Readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f4a1316..b544ee2 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,12 @@ gor --input-tcp replay.local:28020 --output-http http://staging.com --output-htt ``` The given example will follow up to 2 redirects per request. +### HTTP timeouts +By default http timeout for both request and response is 5 seconds. You can override it like this: +``` +gor --input-tcp replay.local:28020 --output-http http://staging.com --output-http-timeout 30s +``` + ### Rate limiting Rate limiting can be useful if you want forward only part of production traffic and not overload your staging environment. There is 2 strategies: dropping random requests or dropping fraction of requests based on Header or URL param value. From ed7c5210be46d027c207b6f238eac61484cb8be0 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Sat, 25 Jul 2015 18:25:11 +0000 Subject: [PATCH 06/13] Print warning if hex decoding fails --- input_tcp.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/input_tcp.go b/input_tcp.go index 9a2da90..47d2c3d 100644 --- a/input_tcp.go +++ b/input_tcp.go @@ -67,7 +67,10 @@ func (i *TCPInput) handleConnection(conn net.Conn) { encodedPayload := scanner.Bytes() // Hex encoding always 2x number of bytes decoded := make([]byte, len(encodedPayload)/2) - hex.Decode(decoded, encodedPayload) + _, err := hex.Decode(decoded, encodedPayload) + if err != nil { + log.Println("[TCPInput] failed to hex decode TCP payload:", err) + } i.data <- decoded } From 5c46db92207cc1684680afe91fb5e1e4d29f54df Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 30 Jul 2015 17:18:36 +0000 Subject: [PATCH 07/13] avoid trailing null in encoded tcp Fixes #175. --- output_tcp.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/output_tcp.go b/output_tcp.go index dd7cdc4..2656a25 100644 --- a/output_tcp.go +++ b/output_tcp.go @@ -60,7 +60,8 @@ func (o *TCPOutput) Write(data []byte) (n int, err error) { // Hex encoding always 2x number of bytes encoded := make([]byte, len(data)*2+1) hex.Encode(encoded, data) - o.buf <- append(encoded, '\n') + encoded[len(encoded)-1] = '\n' + o.buf <- encoded if Settings.outputTCPStats { o.bufStats.Write(len(o.buf)) From dd68d07c755ec70fbf2508264f285b857ba1963e Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Mon, 3 Aug 2015 18:01:46 +0300 Subject: [PATCH 08/13] Fix large responses --- http_client.go | 12 +++++++++++- http_client_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/http_client.go b/http_client.go index f9ab412..8c7948b 100644 --- a/http_client.go +++ b/http_client.go @@ -52,7 +52,7 @@ func NewHTTPClient(baseURL string, config *HTTPClientConfig) *HTTPClient { client.baseURL = u.String() client.host = u.Host client.scheme = u.Scheme - client.respBuf = make([]byte, 4096*10) + client.respBuf = make([]byte, 512*1024) // 500kb client.config = config return client @@ -137,6 +137,16 @@ func (c *HTTPClient) Send(data []byte) (response []byte, err error) { c.conn.SetReadDeadline(timeout) n, err := c.conn.Read(c.respBuf) + // If response large then our buffer, we need to read all reponse buffer + // Otherwise it will corrupt response of next request + // Parsing response body is non trivial thing, especially with keep-alive + // Simples case is to to close connection if response too large + // + // See https://github.com/buger/gor/issues/184 + if n == len(c.respBuf) { + c.Disconnect() + } + if err != nil { Debug("[HTTPClient] Response read error", err, c.conn) return diff --git a/http_client_test.go b/http_client_test.go index feb0326..93051b6 100644 --- a/http_client_test.go +++ b/http_client_test.go @@ -8,6 +8,8 @@ import ( "net/http/httputil" "sync" "testing" + "crypto/rand" + "bytes" _ "time" ) @@ -81,6 +83,36 @@ func TestHTTPClientSend(t *testing.T) { wg.Wait() } +// https://github.com/buger/gor/issues/184 +func TestHTTPClientResponseBuffer(t *testing.T) { + wg := new(sync.WaitGroup) + + payload := []byte("GET / HTTP/1.1\r\n\r\n") + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + size := 1 * 1024 * 1024 // 1 MB + rb := make([]byte, size) + rand.Read(rb) + + w.Write(rb) + + wg.Done() + })) + + client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: true}) + + wg.Add(2) + client.Send(payload) + resp, _ := client.Send(payload) + + if !bytes.Equal(resp[0:8], []byte("HTTP/1.1")) { + t.Error("Response buffer contains data from previous request", string(resp[0:5])) + } + + wg.Wait() +} + func TestHTTPClientHTTPSSend(t *testing.T) { wg := new(sync.WaitGroup) From 961d5a754cb684d37c0e5769ae4e5ee320401928 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Mon, 3 Aug 2015 18:08:35 +0300 Subject: [PATCH 09/13] Style fixes --- http_client.go | 4 ++-- http_client_test.go | 6 +++--- output_http.go | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/http_client.go b/http_client.go index 8c7948b..554642b 100644 --- a/http_client.go +++ b/http_client.go @@ -21,7 +21,7 @@ type HTTPClientConfig struct { FollowRedirects int Debug bool OriginalHost bool - Timeout time.Duration + Timeout time.Duration } type HTTPClient struct { @@ -137,7 +137,7 @@ func (c *HTTPClient) Send(data []byte) (response []byte, err error) { c.conn.SetReadDeadline(timeout) n, err := c.conn.Read(c.respBuf) - // If response large then our buffer, we need to read all reponse buffer + // If response large then our buffer, we need to read all response buffer // Otherwise it will corrupt response of next request // Parsing response body is non trivial thing, especially with keep-alive // Simples case is to to close connection if response too large diff --git a/http_client_test.go b/http_client_test.go index 93051b6..1aa0e51 100644 --- a/http_client_test.go +++ b/http_client_test.go @@ -1,6 +1,8 @@ package main import ( + "bytes" + "crypto/rand" "io/ioutil" "net" "net/http" @@ -8,8 +10,6 @@ import ( "net/http/httputil" "sync" "testing" - "crypto/rand" - "bytes" _ "time" ) @@ -100,7 +100,7 @@ func TestHTTPClientResponseBuffer(t *testing.T) { wg.Done() })) - client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: true}) + client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: false}) wg.Add(2) client.Send(payload) diff --git a/output_http.go b/output_http.go index 2908b2e..005ecd8 100644 --- a/output_http.go +++ b/output_http.go @@ -18,7 +18,7 @@ type HTTPOutputConfig struct { elasticSearch string - Timeout time.Duration + Timeout time.Duration OriginalHost bool Debug bool @@ -98,7 +98,7 @@ func (o *HTTPOutput) startWorker() { FollowRedirects: o.config.redirectLimit, Debug: o.config.Debug, OriginalHost: o.config.OriginalHost, - Timeout: o.config.Timeout, + Timeout: o.config.Timeout, }) deathCount := 0 From 3316447bf5ee1780f235dbe25f8a5ae9361b7465 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Mon, 3 Aug 2015 18:13:36 +0300 Subject: [PATCH 10/13] Verbose output for travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d491b84..63ecff5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: go go: 1.4.2 -script: sudo -E bash -c "source /etc/profile && eval '$(gimme 1.4.2)' && export GOPATH=$HOME/gopath:$GOPATH && go get && GORACE='halt_on_error=1' go test ./... -v -timeout 15s" \ No newline at end of file +script: sudo -E bash -c "source /etc/profile && eval '$(gimme 1.4.2)' && export GOPATH=$HOME/gopath:$GOPATH && go get && GORACE='halt_on_error=1' go test ./... -v -timeout 15s --verbose" \ No newline at end of file From f6864d05a0c9a495d211b77dcb6b61c6c2584e5e Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Mon, 3 Aug 2015 18:20:59 +0300 Subject: [PATCH 11/13] More debugging --- http_client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http_client.go b/http_client.go index 554642b..3b615f1 100644 --- a/http_client.go +++ b/http_client.go @@ -154,6 +154,8 @@ func (c *HTTPClient) Send(data []byte) (response []byte, err error) { payload := c.respBuf[:n] + Debug("[HTTPClient] Received:", n) + if c.config.Debug { Debug("[HTTPClient] Received:", string(payload)) } From f92a0b1242c7fc759276a8a348d7b71049e2c986 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Mon, 3 Aug 2015 18:31:09 +0300 Subject: [PATCH 12/13] Make buffer size configurable --- http_client.go | 7 ++++++- http_client_test.go | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/http_client.go b/http_client.go index 3b615f1..917c084 100644 --- a/http_client.go +++ b/http_client.go @@ -22,6 +22,7 @@ type HTTPClientConfig struct { Debug bool OriginalHost bool Timeout time.Duration + ResponseBufferSize int } type HTTPClient struct { @@ -48,11 +49,15 @@ func NewHTTPClient(baseURL string, config *HTTPClientConfig) *HTTPClient { config.Timeout = 5 * time.Second } + if config.ResponseBufferSize == 0 { + config.ResponseBufferSize = 512*1024 // 500kb + } + client := new(HTTPClient) client.baseURL = u.String() client.host = u.Host client.scheme = u.Scheme - client.respBuf = make([]byte, 512*1024) // 500kb + client.respBuf = make([]byte, config.ResponseBufferSize) client.config = config return client diff --git a/http_client_test.go b/http_client_test.go index 1aa0e51..d14d5be 100644 --- a/http_client_test.go +++ b/http_client_test.go @@ -91,7 +91,7 @@ func TestHTTPClientResponseBuffer(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - size := 1 * 1024 * 1024 // 1 MB + size := 10 * 1024 // 10kb rb := make([]byte, size) rand.Read(rb) @@ -100,7 +100,7 @@ func TestHTTPClientResponseBuffer(t *testing.T) { wg.Done() })) - client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: false}) + client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: false, ResponseBufferSize: 1024}) wg.Add(2) client.Send(payload) From ce193d0d4f1906c35ba311c6ba99e6f7610b79d8 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Mon, 3 Aug 2015 18:33:36 +0300 Subject: [PATCH 13/13] Fix travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 63ecff5..d491b84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: go go: 1.4.2 -script: sudo -E bash -c "source /etc/profile && eval '$(gimme 1.4.2)' && export GOPATH=$HOME/gopath:$GOPATH && go get && GORACE='halt_on_error=1' go test ./... -v -timeout 15s --verbose" \ No newline at end of file +script: sudo -E bash -c "source /etc/profile && eval '$(gimme 1.4.2)' && export GOPATH=$HOME/gopath:$GOPATH && go get && GORACE='halt_on_error=1' go test ./... -v -timeout 15s" \ No newline at end of file