2020-09-13 11:20:11 +02:00
|
|
|
package timeout
|
2020-06-21 14:46:34 +02:00
|
|
|
|
2022-09-16 17:03:02 +03:00
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http/httptest"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2020-09-13 11:20:11 +02:00
|
|
|
|
2022-10-28 17:26:17 +03:00
|
|
|
"github.com/gofiber/fiber/v3"
|
|
|
|
"github.com/stretchr/testify/require"
|
2022-09-16 17:03:02 +03:00
|
|
|
)
|
2020-07-04 10:11:23 +02:00
|
|
|
|
2022-09-16 17:03:02 +03:00
|
|
|
// go test -run Test_Timeout
|
|
|
|
func Test_Timeout(t *testing.T) {
|
|
|
|
// fiber instance
|
|
|
|
app := fiber.New()
|
2022-10-28 17:26:17 +03:00
|
|
|
h := New(func(c fiber.Ctx) error {
|
2022-09-16 17:03:02 +03:00
|
|
|
sleepTime, _ := time.ParseDuration(c.Params("sleepTime") + "ms")
|
|
|
|
if err := sleepWithContext(c.UserContext(), sleepTime, context.DeadlineExceeded); err != nil {
|
|
|
|
return fmt.Errorf("%w: l2 wrap", fmt.Errorf("%w: l1 wrap ", err))
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}, 100*time.Millisecond)
|
|
|
|
app.Get("/test/:sleepTime", h)
|
|
|
|
testTimeout := func(timeoutStr string) {
|
|
|
|
resp, err := app.Test(httptest.NewRequest("GET", "/test/"+timeoutStr, nil))
|
2022-10-28 17:26:17 +03:00
|
|
|
require.Equal(t, nil, err, "app.Test(req)")
|
|
|
|
require.Equal(t, fiber.StatusRequestTimeout, resp.StatusCode, "Status code")
|
2022-09-16 17:03:02 +03:00
|
|
|
}
|
|
|
|
testSucces := func(timeoutStr string) {
|
|
|
|
resp, err := app.Test(httptest.NewRequest("GET", "/test/"+timeoutStr, nil))
|
2022-10-28 17:26:17 +03:00
|
|
|
require.Equal(t, nil, err, "app.Test(req)")
|
|
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
2022-09-16 17:03:02 +03:00
|
|
|
}
|
|
|
|
testTimeout("300")
|
|
|
|
testTimeout("500")
|
|
|
|
testSucces("50")
|
|
|
|
testSucces("30")
|
|
|
|
}
|
2020-07-04 10:11:23 +02:00
|
|
|
|
2022-09-16 17:03:02 +03:00
|
|
|
var ErrFooTimeOut = errors.New("foo context canceled")
|
2020-07-04 10:11:23 +02:00
|
|
|
|
2022-09-16 17:03:02 +03:00
|
|
|
// go test -run Test_TimeoutWithCustomError
|
|
|
|
func Test_TimeoutWithCustomError(t *testing.T) {
|
|
|
|
// fiber instance
|
|
|
|
app := fiber.New()
|
2022-10-28 17:26:17 +03:00
|
|
|
h := New(func(c fiber.Ctx) error {
|
2022-09-16 17:03:02 +03:00
|
|
|
sleepTime, _ := time.ParseDuration(c.Params("sleepTime") + "ms")
|
|
|
|
if err := sleepWithContext(c.UserContext(), sleepTime, ErrFooTimeOut); err != nil {
|
|
|
|
return fmt.Errorf("%w: execution error", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}, 100*time.Millisecond, ErrFooTimeOut)
|
|
|
|
app.Get("/test/:sleepTime", h)
|
|
|
|
testTimeout := func(timeoutStr string) {
|
|
|
|
resp, err := app.Test(httptest.NewRequest("GET", "/test/"+timeoutStr, nil))
|
2022-10-28 17:26:17 +03:00
|
|
|
require.Equal(t, nil, err, "app.Test(req)")
|
|
|
|
require.Equal(t, fiber.StatusRequestTimeout, resp.StatusCode, "Status code")
|
2022-09-16 17:03:02 +03:00
|
|
|
}
|
|
|
|
testSucces := func(timeoutStr string) {
|
|
|
|
resp, err := app.Test(httptest.NewRequest("GET", "/test/"+timeoutStr, nil))
|
2022-10-28 17:26:17 +03:00
|
|
|
require.Equal(t, nil, err, "app.Test(req)")
|
|
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
2022-09-16 17:03:02 +03:00
|
|
|
}
|
|
|
|
testTimeout("300")
|
|
|
|
testTimeout("500")
|
|
|
|
testSucces("50")
|
|
|
|
testSucces("30")
|
|
|
|
}
|
2020-07-04 10:11:23 +02:00
|
|
|
|
2022-09-16 17:03:02 +03:00
|
|
|
func sleepWithContext(ctx context.Context, d time.Duration, te error) error {
|
|
|
|
timer := time.NewTimer(d)
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
if !timer.Stop() {
|
|
|
|
<-timer.C
|
|
|
|
}
|
|
|
|
return te
|
|
|
|
case <-timer.C:
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|