Skip to content

Commit c5e3eb7

Browse files
authored
Merge pull request #52 from awslabs/FB-EC2
Fix for several EC2-related issues & bugs
2 parents 46d3bb0 + e6188fd commit c5e3eb7

File tree

10 files changed

+321
-15
lines changed

10 files changed

+321
-15
lines changed

aws-cpp-sdk-core/source/client/AWSClient.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,14 @@ AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::Htt
592592
{
593593
errorNode = doc.GetRootElement().FirstChild("Error");
594594
}
595+
if (errorNode.IsNull())
596+
{
597+
errorNode = doc.GetRootElement().FirstChild("Errors");
598+
if(!errorNode.IsNull())
599+
{
600+
errorNode = errorNode.FirstChild("Error");
601+
}
602+
}
595603

596604
if (!errorNode.IsNull())
597605
{
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
add_project(aws-cpp-sdk-ec2-integration-tests
2+
"Tests for the AWS ec2 C++ SDK"
3+
aws-cpp-sdk-ec2
4+
testing-resources
5+
aws-cpp-sdk-core)
6+
7+
file(GLOB AWS_EC2_SRC
8+
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
9+
)
10+
11+
file(GLOB AWS_EC2_INTEGRATION_TESTS_SRC
12+
${AWS_EC2_SRC}
13+
)
14+
15+
if(MSVC AND BUILD_SHARED_LIBS)
16+
add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1)
17+
endif()
18+
19+
enable_testing()
20+
21+
if(PLATFORM_ANDROID AND BUILD_SHARED_LIBS)
22+
add_library(${PROJECT_NAME} ${LIBTYPE} ${AWS_EC2_INTEGRATION_TESTS_SRC})
23+
else()
24+
add_executable(${PROJECT_NAME} ${AWS_EC2_INTEGRATION_TESTS_SRC})
25+
endif()
26+
27+
target_link_libraries(${PROJECT_NAME} ${PROJECT_LIBS})
28+
copyDlls(${PROJECT_NAME} ${PROJECT_LIBS})
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#include <aws/external/gtest.h>
17+
18+
#include <aws/core/auth/AWSCredentialsProviderChain.h>
19+
#include <aws/core/utils/memory/AWSMemory.h>
20+
#include <aws/ec2/EC2Client.h>
21+
#include <aws/ec2/model/CreateSecurityGroupRequest.h>
22+
#include <aws/ec2/model/CreateSecurityGroupResponse.h>
23+
#include <aws/ec2/model/CreateVpcRequest.h>
24+
#include <aws/ec2/model/CreateVpcResponse.h>
25+
#include <aws/ec2/model/DeleteSecurityGroupRequest.h>
26+
#include <aws/ec2/model/DeleteVpcRequest.h>
27+
#include <aws/ec2/model/DescribeSecurityGroupsRequest.h>
28+
#include <aws/ec2/model/DescribeSecurityGroupsResponse.h>
29+
#include <aws/ec2/model/DescribeSpotFleetRequestsRequest.h>
30+
#include <aws/ec2/model/DescribeSpotFleetRequestsResponse.h>
31+
#include <aws/ec2/model/DescribeVpcsRequest.h>
32+
#include <aws/ec2/model/DescribeVpcsResponse.h>
33+
34+
#include <chrono>
35+
#include <thread>
36+
37+
using namespace Aws::Auth;
38+
using namespace Aws::Http;
39+
using namespace Aws::Client;
40+
41+
namespace
42+
{
43+
44+
static const char* ALLOCATION_TAG = "EC2Tests";
45+
static const char* SECURITY_GROUP_NAME = "CppSDKIntegrationTestSecurityGroup";
46+
47+
class EC2OperationTest : public ::testing::Test
48+
{
49+
50+
protected:
51+
52+
enum class ObjectState {
53+
Ready,
54+
Nonexistent
55+
};
56+
57+
static std::shared_ptr<Aws::EC2::EC2Client> m_EC2Client;
58+
59+
static Aws::String m_vpcId;
60+
61+
62+
static void SetUpTestCase()
63+
{
64+
ClientConfiguration config;
65+
config.scheme = Scheme::HTTPS;
66+
config.region = Aws::Region::US_EAST_1;
67+
68+
m_EC2Client = Aws::MakeShared<Aws::EC2::EC2Client>(ALLOCATION_TAG, Aws::MakeShared<DefaultAWSCredentialsProviderChain>(ALLOCATION_TAG), config);
69+
70+
Aws::EC2::Model::CreateVpcRequest createVpcRequest;
71+
createVpcRequest.SetCidrBlock("10.0.0.0/16");
72+
createVpcRequest.SetInstanceTenancy(Aws::EC2::Model::Tenancy::default_);
73+
74+
auto createOutcome = m_EC2Client->CreateVpc(createVpcRequest);
75+
ASSERT_TRUE(createOutcome.IsSuccess());
76+
77+
m_vpcId = createOutcome.GetResult().GetVpc().GetVpcId();
78+
WaitOnVpcState(m_vpcId, ObjectState::Ready);
79+
80+
DeleteSecurityGroup(SECURITY_GROUP_NAME);
81+
}
82+
83+
static void TearDownTestCase()
84+
{
85+
DeleteSecurityGroup(SECURITY_GROUP_NAME);
86+
DeleteVpc(m_vpcId);
87+
88+
m_EC2Client = nullptr;
89+
}
90+
91+
static void DeleteSecurityGroup(const Aws::String& groupName)
92+
{
93+
Aws::EC2::Model::DeleteSecurityGroupRequest deleteRequest;
94+
deleteRequest.SetGroupName(groupName);
95+
96+
m_EC2Client->DeleteSecurityGroup(deleteRequest);
97+
WaitOnSecurityGroupState(groupName, ObjectState::Nonexistent);
98+
}
99+
100+
static void WaitOnSecurityGroupState(const Aws::String& groupName, ObjectState objectState)
101+
{
102+
Aws::EC2::Model::DescribeSecurityGroupsRequest describeRequest;
103+
describeRequest.AddGroupNames(groupName);
104+
105+
bool finished = false;
106+
while(!finished)
107+
{
108+
auto describeOutcome = m_EC2Client->DescribeSecurityGroups(describeRequest);
109+
if (describeOutcome.IsSuccess())
110+
{
111+
const Aws::Vector< Aws::EC2::Model::SecurityGroup >& groups = describeOutcome.GetResult().GetSecurityGroups();
112+
bool exists = std::find_if(groups.cbegin(), groups.cend(), [](const Aws::EC2::Model::SecurityGroup& group){ return group.GetGroupName() == SECURITY_GROUP_NAME; }) != groups.cend();
113+
finished = (objectState == ObjectState::Nonexistent && !exists) || (objectState == ObjectState::Ready && exists);
114+
}
115+
else if (describeOutcome.GetError().GetErrorType() == Aws::EC2::EC2Errors::INVALID_GROUP__NOT_FOUND)
116+
{
117+
finished = objectState == ObjectState::Nonexistent;
118+
}
119+
120+
if (!finished)
121+
{
122+
std::this_thread::sleep_for(std::chrono::seconds(1));
123+
}
124+
}
125+
}
126+
127+
static void DeleteVpc(const Aws::String vpcId)
128+
{
129+
Aws::EC2::Model::DeleteVpcRequest deleteVpcRequest;
130+
deleteVpcRequest.SetVpcId(vpcId);
131+
132+
auto deleteOutcome = m_EC2Client->DeleteVpc(deleteVpcRequest);
133+
ASSERT_TRUE(deleteOutcome.IsSuccess());
134+
135+
WaitOnVpcState(vpcId, ObjectState::Nonexistent);
136+
}
137+
138+
static void WaitOnVpcState(const Aws::String& vpcId, ObjectState objectState)
139+
{
140+
Aws::EC2::Model::DescribeVpcsRequest describeRequest;
141+
describeRequest.AddVpcIds(vpcId);
142+
143+
bool finished = false;
144+
while(!finished)
145+
{
146+
auto describeOutcome = m_EC2Client->DescribeVpcs(describeRequest);
147+
if (describeOutcome.IsSuccess())
148+
{
149+
const Aws::Vector< Aws::EC2::Model::Vpc >& vpcs = describeOutcome.GetResult().GetVpcs();
150+
bool exists = std::find_if(vpcs.cbegin(), vpcs.cend(), [vpcId](const Aws::EC2::Model::Vpc& vpc){ return vpc.GetVpcId() == vpcId; }) != vpcs.cend();
151+
finished = (objectState == ObjectState::Nonexistent && !exists) || (objectState == ObjectState::Ready && exists);
152+
}
153+
else if (describeOutcome.GetError().GetErrorType() == Aws::EC2::EC2Errors::INVALID_VPC_I_D__NOT_FOUND)
154+
{
155+
finished = objectState == ObjectState::Nonexistent;
156+
}
157+
158+
if (!finished)
159+
{
160+
std::this_thread::sleep_for(std::chrono::seconds(1));
161+
}
162+
}
163+
}
164+
};
165+
166+
std::shared_ptr<Aws::EC2::EC2Client> EC2OperationTest::m_EC2Client(nullptr);
167+
Aws::String EC2OperationTest::m_vpcId;
168+
169+
} // anonymous namespace
170+
171+
TEST_F(EC2OperationTest, DescribeSpotFleet)
172+
{
173+
Aws::EC2::Model::DescribeSpotFleetRequestsRequest request;
174+
175+
auto outcome = m_EC2Client->DescribeSpotFleetRequests(request);
176+
ASSERT_TRUE(outcome.IsSuccess());
177+
}
178+
179+
TEST_F(EC2OperationTest, CreateSecurityGroup)
180+
{
181+
Aws::EC2::Model::CreateSecurityGroupRequest createRequest;
182+
createRequest.SetGroupName(SECURITY_GROUP_NAME);
183+
createRequest.SetDescription("A dummy description");
184+
185+
auto createOutcome = m_EC2Client->CreateSecurityGroup(createRequest);
186+
ASSERT_TRUE(createOutcome.IsSuccess());
187+
188+
WaitOnSecurityGroupState(SECURITY_GROUP_NAME, ObjectState::Ready);
189+
DeleteSecurityGroup(SECURITY_GROUP_NAME);
190+
}
191+
192+
193+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#include <aws/external/gtest.h>
17+
#include <aws/core/Aws.h>
18+
#include <aws/testing/platform/PlatformTesting.h>
19+
20+
int main(int argc, char** argv)
21+
{
22+
Aws::SDKOptions options;
23+
24+
Aws::Testing::InitPlatformTest(options);
25+
26+
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
27+
Aws::InitAPI(options);
28+
::testing::InitGoogleTest(&argc, argv);
29+
int exitCode = RUN_ALL_TESTS();
30+
Aws::ShutdownAPI(options);
31+
32+
Aws::Testing::ShutdownPlatformTest(options);
33+
return exitCode;
34+
}
35+
36+
37+

