1+ /* *
2+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+ * SPDX-License-Identifier: Apache-2.0.
4+ */
5+
6+ #include < aws/core/AmazonWebServiceResult.h>
7+ #include < aws/core/NoResult.h>
8+ #include < aws/core/client/ClientConfiguration.h>
9+ #include < aws/core/utils/Outcome.h>
10+ #include < aws/core/utils/logging/LogMacros.h>
11+ #include < aws/core/utils/memory/AWSMemory.h>
12+ #include < aws/core/utils/memory/stl/AWSString.h>
13+ #include < aws/dynamodb/DynamoDBClient.h>
14+ #include < aws/dynamodb/DynamoDBServiceClientModel.h>
15+ #include < aws/dynamodb/model/AttributeDefinition.h>
16+ #include < aws/dynamodb/model/AttributeValue.h>
17+ #include < aws/dynamodb/model/BillingMode.h>
18+ #include < aws/dynamodb/model/CreateTableRequest.h>
19+ #include < aws/dynamodb/model/DeleteTableRequest.h>
20+ #include < aws/dynamodb/model/DescribeTableRequest.h>
21+ #include < aws/dynamodb/model/GetItemRequest.h>
22+ #include < aws/dynamodb/model/KeySchemaElement.h>
23+ #include < aws/dynamodb/model/KeyType.h>
24+ #include < aws/dynamodb/model/PutItemRequest.h>
25+ #include < aws/dynamodb/model/ScalarAttributeType.h>
26+ #include < aws/dynamodb/model/TableStatus.h>
27+ #include < performance-tests/Utils.h>
28+ #include < performance-tests/services/dynamodb/DynamoDBPerformanceTest.h>
29+ #include < performance-tests/services/dynamodb/DynamoDBTestConfig.h>
30+
31+ #include < cassert>
32+ #include < chrono>
33+ #include < thread>
34+
35+ PerformanceTest::Services::DynamoDB::DynamoDBPerformanceTest::DynamoDBPerformanceTest (const Aws::Client::ClientConfiguration& clientConfig,
36+ const TestConfig::TestCase& testConfig,
37+ int iterations)
38+ : m_dynamodb(Aws::MakeUnique<Aws::DynamoDB::DynamoDBClient>(" DynamoDBPerformanceTest" , clientConfig)),
39+ m_testConfig(testConfig),
40+ m_iterations(iterations),
41+ m_tableName(" perf-table-" + PerformanceTest::Utils::GenerateUniqueId()) {
42+ assert (m_dynamodb && " DynamoDB client not initialized" );
43+ }
44+
45+ Aws::Utils::Outcome<Aws::NoResult, Aws::String> PerformanceTest::Services::DynamoDB::DynamoDBPerformanceTest::Setup () {
46+ Aws::DynamoDB::Model::CreateTableRequest createTableRequest;
47+ createTableRequest.SetTableName (m_tableName);
48+
49+ Aws::DynamoDB::Model::AttributeDefinition hashKey;
50+ hashKey.SetAttributeName (" data" );
51+ hashKey.SetAttributeType (Aws::DynamoDB::Model::ScalarAttributeType::S);
52+ createTableRequest.AddAttributeDefinitions (hashKey);
53+
54+ Aws::DynamoDB::Model::KeySchemaElement keySchema;
55+ keySchema.WithAttributeName (" data" ).WithKeyType (Aws::DynamoDB::Model::KeyType::HASH);
56+ createTableRequest.AddKeySchema (keySchema);
57+
58+ Aws::DynamoDB::Model::BillingMode const billingMode = Aws::DynamoDB::Model::BillingMode::PAY_PER_REQUEST;
59+ createTableRequest.SetBillingMode (billingMode);
60+
61+ auto createTableOutcome = m_dynamodb->CreateTable (createTableRequest);
62+ if (!createTableOutcome.IsSuccess ()) {
63+ return " DynamoDB Setup() - CreateTable failed: " + createTableOutcome.GetError ().GetMessage ();
64+ }
65+
66+ // Wait for table to become active
67+ const int MAX_QUERIES = 20 ;
68+ Aws::DynamoDB::Model::DescribeTableRequest describeRequest;
69+ describeRequest.SetTableName (m_tableName);
70+
71+ int count = 0 ;
72+ while (count < MAX_QUERIES) {
73+ const Aws::DynamoDB::Model::DescribeTableOutcome& describeOutcome = m_dynamodb->DescribeTable (describeRequest);
74+ if (describeOutcome.IsSuccess ()) {
75+ Aws::DynamoDB::Model::TableStatus const status = describeOutcome.GetResult ().GetTable ().GetTableStatus ();
76+ if (Aws::DynamoDB::Model::TableStatus::ACTIVE == status) {
77+ break ;
78+ }
79+ std::this_thread::sleep_for (std::chrono::seconds (1 ));
80+ } else {
81+ return " DynamoDB Setup() - DescribeTable failed: " + describeOutcome.GetError ().GetMessage ();
82+ }
83+ count++;
84+ }
85+
86+ if (count >= MAX_QUERIES) {
87+ return " DynamoDB Setup() - Table did not become active within timeout" ;
88+ }
89+ return Aws::NoResult ();
90+ }
91+
92+ void PerformanceTest::Services::DynamoDB::DynamoDBPerformanceTest::Run () {
93+ const auto payload = PerformanceTest::Utils::RandomString (TestConfig::GetPayloadSizeInBytes (m_testConfig.payloadSize ));
94+
95+ // Run PutItem multiple times
96+ for (int i = 0 ; i < m_iterations; i++) {
97+ Aws::DynamoDB::Model::PutItemRequest putItemRequest;
98+ putItemRequest.SetTableName (m_tableName);
99+ putItemRequest.SetAdditionalCustomHeaderValue (" test-dimension-size" , TestConfig::GetPayloadSizeLabel (m_testConfig.payloadSize ));
100+ putItemRequest.AddItem (" data" , Aws::DynamoDB::Model::AttributeValue ().SetS (payload));
101+
102+ auto putItemOutcome = m_dynamodb->PutItem (putItemRequest);
103+ if (!putItemOutcome.IsSuccess ()) {
104+ AWS_LOG_ERROR (" PerformanceTest" , (" DynamoDB Run() - PutItem failed: " + putItemOutcome.GetError ().GetMessage ()).c_str ());
105+ }
106+ }
107+
108+ // Run GetItem multiple times
109+ for (int i = 0 ; i < m_iterations; i++) {
110+ Aws::DynamoDB::Model::GetItemRequest getItemRequest;
111+ getItemRequest.SetTableName (m_tableName);
112+ getItemRequest.SetAdditionalCustomHeaderValue (" test-dimension-size" , TestConfig::GetPayloadSizeLabel (m_testConfig.payloadSize ));
113+ getItemRequest.AddKey (" data" , Aws::DynamoDB::Model::AttributeValue ().SetS (payload));
114+
115+ auto getItemOutcome = m_dynamodb->GetItem (getItemRequest);
116+ if (!getItemOutcome.IsSuccess ()) {
117+ AWS_LOG_ERROR (" PerformanceTest" , (" DynamoDB Run() - GetItem failed: " + getItemOutcome.GetError ().GetMessage ()).c_str ());
118+ }
119+ }
120+ }
121+
122+ void PerformanceTest::Services::DynamoDB::DynamoDBPerformanceTest::TearDown () {
123+ Aws::DynamoDB::Model::DeleteTableRequest deleteTableRequest;
124+ deleteTableRequest.SetTableName (m_tableName);
125+ auto deleteTableOutcome = m_dynamodb->DeleteTable (deleteTableRequest);
126+ if (!deleteTableOutcome.IsSuccess ()) {
127+ AWS_LOG_ERROR (" PerformanceTest" , (" DynamoDB TearDown() - DeleteTable failed: " + deleteTableOutcome.GetError ().GetMessage ()).c_str ());
128+ }
129+ }
0 commit comments