Skip to content

Commit e7a028f

Browse files
committed
Python Performance Tests - Item Encryptor
1 parent 4a23303 commit e7a028f

40 files changed

+9780
-712
lines changed

DynamoDbEncryption/runtimes/python/tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ commands =
8484
src/aws_dbesdk_dynamodb/ \
8585
../../../Examples/runtimes/python/DynamoDBEncryption/ \
8686
../../../Examples/runtimes/python/Migration/ \
87+
../../../PerfTest/runtimes/python/DynamoDBEncryption/ \
8788
test/ \
8889
{posargs}
8990

PerfTest/runtimes/java/DynamoDbEncryption/README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# AWS Database Encryption SDK Performance Test
22

3-
This project contains tests to benchmark the old v2 and the new v3 AWS Database Encryption SDK for DynamoDb in Java.
3+
This project contains tests to benchmark the old v2 and the new v3 AWS Database Encryption SDK for DynamoDb in Java.
44

55
## Benchmarking
6+
67
### Prerequisites
8+
79
You'd need the appropriate security credentials to run the Kms Key based tests. Also, build all the Gazelle dependecies and deploy to maven local.
810
The idea of perf test is to run everything from local, before the changes make it to maven central.
911

@@ -14,9 +16,10 @@ In case of any failures, look into the `README` for `DynamoDbEncryption`.
1416

1517
### Gradle Jmh
1618

17-
`` ./gradlew jmh``
19+
` ./gradlew jmh`
1820

