Skip to content

Commit

Permalink
add integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
Junchao Lyu committed Dec 20, 2019
1 parent 974d35c commit e6cf1ec
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 96 deletions.
226 changes: 130 additions & 96 deletions test/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,47 @@ func newDescriptorStatusLegacy(
}
}


func TestBasicConfig(t *testing.T) {
t.Run("WithoutPerSecondRedis", testBasicConfig("8083", "false"))
t.Run("WithPerSecondRedis", testBasicConfig("8085", "true"))
t.Run("WithoutPerSecondRedis", testBasicConfig("8083", "false", "0"))
t.Run("WithPerSecondRedis", testBasicConfig("8085", "true", "0"))
t.Run("WithoutPerSecondRedisWithLocalCache", testBasicConfig("8083", "false", "1000"))
t.Run("WithPerSecondRedisWithLocalCache", testBasicConfig("8085", "true", "1000"))
}


func TestBasicTLSConfig(t *testing.T) {
t.Run("WithoutPerSecondRedisTLS", testBasicConfigAuthTLS("8087", "false"))
t.Run("WithPerSecondRedisTLS", testBasicConfigAuthTLS("8089", "true"))
t.Run("WithoutPerSecondRedisTLS", testBasicConfigAuthTLS("8087", "false", "0"))
t.Run("WithPerSecondRedisTLS", testBasicConfigAuthTLS("8089", "true", "0"))
t.Run("WithoutPerSecondRedisTLSWithLocalCache", testBasicConfigAuthTLS("8087", "false", "1000"))
t.Run("WithPerSecondRedisTLSWithLocalCache", testBasicConfigAuthTLS("8089", "true", "1000"))
}
func testBasicConfigAuthTLS(grpcPort, perSecond string) func(*testing.T) {

func testBasicConfigAuthTLS(grpcPort, perSecond string, local_cache_size string) func(*testing.T) {
os.Setenv("REDIS_PERSECOND_URL", "localhost:16382")
os.Setenv("REDIS_URL", "localhost:16381")
os.Setenv("REDIS_AUTH", "password123")
os.Setenv("REDIS_PERSECOND_AUTH", "password123")
return testBasicBaseConfig(grpcPort, perSecond)
return testBasicBaseConfig(grpcPort, perSecond, local_cache_size)
}
func testBasicConfig(grpcPort, perSecond string) func(*testing.T) {

func testBasicConfig(grpcPort, perSecond string, local_cache_size string) func(*testing.T) {
os.Setenv("REDIS_PERSECOND_URL", "localhost:6380")
os.Setenv("REDIS_URL", "localhost:6379")
os.Setenv("REDIS_TLS", "false")
os.Setenv("REDIS_PERSECOND_TLS", "false")
return testBasicBaseConfig(grpcPort, perSecond)
return testBasicBaseConfig(grpcPort, perSecond, local_cache_size)
}
func testBasicBaseConfig(grpcPort, perSecond string) func(*testing.T) {

func getCacheKey(cacheKey string, enableLocalCache bool) string {
if enableLocalCache {
return cacheKey + "_local"
}

return cacheKey
}

func testBasicBaseConfig(grpcPort, perSecond string, local_cache_size string) func(*testing.T) {
return func(t *testing.T) {
os.Setenv("REDIS_PERSECOND", perSecond)
os.Setenv("PORT", "8082")
Expand All @@ -73,6 +91,10 @@ func testBasicBaseConfig(grpcPort, perSecond string) func(*testing.T) {
os.Setenv("RUNTIME_SUBDIRECTORY", "ratelimit")
os.Setenv("REDIS_PERSECOND_SOCKET_TYPE", "tcp")
os.Setenv("REDIS_SOCKET_TYPE", "tcp")
os.Setenv("LOCAL_CACHE_SIZE", local_cache_size)

local_cache_size_val, _ := strconv.Atoi(local_cache_size)
enable_local_cache := local_cache_size_val > 0

go func() {
runner.Run()
Expand All @@ -89,7 +111,7 @@ func testBasicBaseConfig(grpcPort, perSecond string) func(*testing.T) {

response, err := c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequest("foo", [][][2]string{{{"hello", "world"}}}, 1))
common.NewRateLimitRequest("foo", [][][2]string{{{getCacheKey("hello", enable_local_cache), "world"}}}, 1))
assert.Equal(
&pb.RateLimitResponse{
OverallCode: pb.RateLimitResponse_OK,
Expand All @@ -99,7 +121,7 @@ func testBasicBaseConfig(grpcPort, perSecond string) func(*testing.T) {

response, err = c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequest("basic", [][][2]string{{{"key1", "foo"}}}, 1))
common.NewRateLimitRequest("basic", [][][2]string{{{getCacheKey("key1", enable_local_cache), "foo"}}}, 1))
assert.Equal(
&pb.RateLimitResponse{
OverallCode: pb.RateLimitResponse_OK,
Expand All @@ -115,7 +137,7 @@ func testBasicBaseConfig(grpcPort, perSecond string) func(*testing.T) {
response, err = c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequest(
"another", [][][2]string{{{"key2", strconv.Itoa(randomInt)}}}, 1))
"another", [][][2]string{{{getCacheKey("key2", enable_local_cache), strconv.Itoa(randomInt)}}}, 1))

status := pb.RateLimitResponse_OK
limitRemaining := uint32(20 - (i + 1))
Expand All @@ -141,8 +163,8 @@ func testBasicBaseConfig(grpcPort, perSecond string) func(*testing.T) {
common.NewRateLimitRequest(
"another",
[][][2]string{
{{"key2", strconv.Itoa(randomInt)}},
{{"key3", strconv.Itoa(randomInt)}}}, 1))
{{getCacheKey("key2", enable_local_cache), strconv.Itoa(randomInt)}},
{{getCacheKey("key3", enable_local_cache), strconv.Itoa(randomInt)}}}, 1))

status := pb.RateLimitResponse_OK
limitRemaining1 := uint32(20 - (i + 1))
Expand All @@ -165,101 +187,113 @@ func testBasicBaseConfig(grpcPort, perSecond string) func(*testing.T) {
}

func TestBasicConfigLegacy(t *testing.T) {
os.Setenv("PORT", "8082")
os.Setenv("GRPC_PORT", "8083")
os.Setenv("DEBUG_PORT", "8084")
os.Setenv("RUNTIME_ROOT", "runtime/current")
os.Setenv("RUNTIME_SUBDIRECTORY", "ratelimit")
t.Run("testBasicConfigLegacy", testBasicConfigLegacy("0"))
t.Run("testBasicConfigLegacyWithLocalCache", testBasicConfigLegacy("1000"))
}

os.Setenv("REDIS_PERSECOND_URL", "localhost:6380")
os.Setenv("REDIS_URL", "localhost:6379")
os.Setenv("REDIS_TLS", "false")
os.Setenv("REDIS_PERSECOND_TLS", "false")
go func() {
runner.Run()
}()

// HACK: Wait for the server to come up. Make a hook that we can wait on.
time.Sleep(100 * time.Millisecond)

assert := assert.New(t)
conn, err := grpc.Dial("localhost:8083", grpc.WithInsecure())
assert.NoError(err)
defer conn.Close()
c := pb_legacy.NewRateLimitServiceClient(conn)

response, err := c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequestLegacy("foo", [][][2]string{{{"hello", "world"}}}, 1))
assert.Equal(
&pb_legacy.RateLimitResponse{
OverallCode: pb_legacy.RateLimitResponse_OK,
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{{Code: pb_legacy.RateLimitResponse_OK, CurrentLimit: nil, LimitRemaining: 0}}},
response)
assert.NoError(err)

response, err = c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequestLegacy("basic_legacy", [][][2]string{{{"key1", "foo"}}}, 1))
assert.Equal(
&pb_legacy.RateLimitResponse{
OverallCode: pb_legacy.RateLimitResponse_OK,
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
newDescriptorStatusLegacy(pb_legacy.RateLimitResponse_OK, 50, pb_legacy.RateLimit_SECOND, 49)}},
response)
assert.NoError(err)

// Now come up with a random key, and go over limit for a minute limit which should always work.
r := rand.New(rand.NewSource(time.Now().UnixNano()))
randomInt := r.Int()
for i := 0; i < 25; i++ {
response, err = c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequestLegacy(
"another", [][][2]string{{{"key2", strconv.Itoa(randomInt)}}}, 1))

status := pb_legacy.RateLimitResponse_OK
limitRemaining := uint32(20 - (i + 1))
if i >= 20 {
status = pb_legacy.RateLimitResponse_OVER_LIMIT
limitRemaining = 0
}
func testBasicConfigLegacy(local_cache_size string) func(*testing.T) {
return func(t *testing.T) {
os.Setenv("PORT", "8082")
os.Setenv("GRPC_PORT", "8083")
os.Setenv("DEBUG_PORT", "8084")
os.Setenv("RUNTIME_ROOT", "runtime/current")
os.Setenv("RUNTIME_SUBDIRECTORY", "ratelimit")

os.Setenv("REDIS_PERSECOND_URL", "localhost:6380")
os.Setenv("REDIS_URL", "localhost:6379")
os.Setenv("REDIS_TLS", "false")
os.Setenv("REDIS_PERSECOND_TLS", "false")
os.Setenv("LOCAL_CACHE_SIZE", local_cache_size)
local_cache_size_val, _ := strconv.Atoi(local_cache_size)
enable_local_cache := local_cache_size_val > 0


go func() {
runner.Run()
}()

// HACK: Wait for the server to come up. Make a hook that we can wait on.
time.Sleep(100 * time.Millisecond)

assert := assert.New(t)
conn, err := grpc.Dial("localhost:8083", grpc.WithInsecure())
assert.NoError(err)
defer conn.Close()
c := pb_legacy.NewRateLimitServiceClient(conn)

response, err := c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequestLegacy("foo", [][][2]string{{{getCacheKey("hello", enable_local_cache), "world"}}}, 1))
assert.Equal(
&pb_legacy.RateLimitResponse{
OverallCode: status,
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
newDescriptorStatusLegacy(status, 20, pb_legacy.RateLimit_MINUTE, limitRemaining)}},
OverallCode: pb_legacy.RateLimitResponse_OK,
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{{Code: pb_legacy.RateLimitResponse_OK, CurrentLimit: nil, LimitRemaining: 0}}},
response)
assert.NoError(err)
}

