2022-02-07 13:58:04 +03:00
package integration
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
"strconv"
2024-01-09 19:00:07 +03:00
"testing"
2022-02-07 13:58:04 +03:00
"time"
2024-01-09 19:00:07 +03:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
2023-02-03 17:24:05 +03:00
"github.com/traefik/traefik/v3/integration/try"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
2022-02-07 13:58:04 +03:00
)
type ThrottlingSuite struct { BaseSuite }
2024-01-09 19:00:07 +03:00
func TestThrottlingSuite ( t * testing . T ) {
suite . Run ( t , new ( ThrottlingSuite ) )
2022-02-07 13:58:04 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ThrottlingSuite ) SetupSuite ( ) {
s . BaseSuite . SetupSuite ( )
s . createComposeProject ( "rest" )
s . composeUp ( )
}
2022-02-07 13:58:04 +03:00
2024-01-09 19:00:07 +03:00
func ( s * ThrottlingSuite ) TestThrottleConfReload ( ) {
s . traefikCmd ( withConfigFile ( "fixtures/throttling/simple.toml" ) )
2022-02-07 13:58:04 +03:00
// wait for Traefik
2024-03-12 11:48:04 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 5 * time . Second , try . BodyContains ( "rest@internal" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-02-07 13:58:04 +03:00
// Expected a 404 as we did not configure anything.
2024-03-12 11:48:04 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/" , 2 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-02-07 13:58:04 +03: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 19:00:07 +03:00
URL : "http://" + s . getComposeServiceIP ( "whoami1" ) + ":80" ,
2022-02-07 13:58:04 +03:00
} ,
} ,
} ,
} ,
} ,
} ,
}
router := & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Middlewares : [ ] string { } ,
Service : "serviceHTTP" ,
Rule : "PathPrefix(`/`)" ,
}
confChanges := 10
2024-02-19 17:44:03 +03:00
for i := range confChanges {
2022-02-07 13:58:04 +03:00
config . HTTP . Routers [ fmt . Sprintf ( "routerHTTP%d" , i ) ] = router
data , err := json . Marshal ( config )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-02-07 13:58:04 +03:00
request , err := http . NewRequest ( http . MethodPut , "http://127.0.0.1:8080/api/providers/rest" , bytes . NewReader ( data ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-02-07 13:58:04 +03:00
response , err := http . DefaultClient . Do ( request )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
assert . Equal ( s . T ( ) , http . StatusOK , response . StatusCode )
2022-02-07 13:58:04 +03: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 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-02-07 13:58:04 +03:00
defer resp . Body . Close ( )
body , err := io . ReadAll ( resp . Body )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-02-07 13:58:04 +03:00
fields := reloadsRegexp . FindStringSubmatch ( string ( body ) )
2024-01-09 19:00:07 +03:00
assert . Len ( s . T ( ) , fields , 2 )
2022-02-07 13:58:04 +03: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 19:00:07 +03:00
assert . LessOrEqual ( s . T ( ) , reloads , 6 )
2022-02-07 13:58:04 +03:00
}