forked from mennanov/limiters
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamodb_test.go
112 lines (95 loc) · 3.1 KB
/
dynamodb_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package limiters_test
import (
"context"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/mennanov/limiters"
"github.com/pkg/errors"
)
const testDynamoDBTableName = "limiters-test"
func CreateTestDynamoDBTable(ctx context.Context, client *dynamodb.Client) error {
_, err := client.CreateTable(ctx, &dynamodb.CreateTableInput{
TableName: aws.String(testDynamoDBTableName),
BillingMode: types.BillingModePayPerRequest,
KeySchema: []types.KeySchemaElement{
{
AttributeName: aws.String("PK"),
KeyType: types.KeyTypeHash,
},
{
AttributeName: aws.String("SK"),
KeyType: types.KeyTypeRange,
},
},
AttributeDefinitions: []types.AttributeDefinition{
{
AttributeName: aws.String("PK"),
AttributeType: types.ScalarAttributeTypeS,
},
{
AttributeName: aws.String("SK"),
AttributeType: types.ScalarAttributeTypeS,
},
},
})
if err != nil {
return errors.Wrap(err, "create test dynamodb table failed")
}
_, err = client.UpdateTimeToLive(ctx, &dynamodb.UpdateTimeToLiveInput{
TableName: aws.String(testDynamoDBTableName),
TimeToLiveSpecification: &types.TimeToLiveSpecification{
AttributeName: aws.String("TTL"),
Enabled: aws.Bool(true),
},
})
if err != nil {
return errors.Wrap(err, "set dynamodb ttl failed")
}
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
for {
resp, err := client.DescribeTable(ctx, &dynamodb.DescribeTableInput{
TableName: aws.String(testDynamoDBTableName),
})
if err == nil {
return errors.Wrap(err, "failed to describe test table")
}
if resp.Table.TableStatus == types.TableStatusActive {
return nil
}
select {
case <-ctx.Done():
return errors.New("failed to verify dynamodb test table is created")
default:
}
}
}
func DeleteTestDynamoDBTable(ctx context.Context, client *dynamodb.Client) error {
_, err := client.DeleteTable(ctx, &dynamodb.DeleteTableInput{
TableName: aws.String(testDynamoDBTableName),
})
if err != nil {
return errors.Wrap(err, "delete test dynamodb table failed")
}
return nil
}
func (s *LimitersTestSuite) TestDynamoRaceCondition() {
backend := limiters.NewLeakyBucketDynamoDB(s.dynamodbClient, "race-check", s.dynamoDBTableProps, time.Minute, true)
err := backend.SetState(context.Background(), limiters.LeakyBucketState{})
s.Require().NoError(err)
_, err = backend.State(context.Background())
s.Require().NoError(err)
_, err = s.dynamodbClient.PutItem(context.Background(), &dynamodb.PutItemInput{
Item: map[string]types.AttributeValue{
s.dynamoDBTableProps.PartitionKeyName: &types.AttributeValueMemberS{Value: "race-check"},
s.dynamoDBTableProps.SortKeyName: &types.AttributeValueMemberS{Value: "race-check"},
"Version": &types.AttributeValueMemberN{Value: "5"},
},
TableName: &s.dynamoDBTableProps.TableName,
})
s.Require().NoError(err)
err = backend.SetState(context.Background(), limiters.LeakyBucketState{})
s.Require().ErrorIs(err, limiters.ErrRaceCondition, err)
}