Ver código fonte

unit test for EndpointProvider and StsAssumeRoleCrendentialsProvider

zhangzifa 7 anos atrás
pai
commit
48fc5dfe8c

+ 1 - 1
core/include/alibabacloud/core/CoreClient.h

@@ -39,7 +39,7 @@ namespace AlibabaCloud
 		ClientConfiguration configuration()const;
 		std::string serviceName()const;
 	protected:
-		HttpClient::HttpResponseOutcome AttemptRequest(const std::string & endpoint, const ServiceRequest &request, HttpRequest::Method method)const;
+		virtual HttpClient::HttpResponseOutcome AttemptRequest(const std::string & endpoint, const ServiceRequest &request, HttpRequest::Method method)const;
 		Error buildCoreError(const HttpResponse &response)const;
 		bool hasResponseError(const HttpResponse &response)const;
 		virtual HttpRequest buildHttpRequest(const std::string & endpoint, const ServiceRequest &msg, HttpRequest::Method method)const = 0;

+ 8 - 6
core/include/alibabacloud/core/EndpointProvider.h

@@ -27,19 +27,22 @@
 
 namespace AlibabaCloud
 {
-	class ALIBABACLOUD_CORE_EXPORT EndpointProvider
+	class ALIBABACLOUD_CORE_EXPORT EndpointProvider : public Location::LocationClient
 	{
 	public:
 		typedef Outcome<Error, std::string> EndpointOutcome;
 
-		EndpointProvider(const std::shared_ptr<Location::LocationClient>& locationClient,
-			const std::string regionId,
-			const std::string product,
-			const std::string serviceCode = std::string(),
+		EndpointProvider(
+			const Credentials &credentials,
+			const ClientConfiguration &configuration,
+			const std::string &regionId,
+			const std::string &product,
+			const std::string &serviceCode = std::string(),
 			int durationSeconds = 3600);
 		~EndpointProvider();
 
 		EndpointOutcome getEndpoint();
+		using LocationClient::describeEndpoints;
 	private:
 		struct Product
 		{
@@ -58,7 +61,6 @@ namespace AlibabaCloud
 
 		std::mutex cachedMutex_;
 		std::string cachedEndpoint_;
-		std::shared_ptr<Location::LocationClient> locationClient_;
 		int durationSeconds_;
 		std::chrono::system_clock::time_point expiry_;
 		std::string regionId_;

+ 7 - 5
core/include/alibabacloud/core/RpcServiceClient.h

@@ -1,12 +1,12 @@
 /*
  * Copyright 2009-2017 Alibaba Cloud All rights reserved.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -40,14 +40,16 @@ namespace AlibabaCloud
 			const ClientConfiguration &configuration,
 			const std::shared_ptr<Signer> &signer = std::make_shared<HmacSha1Signer>());
 		virtual ~RpcServiceClient();
-		
+		using CoreClient::configuration;
+		using CoreClient::AttemptRequest;
+
 	protected:
 		virtual JsonOutcome makeRequest(const std::string &endpoint, const RpcServiceRequest &msg, HttpRequest::Method method = HttpRequest::Method::Get)const;
 		virtual HttpRequest buildHttpRequest(const std::string & endpoint, const ServiceRequest &msg, HttpRequest::Method method)const override;
 		HttpRequest buildHttpRequest(const std::string & endpoint, const RpcServiceRequest &msg, HttpRequest::Method method)const;
 	private:
 		std::string canonicalizedQuery(const std::map <std::string, std::string> &params)const;
-		
+
 		std::shared_ptr<CredentialsProvider> credentialsProvider_;
 		std::shared_ptr<Signer> signer_;
 	};

+ 5 - 3
core/include/alibabacloud/core/StsAssumeRoleCredentialsProvider.h

@@ -24,10 +24,12 @@
 
 namespace AlibabaCloud
 {
-	class ALIBABACLOUD_CORE_EXPORT StsAssumeRoleCredentialsProvider : public CredentialsProvider
+	class ALIBABACLOUD_CORE_EXPORT StsAssumeRoleCredentialsProvider : public CredentialsProvider, public Sts::StsClient
 	{
 	public:
-		StsAssumeRoleCredentialsProvider(const std::shared_ptr<Sts::StsClient>& stsClient,
+		StsAssumeRoleCredentialsProvider(
+			const Credentials &credentials,
+			const ClientConfiguration &configuration,
 			const std::string &roleArn,
 			const std::string &roleSessionName,
 			const std::string &policy = "",
@@ -35,13 +37,13 @@ namespace AlibabaCloud
 		~StsAssumeRoleCredentialsProvider();
 
 		virtual Credentials getCredentials() override;
+		using StsClient::assumeRole;
 	private:
 		void loadCredentials();
 		bool checkExpiry()const;
 
 		std::mutex cachedMutex_;
 		Credentials cachedCredentials_;
-		std::shared_ptr<Sts::StsClient> stsClient_;
 		int durationSeconds_;
 		std::chrono::system_clock::time_point expiry_;
 		std::string policy_;

+ 2 - 2
core/include/alibabacloud/core/location/LocationClient.h

@@ -38,11 +38,11 @@ namespace AlibabaCloud
 			LocationClient(const std::shared_ptr<CredentialsProvider> &credentialsProvider, const ClientConfiguration &configuration);
 			LocationClient(const std::string &accessKeyId, const std::string &accessKeySecret, const ClientConfiguration &configuration);
 			~LocationClient();
-
-			DescribeEndpointsOutcome describeEndpoints(const Model::DescribeEndpointsRequest &request)const;
+			virtual DescribeEndpointsOutcome describeEndpoints(const Model::DescribeEndpointsRequest &request)const;
 			void describeEndpointsAsync(const Model::DescribeEndpointsRequest& request, const DescribeEndpointsAsyncHandler& handler, const std::shared_ptr<const AsyncCallerContext>& context = nullptr) const;
 			DescribeEndpointsOutcomeCallable describeEndpointsCallable(const Model::DescribeEndpointsRequest& request) const;
 			using RpcServiceClient::makeRequest;
+			using RpcServiceClient::configuration;
 		};
 	}
 }

+ 2 - 2
core/include/alibabacloud/core/sts/StsClient.h

@@ -39,13 +39,13 @@ namespace AlibabaCloud
 			typedef Outcome<Error, Model::GetCallerIdentityResult> GetCallerIdentityOutcome;
 			typedef std::future<GetCallerIdentityOutcome> GetCallerIdentityOutcomeCallable;
 			typedef std::function<void(const StsClient*, const Model::GetCallerIdentityRequest&, const GetCallerIdentityOutcome&, const std::shared_ptr<const AsyncCallerContext>&)> GetCallerIdentityAsyncHandler;
-			
+
 			StsClient(const Credentials &credentials, const ClientConfiguration &configuration);
 			StsClient(const std::shared_ptr<CredentialsProvider> &credentialsProvider, const ClientConfiguration &configuration);
 			StsClient(const std::string &accessKeyId, const std::string &accessKeySecret, const ClientConfiguration &configuration);
 			~StsClient();
 
-			AssumeRoleOutcome assumeRole(const Model::AssumeRoleRequest &request)const;
+			virtual AssumeRoleOutcome assumeRole(const Model::AssumeRoleRequest &request)const;
 			void assumeRoleAsync(const Model::AssumeRoleRequest& request, const AssumeRoleAsyncHandler& handler, const std::shared_ptr<const AsyncCallerContext>& context = nullptr) const;
 			AssumeRoleOutcomeCallable assumeRoleCallable(const Model::AssumeRoleRequest& request) const;
 			GetCallerIdentityOutcome getCallerIdentity(const Model::GetCallerIdentityRequest &request)const;

+ 4 - 4
core/src/CoreClient.cc

@@ -1,12 +1,12 @@
 /*
  * Copyright 2009-2017 Alibaba Cloud All rights reserved.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -58,7 +58,7 @@ void CoreClient::asyncExecute(Runnable * r)const
 HttpClient::HttpResponseOutcome CoreClient::AttemptRequest(const std::string & endpoint, const ServiceRequest & request, HttpRequest::Method method) const
 {
 	auto r = buildHttpRequest(endpoint, request, method);
-	auto outcome = httpClient_->makeRequest(r);	
+	auto outcome = httpClient_->makeRequest(r);
 	if (!outcome.isSuccess())
 		return outcome;
 	if(hasResponseError(outcome.result()))

+ 11 - 5
core/src/EndpointProvider.cc

@@ -82,8 +82,14 @@ namespace
 		"]}";
 }
 
-EndpointProvider::EndpointProvider(const std::shared_ptr<Location::LocationClient>& locationClient, const std::string regionId, const std::string product, const std::string serviceCode, int durationSeconds) :
-	locationClient_(locationClient),
+EndpointProvider::EndpointProvider(
+	  const Credentials& credentials,
+	  const ClientConfiguration &configuration,
+	  const std::string &regionId,
+	  const std::string &product,
+	  const std::string &serviceCode,
+	  int durationSeconds) :
+	LocationClient(credentials, configuration),
 	regionId_(regionId),
 	product_(product),
 	serviceCode_(serviceCode),
@@ -157,8 +163,8 @@ std::string EndpointProvider::internalEndpoint(const std::string regionId, const
 
 EndpointProvider::EndpointOutcome EndpointProvider::getEndpoint()
 {
-	if (!locationClient_->configuration().endpoint().empty())
-		return EndpointOutcome(locationClient_->configuration().endpoint());
+	if (!configuration().endpoint().empty())
+		return EndpointOutcome(configuration().endpoint());
 
 	if (!serviceCode_.empty())
 	{
@@ -188,7 +194,7 @@ EndpointProvider::EndpointOutcome EndpointProvider::loadRemoteEndpoint()
 			request.setId(regionId_);
 			request.setServiceCode(serviceCode_);
 			request.setType("openAPI");
-			auto outcome = locationClient_->describeEndpoints(request);
+			auto outcome = describeEndpoints(request);
 			if (!outcome.isSuccess())
 				return EndpointOutcome(outcome.error());
 

+ 3 - 3
core/src/RpcServiceClient.cc

@@ -1,12 +1,12 @@
 /*
  * Copyright 2009-2017 Alibaba Cloud All rights reserved.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ 9 - 3
core/src/StsAssumeRoleCredentialsProvider.cc

@@ -21,9 +21,15 @@
 using namespace AlibabaCloud;
 using namespace AlibabaCloud::Sts;
 
-StsAssumeRoleCredentialsProvider::StsAssumeRoleCredentialsProvider(const std::shared_ptr<StsClient>& stsClient, const std::string & roleArn, const std::string & roleSessionName, const std::string & policy, int durationSeconds) :
+StsAssumeRoleCredentialsProvider::StsAssumeRoleCredentialsProvider(
+	  const Credentials &credentials,
+	  const ClientConfiguration &configuration,
+	  const std::string & roleArn,
+	  const std::string & roleSessionName,
+	  const std::string & policy,
+	  int durationSeconds):
 	CredentialsProvider(),
-	stsClient_(stsClient),
+	StsClient(credentials, configuration),
 	roleArn_(roleArn),
 	roleSessionName_(roleSessionName),
 	policy_(policy),
@@ -66,7 +72,7 @@ void StsAssumeRoleCredentialsProvider::loadCredentials()
 			request.setPolicy(policy_);
 			request.setDurationSeconds(durationSeconds_);
 
-			auto assumeRoleOutcome = stsClient_->assumeRole(request);
+			auto assumeRoleOutcome = assumeRole(request);
 			if (assumeRoleOutcome.isSuccess())
 			{
 				const auto stsCredentials = assumeRoleOutcome.result().credentials();

+ 2 - 0
test/core/CMakeLists.txt

@@ -55,6 +55,7 @@ add_executable(core_ut
   networkproxy_ut.cc
   roaserviceclient_ut.cc
   roaservicerequest_ut.cc
+  rpcserviceclient_ut.cc
   rpcservicerequest_ut.cc
   runnable_ut.cc
   serviceresult_ut.cc
@@ -68,6 +69,7 @@ add_executable(core_ut
   location_model_describeendpoints_result_ut.cc
 
   stsclient_ut.cc
+  stsassumerolecredentialsprovider_ut.cc
   sts_model_assumerole_request_ut.cc
   sts_model_assumerole_result_ut.cc
   sts_model_getcalleridentity_request_ut.cc

+ 0 - 1
test/core/ecsmetadatafetcher_ut.cc

@@ -29,6 +29,5 @@ namespace {
     EcsMetadataFetcher fetcher;
     string out = fetcher.getMetadata("a", "b");
     EXPECT_TRUE(out == "NetworkError");
-    out = fetcher.getMetadata("127.0.0.1");
   }
 }

+ 71 - 48
test/core/endpointprovider_ut.cc

@@ -1,69 +1,92 @@
 #include <iostream>
 #include <stdio.h>
 #include "gtest/gtest.h"
+#include "gmock/gmock.h"
 #include "alibabacloud/core/EndpointProvider.h"
 
 using namespace std;
 using namespace AlibabaCloud;
 using namespace AlibabaCloud::Location;
 
-TEST(EndpointProvider, basic) {
-  ClientConfiguration configuration("cn-hangzhou");
-
-  char* key = getenv("ENV_AccessKeyId");
-  char* secret = getenv("ENV_AccessKeySecret");
-
-  bool no_key_provided = false;
-
-  string accessKeyId, accessKeySecret;
-  if (key == nullptr) {
-    accessKeyId = "no-AccessKeyId";
-    no_key_provided = true;
-  } else {
-    accessKeyId = string(key);
-  }
-  if (secret == nullptr) {
-    accessKeySecret = "no-AccessKeySecret";
-    no_key_provided = true;
-  } else {
-    accessKeySecret = string(secret);
-  }
-  auto locationClient = std::make_shared<LocationClient>(accessKeyId, accessKeySecret, configuration);
-
-  EndpointProvider ep(locationClient, configuration.regionId(), "Ecs", "ecs");
-  EndpointProvider::EndpointOutcome out = ep.getEndpoint();
-
-  if (no_key_provided) {
-    EXPECT_TRUE(out.error().errorCode() == "InvalidAccessKeyId.NotFound");
-  } else {
-    EXPECT_TRUE(out.result() == "ecs-cn-hangzhou.aliyuncs.com");
-  }
+using ::testing::_;
+using ::testing::DefaultValue;
+
+
+class mockEndpointProvider: public EndpointProvider {
+ public:
+  mockEndpointProvider(
+      const Credentials &credentials,
+      const ClientConfiguration &configuration,
+      const std::string &regionId,
+      const std::string &product,
+      const std::string &serviceCode = std::string(),
+      int durationSeconds = 3600
+    ):
+  EndpointProvider(credentials, configuration, regionId, product, serviceCode, durationSeconds) {}
+
+  MOCK_CONST_METHOD1(describeEndpoints, LocationClient::DescribeEndpointsOutcome(const Model::DescribeEndpointsRequest &request));
+};
+
+TEST(EndpointProvider, service_code_empty) {
+  const Credentials sub_user_credentials("key", "secret");
+  ClientConfiguration config; // default is cn-hangzhou
+  // config.setEndpoint("test-endpoint"); // endpoint should be empty
+
+  // invalid product
+  mockEndpointProvider provider1(sub_user_credentials, config, config.regionId(), "non-exist-product", "");
+  EndpointProvider::EndpointOutcome out1 = provider1.getEndpoint();
+  EXPECT_TRUE(out1.error().errorCode() == "InvalidRegionId");
+
+  // ecs has no global_endpoint
+  mockEndpointProvider provider2(sub_user_credentials, config, config.regionId(), "ecs", "");
+  EndpointProvider::EndpointOutcome out2 = provider2.getEndpoint();
+  EXPECT_TRUE(out2.error().errorCode() == "InvalidRegionId");
+
+  // aegis has global_endpoint
+  mockEndpointProvider provider3(sub_user_credentials, config, config.regionId(), "aegis", "");
+  EndpointProvider::EndpointOutcome out3 = provider3.getEndpoint();
+  EXPECT_TRUE(out3.error().errorCode().empty());
+  EXPECT_TRUE(out3.result() == "aegis.cn-hangzhou.aliyuncs.com");
+
+  // arms has regional_endpoint, get from region
+  mockEndpointProvider provider4(sub_user_credentials, config, config.regionId(), "arms", "");
+  EndpointProvider::EndpointOutcome out4 = provider4.getEndpoint();
+  EXPECT_TRUE(out4.error().errorCode().empty());
+  EXPECT_TRUE(out4.result() == "arms.cn-hangzhou.aliyuncs.com");
 }
 
-TEST(EndpointProvider, basic1) {
-  ClientConfiguration configuration("cn-hangzhou");
+TEST(EndpointProvider, mock_remote) {
+  const Credentials sub_user_credentials("key", "secret");
+  ClientConfiguration config; // default is cn-hangzhou
+  // config.setEndpoint("test-endpoint");
 
-  const string accessKeyId = "no-AccessKeyId";
-  const string accessKeySecret = "no-AccessKeySecret";
+  mockEndpointProvider provider(sub_user_credentials, config, config.regionId(), "ecs", "ecs");
 
-  auto locationClient = std::make_shared<LocationClient>(accessKeyId, accessKeySecret, configuration);
+  Model::DescribeEndpointsRequest request;
 
-  EndpointProvider ep(locationClient, configuration.regionId(), "Ecs");
-  EndpointProvider::EndpointOutcome out = ep.getEndpoint();
+  const string payload = "{\"RequestId\":\"test-request-id\",\"Success\":true,\"Endpoints\":{\"Endpoint\":[{\"Endpoint\":\"test-ep\",\"Id\":\"test-id\",\"Namespace\":\"test-namespace\",\"SerivceCode\":\"test-service-code\",\"Type\":\"test-type\",\"Protocols\":{\"Protocols\":[\"a\",\"b\"]}}]}}";
+  Location::Model::DescribeEndpointsResult res(payload);
+  LocationClient::DescribeEndpointsOutcome xout(res);
 
-  EXPECT_TRUE(out.error().errorCode() == "InvalidRegionId");
-}
+  DefaultValue<LocationClient::DescribeEndpointsOutcome>::Set(xout);
+  EXPECT_CALL(provider, describeEndpoints(_));
+  EndpointProvider::EndpointOutcome out = provider.getEndpoint();
 
+  EXPECT_TRUE(out.error().errorCode().empty());
+  EXPECT_TRUE(out.result() == "test-ep");
+}
 
-TEST(EndpointProvider, basic2) {
-  ClientConfiguration configuration("xxxcn-hangzhou");
+TEST(EndpointProvider, mock_remote_error) {
+  const Credentials sub_user_credentials("key", "secret");
+  ClientConfiguration config; // default is cn-hangzhou
+  // config.setEndpoint("test-endpoint");
 
-  const string accessKeyId = "no-AccessKeyId";
-  const string accessKeySecret = "no-AccessKeySecret";
+  mockEndpointProvider provider(sub_user_credentials, config, config.regionId(), "ecs", "ecs");
+  LocationClient::DescribeEndpointsOutcome xout(Error("any-error-code", "any-error-message"));
 
-  auto locationClient = std::make_shared<LocationClient>(accessKeyId, accessKeySecret, configuration);
+  DefaultValue<LocationClient::DescribeEndpointsOutcome>::Set(xout);
+  EXPECT_CALL(provider, describeEndpoints(_));
+  EndpointProvider::EndpointOutcome out = provider.getEndpoint();
 
-  EndpointProvider ep(locationClient, configuration.regionId(), "Ecs", "ecs");
-  EndpointProvider::EndpointOutcome out = ep.getEndpoint();
-  EXPECT_TRUE(out.error().errorCode() == "InvalidAccessKeyId.NotFound");
+  EXPECT_TRUE(out.error().errorCode() == "any-error-code");
 }

+ 145 - 0
test/core/rpcserviceclient_ut.cc

@@ -0,0 +1,145 @@
+#include <iostream>
+#include <stdio.h>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "alibabacloud/core/SimpleCredentialsProvider.h"
+#include "alibabacloud/core/RpcServiceClient.h"
+#include "alibabacloud/core/HttpMessage.h"
+#include "alibabacloud/core/HttpClient.h"
+#include "alibabacloud/core/HttpRequest.h"
+
+using namespace std;
+using namespace AlibabaCloud;
+
+using ::testing::_;
+using ::testing::DefaultValue;
+
+namespace AlibabaCloud {
+  class mockRpcServiceClient : public RpcServiceClient {
+   public:
+    mockRpcServiceClient(const std::string & servicename, const std::shared_ptr<CredentialsProvider> &credentialsProvider,
+      const ClientConfiguration &configuration,
+      const std::shared_ptr<Signer> &signer = std::make_shared<HmacSha1Signer>()):
+    RpcServiceClient(servicename, credentialsProvider, configuration, signer)
+    {}
+    MOCK_CONST_METHOD3(AttemptRequest, HttpClient::HttpResponseOutcome (const std::string & endpoint, const ServiceRequest &request, HttpRequest::Method method));
+    using RpcServiceClient::makeRequest;
+    using RpcServiceClient::buildHttpRequest;
+
+  };
+
+  class mockServiceRequest: public ServiceRequest {
+   public:
+    mockServiceRequest(const std::string &product, const std::string &version):
+    ServiceRequest(product, version){}
+
+    using ServiceRequest::addParameter;
+    using ServiceRequest::parameter;
+    using ServiceRequest::removeParameter;
+    using ServiceRequest::setContent;
+    using ServiceRequest::setParameter;
+    using ServiceRequest::setParameters;
+    using ServiceRequest::setResourcePath;
+    using ServiceRequest::setProduct;
+    using ServiceRequest::setVersion;
+  };
+}
+
+TEST(RpcServiceClient, basic) {
+  const ClientConfiguration config;
+
+  std::string key    = "fake-key";
+  std::string secret = "fake-secret";
+  std::string token  = "fake-token";
+
+  const Credentials credentials(key, secret, token);
+
+  mockRpcServiceClient client("ecs", std::make_shared<SimpleCredentialsProvider>(credentials), config);
+
+  const string product = "ECS";
+  const string version = "1.0";
+  const string action = "fake-action";
+  const string endpoint = "test-cn-shanghai";
+
+  RpcServiceRequest req(product, version, action);
+
+  HttpRequest http_req = client.buildHttpRequest(endpoint, req, HttpRequest::Method::Get);
+  EXPECT_TRUE(http_req.header("x-sdk-client") == std::string("CPP/").append(ALIBABACLOUD_VERSION_STR));
+  EXPECT_TRUE(http_req.header("Host") == endpoint);
+  EXPECT_TRUE(http_req.method() == HttpRequest::Method::Get);
+  EXPECT_TRUE(http_req.url().query().find("AccessKeySecret") == string::npos);
+  EXPECT_TRUE(http_req.url().query().find("AccessKeyId=fake-key") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&SecurityToken=fake-token") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&Action=fake-action") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&Format=JSON") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&RegionId=cn-hangzhou") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&Signature=") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&SignatureMethod=HMAC-SHA1") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&SignatureNonce=") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&SignatureVersion=1.0") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&Version=1.0") != string::npos);
+  EXPECT_TRUE(http_req.url().query().find("&Timestamp=") != string::npos);
+}
+
+TEST(RpcServiceClient, mock) {
+  const string product = "ECS";
+  const string version = "1.0";
+  const string action = "fake-action";
+  const string endpoint = "test-cn-shanghai";
+  const string servicename = "fake-service-name";
+
+  const ClientConfiguration configuration;
+
+  std::string key    = "fake-key";
+  std::string secret = "fake-secret";
+  std::string token  = "fake-token";
+
+  const Credentials credentials(key, secret, token);
+
+  RpcServiceRequest rpc_req(product, version, action);
+  HttpClient::HttpResponseOutcome xout(Error("any-error-code", "any-error-message"));
+  DefaultValue<HttpClient::HttpResponseOutcome>::Set(xout);
+
+
+  mockRpcServiceClient client(servicename, std::make_shared<SimpleCredentialsProvider>(credentials), configuration);
+  EXPECT_CALL(client, AttemptRequest(_, _, _));
+
+  RpcServiceClient::JsonOutcome out = client.makeRequest(endpoint, rpc_req, HttpRequest::Method::Get);
+  EXPECT_TRUE(out.error().errorCode() == "any-error-code");
+}
+
+TEST(RpcServiceClient, mock_1) {
+  const string product = "ECS";
+  const string version = "1.0";
+  const string action = "fake-action";
+  const string endpoint = "test-cn-shanghai";
+  const string servicename = "fake-service-name";
+
+  const ClientConfiguration configuration;
+
+  std::string key    = "fake-key";
+  std::string secret = "fake-secret";
+  std::string token  = "fake-token";
+
+  const Credentials credentials(key, secret, token);
+
+  RpcServiceRequest rpc_req(product, version, action);
+
+  Url url;
+  url.setHost("example.com");
+  HttpRequest req(url, HttpRequest::Method::Post);
+  HttpResponse res(req);
+  res.setBody("any-body", 8);
+
+  HttpClient::HttpResponseOutcome xout(res);
+  DefaultValue<HttpClient::HttpResponseOutcome>::Set(xout);
+
+  mockRpcServiceClient client(servicename, std::make_shared<SimpleCredentialsProvider>(credentials), configuration);
+  EXPECT_CALL(client, AttemptRequest(_, _, _));
+
+  RpcServiceClient::JsonOutcome out = client.makeRequest(endpoint, rpc_req, HttpRequest::Method::Get);
+  EXPECT_TRUE(out.error().errorCode().empty());
+  EXPECT_TRUE(out.result() == "any-body");
+}
+
+

+ 47 - 72
test/core/servicerequest_ut.cc

@@ -8,7 +8,7 @@
 using namespace std;
 using namespace AlibabaCloud;
 
-namespace AlibabaCloud{
+namespace {
   class TestServiceRequest: public ServiceRequest {
    public:
     explicit TestServiceRequest(const std::string &product, const std::string &version):
@@ -21,90 +21,65 @@ namespace AlibabaCloud{
       ServiceRequest(other)
     {}
 
-
-    void addParameter(const ParameterNameType &k, const ParameterValueType &v) {
-      ServiceRequest::addParameter(k, v);
-    }
-
-    void removeParameter(const ParameterNameType &k) {
-      ServiceRequest::removeParameter(k);
-    }
-
-    ServiceRequest::ParameterValueType parameter (const ParameterNameType &name) {
-      return ServiceRequest::parameter(name);
-    }
-
-    void setContent(const char* data, size_t size) {
-      ServiceRequest::setContent(data, size);
-    }
-    void setParameter(const ParameterNameType &k, const ParameterValueType &v) {
-      ServiceRequest::setParameter(k, v);
-    }
-    void setParameters(const ParameterCollection &params) {
-      ServiceRequest::setParameters(params);
-    }
-
-    void setResourcePath (const std::string &p) {
-      ServiceRequest::setResourcePath(p);
-    }
-
-    void setProduct (const std::string &product) {
-      ServiceRequest::setProduct(product);
-    }
-
-    void setVersion(const std::string &version) {
-      ServiceRequest::setVersion(version);
-    }
+    using ServiceRequest::addParameter;
+    using ServiceRequest::removeParameter;
+    using ServiceRequest::parameter;
+    using ServiceRequest::setContent;
+    using ServiceRequest::setParameter;
+    using ServiceRequest::setParameters;
+    using ServiceRequest::setResourcePath;
+    using ServiceRequest::setProduct;
+    using ServiceRequest::setVersion;
   };
-}
 
-TEST(ServiceRequestTest, basic) {
+  TEST(ServiceRequestTest, basic) {
 
-  TestServiceRequest sr1("ECS", "1.0");
-  TestServiceRequest sr2(sr1);
+    TestServiceRequest sr1("ECS", "1.0");
+    TestServiceRequest sr2(sr1);
 
-  sr1.addParameter("k1", "v1");
-  sr2.addParameter("k2", "v2");
+    sr1.addParameter("k1", "v1");
+    sr2.addParameter("k2", "v2");
 
-  ServiceRequest::ParameterCollection p1 = sr1.parameters();
-  ServiceRequest::ParameterCollection p2 = sr2.parameters();
+    ServiceRequest::ParameterCollection p1 = sr1.parameters();
+    ServiceRequest::ParameterCollection p2 = sr2.parameters();
 
-  EXPECT_TRUE(sr1.parameter("k1") == "v1");
-  sr1.addParameter("kx", "vx");
-  EXPECT_TRUE(sr1.parameter("kx") == "vx");
+    EXPECT_TRUE(sr1.parameter("k1") == "v1");
+    sr1.addParameter("kx", "vx");
+    EXPECT_TRUE(sr1.parameter("kx") == "vx");
 
-  EXPECT_TRUE(sr1.parameters().size() == 2);
+    EXPECT_TRUE(sr1.parameters().size() == 2);
 
-  sr1.removeParameter("k1");
-  EXPECT_TRUE(sr1.parameters().size() == 1);
+    sr1.removeParameter("k1");
+    EXPECT_TRUE(sr1.parameters().size() == 1);
 
-  sr1.setParameter("ka", "va");
-  EXPECT_TRUE(sr1.parameter("ka") == "va");
+    sr1.setParameter("ka", "va");
+    EXPECT_TRUE(sr1.parameter("ka") == "va");
 
-  sr1.setContent("123456", 6);
-  EXPECT_TRUE(sr1.contentSize() == 6);
-  EXPECT_TRUE(sr1.hasContent() == true);
-  EXPECT_TRUE(strncmp(sr1.content(), "123456", 6) == 0);
+    sr1.setContent("123456", 6);
+    EXPECT_TRUE(sr1.contentSize() == 6);
+    EXPECT_TRUE(sr1.hasContent() == true);
+    EXPECT_TRUE(strncmp(sr1.content(), "123456", 6) == 0);
 
-  sr1.setContent("aliyunsdk", 9);
-  EXPECT_TRUE(sr1.contentSize() == 9);
-  EXPECT_TRUE(sr1.hasContent() == true);
-  EXPECT_TRUE(strncmp(sr1.content(), "aliyunsdk", 9) == 0);
+    sr1.setContent("aliyunsdk", 9);
+    EXPECT_TRUE(sr1.contentSize() == 9);
+    EXPECT_TRUE(sr1.hasContent() == true);
+    EXPECT_TRUE(strncmp(sr1.content(), "aliyunsdk", 9) == 0);
 
-  sr1.setProduct("OSS");
-  EXPECT_TRUE(sr1.product() == "OSS");
+    sr1.setProduct("OSS");
+    EXPECT_TRUE(sr1.product() == "OSS");
 
-  sr1.setVersion("3.0");
-  EXPECT_TRUE(sr1.version() == "3.0");
+    sr1.setVersion("3.0");
+    EXPECT_TRUE(sr1.version() == "3.0");
 
-  sr1.setResourcePath("http://abc.com/a/b/c");
-  EXPECT_TRUE(sr1.resourcePath() == "http://abc.com/a/b/c");
+    sr1.setResourcePath("http://abc.com/a/b/c");
+    EXPECT_TRUE(sr1.resourcePath() == "http://abc.com/a/b/c");
 
-  ServiceRequest::ParameterCollection ps;
-  ps["km"] = "vm";
-  ps["kn"] = "vn";
-  sr1.setParameters(ps);
-  ServiceRequest::ParameterCollection pc = sr1.parameters();
-  EXPECT_TRUE(pc.at("km") == "vm");
-  EXPECT_TRUE(pc.at("kn") == "vn");
+    ServiceRequest::ParameterCollection ps;
+    ps["km"] = "vm";
+    ps["kn"] = "vn";
+    sr1.setParameters(ps);
+    ServiceRequest::ParameterCollection pc = sr1.parameters();
+    EXPECT_TRUE(pc.at("km") == "vm");
+    EXPECT_TRUE(pc.at("kn") == "vn");
+  }
 }

+ 58 - 0
test/core/stsassumerolecredentialsprovider_ut.cc

@@ -0,0 +1,58 @@
+#include <iostream>
+#include <stdio.h>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "alibabacloud/core/AlibabaCloud.h"
+#include "alibabacloud/core/sts/StsClient.h"
+#include "alibabacloud/core/StsAssumeRoleCredentialsProvider.h"
+
+using namespace std;
+using namespace AlibabaCloud;
+using namespace AlibabaCloud::Sts;
+
+using ::testing::_;
+using ::testing::DefaultValue;
+
+namespace {
+
+  class mockStsAssumeRoleCredentialsProvider : public StsAssumeRoleCredentialsProvider {
+   public:
+    mockStsAssumeRoleCredentialsProvider(
+      const Credentials &credentials,
+      const ClientConfiguration &configuration,
+      const std::string &roleArn,
+      const std::string &roleSessionName,
+      const std::string &policy = "",
+      int durationSeconds = 3600):
+    StsAssumeRoleCredentialsProvider(credentials, configuration, roleArn, roleSessionName, policy, durationSeconds) {}
+    MOCK_CONST_METHOD1(assumeRole, StsClient::AssumeRoleOutcome(const Model::AssumeRoleRequest &request));
+  };
+
+  TEST(StsAssumeRoleCredentialsProvider, mock) {
+    ClientConfiguration configuration("cn-hangzhou");
+    const string sub_user_key = "key";
+    const string sub_user_secret = "secret";
+
+    const Credentials sub_user_credentials(sub_user_key, sub_user_secret);
+
+    const string arn = "acs:ram::1940345800212929:role/testassumerole";
+    const string session = "roleSessionName";
+    const string policy = "";
+    int duration = 1800;
+
+    const string payload = "{\"RequestId\":\"a-b-c-d\",\"AssumedRoleUser\":{\"AssumedRoleId\":\"test_assumed_role_id\",\"Arn\":\"test_arn\"},\"Credentials\":{\"AccessKeyId\":\"test_access_key_id\",\"AccessKeySecret\":\"test_access_key_secret\",\"Expiration\":\"100\",\"SecurityToken\":\"test_security_token\"}}";
+    Model::AssumeRoleResult res(payload);
+
+    mockStsAssumeRoleCredentialsProvider provider(sub_user_credentials, configuration, arn, session, policy, duration);
+
+    StsClient::AssumeRoleOutcome xout(res);
+    DefaultValue<StsClient::AssumeRoleOutcome>::Set(xout);
+    EXPECT_CALL(provider, assumeRole(_));
+
+    Credentials assumed_role_credentials = provider.getCredentials();
+
+    EXPECT_TRUE(assumed_role_credentials.accessKeyId() == "test_access_key_id");
+    EXPECT_TRUE(assumed_role_credentials.accessKeySecret() == "test_access_key_secret");
+    EXPECT_TRUE(assumed_role_credentials.sessionToken() == "test_security_token");
+  }
+}