From 32c7555eb2a5ed08f93625be3a579da91dc4f097 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Tue, 28 Jun 2022 02:32:11 +0530 Subject: [PATCH 01/18] Added http status code toxic Signed-off-by: Akash Shrivastava --- toxics/httputils/body.go | 60 +++++++++++++++++++++++++++++++++ toxics/httputils/status_code.go | 59 ++++++++++++++++++++++++++++++++ toxics/limit_data_test.go | 3 +- toxics/status_code.go | 54 +++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 toxics/httputils/body.go create mode 100644 toxics/httputils/status_code.go create mode 100644 toxics/status_code.go diff --git a/toxics/httputils/body.go b/toxics/httputils/body.go new file mode 100644 index 00000000..eceb1f42 --- /dev/null +++ b/toxics/httputils/body.go @@ -0,0 +1,60 @@ +package httputils + +import ( + "io/ioutil" + "net/http" + "strings" +) + +const ( + // 3xx pages + status301 = "301 Moved Permanently

301 Moved Permanently

" + status302 = "302 Found

302 Found

" + status304 = "304 Not Modified

304 Not Modified

" + // 4xx error pages + status400 = "400 Bad Request

400 Bad Request


" + status401 = "401 Unauthorized

401 Unauthorized


" + status403 = "403 Forbidden

403 Forbidden


" + status404 = "404 Not Found

404 Not Found


" + // 5xx error pages + status500 = "500 Internal Server Error

500 Internal Server Error

" + status501 = "501 Not Implemented

501 Not Implemented

" + status502 = "502 Bad Gateway

502 Bad Gateway

" + status503 = "503 Service Unavailable

503 Service Unavailable

" + status504 = "504 Gateway Timeout

504 Gateway Timeout

" +) + +func SetErrorResponseBody(r *http.Response, statusCode int) { + switch statusCode { + case 301: + SetResponseBody(r, status301) + case 302: + SetResponseBody(r, status302) + case 304: + SetResponseBody(r, status304) + case 400: + SetResponseBody(r, status400) + case 401: + SetResponseBody(r, status401) + case 403: + SetResponseBody(r, status403) + case 404: + SetResponseBody(r, status404) + case 500: + SetResponseBody(r, status500) + case 501: + SetResponseBody(r, status501) + case 502: + SetResponseBody(r, status502) + case 503: + SetResponseBody(r, status503) + case 504: + SetResponseBody(r, status504) + default: + } +} + +func SetResponseBody(r *http.Response, body string) { + r.Body = ioutil.NopCloser(strings.NewReader(body)) + r.ContentLength = int64(len(body)) +} diff --git a/toxics/httputils/status_code.go b/toxics/httputils/status_code.go new file mode 100644 index 00000000..ab653f46 --- /dev/null +++ b/toxics/httputils/status_code.go @@ -0,0 +1,59 @@ +package httputils + +import "net/http" + +// SetHttpStatusCode sets the status code of the response +func SetHttpStatusCode(r *http.Response, statusCode int) { + switch statusCode { + case 200: + r.StatusCode = 200 + r.Status = "200 OK" + case 201: + r.StatusCode = 201 + r.Status = "201 Created" + case 202: + r.StatusCode = 202 + r.Status = "202 Accepted" + case 204: + r.StatusCode = 204 + r.Status = "204 No Content" + case 301: + r.StatusCode = 301 + r.Status = "301 Moved Permanently" + case 302: + r.StatusCode = 302 + r.Status = "302 Found" + case 304: + r.StatusCode = 304 + r.Status = "304 Not Modified" + case 400: + r.StatusCode = 400 + r.Status = "400 Bad Request" + case 401: + r.StatusCode = 401 + r.Status = "401 Unauthorized" + case 403: + r.StatusCode = 403 + r.Status = "403 Forbidden" + case 404: + r.StatusCode = 404 + r.Status = "404 Not Found" + case 500: + r.StatusCode = 500 + r.Status = "500 Internal Server Error" + case 501: + r.StatusCode = 501 + r.Status = "501 Not Implemented" + case 502: + r.StatusCode = 502 + r.Status = "502 Bad Gateway" + case 503: + r.StatusCode = 503 + r.Status = "503 Service Unavailable" + case 504: + r.StatusCode = 504 + r.Status = "504 Gateway Timeout" + default: + // if the status code is not recognized, do not change it + } +} diff --git a/toxics/limit_data_test.go b/toxics/limit_data_test.go index 201c9f97..881d4ca4 100644 --- a/toxics/limit_data_test.go +++ b/toxics/limit_data_test.go @@ -3,7 +3,6 @@ package toxics_test import ( "bytes" "crypto/rand" - "fmt" "testing" "github.com/Shopify/toxiproxy/v2/stream" @@ -26,7 +25,7 @@ func checkOutgoingChunk(t *testing.T, output chan *stream.StreamChunk, expected func checkRemainingChunks(t *testing.T, output chan *stream.StreamChunk) { if len(output) != 0 { - t.Error(fmt.Sprintf("There is %d chunks in output channel. 0 is expected.", len(output))) + t.Errorf("There is %d chunks in output channel. 0 is expected.", len(output)) } } diff --git a/toxics/status_code.go b/toxics/status_code.go new file mode 100644 index 00000000..a9f2585b --- /dev/null +++ b/toxics/status_code.go @@ -0,0 +1,54 @@ +package toxics + +import ( + "bufio" + "bytes" + "io" + "net/http" + + "github.com/Shopify/toxiproxy/v2/stream" + "github.com/Shopify/toxiproxy/v2/toxics/httputils" +) + +type StatusCodeToxic struct { + StatusCode int `json:"status_code"` + ModifyResponseBody bool `json:"modify_response_body"` +} + +func (t *StatusCodeToxic) ModifyResponseCode(resp *http.Response) { + httputils.SetHttpStatusCode(resp, t.StatusCode) + + if t.ModifyResponseBody { + httputils.SetErrorResponseBody(resp, t.StatusCode) + } +} + +func (t *StatusCodeToxic) Pipe(stub *ToxicStub) { + buffer := bytes.NewBuffer(make([]byte, 0, 32*1024)) + writer := stream.NewChanWriter(stub.Output) + reader := stream.NewChanReader(stub.Input) + reader.SetInterrupt(stub.Interrupt) + for { + tee := io.TeeReader(reader, buffer) + resp, err := http.ReadResponse(bufio.NewReader(tee), nil) + + if err == stream.ErrInterrupted { + buffer.WriteTo(writer) + return + } else if err == io.EOF { + stub.Close() + return + } + if err != nil { + buffer.WriteTo(writer) + } else { + t.ModifyResponseCode(resp) + resp.Write(writer) + } + buffer.Reset() + } +} + +func init() { + Register("status_code", new(StatusCodeToxic)) +} From f44737ef2f93431b71eaa8f3474ab85084b3261e Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Tue, 28 Jun 2022 20:09:27 +0530 Subject: [PATCH 02/18] Added test for status code toxic Signed-off-by: Akash Shrivastava --- toxics/status_code_test.go | 147 +++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 toxics/status_code_test.go diff --git a/toxics/status_code_test.go b/toxics/status_code_test.go new file mode 100644 index 00000000..722c1ec6 --- /dev/null +++ b/toxics/status_code_test.go @@ -0,0 +1,147 @@ +package toxics_test + +import ( + "bytes" + "io/ioutil" + "net" + "net/http" + "testing" + + "github.com/Shopify/toxiproxy/v2/toxics" + "github.com/Shopify/toxiproxy/v2/toxics/httputils" +) + +func echoHelloWorld(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Hello World")) +} + +func TestToxicModifiesHTTPStatusCode(t *testing.T) { + http.HandleFunc("/", echoHelloWorld) + + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal("Failed to create TCP server", err) + } + + go http.Serve(ln, nil) + defer ln.Close() + + proxy := NewTestProxy("test", ln.Addr().String()) + proxy.Start() + defer proxy.Stop() + + resp, err := http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + AssertStatusCodeNotEqual(t, resp.StatusCode, 500) + + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: false})) + + resp, err = http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + AssertStatusCodeEqual(t, resp.StatusCode, 500) +} + +func TestToxicModifiesBodyWithStatusCode(t *testing.T) { + http.HandleFunc("/", echoHelloWorld) + + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal("Failed to create TCP server", err) + } + + go http.Serve(ln, nil) + defer ln.Close() + + proxy := NewTestProxy("test", ln.Addr().String()) + proxy.Start() + defer proxy.Stop() + + resp, err := http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ := ioutil.ReadAll(resp.Body) + + AssertStatusCodeNotEqual(t, resp.StatusCode, 500) + AssertBodyNotEqual(t, body, []byte(httputils.Status500)) + + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: true})) + + resp, err = http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ = ioutil.ReadAll(resp.Body) + + AssertStatusCodeEqual(t, resp.StatusCode, 500) + AssertBodyEqual(t, body, []byte(httputils.Status500)) + +} + +func TestUnsupportedStatusCode(t *testing.T) { + http.HandleFunc("/", echoHelloWorld) + + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal("Failed to create TCP server", err) + } + + go http.Serve(ln, nil) + defer ln.Close() + + proxy := NewTestProxy("test", ln.Addr().String()) + proxy.Start() + defer proxy.Stop() + + resp, err := http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + statusCode := resp.StatusCode + initialBody, _ := ioutil.ReadAll(resp.Body) + + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 1000, ModifyResponseBody: true})) + + resp, err = http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ := ioutil.ReadAll(resp.Body) + + AssertStatusCodeEqual(t, resp.StatusCode, statusCode) + AssertBodyEqual(t, body, initialBody) + +} + +func AssertStatusCodeEqual(t *testing.T, respStatusCode, expectedStatusCode int) { + if respStatusCode != expectedStatusCode { + t.Errorf("Response status code {%v} not equal to expected status code {%v}.", respStatusCode, expectedStatusCode) + } +} + +func AssertStatusCodeNotEqual(t *testing.T, respStatusCode, expectedStatusCode int) { + if respStatusCode == expectedStatusCode { + t.Errorf("Response status code {%v} equal to expected status code {%v}.", respStatusCode, expectedStatusCode) + } +} + +func AssertBodyEqual(t *testing.T, respBody, expectedBody []byte) { + if !bytes.Equal(respBody, expectedBody) { + t.Errorf("Response body {%v} not equal to expected body {%v}.", string(respBody), string(expectedBody)) + } +} + +func AssertBodyNotEqual(t *testing.T, respBody, expectedBody []byte) { + if bytes.Equal(respBody, expectedBody) { + t.Errorf("Response body {%v} equal to expected body {%v}.", string(respBody), string(expectedBody)) + } +} From c2dd0d8c02bcfd97de38819e72fdef9f4a794fa8 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Tue, 28 Jun 2022 20:18:16 +0530 Subject: [PATCH 03/18] Added modify body toxic; Added 2xx body template Signed-off-by: Akash Shrivastava --- toxics/httputils/body.go | 61 +++++++++++++++++++++++--------------- toxics/modify_body.go | 49 ++++++++++++++++++++++++++++++ toxics/modify_body_test.go | 48 ++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 24 deletions(-) create mode 100644 toxics/modify_body.go create mode 100644 toxics/modify_body_test.go diff --git a/toxics/httputils/body.go b/toxics/httputils/body.go index eceb1f42..43ffb04c 100644 --- a/toxics/httputils/body.go +++ b/toxics/httputils/body.go @@ -7,49 +7,62 @@ import ( ) const ( + // 2xx pages + Status200 = "200 Status OK

200 Status OK

" + Status201 = "201 Created

301 Moved Permanently

" + Status202 = "202 Accepted

202 Accepted

" + Status204 = "204 No Content

204 No Content

" // 3xx pages - status301 = "301 Moved Permanently

301 Moved Permanently

" - status302 = "302 Found

302 Found

" - status304 = "304 Not Modified

304 Not Modified

" + Status301 = "301 Moved Permanently

301 Moved Permanently

" + Status302 = "302 Found

302 Found

" + Status304 = "304 Not Modified

304 Not Modified

" // 4xx error pages - status400 = "400 Bad Request

400 Bad Request


" - status401 = "401 Unauthorized

401 Unauthorized


" - status403 = "403 Forbidden

403 Forbidden


" - status404 = "404 Not Found

404 Not Found


" + Status400 = "400 Bad Request

400 Bad Request


" + Status401 = "401 Unauthorized

401 Unauthorized


" + Status403 = "403 Forbidden

403 Forbidden


" + Status404 = "404 Not Found

404 Not Found


" // 5xx error pages - status500 = "500 Internal Server Error

500 Internal Server Error

" - status501 = "501 Not Implemented

501 Not Implemented

" - status502 = "502 Bad Gateway

502 Bad Gateway

" - status503 = "503 Service Unavailable

503 Service Unavailable

" - status504 = "504 Gateway Timeout

504 Gateway Timeout

" + Status500 = "500 Internal Server Error

500 Internal Server Error

" + Status501 = "501 Not Implemented

501 Not Implemented

" + Status502 = "502 Bad Gateway

502 Bad Gateway

" + Status503 = "503 Service Unavailable

503 Service Unavailable

" + Status504 = "504 Gateway Timeout

504 Gateway Timeout

" ) func SetErrorResponseBody(r *http.Response, statusCode int) { switch statusCode { + case 200: + SetResponseBody(r, Status200) + case 201: + SetResponseBody(r, Status201) + case 202: + SetResponseBody(r, Status202) + case 204: + SetResponseBody(r, Status204) case 301: - SetResponseBody(r, status301) + SetResponseBody(r, Status301) case 302: - SetResponseBody(r, status302) + SetResponseBody(r, Status302) case 304: - SetResponseBody(r, status304) + SetResponseBody(r, Status304) case 400: - SetResponseBody(r, status400) + SetResponseBody(r, Status400) case 401: - SetResponseBody(r, status401) + SetResponseBody(r, Status401) case 403: - SetResponseBody(r, status403) + SetResponseBody(r, Status403) case 404: - SetResponseBody(r, status404) + SetResponseBody(r, Status404) case 500: - SetResponseBody(r, status500) + SetResponseBody(r, Status500) case 501: - SetResponseBody(r, status501) + SetResponseBody(r, Status501) case 502: - SetResponseBody(r, status502) + SetResponseBody(r, Status502) case 503: - SetResponseBody(r, status503) + SetResponseBody(r, Status503) case 504: - SetResponseBody(r, status504) + SetResponseBody(r, Status504) default: } } diff --git a/toxics/modify_body.go b/toxics/modify_body.go new file mode 100644 index 00000000..18bcffa4 --- /dev/null +++ b/toxics/modify_body.go @@ -0,0 +1,49 @@ +package toxics + +import ( + "bufio" + "bytes" + "io" + "net/http" + + "github.com/Shopify/toxiproxy/v2/stream" + "github.com/Shopify/toxiproxy/v2/toxics/httputils" +) + +type ModifyBodyToxic struct { + Body string `json:"body"` +} + +func (t *ModifyBodyToxic) ModifyResponseBody(resp *http.Response) { + httputils.SetResponseBody(resp, t.Body) +} + +func (t *ModifyBodyToxic) Pipe(stub *ToxicStub) { + buffer := bytes.NewBuffer(make([]byte, 0, 32*1024)) + writer := stream.NewChanWriter(stub.Output) + reader := stream.NewChanReader(stub.Input) + reader.SetInterrupt(stub.Interrupt) + for { + tee := io.TeeReader(reader, buffer) + resp, err := http.ReadResponse(bufio.NewReader(tee), nil) + + if err == stream.ErrInterrupted { + buffer.WriteTo(writer) + return + } else if err == io.EOF { + stub.Close() + return + } + if err != nil { + buffer.WriteTo(writer) + } else { + t.ModifyResponseBody(resp) + resp.Write(writer) + } + buffer.Reset() + } +} + +func init() { + Register("modify_body", new(ModifyBodyToxic)) +} diff --git a/toxics/modify_body_test.go b/toxics/modify_body_test.go new file mode 100644 index 00000000..bd7231f7 --- /dev/null +++ b/toxics/modify_body_test.go @@ -0,0 +1,48 @@ +package toxics_test + +import ( + "io/ioutil" + "net" + "net/http" + "testing" + + "github.com/Shopify/toxiproxy/v2/toxics" + "github.com/Shopify/toxiproxy/v2/toxics/httputils" +) + +func TestToxicModifiesHTTPResponseBody(t *testing.T) { + http.HandleFunc("/", echoHelloWorld) + + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal("Failed to create TCP server", err) + } + + go http.Serve(ln, nil) + defer ln.Close() + + proxy := NewTestProxy("test", ln.Addr().String()) + proxy.Start() + defer proxy.Stop() + + resp, err := http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ := ioutil.ReadAll(resp.Body) + + AssertBodyNotEqual(t, body, []byte(httputils.Status400)) + + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "modify_body", "downstream", &toxics.ModifyBodyToxic{Body: httputils.Status400})) + + resp, err = http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ = ioutil.ReadAll(resp.Body) + + AssertBodyEqual(t, body, []byte(httputils.Status400)) + +} From ddb23c8ec97f2265e62d4fda58b7871805592c65 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Thu, 7 Jul 2022 13:07:03 +0530 Subject: [PATCH 04/18] Added build script; Improved toxics Signed-off-by: Akash Shrivastava --- .gitignore | 2 + Makefile | 4 +- cmd/cli/cli.go | 6 +- go.sum | 1 - scripts/build.sh | 44 ++++++++++++++ toxics/header.go | 95 +++++++++++++++++++++++++++++ toxics/header_test.go | 118 +++++++++++++++++++++++++++++++++++++ toxics/modify_body.go | 3 + toxics/status_code.go | 6 +- toxics/status_code_test.go | 6 +- 10 files changed, 275 insertions(+), 10 deletions(-) create mode 100644 scripts/build.sh create mode 100644 toxics/header.go create mode 100644 toxics/header_test.go diff --git a/.gitignore b/.gitignore index 3dd38f5f..b631e8d2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ dist/ vendor/ tmp/ + +.vscode/ \ No newline at end of file diff --git a/Makefile b/Makefile index 9d228dbd..50e9b747 100644 --- a/Makefile +++ b/Makefile @@ -42,8 +42,8 @@ lint: .PHONY: build build: dist clean - go build -ldflags="-s -w" -o ./dist/toxiproxy-server ./cmd/server - go build -ldflags="-s -w" -o ./dist/toxiproxy-cli ./cmd/cli + @bash scripts/build.sh ./cmd/server server + @bash scripts/build.sh ./cmd/cli cli .PHONY: release release: diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index 9659b8c1..720516a3 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "os" "sort" @@ -574,7 +575,7 @@ func parseAddToxicParams(c *cli.Context) (*toxiproxy.ToxicOptions, error) { func parseAttributes(c *cli.Context, name string) toxiproxy.Attributes { parsed := map[string]interface{}{} args := c.StringSlice(name) - + var t map[string]interface{} for _, raw := range args { kv := strings.SplitN(raw, "=", 2) if len(kv) < 2 { @@ -582,6 +583,9 @@ func parseAttributes(c *cli.Context, name string) toxiproxy.Attributes { } if float, err := strconv.ParseFloat(kv[1], 64); err == nil { parsed[kv[0]] = float + } else if err := json.Unmarshal([]byte(kv[1]), &t); err == nil { + parsed[kv[0]] = t + continue } else { parsed[kv[0]] = kv[1] } diff --git a/go.sum b/go.sum index e4cf4274..95da025a 100644 --- a/go.sum +++ b/go.sum @@ -321,7 +321,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 00000000..81c63930 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +package_path=$1 +if [[ -z "$package_path" ]]; then + echo "usage: $0 $1 " + exit 1 +fi + +package=$2 + +platforms=( + "darwin/amd64" + "darwin/arm64" + "linux/386" + "linux/amd64" + "linux/arm" + "linux/arm64" + "windows/386" + "windows/amd64" + "windows/arm" +) + +rm -rf dist/$package/* +for platform in "${platforms[@]}" +do + platform_split=(${platform//\// }) + GOOS=${platform_split[0]}`` + GOARCH=${platform_split[1]} + echo 'Building' $GOOS-$GOARCH + output_name=toxiproxy-$package-$GOOS-$GOARCH + + env GOOS=$GOOS GOARCH=$GOARCH go build -v -o dist/$package/$output_name $package_path > /dev/null + + if [ $? -ne 0 ]; then + echo 'An error has occurred! Aborting the script execution...' + exit 1 + fi + + cd dist/$package + mv $output_name toxiproxy-$package + tar -czvf $output_name.tar.gz toxiproxy-$package + rm -rf toxiproxy-$package + cd ../.. +done \ No newline at end of file diff --git a/toxics/header.go b/toxics/header.go new file mode 100644 index 00000000..8bcb3c4e --- /dev/null +++ b/toxics/header.go @@ -0,0 +1,95 @@ +package toxics + +import ( + "bufio" + "bytes" + "fmt" + "io" + "net/http" + "strings" + + "github.com/Shopify/toxiproxy/v2/stream" +) + +type HeaderToxic struct { + Mode string `json:"mode"` + Headers map[string]string `json:"headers"` +} + +func (t *HeaderToxic) ModifyResponseHeader(resp *http.Response) { + for key, value := range t.Headers { + resp.Header.Set(key, value) + } +} + +func (t *HeaderToxic) ModifyRequestHeader(req *http.Request) { + for key, value := range t.Headers { + if strings.EqualFold("Host", key) { + req.Host = value + } else { + req.Header.Set(key, value) + } + } +} + +func (t *HeaderToxic) PrepareRequest(stub *ToxicStub, buffer *bytes.Buffer, reader *stream.ChanReader, writer *stream.ChanWriter) interface{} { + for { + tee := io.TeeReader(reader, buffer) + req, err := http.ReadRequest(bufio.NewReader(tee)) + + if err == stream.ErrInterrupted { + buffer.WriteTo(writer) + } else if err == io.EOF { + stub.Close() + } + if err != nil { + fmt.Println(err) + buffer.WriteTo(writer) + } else { + t.ModifyRequestHeader(req) + fmt.Println("Req headers") + for k, v := range req.Header { + fmt.Print(k, ":", v, "\n") + } + req.Write(writer) + } + buffer.Reset() + } +} + +func (t *HeaderToxic) PrepareResponse(stub *ToxicStub, buffer *bytes.Buffer, reader *stream.ChanReader, writer *stream.ChanWriter) { + for { + tee := io.TeeReader(reader, buffer) + resp, err := http.ReadResponse(bufio.NewReader(tee), nil) + + if err == stream.ErrInterrupted { + buffer.WriteTo(writer) + } else if err == io.EOF { + stub.Close() + } + if err != nil { + buffer.WriteTo(writer) + } else { + t.ModifyResponseHeader(resp) + resp.Write(writer) + } + buffer.Reset() + } +} + +func (t *HeaderToxic) Pipe(stub *ToxicStub) { + buffer := bytes.NewBuffer(make([]byte, 0, 32*1024)) + writer := stream.NewChanWriter(stub.Output) + reader := stream.NewChanReader(stub.Input) + reader.SetInterrupt(stub.Interrupt) + + if t.Mode == "response" { + t.PrepareResponse(stub, buffer, reader, writer) + } else { + t.PrepareRequest(stub, buffer, reader, writer) + } +} + +func init() { + Register("header", new(HeaderToxic)) +} diff --git a/toxics/header_test.go b/toxics/header_test.go new file mode 100644 index 00000000..5fa11024 --- /dev/null +++ b/toxics/header_test.go @@ -0,0 +1,118 @@ +package toxics_test + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net" + "net/http" + "strings" + "testing" + + "github.com/Shopify/toxiproxy/v2/toxics" +) + +func echoRequestHeaders(w http.ResponseWriter, r *http.Request) { + headersMap := map[string]string{} + + for k, v := range r.Header { + // headers can contain multiple elements. for the purposes of this test we pick the 1st + headersMap[k] = v[0] + } + mapAsJson, _ := json.Marshal(headersMap) + w.Write([]byte(mapAsJson)) +} + +func TestToxicAddsHTTPResponseHeaders(t *testing.T) { + http.HandleFunc("/", echoRequestHeaders) + + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal("Failed to create TCP server", err) + } + + go http.Serve(ln, nil) + defer ln.Close() + + proxy := NewTestProxy("test", ln.Addr().String()) + proxy.Start() + defer proxy.Stop() + + resp, err := http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ := ioutil.ReadAll(resp.Body) + fmt.Print(string(body)) + + AssertDoesNotContainHeader(t, string(body), "Foo", "Bar") + AssertDoesNotContainHeader(t, string(body), "Lorem", "Ipsum") + + proxy.Toxics.AddToxicJson(ToxicToJson(t, "header_downstream", "header", "downstream", &toxics.HeaderToxic{Headers: map[string]string{"Foo": "Bar", "Lorem": "Ipsum"}, Mode: "response"})) + + resp, err = http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ = ioutil.ReadAll(resp.Body) + fmt.Println(string(body)) + + AssertContainsHeader(t, string(body), "Foo", "Bar") + AssertContainsHeader(t, string(body), "Lorem", "Ipsum") +} + +func TestToxicAddsHTTPRequestHeaders(t *testing.T) { + http.HandleFunc("/", echoRequestHeaders) + + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal("Failed to create TCP server", err) + } + + go http.Serve(ln, nil) + defer ln.Close() + + proxy := NewTestProxy("test", ln.Addr().String()) + proxy.Start() + defer proxy.Stop() + + resp, err := http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ := ioutil.ReadAll(resp.Body) + + AssertDoesNotContainHeader(t, string(body), "Foo", "Bar") + AssertDoesNotContainHeader(t, string(body), "Lorem", "Ipsum") + + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "header", "upstream", &toxics.HeaderToxic{Headers: map[string]string{"Foo": "Bar", "Lorem": "Ipsum"}, Mode: "request"})) + + resp, err = http.Get("http://" + proxy.Listen) + if err != nil { + t.Error("Failed to connect to proxy", err) + } + + body, _ = ioutil.ReadAll(resp.Body) + + AssertContainsHeader(t, string(body), "Foo", "Bar") + AssertContainsHeader(t, string(body), "Lorem", "Ipsum") +} + +func AssertDoesNotContainHeader(t *testing.T, body string, headerKey string, headerValue string) { + containsHeader := strings.Contains(string(body), fmt.Sprintf(`"%s":"%s"`, headerKey, headerValue)) + + if containsHeader { + t.Errorf("Unexpected header found. Header=%s", headerKey) + } +} + +func AssertContainsHeader(t *testing.T, body string, headerKey string, headerValue string) { + containsHeader := strings.Contains(string(body), fmt.Sprintf(`"%s":"%s"`, headerKey, headerValue)) + + if !containsHeader { + t.Errorf("Expected header not found. Header=%s", headerKey) + } +} diff --git a/toxics/modify_body.go b/toxics/modify_body.go index 18bcffa4..db57cfc5 100644 --- a/toxics/modify_body.go +++ b/toxics/modify_body.go @@ -15,6 +15,9 @@ type ModifyBodyToxic struct { } func (t *ModifyBodyToxic) ModifyResponseBody(resp *http.Response) { + if t.Body == "" { + return + } httputils.SetResponseBody(resp, t.Body) } diff --git a/toxics/status_code.go b/toxics/status_code.go index a9f2585b..229e1019 100644 --- a/toxics/status_code.go +++ b/toxics/status_code.go @@ -11,14 +11,14 @@ import ( ) type StatusCodeToxic struct { - StatusCode int `json:"status_code"` - ModifyResponseBody bool `json:"modify_response_body"` + StatusCode int `json:"status_code"` + ModifyResponseBody int `json:"modify_response_body"` } func (t *StatusCodeToxic) ModifyResponseCode(resp *http.Response) { httputils.SetHttpStatusCode(resp, t.StatusCode) - if t.ModifyResponseBody { + if t.ModifyResponseBody == 1 { httputils.SetErrorResponseBody(resp, t.StatusCode) } } diff --git a/toxics/status_code_test.go b/toxics/status_code_test.go index 722c1ec6..6d590f23 100644 --- a/toxics/status_code_test.go +++ b/toxics/status_code_test.go @@ -37,7 +37,7 @@ func TestToxicModifiesHTTPStatusCode(t *testing.T) { AssertStatusCodeNotEqual(t, resp.StatusCode, 500) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: false})) + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: 0})) resp, err = http.Get("http://" + proxy.Listen) if err != nil { @@ -71,7 +71,7 @@ func TestToxicModifiesBodyWithStatusCode(t *testing.T) { AssertStatusCodeNotEqual(t, resp.StatusCode, 500) AssertBodyNotEqual(t, body, []byte(httputils.Status500)) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: true})) + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: 1})) resp, err = http.Get("http://" + proxy.Listen) if err != nil { @@ -108,7 +108,7 @@ func TestUnsupportedStatusCode(t *testing.T) { statusCode := resp.StatusCode initialBody, _ := ioutil.ReadAll(resp.Body) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 1000, ModifyResponseBody: true})) + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 1000, ModifyResponseBody: 1})) resp, err = http.Get("http://" + proxy.Listen) if err != nil { From cc5470d3186f28a3ba4141e146c2a454efa528b7 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Fri, 8 Jul 2022 19:35:48 +0530 Subject: [PATCH 05/18] Added push workflow Signed-off-by: Akash Shrivastava --- .github/workflows/push.yaml | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/workflows/push.yaml diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml new file mode 100644 index 00000000..58215f7d --- /dev/null +++ b/.github/workflows/push.yaml @@ -0,0 +1,53 @@ +name: push-release-pipeline +on: + push: + branches: + - master + tags: + - '*' + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + # Install golang + - uses: actions/setup-go@v2 + with: + go-version: 1.16 + + # Checkout to the latest commit + # On specific directory/path + - name: Checkout + uses: actions/checkout@v2 + + - name: gofmt check + run: | + if [ "$(gofmt -s -l . | wc -l)" -ne 0 ] + then + echo "The following files were found to be not go formatted:" + gofmt -s -l . + exit 1 + fi + + - name: golangci-lint + uses: reviewdog/action-golangci-lint@v1 + + - name: unused-package check + run: | + make unused-package-check + + + - name: Building toxiproxy + run: | + make build + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Copy binaries to the toxiproxy s3 bucket + run: | + aws s3 sync dist s3://${{ secrets.AWS_S3_BUCKET }} From 613a41efcb7c9276f8fe9f8c74edd606d5ef3a38 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Mon, 11 Jul 2022 12:16:48 +0530 Subject: [PATCH 06/18] removed debug code Signed-off-by: Akash Shrivastava --- toxics/header.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/toxics/header.go b/toxics/header.go index 8bcb3c4e..3e350f82 100644 --- a/toxics/header.go +++ b/toxics/header.go @@ -48,9 +48,6 @@ func (t *HeaderToxic) PrepareRequest(stub *ToxicStub, buffer *bytes.Buffer, read } else { t.ModifyRequestHeader(req) fmt.Println("Req headers") - for k, v := range req.Header { - fmt.Print(k, ":", v, "\n") - } req.Write(writer) } buffer.Reset() From 8c7bd27641c480750eb02dc6f40b996dc3b0d72a Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Mon, 11 Jul 2022 16:46:27 +0530 Subject: [PATCH 07/18] Improved httputils code to be more concise Signed-off-by: Akash Shrivastava --- api_test.go | 8 +-- toxics/httputils/body.go | 96 ++++++++++++++------------------- toxics/httputils/status_code.go | 81 ++++++++++------------------ toxics/modify_body_test.go | 7 ++- toxics/status_code_test.go | 8 +-- 5 files changed, 81 insertions(+), 119 deletions(-) diff --git a/api_test.go b/api_test.go index 548ab0a8..2c6640b1 100644 --- a/api_test.go +++ b/api_test.go @@ -228,7 +228,7 @@ func TestPopulateExistingProxy(t *testing.T) { t.Fatal("Unable to create proxy:", err) } - // Create a toxic so we can make sure the proxy wasn't replaced + // Create a toxic, so we can make sure the proxy wasn't replaced _, err = testProxy.AddToxic("", "latency", "downstream", 1, nil) if err != nil { t.Fatal("Unable to create toxic:", err) @@ -476,7 +476,7 @@ func TestCreateProxyWithSave(t *testing.T) { proxy, err := client.Proxy("mysql_master") if err != nil { - t.Fatal("Unable to retriecve proxy:", err) + t.Fatal("Unable to retrieve proxy:", err) } if proxy.Name != "mysql_master" || proxy.Listen != "127.0.0.1:3310" || @@ -509,7 +509,7 @@ func TestCreateDisabledProxy(t *testing.T) { proxy, err := client.Proxy("mysql_master") if err != nil { - t.Fatal("Unable to retriecve proxy:", err) + t.Fatal("Unable to retrieve proxy:", err) } if proxy.Name != "mysql_master" || proxy.Listen != "localhost:3310" || @@ -542,7 +542,7 @@ func TestCreateDisabledProxyAndEnable(t *testing.T) { proxy, err := client.Proxy("mysql_master") if err != nil { - t.Fatal("Unable to retriecve proxy:", err) + t.Fatal("Unable to retrieve proxy:", err) } if proxy.Name != "mysql_master" || proxy.Listen != "localhost:3310" || diff --git a/toxics/httputils/body.go b/toxics/httputils/body.go index 43ffb04c..14d765ba 100644 --- a/toxics/httputils/body.go +++ b/toxics/httputils/body.go @@ -6,64 +6,48 @@ import ( "strings" ) -const ( - // 2xx pages - Status200 = "200 Status OK

200 Status OK

" - Status201 = "201 Created

301 Moved Permanently

" - Status202 = "202 Accepted

202 Accepted

" - Status204 = "204 No Content

204 No Content

" - // 3xx pages - Status301 = "301 Moved Permanently

301 Moved Permanently

" - Status302 = "302 Found

302 Found

" - Status304 = "304 Not Modified

304 Not Modified

" - // 4xx error pages - Status400 = "400 Bad Request

400 Bad Request


" - Status401 = "401 Unauthorized

401 Unauthorized


" - Status403 = "403 Forbidden

403 Forbidden


" - Status404 = "404 Not Found

404 Not Found


" - // 5xx error pages - Status500 = "500 Internal Server Error

500 Internal Server Error

" - Status501 = "501 Not Implemented

501 Not Implemented

" - Status502 = "502 Bad Gateway

502 Bad Gateway

" - Status503 = "503 Service Unavailable

503 Service Unavailable

" - Status504 = "504 Gateway Timeout

504 Gateway Timeout

" -) +var statusBodyTemplate = map[int]string{ + // status200 default nginx status page + 200: "200 Status OK

200 Status OK

", + // status201 default nginx error page + 201: "201 Created

301 Moved Permanently

", + // status202 default nginx status page + 202: "202 Accepted

202 Accepted

", + // status204 default nginx status page + 204: "204 No Content

204 No Content

", + // status301 default nginx error page + 301: "301 Moved Permanently

301 Moved Permanently

", + // status302 default nginx error page + 302: "302 Found

302 Found

", + // status304 default nginx error page + 304: "304 Not Modified

304 Not Modified

", + // status305 default nginx error page + 305: "305 Use Proxy

305 Use Proxy

", + // status305 default nginx error page + 307: "307 Temporary Redirect

307 Temporary Redirect

", + // status400 default nginx error page + 400: "400 Bad Request

400 Bad Request


", + // status401 default nginx error page + 401: "401 Unauthorized

401 Unauthorized


", + // status403 default nginx error page + 403: "403 Forbidden

403 Forbidden


", + // status404 default nginx error page + 404: "404 Not Found

404 Not Found


", + // status500 default nginx error page + 500: "500 Internal Server Error

500 Internal Server Error

", + // status501 default nginx error page + 501: "501 Not Implemented

501 Not Implemented

", + // status502 default nginx error page + 502: "502 Bad Gateway

502 Bad Gateway

", + // status503 default nginx error page + 503: "503 Service Unavailable

503 Service Unavailable

", + // status504 default nginx error page + 504: "504 Gateway Timeout

504 Gateway Timeout

", +} func SetErrorResponseBody(r *http.Response, statusCode int) { - switch statusCode { - case 200: - SetResponseBody(r, Status200) - case 201: - SetResponseBody(r, Status201) - case 202: - SetResponseBody(r, Status202) - case 204: - SetResponseBody(r, Status204) - case 301: - SetResponseBody(r, Status301) - case 302: - SetResponseBody(r, Status302) - case 304: - SetResponseBody(r, Status304) - case 400: - SetResponseBody(r, Status400) - case 401: - SetResponseBody(r, Status401) - case 403: - SetResponseBody(r, Status403) - case 404: - SetResponseBody(r, Status404) - case 500: - SetResponseBody(r, Status500) - case 501: - SetResponseBody(r, Status501) - case 502: - SetResponseBody(r, Status502) - case 503: - SetResponseBody(r, Status503) - case 504: - SetResponseBody(r, Status504) - default: + if _, exists := statusBodyTemplate[statusCode]; statusCode >= 200 && statusCode < 600 && exists { + SetResponseBody(r, statusBodyTemplate[statusCode]) } } diff --git a/toxics/httputils/status_code.go b/toxics/httputils/status_code.go index ab653f46..101fd587 100644 --- a/toxics/httputils/status_code.go +++ b/toxics/httputils/status_code.go @@ -1,59 +1,36 @@ package httputils -import "net/http" +import ( + "net/http" +) + +var statusText = map[int]string{ + 200: "200 OK", + 201: "201 Created", + 202: "202 Accepted", + 204: "204 No Content", + 300: "300 Multiple Choices", + 301: "301 Moved Permanently", + 302: "302 Found", + 304: "304 Not Modified", + 305: "305 Use Proxy", + 307: "307 Temporary Redirect", + 400: "400 Bad Request", + 401: "401 Unauthorized", + 403: "403 Forbidden", + 404: "404 Not Found", + 500: "500 Internal Server Error", + 501: "501 Not Implemented", + 502: "502 Bad Gateway", + 503: "503 Service Unavailable", + 504: "504 Gateway Timeout", +} // SetHttpStatusCode sets the status code of the response func SetHttpStatusCode(r *http.Response, statusCode int) { - switch statusCode { - case 200: - r.StatusCode = 200 - r.Status = "200 OK" - case 201: - r.StatusCode = 201 - r.Status = "201 Created" - case 202: - r.StatusCode = 202 - r.Status = "202 Accepted" - case 204: - r.StatusCode = 204 - r.Status = "204 No Content" - case 301: - r.StatusCode = 301 - r.Status = "301 Moved Permanently" - case 302: - r.StatusCode = 302 - r.Status = "302 Found" - case 304: - r.StatusCode = 304 - r.Status = "304 Not Modified" - case 400: - r.StatusCode = 400 - r.Status = "400 Bad Request" - case 401: - r.StatusCode = 401 - r.Status = "401 Unauthorized" - case 403: - r.StatusCode = 403 - r.Status = "403 Forbidden" - case 404: - r.StatusCode = 404 - r.Status = "404 Not Found" - case 500: - r.StatusCode = 500 - r.Status = "500 Internal Server Error" - case 501: - r.StatusCode = 501 - r.Status = "501 Not Implemented" - case 502: - r.StatusCode = 502 - r.Status = "502 Bad Gateway" - case 503: - r.StatusCode = 503 - r.Status = "503 Service Unavailable" - case 504: - r.StatusCode = 504 - r.Status = "504 Gateway Timeout" - default: - // if the status code is not recognized, do not change it + if _, exists := statusText[statusCode]; statusCode >= 200 && statusCode < 600 && exists { + r.StatusCode = statusCode + r.Status = statusText[statusCode] } + // if the status code is not recognized, do not change it } diff --git a/toxics/modify_body_test.go b/toxics/modify_body_test.go index bd7231f7..52977f4d 100644 --- a/toxics/modify_body_test.go +++ b/toxics/modify_body_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/Shopify/toxiproxy/v2/toxics" - "github.com/Shopify/toxiproxy/v2/toxics/httputils" ) func TestToxicModifiesHTTPResponseBody(t *testing.T) { @@ -32,9 +31,9 @@ func TestToxicModifiesHTTPResponseBody(t *testing.T) { body, _ := ioutil.ReadAll(resp.Body) - AssertBodyNotEqual(t, body, []byte(httputils.Status400)) + AssertBodyNotEqual(t, body, []byte(status500)) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "modify_body", "downstream", &toxics.ModifyBodyToxic{Body: httputils.Status400})) + proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "modify_body", "downstream", &toxics.ModifyBodyToxic{Body: status500})) resp, err = http.Get("http://" + proxy.Listen) if err != nil { @@ -43,6 +42,6 @@ func TestToxicModifiesHTTPResponseBody(t *testing.T) { body, _ = ioutil.ReadAll(resp.Body) - AssertBodyEqual(t, body, []byte(httputils.Status400)) + AssertBodyEqual(t, body, []byte(status500)) } diff --git a/toxics/status_code_test.go b/toxics/status_code_test.go index 6d590f23..c9ebe7f8 100644 --- a/toxics/status_code_test.go +++ b/toxics/status_code_test.go @@ -8,9 +8,11 @@ import ( "testing" "github.com/Shopify/toxiproxy/v2/toxics" - "github.com/Shopify/toxiproxy/v2/toxics/httputils" ) +// status500 default nginx error page +var status500 = "500 Internal Server Error

500 Internal Server Error

" + func echoHelloWorld(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World")) } @@ -69,7 +71,7 @@ func TestToxicModifiesBodyWithStatusCode(t *testing.T) { body, _ := ioutil.ReadAll(resp.Body) AssertStatusCodeNotEqual(t, resp.StatusCode, 500) - AssertBodyNotEqual(t, body, []byte(httputils.Status500)) + AssertBodyNotEqual(t, body, []byte(status500)) proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: 1})) @@ -81,7 +83,7 @@ func TestToxicModifiesBodyWithStatusCode(t *testing.T) { body, _ = ioutil.ReadAll(resp.Body) AssertStatusCodeEqual(t, resp.StatusCode, 500) - AssertBodyEqual(t, body, []byte(httputils.Status500)) + AssertBodyEqual(t, body, []byte(status500)) } From 797b19a95b9cc3df22ec6ee7e94df591b4ddc6ba Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Mon, 11 Jul 2022 16:58:32 +0530 Subject: [PATCH 08/18] sanitising user input for logs Signed-off-by: Akash Shrivastava --- proxy.go | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/proxy.go b/proxy.go index 8a1f8dc3..d079d794 100644 --- a/proxy.go +++ b/proxy.go @@ -3,6 +3,7 @@ package toxiproxy import ( "errors" "net" + "strings" "sync" "github.com/Shopify/toxiproxy/v2/stream" @@ -102,9 +103,9 @@ func (proxy *Proxy) listen() error { proxy.started <- nil logrus.WithFields(logrus.Fields{ - "name": proxy.Name, - "proxy": proxy.Listen, - "upstream": proxy.Upstream, + "name": cleanUserInput(proxy.Name), + "proxy": cleanUserInput(proxy.Listen), + "upstream": cleanUserInput(proxy.Upstream), }).Info("Started proxy") return nil @@ -115,8 +116,8 @@ func (proxy *Proxy) close() { err := proxy.listener.Close() if err != nil { logrus.WithFields(logrus.Fields{ - "proxy": proxy.Name, - "listen": proxy.Listen, + "proxy": cleanUserInput(proxy.Name), + "listen": cleanUserInput(proxy.Listen), "err": err, }).Warn("Attempted to close an already closed proxy server") } @@ -164,8 +165,8 @@ func (proxy *Proxy) server() { case <-acceptTomb.Dying(): default: logrus.WithFields(logrus.Fields{ - "proxy": proxy.Name, - "listen": proxy.Listen, + "proxy": cleanUserInput(proxy.Name), + "listen": cleanUserInput(proxy.Listen), "err": err, }).Warn("Error while accepting client") } @@ -173,19 +174,19 @@ func (proxy *Proxy) server() { } logrus.WithFields(logrus.Fields{ - "name": proxy.Name, + "name": cleanUserInput(proxy.Name), "client": client.RemoteAddr(), - "proxy": proxy.Listen, - "upstream": proxy.Upstream, + "proxy": cleanUserInput(proxy.Listen), + "upstream": cleanUserInput(proxy.Upstream), }).Info("Accepted client") upstream, err := net.Dial("tcp", proxy.Upstream) if err != nil { logrus.WithFields(logrus.Fields{ - "name": proxy.Name, + "name": cleanUserInput(proxy.Name), "client": client.RemoteAddr(), - "proxy": proxy.Listen, - "upstream": proxy.Upstream, + "proxy": cleanUserInput(proxy.Listen), + "upstream": cleanUserInput(proxy.Upstream), }).Error("Unable to open connection to upstream: " + err.Error()) client.Close() continue @@ -238,8 +239,12 @@ func stop(proxy *Proxy) { } logrus.WithFields(logrus.Fields{ - "name": proxy.Name, - "proxy": proxy.Listen, - "upstream": proxy.Upstream, + "name": cleanUserInput(proxy.Name), + "proxy": cleanUserInput(proxy.Listen), + "upstream": cleanUserInput(proxy.Upstream), }).Info("Terminated proxy") } + +func cleanUserInput(input string) string { + return strings.Replace(strings.Replace(input, "\r", "", -1), "\r", "", -1) +} From 17aa8004741dcdab6b9ed856e8c629de8e957d65 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Mon, 11 Jul 2022 17:46:18 +0530 Subject: [PATCH 09/18] Changes to fix the golangci-lint errors Signed-off-by: Akash Shrivastava --- api.go | 2 +- proxy.go | 2 +- toxics/header.go | 14 +++++++-- toxics/header_test.go | 19 ++++++++++-- toxics/httputils/body.go | 54 ++++++++++++++++++++++----------- toxics/httputils/status_code.go | 2 +- toxics/modify_body_test.go | 9 ++++-- toxics/status_code_test.go | 47 ++++++++++++++++++++-------- 8 files changed, 109 insertions(+), 40 deletions(-) diff --git a/api.go b/api.go index bddeb399..c59d2442 100644 --- a/api.go +++ b/api.go @@ -53,7 +53,7 @@ func (server *ApiServer) PopulateConfig(filename string) { func StopBrowsersMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.UserAgent(), "Mozilla/") { - http.Error(w, "User agent not allowed", 403) + http.Error(w, "User agent not allowed", http.StatusForbidden) } else { h.ServeHTTP(w, r) } diff --git a/proxy.go b/proxy.go index d079d794..1c221c18 100644 --- a/proxy.go +++ b/proxy.go @@ -246,5 +246,5 @@ func stop(proxy *Proxy) { } func cleanUserInput(input string) string { - return strings.Replace(strings.Replace(input, "\r", "", -1), "\r", "", -1) + return strings.ReplaceAll(strings.ReplaceAll(input, "\r", ""), "\r", "") } diff --git a/toxics/header.go b/toxics/header.go index 3e350f82..9977c513 100644 --- a/toxics/header.go +++ b/toxics/header.go @@ -32,7 +32,12 @@ func (t *HeaderToxic) ModifyRequestHeader(req *http.Request) { } } -func (t *HeaderToxic) PrepareRequest(stub *ToxicStub, buffer *bytes.Buffer, reader *stream.ChanReader, writer *stream.ChanWriter) interface{} { +func (t *HeaderToxic) PrepareRequest( + stub *ToxicStub, + buffer *bytes.Buffer, + reader *stream.ChanReader, + writer *stream.ChanWriter, +) interface{} { for { tee := io.TeeReader(reader, buffer) req, err := http.ReadRequest(bufio.NewReader(tee)) @@ -54,7 +59,12 @@ func (t *HeaderToxic) PrepareRequest(stub *ToxicStub, buffer *bytes.Buffer, read } } -func (t *HeaderToxic) PrepareResponse(stub *ToxicStub, buffer *bytes.Buffer, reader *stream.ChanReader, writer *stream.ChanWriter) { +func (t *HeaderToxic) PrepareResponse( + stub *ToxicStub, + buffer *bytes.Buffer, + reader *stream.ChanReader, + writer *stream.ChanWriter, +) { for { tee := io.TeeReader(reader, buffer) resp, err := http.ReadResponse(bufio.NewReader(tee), nil) diff --git a/toxics/header_test.go b/toxics/header_test.go index 5fa11024..129d247e 100644 --- a/toxics/header_test.go +++ b/toxics/header_test.go @@ -42,6 +42,7 @@ func TestToxicAddsHTTPResponseHeaders(t *testing.T) { if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Print(string(body)) @@ -49,12 +50,18 @@ func TestToxicAddsHTTPResponseHeaders(t *testing.T) { AssertDoesNotContainHeader(t, string(body), "Foo", "Bar") AssertDoesNotContainHeader(t, string(body), "Lorem", "Ipsum") - proxy.Toxics.AddToxicJson(ToxicToJson(t, "header_downstream", "header", "downstream", &toxics.HeaderToxic{Headers: map[string]string{"Foo": "Bar", "Lorem": "Ipsum"}, Mode: "response"})) + proxy.Toxics.AddToxicJson(ToxicToJson( + t, "header_downstream", "header", "downstream", + &toxics.HeaderToxic{ + Headers: map[string]string{"Foo": "Bar", "Lorem": "Ipsum"}, + Mode: "response"}, + )) resp, err = http.Get("http://" + proxy.Listen) if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() body, _ = ioutil.ReadAll(resp.Body) fmt.Println(string(body)) @@ -82,19 +89,27 @@ func TestToxicAddsHTTPRequestHeaders(t *testing.T) { if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) AssertDoesNotContainHeader(t, string(body), "Foo", "Bar") AssertDoesNotContainHeader(t, string(body), "Lorem", "Ipsum") - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "header", "upstream", &toxics.HeaderToxic{Headers: map[string]string{"Foo": "Bar", "Lorem": "Ipsum"}, Mode: "request"})) + proxy.Toxics.AddToxicJson(ToxicToJson( + t, "", "header", "upstream", + &toxics.HeaderToxic{ + Headers: map[string]string{"Foo": "Bar", "Lorem": "Ipsum"}, + Mode: "request"}, + )) resp, err = http.Get("http://" + proxy.Listen) if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() + body, _ = ioutil.ReadAll(resp.Body) AssertContainsHeader(t, string(body), "Foo", "Bar") diff --git a/toxics/httputils/body.go b/toxics/httputils/body.go index 14d765ba..406e2400 100644 --- a/toxics/httputils/body.go +++ b/toxics/httputils/body.go @@ -8,41 +8,59 @@ import ( var statusBodyTemplate = map[int]string{ // status200 default nginx status page - 200: "200 Status OK

200 Status OK

", + 200: `200 Status OK +

200 Status OK

`, // status201 default nginx error page - 201: "201 Created

301 Moved Permanently

", + 201: `201 Created +

301 Moved Permanently

`, // status202 default nginx status page - 202: "202 Accepted

202 Accepted

", + 202: `202 Accepted +

202 Accepted

`, // status204 default nginx status page - 204: "204 No Content

204 No Content

", + 204: `204 No Content +

204 No Content

`, // status301 default nginx error page - 301: "301 Moved Permanently

301 Moved Permanently

", + 301: `301 Moved Permanently +

301 Moved Permanently

`, // status302 default nginx error page - 302: "302 Found

302 Found

", + 302: `302 Found +

302 Found

`, // status304 default nginx error page - 304: "304 Not Modified

304 Not Modified

", + 304: `304 Not Modified +

304 Not Modified

`, // status305 default nginx error page - 305: "305 Use Proxy

305 Use Proxy

", + 305: `305 Use Proxy +

305 Use Proxy

`, // status305 default nginx error page - 307: "307 Temporary Redirect

307 Temporary Redirect

", + 307: `307 Temporary Redirect +

307 Temporary Redirect

`, // status400 default nginx error page - 400: "400 Bad Request

400 Bad Request


", + 400: `400 Bad Request +

400 Bad Request


`, // status401 default nginx error page - 401: "401 Unauthorized

401 Unauthorized


", + 401: `401 Unauthorized +

401 Unauthorized


`, // status403 default nginx error page - 403: "403 Forbidden

403 Forbidden


", + 403: `403 Forbidden +

403 Forbidden


`, // status404 default nginx error page - 404: "404 Not Found

404 Not Found


", + 404: `404 Not Found +

404 Not Found


`, // status500 default nginx error page - 500: "500 Internal Server Error

500 Internal Server Error

", + 500: `500 Internal Server Error +

500 Internal Server Error

`, // status501 default nginx error page - 501: "501 Not Implemented

501 Not Implemented

", + 501: `501 Not Implemented +

501 Not Implemented

`, // status502 default nginx error page - 502: "502 Bad Gateway

502 Bad Gateway

", + 502: `502 Bad Gateway +

502 Bad Gateway

`, // status503 default nginx error page - 503: "503 Service Unavailable

503 Service Unavailable

", + 503: `503 Service Unavailable +

503 Service Unavailable

`, // status504 default nginx error page - 504: "504 Gateway Timeout

504 Gateway Timeout

", + 504: `504 Gateway Timeout +

504 Gateway Timeout

`, } func SetErrorResponseBody(r *http.Response, statusCode int) { diff --git a/toxics/httputils/status_code.go b/toxics/httputils/status_code.go index 101fd587..854ac68d 100644 --- a/toxics/httputils/status_code.go +++ b/toxics/httputils/status_code.go @@ -26,7 +26,7 @@ var statusText = map[int]string{ 504: "504 Gateway Timeout", } -// SetHttpStatusCode sets the status code of the response +// SetHttpStatusCode sets the status code of the response. func SetHttpStatusCode(r *http.Response, statusCode int) { if _, exists := statusText[statusCode]; statusCode >= 200 && statusCode < 600 && exists { r.StatusCode = statusCode diff --git a/toxics/modify_body_test.go b/toxics/modify_body_test.go index 52977f4d..711cdde3 100644 --- a/toxics/modify_body_test.go +++ b/toxics/modify_body_test.go @@ -28,20 +28,25 @@ func TestToxicModifiesHTTPResponseBody(t *testing.T) { if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) AssertBodyNotEqual(t, body, []byte(status500)) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "modify_body", "downstream", &toxics.ModifyBodyToxic{Body: status500})) + proxy.Toxics.AddToxicJson(ToxicToJson( + t, "", "modify_body", "downstream", + &toxics.ModifyBodyToxic{Body: status500}, + )) resp, err = http.Get("http://" + proxy.Listen) if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() + body, _ = ioutil.ReadAll(resp.Body) AssertBodyEqual(t, body, []byte(status500)) - } diff --git a/toxics/status_code_test.go b/toxics/status_code_test.go index c9ebe7f8..1375f06f 100644 --- a/toxics/status_code_test.go +++ b/toxics/status_code_test.go @@ -10,8 +10,9 @@ import ( "github.com/Shopify/toxiproxy/v2/toxics" ) -// status500 default nginx error page -var status500 = "500 Internal Server Error

500 Internal Server Error

" +// status500 default nginx error page. +var status500 = `500 Internal Server Error +

500 Internal Server Error

` func echoHelloWorld(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World")) @@ -36,15 +37,21 @@ func TestToxicModifiesHTTPStatusCode(t *testing.T) { if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() AssertStatusCodeNotEqual(t, resp.StatusCode, 500) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: 0})) + proxy.Toxics.AddToxicJson(ToxicToJson( + t, "", "status_code", "downstream", + &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: 0}, + )) resp, err = http.Get("http://" + proxy.Listen) if err != nil { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() + AssertStatusCodeEqual(t, resp.StatusCode, 500) } @@ -68,23 +75,28 @@ func TestToxicModifiesBodyWithStatusCode(t *testing.T) { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() + body, _ := ioutil.ReadAll(resp.Body) AssertStatusCodeNotEqual(t, resp.StatusCode, 500) AssertBodyNotEqual(t, body, []byte(status500)) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: 1})) + proxy.Toxics.AddToxicJson(ToxicToJson( + t, "", "status_code", "downstream", + &toxics.StatusCodeToxic{StatusCode: 500, ModifyResponseBody: 1}, + )) resp, err = http.Get("http://" + proxy.Listen) if err != nil { t.Error("Failed to connect to proxy", err) } - body, _ = ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + body, _ = ioutil.ReadAll(resp.Body) AssertStatusCodeEqual(t, resp.StatusCode, 500) AssertBodyEqual(t, body, []byte(status500)) - } func TestUnsupportedStatusCode(t *testing.T) { @@ -107,43 +119,52 @@ func TestUnsupportedStatusCode(t *testing.T) { t.Error("Failed to connect to proxy", err) } + defer resp.Body.Close() + statusCode := resp.StatusCode initialBody, _ := ioutil.ReadAll(resp.Body) - proxy.Toxics.AddToxicJson(ToxicToJson(t, "", "status_code", "downstream", &toxics.StatusCodeToxic{StatusCode: 1000, ModifyResponseBody: 1})) + proxy.Toxics.AddToxicJson(ToxicToJson( + t, "", "status_code", "downstream", + &toxics.StatusCodeToxic{StatusCode: 1000, ModifyResponseBody: 1}, + )) resp, err = http.Get("http://" + proxy.Listen) if err != nil { t.Error("Failed to connect to proxy", err) } - body, _ := ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + body, _ := ioutil.ReadAll(resp.Body) AssertStatusCodeEqual(t, resp.StatusCode, statusCode) AssertBodyEqual(t, body, initialBody) - } func AssertStatusCodeEqual(t *testing.T, respStatusCode, expectedStatusCode int) { if respStatusCode != expectedStatusCode { - t.Errorf("Response status code {%v} not equal to expected status code {%v}.", respStatusCode, expectedStatusCode) + t.Errorf("Response status code {%v} not equal to expected status code {%v}.", + respStatusCode, expectedStatusCode) } } func AssertStatusCodeNotEqual(t *testing.T, respStatusCode, expectedStatusCode int) { if respStatusCode == expectedStatusCode { - t.Errorf("Response status code {%v} equal to expected status code {%v}.", respStatusCode, expectedStatusCode) + t.Errorf("Response status code {%v} equal to expected status code {%v}.", + respStatusCode, expectedStatusCode) } } func AssertBodyEqual(t *testing.T, respBody, expectedBody []byte) { if !bytes.Equal(respBody, expectedBody) { - t.Errorf("Response body {%v} not equal to expected body {%v}.", string(respBody), string(expectedBody)) + t.Errorf("Response body {%v} not equal to expected body {%v}.", + string(respBody), string(expectedBody)) } } func AssertBodyNotEqual(t *testing.T, respBody, expectedBody []byte) { if bytes.Equal(respBody, expectedBody) { - t.Errorf("Response body {%v} equal to expected body {%v}.", string(respBody), string(expectedBody)) + t.Errorf("Response body {%v} equal to expected body {%v}.", + string(respBody), string(expectedBody)) } } From a6fb7c605f24e133a8083a4a0baac302f31f30bb Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Mon, 11 Jul 2022 17:50:05 +0530 Subject: [PATCH 10/18] yaml-lint fixes Signed-off-by: Akash Shrivastava --- .github/workflows/push.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 58215f7d..e985b4ad 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -1,8 +1,10 @@ +--- + name: push-release-pipeline on: push: branches: - - master + - "master" tags: - '*' From 7fbbed12a7f480a3c5fa8f3de463d28dc44cc612 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Mon, 11 Jul 2022 17:53:55 +0530 Subject: [PATCH 11/18] reverted build command and added prod-build Signed-off-by: Akash Shrivastava --- .github/workflows/push.yaml | 2 +- Makefile | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index e985b4ad..d3e2888a 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -41,7 +41,7 @@ jobs: - name: Building toxiproxy run: | - make build + make prod-build - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 diff --git a/Makefile b/Makefile index 50e9b747..ba91a201 100644 --- a/Makefile +++ b/Makefile @@ -40,11 +40,16 @@ lint: shfmt -l -s -d -kp -i 2 scripts/test-* yamllint . -.PHONY: build -build: dist clean +.PHONY: prod-build +prod-build: dist clean @bash scripts/build.sh ./cmd/server server @bash scripts/build.sh ./cmd/cli cli +.PHONY: build +build: dist clean + go build -ldflags="-s -w" -o ./dist/toxiproxy-server ./cmd/server + go build -ldflags="-s -w" -o ./dist/toxiproxy-cli ./cmd/cli + .PHONY: release release: goreleaser release --rm-dist From 9abbbcd0ef18ce650e31e7cd7d6b607612c27f0f Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Mon, 11 Jul 2022 18:02:18 +0530 Subject: [PATCH 12/18] yaml-lint fixes Signed-off-by: Akash Shrivastava --- .github/workflows/push.yaml | 4 ++-- .github/workflows/test.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index d3e2888a..7f2e7e60 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -4,9 +4,9 @@ name: push-release-pipeline on: push: branches: - - "master" + - master tags: - - '*' + - "*" jobs: build-and-push: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a2168365..89f08503 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: true matrix: - go: ["1.18", "1.17", "1.16", "1.15", "1.14"] + go: ["1.18", "1.17", "1.15", "1.14"] name: Go ${{ matrix.go }} steps: - name: Checkout From 3b145e20d013570cf1667f6ce2b2d98e3e72f7e5 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Fri, 15 Jul 2022 01:00:49 +0530 Subject: [PATCH 13/18] fixed header test case Signed-off-by: Akash Shrivastava --- toxics/header_test.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/toxics/header_test.go b/toxics/header_test.go index 129d247e..8a9e3a04 100644 --- a/toxics/header_test.go +++ b/toxics/header_test.go @@ -63,11 +63,16 @@ func TestToxicAddsHTTPResponseHeaders(t *testing.T) { } defer resp.Body.Close() - body, _ = ioutil.ReadAll(resp.Body) - fmt.Println(string(body)) + headersMap := map[string]string{} + for k, v := range resp.Header { + // headers can contain multiple elements. for the purposes of this test we pick the 1st + headersMap[k] = v[0] + } + mapAsJson, _ := json.Marshal(headersMap) + fmt.Print(string(mapAsJson)) - AssertContainsHeader(t, string(body), "Foo", "Bar") - AssertContainsHeader(t, string(body), "Lorem", "Ipsum") + AssertContainsHeader(t, string(mapAsJson), "Foo", "Bar") + AssertContainsHeader(t, string(mapAsJson), "Lorem", "Ipsum") } func TestToxicAddsHTTPRequestHeaders(t *testing.T) { From 13751db8ff9c66f910e4703fc82e0a386fcab059 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Fri, 15 Jul 2022 12:33:40 +0530 Subject: [PATCH 14/18] minor fix Signed-off-by: Akash Shrivastava --- cmd/cli/cli.go | 2 +- proxy.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index 720516a3..c9506a46 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -623,7 +623,7 @@ func (a attributeList) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func sortedAttributes(attrs toxiproxy.Attributes) attributeList { li := make(attributeList, 0, len(attrs)) for k, v := range attrs { - li = append(li, attribute{k, v.(float64)}) + li = append(li, attribute{k, v}) } sort.Sort(li) return li diff --git a/proxy.go b/proxy.go index 1c221c18..38defbe1 100644 --- a/proxy.go +++ b/proxy.go @@ -246,5 +246,5 @@ func stop(proxy *Proxy) { } func cleanUserInput(input string) string { - return strings.ReplaceAll(strings.ReplaceAll(input, "\r", ""), "\r", "") + return strings.ReplaceAll(strings.ReplaceAll(input, "\n", ""), "\r", "") } From 09175a563b359ca665fef00700212afe691fbed8 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Fri, 15 Jul 2022 12:44:55 +0530 Subject: [PATCH 15/18] update go version Signed-off-by: Akash Shrivastava --- .github/workflows/push.yaml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 7f2e7e60..26c783a1 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -15,7 +15,7 @@ jobs: # Install golang - uses: actions/setup-go@v2 with: - go-version: 1.16 + go-version: 1.17 # Checkout to the latest commit # On specific directory/path diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 89f08503..a2168365 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: true matrix: - go: ["1.18", "1.17", "1.15", "1.14"] + go: ["1.18", "1.17", "1.16", "1.15", "1.14"] name: Go ${{ matrix.go }} steps: - name: Checkout From cd7f79a23b43e7d5e777ab65af6037196f0381c5 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Fri, 15 Jul 2022 12:52:34 +0530 Subject: [PATCH 16/18] removed go<1.17 from test Signed-off-by: Akash Shrivastava --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a2168365..a5e2d2a6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: true matrix: - go: ["1.18", "1.17", "1.16", "1.15", "1.14"] + go: ["1.18", "1.17"] name: Go ${{ matrix.go }} steps: - name: Checkout From cf60d68a915eb8b3c691a6dfba4fc1ccf3ccd072 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Fri, 15 Jul 2022 12:58:15 +0530 Subject: [PATCH 17/18] added unused package check Signed-off-by: Akash Shrivastava --- .github/workflows/push.yaml | 1 + Makefile | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 26c783a1..42b0dc67 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -5,6 +5,7 @@ on: push: branches: - master + - http-status-code tags: - "*" diff --git a/Makefile b/Makefile index ba91a201..f217b560 100644 --- a/Makefile +++ b/Makefile @@ -69,3 +69,13 @@ dist: .PHONY: clean clean: rm -fr dist/* + +.PHONY: unused-package-check +unused-package-check: + @echo "------------------" + @echo "--> Check unused packages for the litmusctl" + @echo "------------------" + @tidy=$$(go mod tidy); \ + if [ -n "$${tidy}" ]; then \ + echo "go mod tidy checking failed!"; echo "$${tidy}"; echo; \ + fi \ No newline at end of file From 3cce6336481e0114ed57f24ad84f20cd8e711544 Mon Sep 17 00:00:00 2001 From: Akash Shrivastava Date: Fri, 15 Jul 2022 13:04:40 +0530 Subject: [PATCH 18/18] reverted branch addition Signed-off-by: Akash Shrivastava --- .github/workflows/push.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 42b0dc67..26c783a1 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -5,7 +5,6 @@ on: push: branches: - master - - http-status-code tags: - "*"