cmake/sdks.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ list(APPEND SDK_TEST_PROJECT_LIST "s3:aws-cpp-sdk-s3-integration-tests")
108108
list(APPEND SDK_TEST_PROJECT_LIST "sqs:aws-cpp-sdk-sqs-integration-tests")
109109
list(APPEND SDK_TEST_PROJECT_LIST "transfer:aws-cpp-sdk-transfer-tests")
110110
list(APPEND SDK_TEST_PROJECT_LIST "s3-encryption:aws-cpp-sdk-s3-encryption-tests,aws-cpp-sdk-s3-encryption-integration-tests")
111+
list(APPEND SDK_TEST_PROJECT_LIST "ec2:aws-cpp-sdk-ec2-integration-tests")
111112
list(APPEND SDK_TEST_PROJECT_LIST "core:aws-cpp-sdk-core-tests")
112113

113114
set(SDK_DEPENDENCY_LIST "")

code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppViewHelper.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,18 @@ else if(entry.getValue().isUsedForHeader() || entry.getValue().isUsedForQueryStr
241241
}
242242

243243
public static String computeOperationNameFromInputOutputShape(String shapeName) {
244-
return shapeName.replace("Request", "").replace("Result", "");
244+
String requestString = "Request";
245+
String resultString = "Result";
246+
int length = shapeName.length();
247+
int suffixIndex = length;
248+
249+
if(shapeName.endsWith(requestString)) {
250+
suffixIndex = length - requestString.length();
251+
} else if (shapeName.endsWith(resultString)) {
252+
suffixIndex = length - resultString.length();
253+
}
254+
255+
return shapeName.substring(0, suffixIndex);
245256
}
246257