1921
This will generate a report on console as well as in `build/results/jmh/results.txt` with the following format:
22+
2023
```
2124
Benchmark (plainTextFile) Mode Cnt Score Error Units
2225
s.a.c.p.i.v2.AesKeyProviderTest.decrypt single_attribute.json avgt 3 2.428 ± 1.484 ms/op
@@ -39,9 +42,11 @@ AwsKmsKeyProviderTest_encrypt_jmhTest 205152 274349
3942
where the columns are `OperationName OriginalSize EncryptedSize Diff`
4043

4144
### IDE (or Main Class)
45+
4246
1. Run the `main()` method in the TestBase class, or you can also run individual tests by executing the `main()` method in the respective classes.
4347
2. This serves the purpose of quickly debugging benchmarking/jmh issues.
4448

4549
## Profiling (Flamegraph) in IntelliJ
50+
4651
1. Use the main method in each Test class and `Run with Profiler`.
47-
2. The graph would show the stack and the relative time taken by each of the method call
52+
2. The graph would show the stack and the relative time taken by each of the method call
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package software.aws.cryptography.performance.itemencryptor;
22

33
public class TestConstants {
4-
public static final String PARTITION_ATTRIBUTE = "partition_key";
5-
public static final String SORT_ATTRIBUTE = "sort_key";
6-
public static final String DATA_TO_ENCRYPT = "data_to_encrypt";
7-
public static final String DATA_TO_SIGN = "data_to_sign";
8-
public static final String DATA_TO_IGNORE = ":data_to_ignore";
9-
public static final String TEST_TABLE = "Test_Table";
10-
public static final String TEST_PK = "Test_pk";
11-
public static final String SORT_NUMBER = "10";
12-
public static final String UNAUTH_PREFIX = ":";
13-
public static final String KMS_KEY_ARN = "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126";
14-
public static final String KEY_NAMESPACE = "Key_Namespace";
15-
public static final String KEY_NAME = "Key_Name";
164

17-
public static final String SIZE_RESULTS_FILE = "build/results/size.txt";
5+
public static final String PARTITION_ATTRIBUTE = "partition_key";
6+
public static final String SORT_ATTRIBUTE = "sort_key";
7+
public static final String DATA_TO_ENCRYPT = "data_to_encrypt";
8+
public static final String DATA_TO_SIGN = "data_to_sign";
9+
public static final String DATA_TO_IGNORE = ":data_to_ignore";
10+
public static final String TEST_TABLE = "Test_Table";
11+
public static final String TEST_PK = "Test_pk";
12+
public static final String SORT_NUMBER = "10";
13+
public static final String UNAUTH_PREFIX = ":";
14+
public static final String KMS_KEY_ARN =
15+
"arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126";
16+
public static final String KEY_NAMESPACE = "Key_Namespace";
17+
public static final String KEY_NAME = "Key_Name";
1818

19+
public static final String SIZE_RESULTS_FILE = "build/results/size.txt";
1920
}

PerfTest/runtimes/java/DynamoDbEncryption/src/main/java/software/aws/cryptography/performance/itemencryptor/utils/GenerateDataFlat.java

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,45 @@
22

33
import com.fasterxml.jackson.annotation.JsonInclude;
44
import com.fasterxml.jackson.databind.json.JsonMapper;
5-
import software.amazon.awssdk.core.SdkBytes;
6-
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
7-
85
import java.io.File;
96
import java.io.FileOutputStream;
107
import java.util.HashMap;
118
import java.util.Map;
129
import java.util.Random;
10+
import software.amazon.awssdk.core.SdkBytes;
11+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
1312

1413
/**
1514
* A convenient class to generate some random binary data with flat attributes. The logic is not thoroughly tested
1615
* and is mainly for debugging purpose (and avoid handwriting data).
1716
*/
1817
public class GenerateDataFlat {
19-
public static void main(final String[] args) throws Exception {
20-
final File myFile = new File("flat_attributes.json");
21-
myFile.createNewFile();
22-
final Map<String, AttributeValue.Builder> jsonData = new HashMap<>();
23-
//First 2 attributes are pk and sk
24-
for (Integer topLevelAttributeIndex = 2; topLevelAttributeIndex < 100; topLevelAttributeIndex++) {
25-
byte[] randomData = new byte[2000];
26-
new Random().nextBytes(randomData);
27-
jsonData.put("Attribute".concat(topLevelAttributeIndex.toString()), AttributeValue.builder().b(SdkBytes.fromByteArray(randomData)));
28-
}
29-
final FileOutputStream fileOutputStream = new FileOutputStream(myFile);
30-
fileOutputStream.write(JsonMapper.builder()
31-
.serializationInclusion(JsonInclude.Include.NON_NULL)
32-
.build()
33-
.writeValueAsBytes(jsonData));
34-
fileOutputStream.close();
18+
19+
public static void main(final String[] args) throws Exception {
20+
final File myFile = new File("flat_attributes.json");
21+
myFile.createNewFile();
22+
final Map<String, AttributeValue.Builder> jsonData = new HashMap<>();
23+
//First 2 attributes are pk and sk
24+
for (
25+
Integer topLevelAttributeIndex = 2;
26+
topLevelAttributeIndex < 100;
27+
topLevelAttributeIndex++
28+
) {
29+
byte[] randomData = new byte[2000];
30+
new Random().nextBytes(randomData);
31+
jsonData.put(
32+
"Attribute".concat(topLevelAttributeIndex.toString()),
33+
AttributeValue.builder().b(SdkBytes.fromByteArray(randomData))
34+
);
3535
}
36+
final FileOutputStream fileOutputStream = new FileOutputStream(myFile);
37+
fileOutputStream.write(
38+
JsonMapper
39+
.builder()
40+
.serializationInclusion(JsonInclude.Include.NON_NULL)
41+
.build()
42+
.writeValueAsBytes(jsonData)
43+
);
44+
fileOutputStream.close();
45+
}
3646
}

PerfTest/runtimes/java/DynamoDbEncryption/src/main/java/software/aws/cryptography/performance/itemencryptor/utils/GenerateDataNested.java

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,71 @@
22

33
import com.fasterxml.jackson.annotation.JsonInclude;
44
import com.fasterxml.jackson.databind.json.JsonMapper;
5-
import software.amazon.awssdk.core.SdkBytes;
6-
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
7-
85
import java.io.File;
96
import java.io.FileOutputStream;
107
import java.util.HashMap;
118
import java.util.Map;
129
import java.util.Random;
10+
import software.amazon.awssdk.core.SdkBytes;
11+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
1312

1413
/**
1514
* A convenient class to generate some random binary data with flat attributes. The logic is not thoroughly tested
1615
* and is mainly for debugging purpose (and avoid handwriting data).
1716
*/
1817
public class GenerateDataNested {
19-
public static void main(final String[] args) throws Exception {
20-
final File myFile = new File("nested_attributes.json");
21-
myFile.createNewFile();
22-
final Map<String, AttributeValue.Builder> jsonData = new HashMap<>();
23-
//First 2 attributes are pk and sk
24-
for (Integer topLevelAttributeIndex = 2; topLevelAttributeIndex < 100; topLevelAttributeIndex++) {
25-
//Randomise level of nesting
26-
final Integer nestedChildAttributeIndex = new Random().nextInt(31);
27-
jsonData.put("Attribute".concat(topLevelAttributeIndex.toString()),
28-
AttributeValue.builder().m(generateNestedChildren(nestedChildAttributeIndex)));
29-
}
30-
final FileOutputStream fileOutputStream = new FileOutputStream(myFile);
31-
fileOutputStream.write(JsonMapper.builder()
32-
.serializationInclusion(JsonInclude.Include.NON_NULL)
33-
.build()
34-
.writeValueAsBytes(jsonData));
35-
fileOutputStream.close();
18+
19+
public static void main(final String[] args) throws Exception {
20+
final File myFile = new File("nested_attributes.json");
21+
myFile.createNewFile();
22+
final Map<String, AttributeValue.Builder> jsonData = new HashMap<>();
23+
//First 2 attributes are pk and sk
24+
for (
25+
Integer topLevelAttributeIndex = 2;
26+
topLevelAttributeIndex < 100;
27+
topLevelAttributeIndex++
28+
) {
29+
//Randomise level of nesting
30+
final Integer nestedChildAttributeIndex = new Random().nextInt(31);
31+
jsonData.put(
32+
"Attribute".concat(topLevelAttributeIndex.toString()),
33+
AttributeValue
34+
.builder()
35+
.m(generateNestedChildren(nestedChildAttributeIndex))
36+
);
3637
}
37-
static Map<String, AttributeValue> generateNestedChildren(final Integer nestedChildAttributeIndex) {
38-
if (nestedChildAttributeIndex == 0) {
39-
byte[] randomData = new byte[1000];
40-
new Random().nextBytes(randomData);
41-
Map<String, AttributeValue> leafNode = new HashMap<>();
42-
leafNode.put("Attribute".concat(nestedChildAttributeIndex.toString()), AttributeValue.fromB(SdkBytes.fromByteArray(randomData)));
43-
return leafNode;
44-
}
45-
Map<String, AttributeValue> nested = generateNestedChildren(nestedChildAttributeIndex - 1);
46-
Map<String, AttributeValue> parent = new HashMap<>();
47-
parent.put("Attribute".concat(nestedChildAttributeIndex.toString()), AttributeValue.fromM(nested));
48-
return parent;
38+
final FileOutputStream fileOutputStream = new FileOutputStream(myFile);
39+
fileOutputStream.write(
40+
JsonMapper
41+
.builder()
42+
.serializationInclusion(JsonInclude.Include.NON_NULL)
43+
.build()
44+
.writeValueAsBytes(jsonData)
45+
);
46+
fileOutputStream.close();
47+
}
48+
49+
static Map<String, AttributeValue> generateNestedChildren(
50+
final Integer nestedChildAttributeIndex
51+
) {
52+
if (nestedChildAttributeIndex == 0) {
53+
byte[] randomData = new byte[1000];
54+
new Random().nextBytes(randomData);
55+
Map<String, AttributeValue> leafNode = new HashMap<>();
56+
leafNode.put(
57+
"Attribute".concat(nestedChildAttributeIndex.toString()),
58+
AttributeValue.fromB(SdkBytes.fromByteArray(randomData))
59+
);
60+
return leafNode;
4961
}
62+
Map<String, AttributeValue> nested = generateNestedChildren(
63+
nestedChildAttributeIndex - 1
64+
);
65+
Map<String, AttributeValue> parent = new HashMap<>();
66+
parent.put(
67+
"Attribute".concat(nestedChildAttributeIndex.toString()),
68+
AttributeValue.fromM(nested)
69+
);
70+
return parent;
71+
}
5072
}

PerfTest/runtimes/java/DynamoDbEncryption/src/main/java/software/aws/cryptography/performance/itemencryptor/v2/AesKeyProviderTest.java

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,44 @@
22

33
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.providers.EncryptionMaterialsProvider;
44
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.providers.WrappedMaterialsProvider;
5-
5+
import java.security.SecureRandom;
66
import javax.crypto.SecretKey;
77
import javax.crypto.spec.SecretKeySpec;
8-
import java.security.SecureRandom;
98

109
public class AesKeyProviderTest extends TestBase {
11-
@Override
12-
protected EncryptionMaterialsProvider createMasterKeyProvider() {
13-
final SecureRandom secureRandom = new SecureRandom();
14-
byte[] rawAes = new byte[32];
15-
byte[] rawHmac = new byte[32];
16-
secureRandom.nextBytes(rawAes);
17-
secureRandom.nextBytes(rawHmac);
18-
final SecretKey wrappingKeys = new SecretKeySpec(rawAes, "AES");
19-
final SecretKey signingKeys = new SecretKeySpec(rawHmac, "HmacSHA256");
20-
final WrappedMaterialsProvider cmp =
21-
new WrappedMaterialsProvider(wrappingKeys, wrappingKeys, signingKeys);
22-
return cmp;
23-
}
24-
public AesKeyProviderTest() {
25-
}
2610

27-
AesKeyProviderTest(String plainTextFileJson) {
28-
this.plainTextFile = plainTextFileJson;
29-
}
11+
@Override
12+
protected EncryptionMaterialsProvider createMasterKeyProvider() {
13+
final SecureRandom secureRandom = new SecureRandom();
14+
byte[] rawAes = new byte[32];
15+
byte[] rawHmac = new byte[32];
16+
secureRandom.nextBytes(rawAes);
17+
secureRandom.nextBytes(rawHmac);
18+
final SecretKey wrappingKeys = new SecretKeySpec(rawAes, "AES");
19+
final SecretKey signingKeys = new SecretKeySpec(rawHmac, "HmacSHA256");
20+
final WrappedMaterialsProvider cmp = new WrappedMaterialsProvider(
21+
wrappingKeys,
22+
wrappingKeys,
23+
signingKeys
24+
);
25+
return cmp;
26+
}
3027

31-
/**
32-
* main Method to execute tests without JMH. This is helpful in profiling in IDEs (especially IntelliJ) which fails
33-
* to profile JMH annotated runs.
34-
* @param args
35-
* @throws Exception
36-
*/
37-
public static void main(String[] args) throws Exception {
38-
TestBase testBase = new AesKeyProviderTest("single_attribute.json");
39-
testBase.setup();
40-
testBase.decrypt();
28+
public AesKeyProviderTest() {}
4129

42-
}
30+
AesKeyProviderTest(String plainTextFileJson) {
31+
this.plainTextFile = plainTextFileJson;
32+
}
4333

34+
/**
35+
* main Method to execute tests without JMH. This is helpful in profiling in IDEs (especially IntelliJ) which fails
36+
* to profile JMH annotated runs.
37+
* @param args
38+
* @throws Exception
39+
*/
40+
public static void main(String[] args) throws Exception {
41+
TestBase testBase = new AesKeyProviderTest("single_attribute.json");
42+
testBase.setup();
43+
testBase.decrypt();
44+
}
4445
}
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,43 @@
11
package software.aws.cryptography.performance.itemencryptor.v2;
22

3+
import static software.aws.cryptography.performance.itemencryptor.TestConstants.KMS_KEY_ARN;
4+
35
import com.amazonaws.regions.Regions;
46
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.providers.DirectKmsMaterialProvider;
57
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.providers.EncryptionMaterialsProvider;
68
import com.amazonaws.services.kms.AWSKMS;
79
import com.amazonaws.services.kms.AWSKMSClientBuilder;
810

9-
import static software.aws.cryptography.performance.itemencryptor.TestConstants.KMS_KEY_ARN;
10-
1111
public class AwsKmsKeyProviderTest extends TestBase {
12-
@Override
13-
protected EncryptionMaterialsProvider createMasterKeyProvider() {
14-
AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
15-
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, KMS_KEY_ARN);
16-
return cmp;
17-
}
1812

19-
public AwsKmsKeyProviderTest() {
20-
}
13+
@Override
14+
protected EncryptionMaterialsProvider createMasterKeyProvider() {
15+
AWSKMS kms = AWSKMSClientBuilder
16+
.standard()
17+
.withRegion(Regions.DEFAULT_REGION)
18+
.build();
19+
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(
20+
kms,
21+
KMS_KEY_ARN
22+
);
23+
return cmp;
24+
}
2125

22-
AwsKmsKeyProviderTest(String plainTextFileJson) {
23-
this.plainTextFile = plainTextFileJson;
24-
}
26+
public AwsKmsKeyProviderTest() {}
2527

26-
/**
27-
* main Method to execute tests without JMH. This is helpful in profiling in IDEs (especially IntelliJ) which fails
28-
* to profile JMH annotated runs.
29-
* @param args
30-
* @throws Exception
31-
*/
32-
public static void main(String[] args) throws Exception {
33-
TestBase testBase = new AwsKmsKeyProviderTest("single_attribute.json");
34-
testBase.setup();
35-
testBase.decrypt();
28+
AwsKmsKeyProviderTest(String plainTextFileJson) {
29+
this.plainTextFile = plainTextFileJson;
30+
}
3631

37-
}
32+
/**
33+
* main Method to execute tests without JMH. This is helpful in profiling in IDEs (especially IntelliJ) which fails
34+
* to profile JMH annotated runs.
35+
* @param args
36+
* @throws Exception
37+
*/
38+
public static void main(String[] args) throws Exception {
39+
TestBase testBase = new AwsKmsKeyProviderTest("single_attribute.json");
40+
testBase.setup();
41+
testBase.decrypt();
42+
}
3843
}

0 commit comments

Comments
 (0)