From cc043a1dc8ba5cc3422ab2f8d39dbd97fc3945d5 Mon Sep 17 00:00:00 2001 From: hlts2 Date: Tue, 5 Jan 2021 15:00:41 +0900 Subject: [PATCH 1/5] feat: add http error test Signed-off-by: hlts2 --- internal/errors/http_test.go | 488 +++++++++++++++++++++++++++++++++++ 1 file changed, 488 insertions(+) create mode 100644 internal/errors/http_test.go diff --git a/internal/errors/http_test.go b/internal/errors/http_test.go new file mode 100644 index 00000000000..23e002d7a4b --- /dev/null +++ b/internal/errors/http_test.go @@ -0,0 +1,488 @@ +package errors + +import ( + "math" + "testing" + "time" +) + +func TestErrInvalidAPIConfig(t *testing.T) { + type want struct { + want error + } + type test struct { + name string + want want + checkFunc func(want, error) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "return ErrInvalidAPIConfig error", + want: want{ + want: New("invalid api config"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrInvalidAPIConfig + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} + +func TestErrInvalidRequest(t *testing.T) { + type want struct { + want error + } + type test struct { + name string + want want + checkFunc func(want, error) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "return ErrInvalidRequest error", + want: want{ + want: New("invalid request"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrInvalidRequest + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} + +func TestErrHandler(t *testing.T) { + type args struct { + err error + } + type want struct { + want error + } + type test struct { + name string + args args + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "return wrapped ErrHandler error with the err is database error", + args: args{ + err: New("database error"), + }, + want: want{ + want: New("handler returned error: database error"), + }, + }, + { + name: "return ErrHandler error with the err is nil", + args: args{ + err: nil, + }, + want: want{ + want: New("handler returned error"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrHandler(test.args.err) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} + +func TestErrHandlerTimeout(t *testing.T) { + type args struct { + err error + dur time.Duration + } + type want struct { + want error + } + type test struct { + name string + args args + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is 100", + args: args{ + err: New("database error"), + dur: 100, + }, + want: want{ + want: New("handler timeout 100ns: database error"), + }, + }, + { + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is 0", + args: args{ + err: New("database error"), + dur: 0, + }, + want: want{ + want: New("handler timeout 0s: database error"), + }, + }, + { + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the maximum number of int64", + args: args{ + err: New("database error"), + dur: math.MaxInt64, + }, + want: want{ + want: New("handler timeout 2562047h47m16.854775807s: database error"), + }, + }, + { + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is -1", + args: args{ + err: New("database error"), + dur: -1, + }, + want: want{ + want: New("handler timeout -1ns: database error"), + }, + }, + { + name: "returns ErrHandlerTimeout error when the err is nil and the dur is 100", + args: args{ + err: nil, + dur: 1, + }, + want: want{ + want: New("handler timeout 1ns"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrHandlerTimeout(test.args.err, test.args.dur) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} + +func TestErrRequestBodyCloseAndFlush(t *testing.T) { + type args struct { + err error + } + type want struct { + want error + } + type test struct { + name string + args args + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "returns wrapped ErrRequestBodyCloseAndFlush error when the err is close error", + args: args{ + err: New("close error"), + }, + want: want{ + want: New("request body flush & close failed: close error"), + }, + }, + { + name: "returns ErrRequestBodyCloseAndFlush error when the err is nil", + args: args{ + err: nil, + }, + want: want{ + want: New("request body flush & close failed"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrRequestBodyCloseAndFlush(test.args.err) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} + +func TestErrRequestBodyClose(t *testing.T) { + type args struct { + err error + } + type want struct { + want error + } + type test struct { + name string + args args + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "returns wrapped ErrRequestBodyClose error when the err is close error", + args: args{ + err: New("close error"), + }, + want: want{ + want: New("request body close failed: close error"), + }, + }, + { + name: "returns ErrRequestBodyClose error when the err is nil", + args: args{ + err: nil, + }, + want: want{ + want: New("request body close failed"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrRequestBodyClose(test.args.err) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} + +func TestErrRequestBodyFlush(t *testing.T) { + type args struct { + err error + } + type want struct { + want error + } + type test struct { + name string + args args + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "returns wrapped ErrRequestBodyFlush error when the err is close error", + args: args{ + err: New("close error"), + }, + want: want{ + want: New("request body flush failed: close error"), + }, + }, + { + name: "returns ErrRequestBodyFlush error when the err is nil", + args: args{ + err: nil, + }, + want: want{ + want: New("request body flush failed"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrRequestBodyFlush(test.args.err) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} + +func TestErrTransportRetryable(t *testing.T) { + type want struct { + want error + } + type test struct { + name string + want want + checkFunc func(want, error) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got error) error { + if !Is(got, w.want) { + return Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + } + return nil + } + tests := []test{ + { + name: "return ErrTransportRetryable error", + want: want{ + want: New("transport is retryable"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := ErrTransportRetryable + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} From c835e2ef72913a4c5f5467c746d35eeaf823a7a6 Mon Sep 17 00:00:00 2001 From: hlts2 Date: Wed, 6 Jan 2021 12:51:43 +0900 Subject: [PATCH 2/5] feat: add godoc comment and test case for boundary value Signed-off-by: hlts2 --- internal/errors/http.go | 10 ++++++++-- internal/errors/http_test.go | 37 +++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/internal/errors/http.go b/internal/errors/http.go index 77385fba4e2..6949f690403 100644 --- a/internal/errors/http.go +++ b/internal/errors/http.go @@ -20,31 +20,37 @@ package errors import "time" var ( - // HTTP. - + // ErrInvalidAPIConfig represents an error that the API configuration is invalid. ErrInvalidAPIConfig = New("invalid api config") + // ErrInvalidRequest represents an error that the API request is invalid. ErrInvalidRequest = New("invalid request") + // ErrHandler represents a function to generate an error that the handler returned an error. ErrHandler = func(err error) error { return Wrap(err, "handler returned error") } + // ErrHandlerTimeout represents a function to generate an error that the handler was time out. ErrHandlerTimeout = func(err error, dur time.Duration) error { return Wrapf(err, "handler timeout %s", dur.String()) } + // ErrRequestBodyCloseAndFlush represents a function to generate an error that the flush of the request body and the close failed. ErrRequestBodyCloseAndFlush = func(err error) error { return Wrap(err, "request body flush & close failed") } + // ErrRequestBodyClose represents a function to generate an error that the close of the request body failed. ErrRequestBodyClose = func(err error) error { return Wrap(err, "request body close failed") } + // ErrRequestBodyFlush represents a function to generate an error that the flush of the request body failed. ErrRequestBodyFlush = func(err error) error { return Wrap(err, "request body flush failed") } + // ErrTransportRetryable represents an error that the transport is retryable. ErrTransportRetryable = New("transport is retryable") ) diff --git a/internal/errors/http_test.go b/internal/errors/http_test.go index 23e002d7a4b..c760882ea3c 100644 --- a/internal/errors/http_test.go +++ b/internal/errors/http_test.go @@ -1,6 +1,7 @@ package errors import ( + "fmt" "math" "testing" "time" @@ -184,17 +185,27 @@ func TestErrHandlerTimeout(t *testing.T) { } tests := []test{ { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is 100", + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the minimum number of int64", args: args{ err: New("database error"), - dur: 100, + dur: math.MinInt64, }, want: want{ - want: New("handler timeout 100ns: database error"), + want: New(fmt.Sprintf("handler timeout %s: database error", time.Duration(math.MinInt64).String())), + }, + }, + { + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the 'MinInt64+1'", + args: args{ + err: New("database error"), + dur: math.MinInt64 + 1, + }, + want: want{ + want: New(fmt.Sprintf("handler timeout %s: database error", time.Duration(math.MinInt64+1).String())), }, }, { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is 0", + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is '0'", args: args{ err: New("database error"), dur: 0, @@ -204,33 +215,33 @@ func TestErrHandlerTimeout(t *testing.T) { }, }, { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the maximum number of int64", + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is '100'", args: args{ err: New("database error"), - dur: math.MaxInt64, + dur: 100, }, want: want{ - want: New("handler timeout 2562047h47m16.854775807s: database error"), + want: New("handler timeout 100ns: database error"), }, }, { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is -1", + name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the maximum number of int64", args: args{ err: New("database error"), - dur: -1, + dur: math.MaxInt64, }, want: want{ - want: New("handler timeout -1ns: database error"), + want: Errorf("handler timeout %s: database error", time.Duration(math.MaxInt64)), }, }, { - name: "returns ErrHandlerTimeout error when the err is nil and the dur is 100", + name: "returns ErrHandlerTimeout error when the err is nil and the dur is '100'", args: args{ err: nil, - dur: 1, + dur: 100, }, want: want{ - want: New("handler timeout 1ns"), + want: New("handler timeout 100ns"), }, }, } From 654e24fa112f92366486dd5004a8caa1a9c990bb Mon Sep 17 00:00:00 2001 From: Hiroto Funakoshi Date: Wed, 6 Jan 2021 14:28:41 +0900 Subject: [PATCH 3/5] Apply suggestions from code review --- internal/errors/http_test.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/errors/http_test.go b/internal/errors/http_test.go index c760882ea3c..b10a50f338d 100644 --- a/internal/errors/http_test.go +++ b/internal/errors/http_test.go @@ -185,7 +185,7 @@ func TestErrHandlerTimeout(t *testing.T) { } tests := []test{ { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the minimum number of int64", + name: "return wrapped ErrHandlerTimeout error when the err is database error and the dur is the minimum number of int64", args: args{ err: New("database error"), dur: math.MinInt64, @@ -195,7 +195,7 @@ func TestErrHandlerTimeout(t *testing.T) { }, }, { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the 'MinInt64+1'", + name: "return wrapped ErrHandlerTimeout error when the err is database error and the dur is the 'MinInt64+1'", args: args{ err: New("database error"), dur: math.MinInt64 + 1, @@ -205,7 +205,7 @@ func TestErrHandlerTimeout(t *testing.T) { }, }, { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is '0'", + name: "return wrapped ErrHandlerTimeout error when the err is database error and the dur is '0'", args: args{ err: New("database error"), dur: 0, @@ -215,7 +215,7 @@ func TestErrHandlerTimeout(t *testing.T) { }, }, { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is '100'", + name: "return wrapped ErrHandlerTimeout error when the err is database error and the dur is '100'", args: args{ err: New("database error"), dur: 100, @@ -225,7 +225,7 @@ func TestErrHandlerTimeout(t *testing.T) { }, }, { - name: "returns wrapped ErrHandlerTimeout error when the err is database error and the dur is the maximum number of int64", + name: "return wrapped ErrHandlerTimeout error when the err is database error and the dur is the maximum number of int64", args: args{ err: New("database error"), dur: math.MaxInt64, @@ -235,7 +235,7 @@ func TestErrHandlerTimeout(t *testing.T) { }, }, { - name: "returns ErrHandlerTimeout error when the err is nil and the dur is '100'", + name: "return ErrHandlerTimeout error when the err is nil and the dur is '100'", args: args{ err: nil, dur: 100, @@ -289,7 +289,7 @@ func TestErrRequestBodyCloseAndFlush(t *testing.T) { } tests := []test{ { - name: "returns wrapped ErrRequestBodyCloseAndFlush error when the err is close error", + name: "return wrapped ErrRequestBodyCloseAndFlush error when the err is close error", args: args{ err: New("close error"), }, @@ -298,7 +298,7 @@ func TestErrRequestBodyCloseAndFlush(t *testing.T) { }, }, { - name: "returns ErrRequestBodyCloseAndFlush error when the err is nil", + name: "return ErrRequestBodyCloseAndFlush error when the err is nil", args: args{ err: nil, }, @@ -351,7 +351,7 @@ func TestErrRequestBodyClose(t *testing.T) { } tests := []test{ { - name: "returns wrapped ErrRequestBodyClose error when the err is close error", + name: "return wrapped ErrRequestBodyClose error when the err is close error", args: args{ err: New("close error"), }, @@ -360,7 +360,7 @@ func TestErrRequestBodyClose(t *testing.T) { }, }, { - name: "returns ErrRequestBodyClose error when the err is nil", + name: "return ErrRequestBodyClose error when the err is nil", args: args{ err: nil, }, @@ -413,7 +413,7 @@ func TestErrRequestBodyFlush(t *testing.T) { } tests := []test{ { - name: "returns wrapped ErrRequestBodyFlush error when the err is close error", + name: "return wrapped ErrRequestBodyFlush error when the err is close error", args: args{ err: New("close error"), }, @@ -422,7 +422,7 @@ func TestErrRequestBodyFlush(t *testing.T) { }, }, { - name: "returns ErrRequestBodyFlush error when the err is nil", + name: "return ErrRequestBodyFlush error when the err is nil", args: args{ err: nil, }, From 62cfc2a7b3c62183b825eb72d3fd20d9b243668e Mon Sep 17 00:00:00 2001 From: hlts2 Date: Wed, 6 Jan 2021 14:31:06 +0900 Subject: [PATCH 4/5] fix: refactor for error string Signed-off-by: hlts2 --- internal/errors/http_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/errors/http_test.go b/internal/errors/http_test.go index b10a50f338d..11b52175c37 100644 --- a/internal/errors/http_test.go +++ b/internal/errors/http_test.go @@ -1,7 +1,6 @@ package errors import ( - "fmt" "math" "testing" "time" @@ -191,7 +190,7 @@ func TestErrHandlerTimeout(t *testing.T) { dur: math.MinInt64, }, want: want{ - want: New(fmt.Sprintf("handler timeout %s: database error", time.Duration(math.MinInt64).String())), + want: Errorf("handler timeout %s: database error", time.Duration(math.MinInt64).String()), }, }, { @@ -201,7 +200,7 @@ func TestErrHandlerTimeout(t *testing.T) { dur: math.MinInt64 + 1, }, want: want{ - want: New(fmt.Sprintf("handler timeout %s: database error", time.Duration(math.MinInt64+1).String())), + want: Errorf("handler timeout %s: database error", time.Duration(math.MinInt64+1).String()), }, }, { From ff290f97d5bd0139fee7f55c544c5a962dc347d9 Mon Sep 17 00:00:00 2001 From: hlts2 Date: Wed, 6 Jan 2021 14:33:27 +0900 Subject: [PATCH 5/5] fix: grammar. with -> when Signed-off-by: hlts2 --- internal/errors/http_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/errors/http_test.go b/internal/errors/http_test.go index 11b52175c37..7eb0e7b0321 100644 --- a/internal/errors/http_test.go +++ b/internal/errors/http_test.go @@ -121,7 +121,7 @@ func TestErrHandler(t *testing.T) { } tests := []test{ { - name: "return wrapped ErrHandler error with the err is database error", + name: "return wrapped ErrHandler error when the err is database error", args: args{ err: New("database error"), }, @@ -130,7 +130,7 @@ func TestErrHandler(t *testing.T) { }, }, { - name: "return ErrHandler error with the err is nil", + name: "return ErrHandler error when the err is nil", args: args{ err: nil, },