247258
public static String capitalizeFirstChar(final String str) {

code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/ec2/Ec2CppClientGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,8 @@ public SdkFileEntry[] generateSourceFiles(ServiceModel serviceModel) throws Exce
539539
invalidVpcPeeringConnectionIDNotFound.setText("InvalidVpcPeeringConnectionID.NotFound");
540540
serviceErrors.add(invalidVpcPeeringConnectionIDNotFound);
541541
final Error invalidVpcRange = new Error();
542-
invalidVpcRange.setName("InvalidVpcRange");
543-
invalidVpcRange.setText("InvalidVpcRange");
542+
invalidVpcRange.setName("InvalidVpc.Range");
543+
invalidVpcRange.setText("InvalidVpc.Range");
544544
serviceErrors.add(invalidVpcRange);
545545
final Error invalidVpcState = new Error();
546546
invalidVpcState.setName("InvalidVpcState");

code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QueryRequestSource.vm

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,7 @@ Aws::String ${typeInfo.className}::SerializePayload() const
3737
{
3838
#set($spaces = " ")
3939
#end
40-
#if($member.value.shape.blob)
41-
${spaces}ss << "${member.key}=" << HashingUtils::Base64Encode(${memberVarName}) << "&";
42-
#elseif($member.value.shape.timeStamp)
43-
${spaces}ss << "${member.key}=" << StringUtils::URLEncode(${memberVarName}.ToGmtString(DateFormat::ISO_8601).c_str()) << "&";
44-
#elseif($member.value.shape.string)
45-
${spaces}ss << "${member.key}=" << StringUtils::URLEncode(${memberVarName}.c_str()) << "&";
46-
#elseif($member.value.shape.enum)
47-
${spaces}ss << "${member.key}=" << ${member.value.shape.name}Mapper::GetNameFor${member.value.shape.name}(${memberVarName}) << "&";
48-
#elseif($member.value.shape.list)
40+
#if($member.value.shape.list)
4941
${spaces}unsigned ${varName}Count = 1;
5042
${spaces}for(auto& item : $memberVarName)
5143
${spaces}{
@@ -134,12 +126,30 @@ Aws::String ${typeInfo.className}::SerializePayload() const
134126
#end
135127
${spaces} ${varName}Count++;
136128
${spaces}}
129+
#else
130+
#if($member.value.locationName)
131+
#set($location = $member.value.locationName)
132+
#else
133+
#set($location = $member.key)
134+
#end
135+
#if($metadata.protocol == "ec2")
136+
#set($location = $CppViewHelper.capitalizeFirstChar($location))
137+
#end
138+
#if($member.value.shape.blob)
139+
${spaces}ss << "${location}=" << HashingUtils::Base64Encode(${memberVarName}) << "&";
140+
#elseif($member.value.shape.timeStamp)
141+
${spaces}ss << "${location}=" << StringUtils::URLEncode(${memberVarName}.ToGmtString(DateFormat::ISO_8601).c_str()) << "&";
142+
#elseif($member.value.shape.string)
143+
${spaces}ss << "${location}=" << StringUtils::URLEncode(${memberVarName}.c_str()) << "&";
144+
#elseif($member.value.shape.enum)
145+
${spaces}ss << "${location}=" << ${member.value.shape.name}Mapper::GetNameFor${member.value.shape.name}(${memberVarName}) << "&";
137146
#elseif($member.value.shape.structure)
138-
${spaces}${memberVarName}.OutputToStream(ss, "${member.key}");
147+
${spaces}${memberVarName}.OutputToStream(ss, "${location}");
139148
#elseif($member.value.shape.double)
140-
${spaces}ss << "${member.key}=" << StringUtils::URLEncode(${memberVarName}) << "&";
149+
${spaces}ss << "${location}=" << StringUtils::URLEncode(${memberVarName}) << "&";
141150
#else
142-
${spaces}ss << "${member.key}=" << ${memberVarName} << "&";
151+
${spaces}ss << "${location}=" << ${memberVarName} << "&";
152+
#end
143153
#end
144154
#if(!$member.value.required)
145155
}

code-generation/generator/src/test/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppViewHelperTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,5 +287,15 @@ public void testComputeOperationNameFromShapeName() {
287287
assertEquals("OperationName", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameRequest"));
288288
assertEquals("OperationName", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameResult"));
289289
assertEquals("OperationNameOther", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameOther"));
290+
291+
assertEquals("OperationNameRequests", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameRequestsRequest"));
292+
assertEquals("OperationNameRequests", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameRequestsResult"));
293+
assertEquals("OperationNameResults", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameResultsRequest"));
294+
assertEquals("OperationNameResults", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameResultsResult"));
295+
assertEquals("OperationNameResultsRequestResultRequest", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameResultsRequestResultRequestResult"));
296+
assertEquals("OperationNameResultsRequestResultRequest", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameResultsRequestResultRequestRequest"));
297+
298+
assertEquals("OperationNameResultsRequestResultRequestDerp", CppViewHelper.computeOperationNameFromInputOutputShape("OperationNameResultsRequestResultRequestDerp"));
299+
290300
}
291301
}

scripts/run_integration_tests.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ def Main():
106106
AddExecutableBit(s3EncryptionTest)
107107
subprocess.check_call(s3EncryptionTest)
108108

109+
ec2Test = ( arguments["buildDir"] +
110+
"/aws-cpp-sdk-ec2-integration-tests/" +
111+
configDir +
112+
"/aws-cpp-sdk-ec2-integration-tests" +
113+
exeExtension )
114+
AddExecutableBit(ec2Test)
115+
subprocess.check_call(ec2Test)
116+
109117
#These will cost you lots of money, don't run them unless you decide you want to test this functionality
110118
#cloudFrontTests = ( arguments["buildDir"] + "/aws-cpp-sdk-cloudfront-integration-tests/" + configDir + "/aws-cpp-sdk-cloudfront-integration-tests" + exeExtension )
111119
#AddExecutableBit(cloudFrontTests)

0 commit comments

Comments
 (0)