// Limit now against 2 keys in the same domain.
randomInt = r.Int()
for i := 0; i < 15; i++ {
response, err = c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequestLegacy(
"another_legacy",
[][][2]string{
{{"key2", strconv.Itoa(randomInt)}},
{{"key3", strconv.Itoa(randomInt)}}}, 1))

status := pb_legacy.RateLimitResponse_OK
limitRemaining1 := uint32(20 - (i + 1))
limitRemaining2 := uint32(10 - (i + 1))
if i >= 10 {
status = pb_legacy.RateLimitResponse_OVER_LIMIT
limitRemaining2 = 0
}

common.NewRateLimitRequestLegacy("basic_legacy", [][][2]string{{{getCacheKey("key1", enable_local_cache), "foo"}}}, 1))
assert.Equal(
&pb_legacy.RateLimitResponse{
OverallCode: status,
OverallCode: pb_legacy.RateLimitResponse_OK,
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
newDescriptorStatusLegacy(pb_legacy.RateLimitResponse_OK, 20, pb_legacy.RateLimit_MINUTE, limitRemaining1),
newDescriptorStatusLegacy(status, 10, pb_legacy.RateLimit_HOUR, limitRemaining2)}},
newDescriptorStatusLegacy(pb_legacy.RateLimitResponse_OK, 50, pb_legacy.RateLimit_SECOND, 49)}},
response)
assert.NoError(err)

