2022-02-07 10:58:04 +00:00
|
|
|
package integration
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"regexp"
|
|
|
|
"strconv"
|
2024-01-09 16:00:07 +00:00
|
|
|
"testing"
|
2022-02-07 10:58:04 +00:00
|
|
|
"time"
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/stretchr/testify/suite"
|
2023-02-03 14:24:05 +00:00
|
|
|
"github.com/traefik/traefik/v3/integration/try"
|
|
|
|
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
2022-02-07 10:58:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type ThrottlingSuite struct{ BaseSuite }
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func TestThrottlingSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(ThrottlingSuite))
|
2022-02-07 10:58:04 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func (s *ThrottlingSuite) SetupSuite() {
|
|
|
|
s.BaseSuite.SetupSuite()
|
|
|
|
s.createComposeProject("rest")
|
|
|
|
s.composeUp()
|
|
|
|
}
|
2022-02-07 10:58:04 +00:00
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func (s *ThrottlingSuite) TestThrottleConfReload() {
|
|
|
|
s.traefikCmd(withConfigFile("fixtures/throttling/simple.toml"))
|
2022-02-07 10:58:04 +00:00
|
|
|
|
|
|
|
// wait for Traefik
|
2024-01-09 16:00:07 +00:00
|
|
|
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("rest@internal"))
|
|
|
|
require.NoError(s.T(), err)
|
2022-02-07 10:58:04 +00:00
|
|
|
|
|
|
|
// Expected a 404 as we did not configure anything.
|
|
|
|
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
2022-02-07 10:58:04 +00:00
|
|
|
|
|
|
|
config := &dynamic.Configuration{
|
|
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
|
|
Routers: map[string]*dynamic.Router{},
|
|
|
|
Services: map[string]*dynamic.Service{
|
|
|
|
"serviceHTTP": {
|
|
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
|
|
Servers: []dynamic.Server{
|
|
|
|
{
|
2024-01-09 16:00:07 +00:00
|
|
|
URL: "http://" + s.getComposeServiceIP("whoami1") + ":80",
|
2022-02-07 10:58:04 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
router := &dynamic.Router{
|
|
|
|
EntryPoints: []string{"web"},
|
|
|
|
Middlewares: []string{},
|
|
|
|
Service: "serviceHTTP",
|
|
|
|
Rule: "PathPrefix(`/`)",
|
|
|
|
}
|
|
|
|
|
|
|
|
confChanges := 10
|
|
|
|
|
|
|
|
for i := 0; i < confChanges; i++ {
|
|
|
|
config.HTTP.Routers[fmt.Sprintf("routerHTTP%d", i)] = router
|
|
|
|
data, err := json.Marshal(config)
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
2022-02-07 10:58:04 +00:00
|
|
|
|
|
|
|
request, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:8080/api/providers/rest", bytes.NewReader(data))
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
2022-02-07 10:58:04 +00:00
|
|
|
|
|
|
|
response, err := http.DefaultClient.Do(request)
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
|
|
|
assert.Equal(s.T(), http.StatusOK, response.StatusCode)
|
2022-02-07 10:58:04 +00:00
|
|
|
time.Sleep(200 * time.Millisecond)
|
|
|
|
}
|
|
|
|
|
|
|
|
reloadsRegexp := regexp.MustCompile(`traefik_config_reloads_total (\d*)\n`)
|
|
|
|
|
|
|
|
resp, err := http.Get("http://127.0.0.1:8080/metrics")
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
2022-02-07 10:58:04 +00:00
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
2022-02-07 10:58:04 +00:00
|
|
|
|
|
|
|
fields := reloadsRegexp.FindStringSubmatch(string(body))
|
2024-01-09 16:00:07 +00:00
|
|
|
assert.Len(s.T(), fields, 2)
|
2022-02-07 10:58:04 +00:00
|
|
|
|
|
|
|
reloads, err := strconv.Atoi(fields[1])
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The test tries to trigger a config reload with the REST API every 200ms,
|
|
|
|
// 10 times (so for 2s in total).
|
|
|
|
// Therefore the throttling (set at 400ms for this test) should only let
|
|
|
|
// (2s / 400 ms =) 5 config reloads happen in theory.
|
|
|
|
// In addition, we have to take into account the extra config reload from the internal provider (5 + 1).
|
2024-01-09 16:00:07 +00:00
|
|
|
assert.LessOrEqual(s.T(), reloads, 6)
|
2022-02-07 10:58:04 +00:00
|
|
|
}
|