// Now come up with a random key, and go over limit for a minute limit which should always work.
r := rand.New(rand.NewSource(time.Now().UnixNano()))
randomInt := r.Int()
for i := 0; i < 25; i++ {
response, err = c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequestLegacy(
"another", [][][2]string{{{getCacheKey("key2", enable_local_cache), strconv.Itoa(randomInt)}}}, 1))

status := pb_legacy.RateLimitResponse_OK
limitRemaining := uint32(20 - (i + 1))
if i >= 20 {
status = pb_legacy.RateLimitResponse_OVER_LIMIT
limitRemaining = 0
}

assert.Equal(
&pb_legacy.RateLimitResponse{
OverallCode: status,
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
newDescriptorStatusLegacy(status, 20, pb_legacy.RateLimit_MINUTE, limitRemaining)}},
response)
assert.NoError(err)
}

// Limit now against 2 keys in the same domain.
randomInt = r.Int()
for i := 0; i < 15; i++ {
response, err = c.ShouldRateLimit(
context.Background(),
common.NewRateLimitRequestLegacy(
"another_legacy",
[][][2]string{
{{getCacheKey("key2", enable_local_cache), strconv.Itoa(randomInt)}},
{{getCacheKey("key3", enable_local_cache), strconv.Itoa(randomInt)}}}, 1))

status := pb_legacy.RateLimitResponse_OK
limitRemaining1 := uint32(20 - (i + 1))
limitRemaining2 := uint32(10 - (i + 1))
if i >= 10 {
status = pb_legacy.RateLimitResponse_OVER_LIMIT
limitRemaining2 = 0
}

assert.Equal(
&pb_legacy.RateLimitResponse{
OverallCode: status,
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
newDescriptorStatusLegacy(pb_legacy.RateLimitResponse_OK, 20, pb_legacy.RateLimit_MINUTE, limitRemaining1),
newDescriptorStatusLegacy(status, 10, pb_legacy.RateLimit_HOUR, limitRemaining2)}},
response)
assert.NoError(err)
}
}
}
10 changes: 10 additions & 0 deletions test/integration/runtime/current/ratelimit/config/another.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@ descriptors:
rate_limit:
unit: hour
requests_per_unit: 10

- key: key2_local
rate_limit:
unit: minute
requests_per_unit: 20

- key: key3_local
rate_limit:
unit: hour
requests_per_unit: 10
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@ descriptors:
rate_limit:
unit: hour
requests_per_unit: 10

- key: key2_local
rate_limit:
unit: minute
requests_per_unit: 20

- key: key3_local
rate_limit:
unit: hour
requests_per_unit: 10
5 changes: 5 additions & 0 deletions test/integration/runtime/current/ratelimit/config/basic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ descriptors:
rate_limit:
unit: second
requests_per_unit: 50

- key: key1_local
rate_limit:
unit: second
requests_per_unit: 50
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ descriptors:
rate_limit:
unit: second
requests_per_unit: 50

- key: key1_local
rate_limit:
unit: second
requests_per_unit: 50

0 comments on commit e6cf1ec

Please sign in to comment.