Created
February 22, 2014 10:19
-
-
Save benoitc/9151625 to your computer and use it in GitHub Desktop.
patches for erlcloud/erlcloud#55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From f4e7c10492b7b6f6fd805d4059eb44c4ae8eaa8e Mon Sep 17 00:00:00 2001 | |
From: benoitc <[email protected]> | |
Date: Sun, 22 Dec 2013 08:44:38 +0100 | |
Subject: [PATCH 1/2] add hackney dependency | |
--- | |
rebar.config | 13 +++++++++++-- | |
1 file changed, 11 insertions(+), 2 deletions(-) | |
diff --git a/rebar.config b/rebar.config | |
index 3f82f2b..e1e1e96 100644 | |
--- a/rebar.config | |
+++ b/rebar.config | |
@@ -1,4 +1,13 @@ | |
+%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*- | |
+%% ex: ft=erlang ts=4 sw=4 et | |
+ | |
{erl_opts, [debug_info]}. | |
-{deps, [{meck, ".*", {git, "https://github.com/eproxus/meck.git", "master"}}, | |
- {jsx, ".*", {git, "git://github.com/talentdeficit/jsx.git", "master"}}]}. | |
+{deps, [ | |
+ {meck, ".*", | |
+ {git, "https://github.com/eproxus/meck.git", "master"}}, | |
+ {jsx, ".*", | |
+ {git, "https://github.com/talentdeficit/jsx.git", "master"}}, | |
+ {hackney, ".*", | |
+ {git, "https://github.com/benoitc/hackney.git", "master"}} | |
+]}. | |
-- | |
1.8.3.2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 2b13c3a572eb49a6ffde8ab4273ef2da8ed5e50c Mon Sep 17 00:00:00 2001 | |
From: benoitc <[email protected]> | |
Date: Sun, 22 Dec 2013 11:10:40 +0100 | |
Subject: [PATCH 2/2] s/httpc/hackney | |
Just some changes to replace httpc by hackney | |
--- | |
include/erlcloud_aws.hrl | 3 +- | |
src/erlcloud_aws.erl | 88 +++++++++--------- | |
src/erlcloud_ddb_impl.erl | 86 +++++++++++------- | |
src/erlcloud_mturk.erl | 15 ++-- | |
src/erlcloud_s3.erl | 48 ++++++---- | |
test/erlcloud_aws_tests.erl | 17 ++-- | |
test/erlcloud_ddb2_tests.erl | 190 +++++++++++++++++++-------------------- | |
test/erlcloud_ddb_tests.erl | 156 ++++++++++++++++---------------- | |
test/erlcloud_ddb_util_tests.erl | 28 +++--- | |
test/erlcloud_ec2_tests.erl | 40 ++++----- | |
test/erlcloud_sdb_tests.erl | 6 +- | |
11 files changed, 360 insertions(+), 317 deletions(-) | |
diff --git a/include/erlcloud_aws.hrl b/include/erlcloud_aws.hrl | |
index 12f510f..7fce430 100644 | |
--- a/include/erlcloud_aws.hrl | |
+++ b/include/erlcloud_aws.hrl | |
@@ -17,6 +17,7 @@ | |
access_key_id::string()|undefined|false, | |
secret_access_key::string()|undefined|false, | |
security_token=undefined::string()|undefined, | |
- timeout=10000::timeout() | |
+ timeout=10000::timeout(), | |
+ pool=default | |
}). | |
-type(aws_config() :: #aws_config{}). | |
diff --git a/src/erlcloud_aws.erl b/src/erlcloud_aws.erl | |
index 3bedbc0..7fdc683 100644 | |
--- a/src/erlcloud_aws.erl | |
+++ b/src/erlcloud_aws.erl | |
@@ -5,13 +5,13 @@ | |
aws_request2/7, | |
aws_request_xml2/5, aws_request_xml2/7, | |
param_list/2, default_config/0, update_config/1, format_timestamp/1, | |
- http_headers_body/1, | |
sign_v4/5]). | |
+-export([http_headers_body/1]). | |
-include("erlcloud.hrl"). | |
-include_lib("erlcloud/include/erlcloud_aws.hrl"). | |
--record(metadata_credentials, | |
+-record(metadata_credentials, | |
{access_key_id :: string(), | |
secret_access_key :: string(), | |
security_token=undefined :: string(), | |
@@ -76,38 +76,40 @@ aws_request2_no_update(Method, Protocol, Host, Port, Path, Params, #aws_config{} | |
undefined -> []; | |
Token -> [{"SecurityToken", Token}] | |
end), | |
- | |
+ | |
QueryToSign = erlcloud_http:make_query_string(QParams), | |
RequestToSign = [string:to_upper(atom_to_list(Method)), $\n, | |
string:to_lower(Host), $\n, Path, $\n, QueryToSign], | |
Signature = base64:encode(erlcloud_util:sha_mac(Config#aws_config.secret_access_key, RequestToSign)), | |
- | |
+ | |
Query = [QueryToSign, "&Signature=", erlcloud_http:url_encode(Signature)], | |
- | |
+ | |
case Protocol of | |
undefined -> UProtocol = "https://"; | |
_ -> UProtocol = [Protocol, "://"] | |
end, | |
- | |
+ | |
case Port of | |
undefined -> URL = [UProtocol, Host, Path]; | |
_ -> URL = [UProtocol, Host, $:, port_to_str(Port), Path] | |
end, | |
- | |
- %% Note: httpc MUST be used with {timeout, timeout()} option | |
+ | |
+ %% Note: hacknet MUST be used with {recv_timeout, timeout()} option | |
%% Many timeout related failures is observed at prod env | |
%% when library is used in 24/7 manner | |
Response = | |
- case Method of | |
- get -> | |
- Req = lists:flatten([URL, $?, Query]), | |
- httpc:request(get, {Req, []}, [{timeout, Config#aws_config.timeout}], []); | |
- _ -> | |
- httpc:request(Method, | |
- {lists:flatten(URL), [], "application/x-www-form-urlencoded; charset=utf-8", | |
- list_to_binary(Query)}, [{timeout, Config#aws_config.timeout}], []) | |
- end, | |
- | |
+ case Method of | |
+ get -> | |
+ URL1 = list_to_binary(lists:flatten([URL, $?, Query])), | |
+ hackney:get(URL, [], <<>>, [{recv_timeout, Config#aws_config.timeout}]); | |
+ _ -> | |
+ URL1 = list_to_binary(URL), | |
+ hackney:request(Method, URL, | |
+ [{<<"Content-Type">>,<<"application/x-www-form-urlencoded; charset=utf-8">>}], | |
+ list_to_binary(Query), | |
+ [{recv_timeout, Config#aws_config.timeout}]) | |
+ end, | |
+ | |
http_body(Response). | |
param_list([], _Key) -> []; | |
@@ -185,18 +187,18 @@ get_metadata_credentials() -> | |
timestamp_to_gregorian_seconds(Timestamp) -> | |
{ok, [Yr, Mo, Da, H, M, S], []} = io_lib:fread("~d-~d-~dT~d:~d:~dZ", binary_to_list(Timestamp)), | |
calendar:datetime_to_gregorian_seconds({{Yr, Mo, Da}, {H, M, S}}). | |
- | |
+ | |
-spec get_credentials_from_metadata() -> {ok, #metadata_credentials{}} | {error, term()}. | |
get_credentials_from_metadata() -> | |
%% TODO this function should retry on errors getting credentials | |
%% First get the list of roles | |
- case http_body(httpc:request("http://169.254.169.254/latest/meta-data/iam/security-credentials/")) of | |
+ case http_body(hackney:get("http://169.254.169.254/latest/meta-data/iam/security-credentials/")) of | |
{error, Reason} -> | |
{error, Reason}; | |
{ok, Body} -> | |
%% Always use the first role | |
Role = string:sub_word(Body, 1, $\n), | |
- case http_body(httpc:request( | |
+ case http_body(hackney:get( | |
"http://169.254.169.254/latest/meta-data/iam/security-credentials/" ++ Role)) of | |
{error, Reason} -> | |
{error, Reason}; | |
@@ -219,26 +221,32 @@ port_to_str(Port) when is_list(Port) -> | |
Port. | |
-spec http_body({ok, tuple()} | {error, term()}) -> {ok, string()} | {error, tuple()}. | |
-%% Extract the body and do error handling on the return of a httpc:request call. | |
-http_body(Return) -> | |
- case http_headers_body(Return) of | |
- {ok, {_, Body}} -> | |
- {ok, Body}; | |
- {error, Reason} -> | |
- {error, Reason} | |
+%% Extract the body and do error handling on the return. | |
+http_body(Resp) -> | |
+ case Resp of | |
+ {ok, _, _, Ref} -> hackney:body(Ref); | |
+ Error -> Error | |
end. | |
--type headers() :: [{string(), string()}]. | |
--spec http_headers_body({ok, tuple()} | {error, term()}) -> {ok, {headers(), string()}} | {error, tuple()}. | |
-%% Extract the headers and body and do error handling on the return of a httpc:request call. | |
-http_headers_body({ok, {{_HTTPVer, OKStatus, _StatusLine}, Headers, Body}}) | |
- when OKStatus >= 200, OKStatus =< 299 -> | |
- {ok, {Headers, Body}}; | |
-http_headers_body({ok, {{_HTTPVer, Status, StatusLine}, _Headers, Body}}) -> | |
- {error, {http_error, Status, StatusLine, Body}}; | |
+http_headers_body({ok, Status, RespHeaders, Ref}) | |
+ when Status >= 200, Status =< 299 -> | |
+ case hackney:body(Ref) of | |
+ {ok, Body} -> | |
+ {ok, RespHeaders, Body}; | |
+ Error -> | |
+ Error | |
+ end; | |
+http_headers_body({ok, Status, _, Ref}) -> | |
+ case hackney:body(Ref) of | |
+ {ok, Body} -> | |
+ {error, {http_error, Status, Body}}; | |
+ Error -> | |
+ Error | |
+ end; | |
http_headers_body({error, Reason}) -> | |
{error, {socket_error, Reason}}. | |
+ | |
%% http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html | |
%% TODO additional parameters - currently only supports what is needed for DynamoDB | |
-spec sign_v4(aws_config(), headers(), binary(), string(), string()) -> headers(). | |
@@ -256,7 +264,7 @@ sign_v4(Config, Headers, Payload, Region, Service) -> | |
Signature = base16(erlcloud_util:sha256_mac( SigningKey, ToSign)), | |
Authorization = authorization(Config, CredentialScope, SignedHeaders, Signature), | |
[{"Authorization", lists:flatten(Authorization)} | Headers2]. | |
- | |
+ | |
iso_8601_basic_time() -> | |
{{Year,Month,Day},{Hour,Min,Sec}} = calendar:now_to_universal_time(os:timestamp()), | |
lists:flatten(io_lib:format( | |
@@ -294,13 +302,13 @@ base16(Data) -> | |
credential_scope(Date, Region, Service) -> | |
DateOnly = string:left(Date, 8), | |
[DateOnly, $/, Region, $/, Service, "/aws4_request"]. | |
- | |
+ | |
to_sign(Date, CredentialScope, Request) -> | |
["AWS4-HMAC-SHA256\n", | |
Date, $\n, | |
CredentialScope, $\n, | |
hash_encode(Request)]. | |
- | |
+ | |
signing_key(Config, Date, Region, Service) -> | |
%% TODO cache the signing key so we don't have to recompute for every request | |
DateOnly = string:left(Date, 8), | |
@@ -308,7 +316,7 @@ signing_key(Config, Date, Region, Service) -> | |
KRegion = erlcloud_util:sha256_mac( KDate, Region), | |
KService = erlcloud_util:sha256_mac( KRegion, Service), | |
erlcloud_util:sha256_mac( KService, "aws4_request"). | |
- | |
+ | |
authorization(Config, CredentialScope, SignedHeaders, Signature) -> | |
["AWS4-HMAC-SHA256" | |
" Credential=", Config#aws_config.access_key_id, $/, CredentialScope, $,, | |
diff --git a/src/erlcloud_ddb_impl.erl b/src/erlcloud_ddb_impl.erl | |
index 9229951..26ba12e 100644 | |
--- a/src/erlcloud_ddb_impl.erl | |
+++ b/src/erlcloud_ddb_impl.erl | |
@@ -80,7 +80,7 @@ request(Config0, Operation, Json) -> | |
%% Sleep after an attempt | |
-spec backoff(pos_integer()) -> ok. | |
backoff(1) -> ok; | |
-backoff(Attempt) -> | |
+backoff(Attempt) -> | |
timer:sleep(random:uniform((1 bsl (Attempt - 1)) * 100)). | |
-type attempt() :: {attempt, pos_integer()} | {error, term()}. | |
@@ -91,51 +91,74 @@ retry(Attempt, Reason) when Attempt >= ?NUM_ATTEMPTS -> | |
retry(Attempt, _) -> | |
backoff(Attempt), | |
{attempt, Attempt + 1}. | |
- | |
+ | |
-type headers() :: [{string(), string()}]. | |
--spec request_and_retry(aws_config(), headers(), jsx:json_text(), attempt()) -> | |
+-spec request_and_retry(aws_config(), headers(), jsx:json_text(), attempt()) -> | |
{ok, jsx:json_term()} | {error, term()}. | |
request_and_retry(_, _, _, {error, Reason}) -> | |
{error, Reason}; | |
request_and_retry(Config, Headers, Body, {attempt, Attempt}) -> | |
RetryFun = Config#aws_config.ddb_retry, | |
- case httpc:request(post, {url(Config), Headers, "application/x-amz-json-1.0", Body}, | |
- [{timeout, 1000}], | |
- [{body_format, binary}]) of | |
- {ok, {{_, 200, _}, _, RespBody}} -> | |
+ Hdrs = [{<<"Content-Type">>, <<"application/x-amz-json-1.0">>} | Headers], | |
+ case hackney:post(post, url(Config), Hdrs, Body, [{recv_timeout, 1000}]) of | |
+ | |
+ {ok, 200, _, Ref} -> | |
%% TODO check crc | |
- {ok, jsx:decode(RespBody)}; | |
+ case hackney:body(Ref) of | |
+ {ok, RespBody} -> {ok, jsx:decode(RespBody)}; | |
+ Error -> Error | |
+ end; | |
- {ok, {{_, Status, StatusLine}, _, RespBody}} when Status >= 400 andalso Status < 500 -> | |
- case client_error(Status, StatusLine, RespBody) of | |
- {retry, Reason} -> | |
- request_and_retry(Config, Headers, Body, RetryFun(Attempt, Reason)); | |
+ {ok, Status, _, Ref} when Status >= 400 andalso Status < 500 -> | |
+ case hackney:body(Ref) of | |
+ {ok, RespBody} -> | |
+ | |
+ case client_error(Status, RespBody) of | |
+ {retry, Reason} -> | |
+ request_and_retry(Config, Headers, Body, | |
+ RetryFun(Attempt, Reason)); | |
+ {error, Reason} -> | |
+ {error, Reason} | |
+ end; | |
+ {error, Reason} -> | |
+ request_and_retry(Config, Headers, Body, | |
+ RetryFun(Attempt, Reason)) | |
+ end; | |
+ {ok, Status, _, Ref} when Status >= 500 -> | |
+ case hackney:body(Ref) of | |
+ {ok, RespBody} -> | |
+ request_and_retry(Config, Headers, Body, | |
+ RetryFun(Attempt, {http_error, Status, RespBody})); | |
{error, Reason} -> | |
- {error, Reason} | |
+ request_and_retry(Config, Headers, Body, | |
+ RetryFun(Attempt, Reason)) | |
+ end; | |
+ | |
+ {ok, Status, _, Ref} -> | |
+ case hackney:body(Ref) of | |
+ {ok, RespBody} -> | |
+ {error, {http_error, Status, RespBody}}; | |
+ {error, Reason} -> | |
+ request_and_retry(Config, Headers, Body, | |
+ RetryFun(Attempt, Reason)) | |
end; | |
- | |
- {ok, {{_, Status, StatusLine}, _, RespBody}} when Status >= 500 -> | |
- request_and_retry(Config, Headers, Body, RetryFun(Attempt, {http_error, Status, StatusLine, RespBody})); | |
- | |
- {ok, {{_, Status, StatusLine}, _, RespBody}} -> | |
- {error, {http_error, Status, StatusLine, RespBody}}; | |
- | |
{error, Reason} -> | |
- %% TODO there may be some http errors, such as certificate error, that we don't want to retry | |
+ %% TODO there may be some http errors, such as certificate | |
+ %% error, that we don't want to retry | |
request_and_retry(Config, Headers, Body, RetryFun(Attempt, Reason)) | |
end. | |
--spec client_error(pos_integer(), string(), binary()) -> {retry, term()} | {error, term()}. | |
-client_error(Status, StatusLine, Body) -> | |
+-spec client_error(pos_integer(), binary()) -> {retry, term()} | {error, term()}. | |
+client_error(Status, Body) -> | |
case jsx:is_json(Body) of | |
false -> | |
- {error, {http_error, Status, StatusLine, Body}}; | |
+ {error, {http_error, Status, Body}}; | |
true -> | |
Json = jsx:decode(Body), | |
case proplists:get_value(<<"__type">>, Json) of | |
undefined -> | |
- {error, {http_error, Status, StatusLine, Body}}; | |
+ {error, {http_error, Status, Body}}; | |
FullType -> | |
Message = proplists:get_value(<<"message">>, Json, <<>>), | |
case binary:split(FullType, <<"#">>) of | |
@@ -146,21 +169,21 @@ client_error(Status, StatusLine, Body) -> | |
[_, Type] -> | |
{error, {Type, Message}}; | |
_ -> | |
- {error, {http_error, Status, StatusLine, Body}} | |
+ {error, {http_error, Status, Body}} | |
end | |
end | |
end. | |
-spec headers(aws_config(), string(), binary()) -> headers(). | |
headers(Config, Operation, Body) -> | |
- Headers = [{"host", Config#aws_config.ddb_host}, | |
- {"x-amz-target", Operation}], | |
- Region = | |
+ Headers = [{<<"host">>, hackney_bstr:to_binary(Config#aws_config.ddb_host)}, | |
+ {<<"x-amz-target">>, hackney_bstr:to_binary(Operation)}], | |
+ Region = | |
case string:tokens(Config#aws_config.ddb_host, ".") of | |
[_, Value, _, _] -> | |
- Value; | |
+ hackney_bstr:to_binary(Value); | |
_ -> | |
- "us-east-1" | |
+ <<"us-east-1">> | |
end, | |
erlcloud_aws:sign_v4(Config, Headers, Body, Region, "dynamodb"). | |
@@ -171,4 +194,3 @@ port_spec(#aws_config{ddb_port=80}) -> | |
""; | |
port_spec(#aws_config{ddb_port=Port}) -> | |
[":", erlang:integer_to_list(Port)]. | |
- | |
diff --git a/src/erlcloud_mturk.erl b/src/erlcloud_mturk.erl | |
index 5580ebb..3b843a8 100644 | |
--- a/src/erlcloud_mturk.erl | |
+++ b/src/erlcloud_mturk.erl | |
@@ -1607,16 +1607,13 @@ mturk_request(Config, Operation, Params) -> | |
{"Signature", Signature}|Params], | |
URL = ["https://", Config#aws_config.mturk_host, "/"], | |
+ Hdrs = [{<<"Content-Type">>, <<"application/x-www-form-urlencoded">>}], | |
+ ReqBody = list_to_binary(erlcloud_http:make_query_string(QParams)), | |
+ Response = hackney:request(post, lists:flatten(URL), Hdrs, ReqBody, []), | |
- Response = httpc:request(post, | |
- {lists:flatten(URL), [], "application/x-www-form-urlencoded", | |
- list_to_binary(erlcloud_http:make_query_string(QParams))}, [], []), | |
- | |
- case Response of | |
- {ok, {{_HTTPVer, 200, _StatusLine}, _Headers, Body}} -> | |
+ case erlcloud:http_headers_body(Response) of | |
+ {ok, _, Body} -> | |
Body; | |
- {ok, {{_HTTPVer, Status, _StatusLine}, _Headers, _Body}} -> | |
- erlang:error({aws_error, {http_error, Status, _StatusLine, _Body}}); | |
{error, Error} -> | |
- erlang:error({aws_error, {socket_error, Error}}) | |
+ erlang:error({aws_error, Error}) | |
end. | |
diff --git a/src/erlcloud_s3.erl b/src/erlcloud_s3.erl | |
index 2c0af4a..a2a5eb5 100644 | |
--- a/src/erlcloud_s3.erl | |
+++ b/src/erlcloud_s3.erl | |
@@ -880,25 +880,31 @@ s3_xml_request2(Config, Method, Host, Path, Subresource, Params, POSTData, Heade | |
Error | |
end. | |
-s3_request2_no_update(Config, Method, Host, Path, Subresource, Params, POSTData, Headers0) -> | |
- {ContentMD5, ContentType, Body} = | |
- case POSTData of | |
- {PD, CT} -> {base64:encode(erlcloud_util:md5(PD)), CT, PD}; PD -> {"", "", PD} | |
- end, | |
+s3_request2_no_update(Config, Method, Host, Path, Subresource, | |
+ Params, POSTData, Headers0) -> | |
+ {ContentMD5, ContentType, Body} = case POSTData of | |
+ {PD, CT} -> {base64:encode(erlcloud_util:md5(PD)), CT, PD}; | |
+ PD -> {<<"">>, <<"">>, PD} | |
+ end, | |
Headers = case Config#aws_config.security_token of | |
- undefined -> Headers0; | |
- Token when is_list(Token) -> [{"x-amz-security-token", Token} | Headers0] | |
- end, | |
- FHeaders = [Header || {_, Value} = Header <- Headers, Value =/= undefined], | |
- AmzHeaders = [Header || {"x-amz-" ++ _, _} = Header <- FHeaders], | |
+ undefined -> Headers0; | |
+ Token when is_list(Token) -> | |
+ [{<<"x-amz-security-token">>, hackney_bstr:to_binary(Token)} | |
+ | Headers0] | |
+ end, | |
+ FHeaders = [{hackney_bstr:to_binary(K),hackney_bstr:to_binary(V)} | |
+ || {K, V} <- Headers, V =/= undefined], | |
+ AmzHeaders = [Header || {<<"x-amz-", _/binary>>, _} = Header <- FHeaders], | |
Date = httpd_util:rfc1123_date(erlang:localtime()), | |
EscapedPath = erlcloud_http:url_encode_loose(Path), | |
Authorization = make_authorization(Config, Method, ContentMD5, ContentType, | |
Date, AmzHeaders, Host, EscapedPath, Subresource, Params), | |
- RequestHeaders = [{"date", Date}, {"authorization", Authorization}|FHeaders] ++ | |
+ RequestHeaders = [{<<"date">>, hackney_bstr:to_binary(Date)}, | |
+ {<<"authorization">>, | |
+ hackney_bstr:to_binary(Authorization)} | FHeaders] ++ | |
case ContentMD5 of | |
- "" -> []; | |
- _ -> [{"content-md5", binary_to_list(ContentMD5)}] | |
+ <<"">> -> []; | |
+ _ -> [{<<"content-md5">>, ContentMD5}] | |
end, | |
RequestURI = lists:flatten([ | |
Config#aws_config.s3_scheme, | |
@@ -914,11 +920,17 @@ s3_request2_no_update(Config, Method, Host, Path, Subresource, Params, POSTData, | |
]), | |
Response = case Method of | |
- get -> httpc:request(Method, {RequestURI, RequestHeaders}, [], []); | |
- head -> httpc:request(Method, {RequestURI, RequestHeaders}, [], []); | |
- delete -> httpc:request(Method, {RequestURI, RequestHeaders}, [], []); | |
- _ -> httpc:request(Method, {RequestURI, RequestHeaders, ContentType, Body}, [], []) | |
- end, | |
+ get -> | |
+ hackney:request(Method, RequestURI, RequestHeaders, <<>>, []); | |
+ head -> | |
+ hackney:request(Method, RequestURI, RequestHeaders, <<>>, []); | |
+ delete -> | |
+ hackney:request(Method, RequestURI, RequestHeaders, <<>>, []); | |
+ _ -> | |
+ Hdrs = [{<<"Content-Type">>, ContentType} | RequestHeaders], | |
+ hackney:request(Method, RequestURI, Hdrs, Body, []) | |
+ end, | |
+ | |
erlcloud_aws:http_headers_body(Response). | |
make_authorization(Config, Method, ContentMD5, ContentType, Date, AmzHeaders, | |
diff --git a/test/erlcloud_aws_tests.erl b/test/erlcloud_aws_tests.erl | |
index d44f1cc..1ac3f77 100644 | |
--- a/test/erlcloud_aws_tests.erl | |
+++ b/test/erlcloud_aws_tests.erl | |
@@ -10,33 +10,36 @@ request_test_() -> | |
fun request_prot_host_port_int_test/1]}. | |
start() -> | |
- meck:new(httpc, [unstick]), | |
- meck:expect(httpc, request, fun(_) -> {ok, {{0, 200, 0}, 0, ok}} end), | |
+ meck:new(hackney, [unstick]), | |
+ meck:expect(hackney, request, fun(_) -> {ok, 200, 0, ok} end), | |
+ meck:expect(hackney, get, fun(_) -> {ok, 200, 0, ok} end), | |
+ meck:expect(hackney, post, fun(_) -> {ok, 200, 0, ok} end), | |
+ | |
ok. | |
stop(_) -> | |
- meck:unload(httpc). | |
+ meck:unload(hackney). | |
request_default_test(_) -> | |
ok = erlcloud_aws:aws_request(get, "host", "/", [], "id", "key"), | |
- Url = get_url_from_history(meck:history(httpc)), | |
+ Url = get_url_from_history(meck:history(hackney)), | |
test_url(https, "host", 443, "/", Url). | |
request_prot_host_port_str_test(_) -> | |
ok = erlcloud_aws:aws_request(get, "http", "host1", "9999", "/path1", [], "id", "key"), | |
- Url = get_url_from_history(meck:history(httpc)), | |
+ Url = get_url_from_history(meck:history(hackney)), | |
test_url(http, "host1", 9999, "/path1", Url). | |
request_prot_host_port_int_test(_) -> | |
ok = erlcloud_aws:aws_request(get, "http", "host1", 9999, "/path1", [], "id", "key"), | |
- Url = get_url_from_history(meck:history(httpc)), | |
+ Url = get_url_from_history(meck:history(hackney)), | |
test_url(http, "host1", 9999, "/path1", Url). | |
% ================== | |
% Internal functions | |
% ================== | |
-get_url_from_history([{_, {httpc, request, [Url]}, _}]) -> | |
+get_url_from_history([{_, {hackney, request, [Url]}, _}]) -> | |
Url. | |
test_url(ExpScheme, ExpHost, ExpPort, ExpPath, Url) -> | |
diff --git a/test/erlcloud_ddb2_tests.erl b/test/erlcloud_ddb2_tests.erl | |
index 07fef0d..39cd600 100644 | |
--- a/test/erlcloud_ddb2_tests.erl | |
+++ b/test/erlcloud_ddb2_tests.erl | |
@@ -5,7 +5,7 @@ | |
-include("erlcloud_ddb2.hrl"). | |
%% Unit tests for ddb. | |
-%% These tests work by using meck to mock httpc. There are two classes of test: input and output. | |
+%% These tests work by using meck to mock hackney. There are two classes of test: input and output. | |
%% | |
%% Input tests verify that different function args produce the desired JSON request. | |
%% An input test list provides a list of funs and the JSON that is expected to result. | |
@@ -19,7 +19,7 @@ | |
-define(_f(F), fun() -> F end). | |
-export([validate_body/2]). | |
- | |
+ | |
%%%=================================================================== | |
%%% Test entry points | |
%%%=================================================================== | |
@@ -58,11 +58,11 @@ operation_test_() -> | |
]}. | |
start() -> | |
- meck:new(httpc, [unstick]), | |
+ meck:new(hackney, [unstick]), | |
ok. | |
stop(_) -> | |
- meck:unload(httpc). | |
+ meck:unload(hackney). | |
%%%=================================================================== | |
%%% Input test helpers | |
@@ -79,7 +79,7 @@ sort_object(V) -> | |
%% verifies that the parameters in the body match the expected parameters | |
-spec validate_body(binary(), expected_body()) -> ok. | |
validate_body(Body, Expected) -> | |
- Want = jsx:decode(list_to_binary(Expected), [{post_decode, fun sort_object/1}]), | |
+ Want = jsx:decode(list_to_binary(Expected), [{post_decode, fun sort_object/1}]), | |
Actual = jsx:decode(Body, [{post_decode, fun sort_object/1}]), | |
case Want =:= Actual of | |
true -> ok; | |
@@ -88,13 +88,13 @@ validate_body(Body, Expected) -> | |
end, | |
?assertEqual(Want, Actual). | |
-%% returns the mock of the httpc function input tests expect to be called. | |
+%% returns the mock of the hackney function input tests expect to be called. | |
%% Validates the request body and responds with the provided response. | |
-spec input_expect(string(), expected_body()) -> fun(). | |
input_expect(Response, Expected) -> | |
- fun(post, {_Url, _Headers, _ContentType, Body}, _HTTPOpts, _Opts) -> | |
+ fun(post, _Url, _Headers, Body}, _Opts) -> | |
validate_body(Body, Expected), | |
- {ok, {{0, 200, 0}, 0, list_to_binary(Response)}} | |
+ {ok, 200, 0, list_to_binary(Response)} | |
end. | |
%% input_test converts an input_test specifier into an eunit test generator | |
@@ -102,10 +102,10 @@ input_expect(Response, Expected) -> | |
-spec input_test(string(), input_test_spec()) -> tuple(). | |
input_test(Response, {Line, {Description, Fun, Expected}}) when | |
is_list(Description) -> | |
- {Description, | |
+ {Description, | |
{Line, | |
fun() -> | |
- meck:expect(httpc, request, input_expect(Response, Expected)), | |
+ meck:expect(hackney, request, input_expect(Response, Expected)), | |
erlcloud_ddb2:configure(string:copies("A", 20), string:copies("a", 40)), | |
Fun() | |
end}}. | |
@@ -121,11 +121,11 @@ input_tests(Response, Tests) -> | |
%%% Output test helpers | |
%%%=================================================================== | |
-%% returns the mock of the httpc function output tests expect to be called. | |
+%% returns the mock of the hackney function output tests expect to be called. | |
-spec output_expect(string()) -> fun(). | |
output_expect(Response) -> | |
- fun(post, {_Url, _Headers, _ContentType, _Body}, _HTTPOpts, _Opts) -> | |
- {ok, {{0, 200, 0}, 0, list_to_binary(Response)}} | |
+ fun(post, _Url, _Headers, _Body, _Opts) -> | |
+ {ok, 200, 0, list_to_binary(Response)} | |
end. | |
%% output_test converts an output_test specifier into an eunit test generator | |
@@ -135,7 +135,7 @@ output_test(Fun, {Line, {Description, Response, Result}}) -> | |
{Description, | |
{Line, | |
fun() -> | |
- meck:expect(httpc, request, output_expect(Response)), | |
+ meck:expect(hackney, request, output_expect(Response)), | |
erlcloud_ddb2:configure(string:copies("A", 20), string:copies("a", 40)), | |
Actual = Fun(), | |
case Result =:= Actual of | |
@@ -147,9 +147,9 @@ output_test(Fun, {Line, {Description, Response, Result}}) -> | |
end}}. | |
%% output_test(Fun, {Line, {Response, Result}}) -> | |
%% output_test(Fun, {Line, {"", Response, Result}}). | |
- | |
+ | |
%% output_tests converts a list of output_test specifiers into an eunit test generator | |
--spec output_tests(fun(), [output_test_spec()]) -> [term()]. | |
+-spec output_tests(fun(), [output_test_spec()]) -> [term()]. | |
output_tests(Fun, Tests) -> | |
[output_test(Fun, Test) || Test <- Tests]. | |
@@ -158,24 +158,24 @@ output_tests(Fun, Tests) -> | |
%%% Error test helpers | |
%%%=================================================================== | |
--spec httpc_response(pos_integer(), string()) -> tuple(). | |
-httpc_response(Code, Body) -> | |
- {ok, {{"", Code, ""}, [], list_to_binary(Body)}}. | |
- | |
+-spec hackney_response(pos_integer(), string()) -> tuple(). | |
+hackney_response(Code, Body) -> | |
+ {ok, Code, [], list_to_binary(Body)}. | |
+ | |
-type error_test_spec() :: {pos_integer(), {string(), list(), term()}}. | |
-spec error_test(fun(), error_test_spec()) -> tuple(). | |
error_test(Fun, {Line, {Description, Responses, Result}}) -> | |
%% Add a bogus response to the end of the request to make sure we don't call too many times | |
- Responses1 = Responses ++ [httpc_response(200, "TOO MANY REQUESTS")], | |
+ Responses1 = Responses ++ [hackney_response(200, "TOO MANY REQUESTS")], | |
{Description, | |
{Line, | |
fun() -> | |
- meck:sequence(httpc, request, 4, Responses1), | |
+ meck:sequence(hackney, request, 4, Responses1), | |
erlcloud_ddb2:configure(string:copies("A", 20), string:copies("a", 40)), | |
Actual = Fun(), | |
?assertEqual(Result, Actual) | |
end}}. | |
- | |
+ | |
-spec error_tests(fun(), [error_test_spec()]) -> [term()]. | |
error_tests(Fun, Tests) -> | |
[error_test(Fun, Test) || Test <- Tests]. | |
@@ -197,21 +197,21 @@ input_exception_test_() -> | |
%% Error handling tests based on: | |
%% http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ErrorHandling.html | |
error_handling_tests(_) -> | |
- OkResponse = httpc_response(200, " | |
+ OkResponse = hackney_response(200, " | |
{\"Item\": | |
{\"friends\":{\"SS\":[\"Lynda\", \"Aaron\"]}, | |
\"status\":{\"S\":\"online\"} | |
}, | |
\"ConsumedCapacityUnits\": 1 | |
-}" | |
+}" | |
), | |
OkResult = {ok, [{<<"friends">>, [<<"Lynda">>, <<"Aaron">>]}, | |
{<<"status">>, <<"online">>}]}, | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"Test retry after ProvisionedThroughputExceededException", | |
- [httpc_response(400, " | |
+ [hackney_response(400, " | |
{\"__type\":\"com.amazonaws.dynamodb.v20111205#ProvisionedThroughputExceededException\", | |
\"message\":\"The level of configured provisioned throughput for the table was exceeded. Consider increasing your provisioning level with the UpdateTable API\"}" | |
), | |
@@ -219,18 +219,18 @@ error_handling_tests(_) -> | |
OkResult}), | |
?_ddb_test( | |
{"Test ConditionalCheckFailed error", | |
- [httpc_response(400, " | |
+ [hackney_response(400, " | |
{\"__type\":\"com.amazonaws.dynamodb.v20111205#ConditionalCheckFailedException\", | |
\"message\":\"The expected value did not match what was stored in the system.\"}" | |
)], | |
{error, {<<"ConditionalCheckFailedException">>, <<"The expected value did not match what was stored in the system.">>}}}), | |
?_ddb_test( | |
{"Test retry after 500", | |
- [httpc_response(500, ""), | |
+ [hackney_response(500, ""), | |
OkResponse], | |
OkResult}) | |
], | |
- | |
+ | |
error_tests(?_f(erlcloud_ddb2:get_item(<<"table">>, {<<"k">>, <<"v">>})), Tests). | |
@@ -241,13 +241,13 @@ batch_get_item_input_tests(_) -> | |
[?_ddb_test( | |
{"BatchGetItem example request", | |
?_f(erlcloud_ddb2:batch_get_item( | |
- [{<<"Forum">>, | |
+ [{<<"Forum">>, | |
[{<<"Name">>, {s, <<"Amazon DynamoDB">>}}, | |
- {<<"Name">>, {s, <<"Amazon RDS">>}}, | |
+ {<<"Name">>, {s, <<"Amazon RDS">>}}, | |
{<<"Name">>, {s, <<"Amazon Redshift">>}}], | |
[{attributes_to_get, [<<"Name">>, <<"Threads">>, <<"Messages">>, <<"Views">>]}]}, | |
- {<<"Thread">>, | |
- [[{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
+ {<<"Thread">>, | |
+ [[{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"Subject">>, {s, <<"Concurrent reads">>}}]], | |
[{attributes_to_get, [<<"Tags">>, <<"Message">>]}]}], | |
[{return_consumed_capacity, total}])), " | |
@@ -360,7 +360,7 @@ batch_get_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
batch_get_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"BatchGetItem example response", " | |
{ | |
@@ -434,10 +434,10 @@ batch_get_item_output_tests(_) -> | |
] | |
}", | |
{ok, #ddb2_batch_get_item | |
- {consumed_capacity = | |
+ {consumed_capacity = | |
[#ddb2_consumed_capacity{table_name = <<"Forum">>, capacity_units = 3}, | |
#ddb2_consumed_capacity{table_name = <<"Thread">>, capacity_units = 1}], | |
- responses = | |
+ responses = | |
[#ddb2_batch_get_item_response | |
{table = <<"Forum">>, | |
items = [[{<<"Name">>, <<"Amazon DynamoDB">>}, | |
@@ -492,19 +492,19 @@ batch_get_item_output_tests(_) -> | |
} | |
}", | |
{ok, #ddb2_batch_get_item | |
- {responses = [], | |
- unprocessed_keys = | |
- [{<<"Forum">>, | |
+ {responses = [], | |
+ unprocessed_keys = | |
+ [{<<"Forum">>, | |
[[{<<"Name">>, {s, <<"Amazon DynamoDB">>}}], | |
- [{<<"Name">>, {s, <<"Amazon RDS">>}}], | |
+ [{<<"Name">>, {s, <<"Amazon RDS">>}}], | |
[{<<"Name">>, {s, <<"Amazon Redshift">>}}]], | |
[{attributes_to_get, [<<"Name">>, <<"Threads">>, <<"Messages">>, <<"Views">>]}]}, | |
- {<<"Thread">>, | |
- [[{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
+ {<<"Thread">>, | |
+ [[{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"Subject">>, {s, <<"Concurrent reads">>}}]], | |
[{attributes_to_get, [<<"Tags">>, <<"Message">>]}]}]}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:batch_get_item([{<<"table">>, [{<<"k">>, <<"v">>}]}], [{out, record}])), Tests). | |
%% BatchWriteItem test based on the API examples: | |
@@ -647,7 +647,7 @@ batch_write_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
batch_write_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"BatchWriteItem example response", " | |
{ | |
@@ -677,7 +677,7 @@ batch_write_item_output_tests(_) -> | |
{ok, #ddb2_batch_write_item | |
{consumed_capacity = [#ddb2_consumed_capacity{table_name = <<"Forum">>, capacity_units = 3}], | |
item_collection_metrics = undefined, | |
- unprocessed_items = [{<<"Forum">>, | |
+ unprocessed_items = [{<<"Forum">>, | |
[{put, [{<<"Name">>, {s, <<"Amazon ElastiCache">>}}, | |
{<<"Category">>, {s, <<"Amazon Web Services">>}}]}]}]}}}), | |
?_ddb_test( | |
@@ -710,7 +710,7 @@ batch_write_item_output_tests(_) -> | |
} | |
}", | |
{ok, #ddb2_batch_write_item | |
- {consumed_capacity = undefined, | |
+ {consumed_capacity = undefined, | |
item_collection_metrics = undefined, | |
unprocessed_items = | |
[{<<"Forum">>, [{put, [{<<"Name">>, {s, <<"Amazon DynamoDB">>}}, | |
@@ -761,8 +761,8 @@ batch_write_item_output_tests(_) -> | |
} | |
}", | |
{ok, #ddb2_batch_write_item | |
- {consumed_capacity = undefined, | |
- item_collection_metrics = | |
+ {consumed_capacity = undefined, | |
+ item_collection_metrics = | |
[{<<"Table1">>, | |
[#ddb2_item_collection_metrics | |
{item_collection_key = <<"value1">>, | |
@@ -778,7 +778,7 @@ batch_write_item_output_tests(_) -> | |
]}], | |
unprocessed_items = []}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:batch_write_item([], [{out, record}])), Tests). | |
%% CreateTable test based on the API examples: | |
@@ -793,7 +793,7 @@ create_table_input_tests(_) -> | |
{<<"Subject">>, s}, | |
{<<"LastPostDateTime">>, s}], | |
{<<"ForumName">>, <<"Subject">>}, | |
- 5, | |
+ 5, | |
5, | |
[{local_secondary_indexes, | |
[{<<"LastPostIndex">>, <<"LastPostDateTime">>, keys_only}]}] | |
@@ -856,7 +856,7 @@ create_table_input_tests(_) -> | |
{<<"Subject">>, s}, | |
{<<"LastPostDateTime">>, s}], | |
{<<"ForumName">>, <<"Subject">>}, | |
- 5, | |
+ 5, | |
5, | |
[{local_secondary_indexes, | |
[{<<"LastPostIndex">>, <<"LastPostDateTime">>, {include, [<<"Author">>, <<"Body">>]}}]}] | |
@@ -918,7 +918,7 @@ create_table_input_tests(_) -> | |
<<"Thread">>, | |
{<<"ForumName">>, s}, | |
<<"ForumName">>, | |
- 1, | |
+ 1, | |
1 | |
)), " | |
{ | |
@@ -1005,7 +1005,7 @@ create_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
create_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"CreateTable example response", " | |
{ | |
@@ -1080,7 +1080,7 @@ create_table_output_tests(_) -> | |
item_count = 0, | |
key_schema = {<<"ForumName">>, <<"LastPostDateTime">>}, | |
projection = keys_only}], | |
- provisioned_throughput = | |
+ provisioned_throughput = | |
#ddb2_provisioned_throughput_description{ | |
last_decrease_date_time = undefined, | |
last_increase_date_time = undefined, | |
@@ -1165,7 +1165,7 @@ create_table_output_tests(_) -> | |
item_count = 0, | |
key_schema = {<<"ForumName">>, <<"LastPostDateTime">>}, | |
projection = {include, [<<"Author">>, <<"Body">>]}}], | |
- provisioned_throughput = | |
+ provisioned_throughput = | |
#ddb2_provisioned_throughput_description{ | |
last_decrease_date_time = undefined, | |
last_increase_date_time = undefined, | |
@@ -1209,7 +1209,7 @@ create_table_output_tests(_) -> | |
item_count = 0, | |
key_schema = <<"ForumName">>, | |
local_secondary_indexes = undefined, | |
- provisioned_throughput = | |
+ provisioned_throughput = | |
#ddb2_provisioned_throughput_description{ | |
last_decrease_date_time = undefined, | |
last_increase_date_time = undefined, | |
@@ -1220,7 +1220,7 @@ create_table_output_tests(_) -> | |
table_size_bytes = 0, | |
table_status = creating}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:create_table(<<"name">>, [{<<"key">>, s}], <<"key">>, 5, 10)), Tests). | |
%% DeleteItem test based on the API examples: | |
@@ -1229,7 +1229,7 @@ delete_item_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"DeleteItem example request", | |
- ?_f(erlcloud_ddb2:delete_item(<<"Thread">>, | |
+ ?_f(erlcloud_ddb2:delete_item(<<"Thread">>, | |
[{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"Subject">>, {s, <<"How do I update multiple items?">>}}], | |
[{return_values, all_old}, | |
@@ -1254,7 +1254,7 @@ delete_item_input_tests(_) -> | |
}), | |
?_ddb_test( | |
{"DeleteItem return metrics", | |
- ?_f(erlcloud_ddb2:delete_item(<<"Thread">>, | |
+ ?_f(erlcloud_ddb2:delete_item(<<"Thread">>, | |
{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
[{return_consumed_capacity, total}, | |
{return_item_collection_metrics, size}])), " | |
@@ -1297,7 +1297,7 @@ delete_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
delete_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"DeleteItem example response", " | |
{ | |
@@ -1357,7 +1357,7 @@ delete_item_output_tests(_) -> | |
size_estimate_range_gb = {1,2}} | |
}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:delete_item(<<"table">>, {<<"k">>, <<"v">>}, [{out, record}])), Tests). | |
%% DeleteTable test based on the API examples: | |
@@ -1390,7 +1390,7 @@ delete_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
delete_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"DeleteTable example response", " | |
{ | |
@@ -1416,7 +1416,7 @@ delete_table_output_tests(_) -> | |
table_size_bytes = 0, | |
table_status = deleting}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:delete_table(<<"name">>)), Tests). | |
%% DescribeTable test based on the API examples: | |
@@ -1494,7 +1494,7 @@ describe_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
describe_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"DescribeTable example response", " | |
{ | |
@@ -1569,7 +1569,7 @@ describe_table_output_tests(_) -> | |
item_count = 0, | |
key_schema = {<<"ForumName">>, <<"LastPostDateTime">>}, | |
projection = keys_only}], | |
- provisioned_throughput = | |
+ provisioned_throughput = | |
#ddb2_provisioned_throughput_description{ | |
last_decrease_date_time = undefined, | |
last_increase_date_time = undefined, | |
@@ -1580,7 +1580,7 @@ describe_table_output_tests(_) -> | |
table_size_bytes = 0, | |
table_status = active}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:describe_table(<<"name">>)), Tests). | |
%% GetItem test based on the API examples: | |
@@ -1606,7 +1606,7 @@ get_item_input_tests(_) -> | |
[?_ddb_test( | |
{"GetItem example request, with fully specified keys", | |
?_f(erlcloud_ddb2:get_item(<<"Thread">>, | |
- [{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
+ [{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"Subject">>, {s, <<"How do I update multiple items?">>}}], | |
[{attributes_to_get, [<<"LastPostDateTime">>, <<"Message">>, <<"Tags">>]}, | |
consistent_read, | |
@@ -1617,7 +1617,7 @@ get_item_input_tests(_) -> | |
Example1Response}), | |
?_ddb_test( | |
{"GetItem example request, with inferred key types", | |
- ?_f(erlcloud_ddb2:get_item(<<"Thread">>, | |
+ ?_f(erlcloud_ddb2:get_item(<<"Thread">>, | |
[{<<"ForumName">>, "Amazon DynamoDB"}, | |
{<<"Subject">>, <<"How do I update multiple items?">>}], | |
[{attributes_to_get, [<<"LastPostDateTime">>, <<"Message">>, <<"Tags">>]}, | |
@@ -1655,7 +1655,7 @@ get_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
get_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"GetItem example response", " | |
{ | |
@@ -1708,15 +1708,15 @@ get_item_output_tests(_) -> | |
{<<"empty">>, <<>>}], | |
consumed_capacity = undefined}}}), | |
?_ddb_test( | |
- {"GetItem item not found", | |
+ {"GetItem item not found", | |
"{}", | |
{ok, #ddb2_get_item{item = undefined}}}), | |
?_ddb_test( | |
- {"GetItem no attributes returned", | |
+ {"GetItem no attributes returned", | |
"{\"Item\":{}}", | |
{ok, #ddb2_get_item{item = []}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:get_item(<<"table">>, {<<"k">>, <<"v">>}, [{out, record}])), Tests). | |
%% ListTables test based on the API examples: | |
@@ -1733,7 +1733,7 @@ list_tables_input_tests(_) -> | |
}), | |
?_ddb_test( | |
{"ListTables empty request", | |
- ?_f(erlcloud_ddb2:list_tables()), | |
+ ?_f(erlcloud_ddb2:list_tables()), | |
"{}" | |
}) | |
@@ -1747,7 +1747,7 @@ list_tables_input_tests(_) -> | |
input_tests(Response, Tests). | |
list_tables_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"ListTables example response", " | |
{ | |
@@ -1758,7 +1758,7 @@ list_tables_output_tests(_) -> | |
{last_evaluated_table_name = <<"Thread">>, | |
table_names = [<<"Forum">>, <<"Reply">>, <<"Thread">>]}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:list_tables([{out, record}])), Tests). | |
%% PutItem test based on the API examples: | |
@@ -1767,7 +1767,7 @@ put_item_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"PutItem example request", | |
- ?_f(erlcloud_ddb2:put_item(<<"Thread">>, | |
+ ?_f(erlcloud_ddb2:put_item(<<"Thread">>, | |
[{<<"LastPostedBy">>, <<"[email protected]">>}, | |
{<<"ForumName">>, <<"Amazon DynamoDB">>}, | |
{<<"LastPostDateTime">>, <<"201303190422">>}, | |
@@ -1809,7 +1809,7 @@ put_item_input_tests(_) -> | |
}), | |
?_ddb_test( | |
{"PutItem float inputs", | |
- ?_f(erlcloud_ddb2:put_item(<<"Thread">>, | |
+ ?_f(erlcloud_ddb2:put_item(<<"Thread">>, | |
[{<<"typed float">>, {n, 1.2}}, | |
{<<"untyped float">>, 3.456}, | |
{<<"mixed set">>, {ns, [7.8, 9.0, 10]}}], | |
@@ -1837,7 +1837,7 @@ put_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
put_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"PutItem example response", " | |
{ | |
@@ -1897,7 +1897,7 @@ put_item_output_tests(_) -> | |
size_estimate_range_gb = {1,2}} | |
}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:put_item(<<"table">>, [], [{out, record}])), Tests). | |
%% Query test based on the API examples: | |
@@ -2009,7 +2009,7 @@ q_input_tests(_) -> | |
input_tests(Response, Tests). | |
q_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"Query example 1 response", " | |
{ | |
@@ -2103,12 +2103,12 @@ q_output_tests(_) -> | |
} | |
}", | |
{ok, #ddb2_q{count = 17, | |
- last_evaluated_key = | |
+ last_evaluated_key = | |
[{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"Subject">>, {s, <<"Exclusive key can have 3 parts">>}}, {<<"LastPostDateTime">>, {s, <<"20130102054211">>}}] | |
}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:q(<<"table">>, [{<<"k">>, <<"v">>, eq}], [{out, record}])), Tests). | |
%% Scan test based on the API examples: | |
@@ -2125,7 +2125,7 @@ scan_input_tests(_) -> | |
}), | |
?_ddb_test( | |
{"Scan example 2 request", | |
- ?_f(erlcloud_ddb2:scan(<<"Reply">>, | |
+ ?_f(erlcloud_ddb2:scan(<<"Reply">>, | |
[{scan_filter, [{<<"PostedBy">>, <<"[email protected]">>, eq}]}, | |
{return_consumed_capacity, total}])), " | |
{ | |
@@ -2145,7 +2145,7 @@ scan_input_tests(_) -> | |
}), | |
?_ddb_test( | |
{"Scan exclusive start key", | |
- ?_f(erlcloud_ddb2:scan(<<"Reply">>, | |
+ ?_f(erlcloud_ddb2:scan(<<"Reply">>, | |
[{exclusive_start_key, [{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"LastPostDateTime">>, {n, 20130102054211}}]}])), " | |
{ | |
@@ -2243,7 +2243,7 @@ scan_input_tests(_) -> | |
input_tests(Response, Tests). | |
scan_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"Scan example 1 response", " | |
{ | |
@@ -2447,7 +2447,7 @@ scan_output_tests(_) -> | |
{<<"LastPostDateTime">>, {n, 20130102054211}}], | |
scanned_count = 4}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:scan(<<"name">>, [{out, record}])), Tests). | |
%% UpdateItem test based on the API examples: | |
@@ -2456,7 +2456,7 @@ update_item_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"UpdateItem example request", | |
- ?_f(erlcloud_ddb2:update_item(<<"Thread">>, | |
+ ?_f(erlcloud_ddb2:update_item(<<"Thread">>, | |
[{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"Subject">>, {s, <<"How do I update multiple items?">>}}], | |
[{<<"LastPostedBy">>, {s, <<"[email protected]">>}, put}], | |
@@ -2544,7 +2544,7 @@ update_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
update_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"UpdateItem example response", " | |
{ | |
@@ -2585,7 +2585,7 @@ update_item_output_tests(_) -> | |
}", | |
{ok, []}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:update_item(<<"table">>, {<<"k">>, <<"v">>}, [])), Tests). | |
%% UpdateTable test based on the API examples: | |
@@ -2606,7 +2606,7 @@ update_table_input_tests(_) -> | |
], | |
Response = " | |
-{ | |
+{ | |
\"TableDescription\": { | |
\"AttributeDefinitions\": [ | |
{ | |
@@ -2668,10 +2668,10 @@ update_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
update_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"UpdateTable example response", " | |
-{ | |
+{ | |
\"TableDescription\": { | |
\"AttributeDefinitions\": [ | |
{ | |
@@ -2744,7 +2744,7 @@ update_table_output_tests(_) -> | |
item_count = 0, | |
key_schema = {<<"ForumName">>, <<"LastPostDateTime">>}, | |
projection = keys_only}], | |
- provisioned_throughput = | |
+ provisioned_throughput = | |
#ddb2_provisioned_throughput_description{ | |
last_decrease_date_time = undefined, | |
last_increase_date_time = 1363801701.282, | |
@@ -2755,6 +2755,6 @@ update_table_output_tests(_) -> | |
table_size_bytes = 0, | |
table_status = updating}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb2:update_table(<<"name">>, 5, 15)), Tests). | |
diff --git a/test/erlcloud_ddb_tests.erl b/test/erlcloud_ddb_tests.erl | |
index 30c1c7a..20dd38e 100644 | |
--- a/test/erlcloud_ddb_tests.erl | |
+++ b/test/erlcloud_ddb_tests.erl | |
@@ -5,7 +5,7 @@ | |
-include("erlcloud_ddb.hrl"). | |
%% Unit tests for ddb. | |
-%% These tests work by using meck to mock httpc. There are two classes of test: input and output. | |
+%% These tests work by using meck to mock hackney. There are two classes of test: input and output. | |
%% | |
%% Input tests verify that different function args produce the desired JSON request. | |
%% An input test list provides a list of funs and the JSON that is expected to result. | |
@@ -19,7 +19,7 @@ | |
-define(_f(F), fun() -> F end). | |
-export([validate_body/2]). | |
- | |
+ | |
%%%=================================================================== | |
%%% Test entry points | |
%%%=================================================================== | |
@@ -58,11 +58,11 @@ operation_test_() -> | |
]}. | |
start() -> | |
- meck:new(httpc, [unstick]), | |
+ meck:new(hackney, [unstick]), | |
ok. | |
stop(_) -> | |
- meck:unload(httpc). | |
+ meck:unload(hackney). | |
%%%=================================================================== | |
%%% Input test helpers | |
@@ -73,7 +73,7 @@ stop(_) -> | |
%% verifies that the parameters in the body match the expected parameters | |
-spec validate_body(binary(), expected_body()) -> ok. | |
validate_body(Body, Expected) -> | |
- Want = jsx:decode(list_to_binary(Expected)), | |
+ Want = jsx:decode(list_to_binary(Expected)), | |
Actual = jsx:decode(Body), | |
case Want =:= Actual of | |
true -> ok; | |
@@ -82,13 +82,13 @@ validate_body(Body, Expected) -> | |
end, | |
?assertEqual(Want, Actual). | |
-%% returns the mock of the httpc function input tests expect to be called. | |
+%% returns the mock of the hackney function input tests expect to be called. | |
%% Validates the request body and responds with the provided response. | |
-spec input_expect(string(), expected_body()) -> fun(). | |
input_expect(Response, Expected) -> | |
- fun(post, {_Url, _Headers, _ContentType, Body}, _HTTPOpts, _Opts) -> | |
+ fun(post, _Url, _Headers, Body, _Opts) -> | |
validate_body(Body, Expected), | |
- {ok, {{0, 200, 0}, 0, list_to_binary(Response)}} | |
+ {ok, 200, 0, list_to_binary(Response)} | |
end. | |
%% input_test converts an input_test specifier into an eunit test generator | |
@@ -96,10 +96,10 @@ input_expect(Response, Expected) -> | |
-spec input_test(string(), input_test_spec()) -> tuple(). | |
input_test(Response, {Line, {Description, Fun, Expected}}) when | |
is_list(Description) -> | |
- {Description, | |
+ {Description, | |
{Line, | |
fun() -> | |
- meck:expect(httpc, request, input_expect(Response, Expected)), | |
+ meck:expect(hackney, request, input_expect(Response, Expected)), | |
erlcloud_ddb:configure(string:copies("A", 20), string:copies("a", 40)), | |
Fun() | |
end}}. | |
@@ -115,11 +115,11 @@ input_tests(Response, Tests) -> | |
%%% Output test helpers | |
%%%=================================================================== | |
-%% returns the mock of the httpc function output tests expect to be called. | |
+%% returns the mock of the hackney function output tests expect to be called. | |
-spec output_expect(string()) -> fun(). | |
output_expect(Response) -> | |
- fun(post, {_Url, _Headers, _ContentType, _Body}, _HTTPOpts, _Opts) -> | |
- {ok, {{0, 200, 0}, 0, list_to_binary(Response)}} | |
+ fun(post, _Url, _Headers, _Body, _Opts) -> | |
+ {ok, 200, 0, list_to_binary(Response)} | |
end. | |
%% output_test converts an output_test specifier into an eunit test generator | |
@@ -129,7 +129,7 @@ output_test(Fun, {Line, {Description, Response, Result}}) -> | |
{Description, | |
{Line, | |
fun() -> | |
- meck:expect(httpc, request, output_expect(Response)), | |
+ meck:expect(hackney, request, output_expect(Response)), | |
erlcloud_ddb:configure(string:copies("A", 20), string:copies("a", 40)), | |
Actual = Fun(), | |
case Result =:= Actual of | |
@@ -141,9 +141,9 @@ output_test(Fun, {Line, {Description, Response, Result}}) -> | |
end}}. | |
%% output_test(Fun, {Line, {Response, Result}}) -> | |
%% output_test(Fun, {Line, {"", Response, Result}}). | |
- | |
+ | |
%% output_tests converts a list of output_test specifiers into an eunit test generator | |
--spec output_tests(fun(), [output_test_spec()]) -> [term()]. | |
+-spec output_tests(fun(), [output_test_spec()]) -> [term()]. | |
output_tests(Fun, Tests) -> | |
[output_test(Fun, Test) || Test <- Tests]. | |
@@ -152,24 +152,24 @@ output_tests(Fun, Tests) -> | |
%%% Error test helpers | |
%%%=================================================================== | |
--spec httpc_response(pos_integer(), string()) -> tuple(). | |
-httpc_response(Code, Body) -> | |
- {ok, {{"", Code, ""}, [], list_to_binary(Body)}}. | |
- | |
+-spec hackney_response(pos_integer(), string()) -> tuple(). | |
+hackney_response(Code, Body) -> | |
+ {ok, Code, [], list_to_binary(Body)}. | |
+ | |
-type error_test_spec() :: {pos_integer(), {string(), list(), term()}}. | |
-spec error_test(fun(), error_test_spec()) -> tuple(). | |
error_test(Fun, {Line, {Description, Responses, Result}}) -> | |
%% Add a bogus response to the end of the request to make sure we don't call too many times | |
- Responses1 = Responses ++ [httpc_response(200, "TOO MANY REQUESTS")], | |
+ Responses1 = Responses ++ [hackney_response(200, "TOO MANY REQUESTS")], | |
{Description, | |
{Line, | |
fun() -> | |
- meck:sequence(httpc, request, 4, Responses1), | |
+ meck:sequence(hackney, request, 4, Responses1), | |
erlcloud_ddb:configure(string:copies("A", 20), string:copies("a", 40)), | |
Actual = Fun(), | |
?assertEqual(Result, Actual) | |
end}}. | |
- | |
+ | |
-spec error_tests(fun(), [error_test_spec()]) -> [term()]. | |
error_tests(Fun, Tests) -> | |
[error_test(Fun, Test) || Test <- Tests]. | |
@@ -191,21 +191,21 @@ input_exception_test_() -> | |
%% Error handling tests based on: | |
%% http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ErrorHandling.html | |
error_handling_tests(_) -> | |
- OkResponse = httpc_response(200, " | |
+ OkResponse = hackney_response(200, " | |
{\"Item\": | |
{\"friends\":{\"SS\":[\"Lynda\", \"Aaron\"]}, | |
\"status\":{\"S\":\"online\"} | |
}, | |
\"ConsumedCapacityUnits\": 1 | |
-}" | |
+}" | |
), | |
OkResult = {ok, [{<<"friends">>, [<<"Lynda">>, <<"Aaron">>]}, | |
{<<"status">>, <<"online">>}]}, | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"Test retry after ProvisionedThroughputExceededException", | |
- [httpc_response(400, " | |
+ [hackney_response(400, " | |
{\"__type\":\"com.amazonaws.dynamodb.v20111205#ProvisionedThroughputExceededException\", | |
\"message\":\"The level of configured provisioned throughput for the table was exceeded. Consider increasing your provisioning level with the UpdateTable API\"}" | |
), | |
@@ -213,18 +213,18 @@ error_handling_tests(_) -> | |
OkResult}), | |
?_ddb_test( | |
{"Test ConditionalCheckFailed error", | |
- [httpc_response(400, " | |
+ [hackney_response(400, " | |
{\"__type\":\"com.amazonaws.dynamodb.v20111205#ConditionalCheckFailedException\", | |
\"message\":\"The expected value did not match what was stored in the system.\"}" | |
)], | |
{error, {<<"ConditionalCheckFailedException">>, <<"The expected value did not match what was stored in the system.">>}}}), | |
?_ddb_test( | |
{"Test retry after 500", | |
- [httpc_response(500, ""), | |
+ [hackney_response(500, ""), | |
OkResponse], | |
OkResult}) | |
], | |
- | |
+ | |
error_tests(?_f(erlcloud_ddb:get_item(<<"table">>, <<"key">>)), Tests). | |
@@ -235,8 +235,8 @@ batch_get_item_input_tests(_) -> | |
[?_ddb_test( | |
{"BatchGetItem example request", | |
?_f(erlcloud_ddb:batch_get_item( | |
- [{<<"comp2">>, [<<"Julie">>, | |
- <<"Mingus">>], | |
+ [{<<"comp2">>, [<<"Julie">>, | |
+ <<"Mingus">>], | |
[{attributes_to_get, [<<"user">>, <<"friends">>]}]}, | |
{<<"comp1">>, [{<<"Casey">>, 1319509152}, | |
{<<"Dave">>, 1319509155}, | |
@@ -277,7 +277,7 @@ batch_get_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
batch_get_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"BatchGetItem example response", " | |
{\"Responses\": | |
@@ -296,7 +296,7 @@ batch_get_item_output_tests(_) -> | |
\"UnprocessedKeys\":{} | |
}", | |
{ok, #ddb_batch_get_item | |
- {responses = | |
+ {responses = | |
[#ddb_batch_get_item_response | |
{table = <<"comp1">>, | |
items = [[{<<"status">>, <<"online">>}, | |
@@ -331,17 +331,17 @@ batch_get_item_output_tests(_) -> | |
} | |
}", | |
{ok, #ddb_batch_get_item | |
- {responses = [], | |
- unprocessed_keys = | |
- [{<<"comp2">>, [{s, <<"Julie">>}, | |
- {s, <<"Mingus">>}], | |
+ {responses = [], | |
+ unprocessed_keys = | |
+ [{<<"comp2">>, [{s, <<"Julie">>}, | |
+ {s, <<"Mingus">>}], | |
[{attributes_to_get, [<<"user">>, <<"friends">>]}]}, | |
{<<"comp1">>, [{{s, <<"Casey">>}, {n, 1319509152}}, | |
{{s, <<"Dave">>}, {n, 1319509155}}, | |
{{s, <<"Riley">>}, {n, 1319509158}}], | |
[{attributes_to_get, [<<"user">>, <<"status">>]}]}]}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:batch_get_item([{<<"table">>, [<<"key">>]}], [{out, record}])), Tests). | |
%% BatchWriteItem test based on the API examples: | |
@@ -434,7 +434,7 @@ batch_write_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
batch_write_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"BatchWriteItem example response", " | |
{ | |
@@ -464,7 +464,7 @@ batch_write_item_output_tests(_) -> | |
} | |
}", | |
{ok, #ddb_batch_write_item | |
- {responses = | |
+ {responses = | |
[#ddb_batch_write_item_response | |
{table = <<"Thread">>, | |
consumed_capacity_units = 1.0}, | |
@@ -530,7 +530,7 @@ batch_write_item_output_tests(_) -> | |
{<<"Thread">>, [{put, [{<<"ForumName">>, {s, <<"Amazon DynamoDB">>}}, | |
{<<"Subject">>, {s, <<"DynamoDB Thread 5">>}}]}]}]}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:batch_write_item([], [{out, record}])), Tests). | |
%% CreateTable test based on the API examples: | |
@@ -563,7 +563,7 @@ create_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
create_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"CreateTable example response", " | |
{\"TableDescription\": | |
@@ -587,7 +587,7 @@ create_table_output_tests(_) -> | |
table_name = <<"comp-table">>, | |
table_status = <<"CREATING">>}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:create_table(<<"name">>, {<<"key">>, s}, 5, 10)), Tests). | |
%% DeleteItem test based on the API examples: | |
@@ -621,7 +621,7 @@ delete_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
delete_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"DeleteItem example response", " | |
{\"Attributes\": | |
@@ -637,7 +637,7 @@ delete_item_output_tests(_) -> | |
{<<"time">>, 200}, | |
{<<"user">>, <<"Mingus">>}]}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:delete_item(<<"table">>, <<"key">>)), Tests). | |
%% DeleteTable test based on the API examples: | |
@@ -646,7 +646,7 @@ delete_table_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"DeleteTable example request", | |
- ?_f(erlcloud_ddb:delete_table(<<"Table1">>)), | |
+ ?_f(erlcloud_ddb:delete_table(<<"Table1">>)), | |
"{\"TableName\":\"Table1\"}" | |
}) | |
], | |
@@ -665,7 +665,7 @@ delete_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
delete_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"DeleteTable example response", " | |
{\"TableDescription\": | |
@@ -689,7 +689,7 @@ delete_table_output_tests(_) -> | |
table_name = <<"Table1">>, | |
table_status = <<"DELETING">>}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:delete_table(<<"name">>)), Tests). | |
%% DescribeTable test based on the API examples: | |
@@ -698,7 +698,7 @@ describe_table_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"DescribeTable example request", | |
- ?_f(erlcloud_ddb:describe_table(<<"Table1">>)), | |
+ ?_f(erlcloud_ddb:describe_table(<<"Table1">>)), | |
"{\"TableName\":\"Table1\"}" | |
}) | |
], | |
@@ -719,7 +719,7 @@ describe_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
describe_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"DescribeTable example response", " | |
{\"Table\": | |
@@ -747,7 +747,7 @@ describe_table_output_tests(_) -> | |
table_size_bytes = 949, | |
table_status = <<"ACTIVE">>}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:describe_table(<<"name">>)), Tests). | |
%% GetItem test based on the API examples: | |
@@ -765,14 +765,14 @@ get_item_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"GetItem example request, with fully specified keys", | |
- ?_f(erlcloud_ddb:get_item(<<"comptable">>, {{s, <<"Julie">>}, {n, 1307654345}}, | |
+ ?_f(erlcloud_ddb:get_item(<<"comptable">>, {{s, <<"Julie">>}, {n, 1307654345}}, | |
[consistent_read, | |
{attributes_to_get, [<<"status">>, <<"friends">>]}])), | |
Example1Response}), | |
?_ddb_test( | |
{"GetItem example request, with inferred key types", | |
- ?_f(erlcloud_ddb:get_item(<<"comptable">>, {"Julie", 1307654345}, | |
- [consistent_read, | |
+ ?_f(erlcloud_ddb:get_item(<<"comptable">>, {"Julie", 1307654345}, | |
+ [consistent_read, | |
{attributes_to_get, [<<"status">>, <<"friends">>]}])), | |
Example1Response}), | |
?_ddb_test( | |
@@ -795,7 +795,7 @@ get_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
get_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"GetItem example response", " | |
{\"Item\": | |
@@ -831,15 +831,15 @@ get_item_output_tests(_) -> | |
{<<"b">>, <<5,182>>}, | |
{<<"empty">>, <<>>}]}}), | |
?_ddb_test( | |
- {"GetItem item not found", | |
+ {"GetItem item not found", | |
"{\"ConsumedCapacityUnits\": 0.5}", | |
{ok, []}}), | |
?_ddb_test( | |
- {"GetItem no attributes returned", | |
+ {"GetItem no attributes returned", | |
"{\"ConsumedCapacityUnits\":0.5,\"Item\":{}}", | |
{ok, []}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:get_item(<<"table">>, <<"key">>)), Tests). | |
%% ListTables test based on the API examples: | |
@@ -848,12 +848,12 @@ list_tables_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"ListTables example request", | |
- ?_f(erlcloud_ddb:list_tables([{limit, 3}, {exclusive_start_table_name, <<"comp2">>}])), | |
+ ?_f(erlcloud_ddb:list_tables([{limit, 3}, {exclusive_start_table_name, <<"comp2">>}])), | |
"{\"ExclusiveStartTableName\":\"comp2\",\"Limit\":3}" | |
}), | |
?_ddb_test( | |
{"ListTables empty request", | |
- ?_f(erlcloud_ddb:list_tables()), | |
+ ?_f(erlcloud_ddb:list_tables()), | |
"{}" | |
}) | |
@@ -863,7 +863,7 @@ list_tables_input_tests(_) -> | |
input_tests(Response, Tests). | |
list_tables_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"ListTables example response", | |
"{\"LastEvaluatedTableName\":\"comp5\",\"TableNames\":[\"comp3\",\"comp4\",\"comp5\"]}", | |
@@ -871,7 +871,7 @@ list_tables_output_tests(_) -> | |
{last_evaluated_table_name = <<"comp5">>, | |
table_names = [<<"comp3">>, <<"comp4">>, <<"comp5">>]}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:list_tables([{out, record}])), Tests). | |
%% PutItem test based on the API examples: | |
@@ -880,8 +880,8 @@ put_item_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"PutItem example request", | |
- ?_f(erlcloud_ddb:put_item(<<"comp5">>, | |
- [{<<"time">>, 300}, | |
+ ?_f(erlcloud_ddb:put_item(<<"comp5">>, | |
+ [{<<"time">>, 300}, | |
{<<"feeling">>, <<"not surprised">>}, | |
{<<"user">>, <<"Riley">>}], | |
[{return_values, all_old}, | |
@@ -899,8 +899,8 @@ put_item_input_tests(_) -> | |
}), | |
?_ddb_test( | |
{"PutItem float inputs", | |
- ?_f(erlcloud_ddb:put_item(<<"comp5">>, | |
- [{<<"time">>, 300}, | |
+ ?_f(erlcloud_ddb:put_item(<<"comp5">>, | |
+ [{<<"time">>, 300}, | |
{<<"typed float">>, {n, 1.2}}, | |
{<<"untyped float">>, 3.456}, | |
{<<"mixed set">>, {ns, [7.8, 9.0, 10]}}], | |
@@ -926,7 +926,7 @@ put_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
put_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"PutItem example response", " | |
{\"Attributes\": | |
@@ -939,7 +939,7 @@ put_item_output_tests(_) -> | |
{<<"time">>, 300}, | |
{<<"user">>, <<"Riley">>}]}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:put_item(<<"table">>, [])), Tests). | |
%% Query test based on the API examples: | |
@@ -998,7 +998,7 @@ q_input_tests(_) -> | |
input_tests(Response, Tests). | |
q_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"Query example 1 response", " | |
{\"Count\":2,\"Items\":[{ | |
@@ -1044,7 +1044,7 @@ q_output_tests(_) -> | |
last_evaluated_key = undefined, | |
consumed_capacity_units = 1}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:q(<<"table">>, <<"key">>, [{out, record}])), Tests). | |
%% Scan test based on the API examples: | |
@@ -1053,7 +1053,7 @@ scan_input_tests(_) -> | |
Tests = | |
[?_ddb_test( | |
{"Scan example 1 request", | |
- ?_f(erlcloud_ddb:scan(<<"1-hash-rangetable">>)), | |
+ ?_f(erlcloud_ddb:scan(<<"1-hash-rangetable">>)), | |
"{\"TableName\":\"1-hash-rangetable\"}" | |
}), | |
?_ddb_test( | |
@@ -1100,7 +1100,7 @@ scan_input_tests(_) -> | |
input_tests(Response, Tests). | |
scan_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"Scan example 1 response", " | |
{\"Count\":4,\"Items\":[{ | |
@@ -1198,7 +1198,7 @@ scan_output_tests(_) -> | |
scanned_count = 2, | |
consumed_capacity_units = 0.5}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:scan(<<"name">>, [{out, record}])), Tests). | |
%% UpdateItem test based on the API examples: | |
@@ -1254,7 +1254,7 @@ update_item_input_tests(_) -> | |
input_tests(Response, Tests). | |
update_item_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"UpdateItem example response", " | |
{\"Attributes\": | |
@@ -1269,7 +1269,7 @@ update_item_output_tests(_) -> | |
{<<"time">>, 1307654350}, | |
{<<"user">>, <<"Julie">>}]}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:update_item(<<"table">>, <<"key">>, [])), Tests). | |
%% UpdateTable test based on the API examples: | |
@@ -1302,7 +1302,7 @@ update_table_input_tests(_) -> | |
input_tests(Response, Tests). | |
update_table_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ddb_test( | |
{"UpdateTable example response", " | |
{\"TableDescription\": | |
@@ -1329,6 +1329,6 @@ update_table_output_tests(_) -> | |
table_name = <<"comp1">>, | |
table_status = <<"UPDATING">>}}}) | |
], | |
- | |
+ | |
output_tests(?_f(erlcloud_ddb:update_table(<<"name">>, 5, 15)), Tests). | |
diff --git a/test/erlcloud_ddb_util_tests.erl b/test/erlcloud_ddb_util_tests.erl | |
index c1deb2a..7bf9f3c 100644 | |
--- a/test/erlcloud_ddb_util_tests.erl | |
+++ b/test/erlcloud_ddb_util_tests.erl | |
@@ -5,7 +5,7 @@ | |
-include("erlcloud_ddb.hrl"). | |
%% Unit tests for erlcloud_ddb_util. | |
-%% These tests work by using meck to mock httpc. | |
+%% These tests work by using meck to mock hackney. | |
%% | |
%% Input tests verify that different function args produce the desired JSON request. | |
%% An input test list provides a list of funs and the JSON that is expected to result. | |
@@ -17,7 +17,7 @@ | |
-define(_ddb_test(T), {?LINE, T}). | |
%% The _f macro is a terse way to wrap code in a fun. Similar to _test but doesn't annotate with a line number | |
-define(_f(F), fun() -> F end). | |
- | |
+ | |
%%%=================================================================== | |
%%% Test entry points | |
%%%=================================================================== | |
@@ -32,11 +32,11 @@ operation_test_() -> | |
]}. | |
start() -> | |
- meck:new(httpc, [unstick]), | |
+ meck:new(hackney, [unstick]), | |
ok. | |
stop(_) -> | |
- meck:unload(httpc). | |
+ meck:unload(hackney). | |
%%%=================================================================== | |
%%% Multi-call test helpers | |
@@ -47,22 +47,22 @@ stop(_) -> | |
-type response_body() :: string(). | |
-type http_call() :: {expected_body(), response_body()}. | |
-%% returns the mock of the httpc function multi-call tests expect to be called. | |
+%% returns the mock of the hackney function multi-call tests expect to be called. | |
-spec multi_call_expect([http_call(),...]) -> fun(). | |
multi_call_expect([{Expected, Response} | TCalls]) -> | |
- fun(post, {_Url, _Headers, _ContentType, Body}, _HTTPOpts, _Opts) -> | |
+ fun(post, _Url, _Headers, Body, _Opts) -> | |
erlcloud_ddb2_tests:validate_body(Body, Expected), | |
case TCalls of | |
[] -> | |
%% No more calls expected | |
- meck:delete(httpc, request, 4); | |
+ meck:delete(hackney, request, 4); | |
_ -> | |
%% Set up the expectation for the next call | |
- meck:expect(httpc, request, multi_call_expect(TCalls)) | |
+ meck:expect(hackney, request, multi_call_expect(TCalls)) | |
end, | |
- {ok, {{0, 200, 0}, 0, list_to_binary(Response)}} | |
+ {ok, 200, 0, list_to_binary(Response)}} | |
end. | |
- | |
+ | |
%% mutil_call_test converts a multi_call_test specifier into an eunit test generator | |
-type multi_call_test_spec() :: {pos_integer(), {description(), fun(), [http_call()], term()}}. | |
@@ -71,7 +71,7 @@ multi_call_test({Line, {Description, Fun, Calls, Result}}) -> | |
{Description, | |
{Line, | |
fun() -> | |
- meck:expect(httpc, request, multi_call_expect(Calls)), | |
+ meck:expect(hackney, request, multi_call_expect(Calls)), | |
erlcloud_ddb:configure(string:copies("A", 20), string:copies("a", 40)), | |
Actual = Fun(), | |
case Result =:= Actual of | |
@@ -81,9 +81,9 @@ multi_call_test({Line, {Description, Fun, Calls, Result}}) -> | |
end, | |
?assertEqual(Result, Actual) | |
end}}. | |
- | |
+ | |
%% multi_call_tests converts a list of multi_call_test specifiers into an eunit test generator | |
--spec multi_call_tests([multi_call_test_spec()]) -> [term()]. | |
+-spec multi_call_tests([multi_call_test_spec()]) -> [term()]. | |
multi_call_tests(Tests) -> | |
[multi_call_test(Test) || Test <- Tests]. | |
@@ -456,7 +456,7 @@ q_all_tests(_) -> | |
\"S\": \"rk2\" | |
} | |
} | |
-}"}, | |
+}"}, | |
{" | |
{ | |
\"TableName\": \"tn\", | |
diff --git a/test/erlcloud_ec2_tests.erl b/test/erlcloud_ec2_tests.erl | |
index 5d6bd80..b5eb525 100644 | |
--- a/test/erlcloud_ec2_tests.erl | |
+++ b/test/erlcloud_ec2_tests.erl | |
@@ -5,7 +5,7 @@ | |
-include("erlcloud_ec2.hrl"). | |
%% Unit tests for ec2. | |
-%% These tests work by using meck to mock httpc. There are two classes of test: input and output. | |
+%% These tests work by using meck to mock hackney. There are two classes of test: input and output. | |
%% | |
%% Input tests verify that different function args produce the desired query parameters. | |
%% An input test list provides a list of funs and the parameters that are expected to result. | |
@@ -17,7 +17,7 @@ | |
-define(_ec2_test(T), {?LINE, T}). | |
%% The _f macro is a terse way to wrap code in a fun. Similar to _test but doesn't annotate with a line number | |
-define(_f(F), fun() -> F end). | |
- | |
+ | |
%%%=================================================================== | |
%%% Test entry points | |
%%%=================================================================== | |
@@ -30,11 +30,11 @@ describe_tags_test_() -> | |
fun describe_tags_output_tests/1]}. | |
start() -> | |
- meck:new(httpc, [unstick]), | |
+ meck:new(hackney, [unstick]), | |
ok. | |
stop(_) -> | |
- meck:unload(httpc). | |
+ meck:unload(hackney). | |
%%%=================================================================== | |
%%% Input test helpers | |
@@ -58,7 +58,7 @@ common_params() -> | |
-spec validate_param(string(), [expected_param()]) -> [expected_param()]. | |
validate_param(Param, Expected) -> | |
case string:tokens(Param, "=") of | |
- [Key, Value] -> | |
+ [Key, Value] -> | |
ok; | |
[Key] -> | |
Value = "", | |
@@ -72,7 +72,7 @@ validate_param(Param, Expected) -> | |
%?debugFmt("EXPECTED ~p~nEXPECTED1 ~p", [Expected, Expected1]), | |
case length(Expected) - 1 =:= length(Expected1) of | |
true -> ok; | |
- false -> | |
+ false -> | |
?debugFmt("Parameter not expected: ~p", [{Key, Value}]) | |
end, | |
?assertEqual(length(Expected) - 1, length(Expected1)), | |
@@ -86,13 +86,13 @@ validate_params(Body, Expected) -> | |
Remain = lists:foldl(fun validate_param/2, Expected, ParamList), | |
?assertEqual([], Remain). | |
-%% returns the mock of the httpc function input tests expect to be called. | |
+%% returns the mock of the hackney function input tests expect to be called. | |
%% Validates the query body and responds with the provided response. | |
-spec input_expect(string(), [expected_param()]) -> fun(). | |
input_expect(Response, Expected) -> | |
- fun(post, {_Url, [] = _Headers, _ContentType, Body}, [], []) -> | |
+ fun(post, _Url, [] = _Headers, Body, []) -> | |
validate_params(Body, Expected), | |
- {ok, {{0, 200, 0}, 0, Response}} | |
+ {ok, 200, 0, Response} | |
end. | |
%% input_test converts an input_test specifier into an eunit test generator | |
@@ -100,10 +100,10 @@ input_expect(Response, Expected) -> | |
-spec input_test(string(), input_test_spec()) -> tuple(). | |
input_test(Response, {Line, {Description, Fun, Params}}) when | |
is_list(Description) -> | |
- {Description, | |
+ {Description, | |
{Line, | |
fun() -> | |
- meck:expect(httpc, request, input_expect(Response, Params)), | |
+ meck:expect(hackney, request, input_expect(Response, Params)), | |
%% Configure to make sure there is a key. Would like to do this in start, but | |
%% that isn't called in the same process | |
erlcloud_ec2:configure(string:copies("A", 20), string:copies("a", 40)), | |
@@ -121,11 +121,11 @@ input_tests(Response, Tests) -> | |
%%% Output test helpers | |
%%%=================================================================== | |
-%% returns the mock of the httpc function output tests expect to be called. | |
+%% returns the mock of the hackney function output tests expect to be called. | |
-spec output_expect(string()) -> fun(). | |
output_expect(Response) -> | |
- fun(post, {_Url, [] = _Headers, _ContentType, _Body}, [], []) -> | |
- {ok, {{0, 200, 0}, 0, Response}} | |
+ fun(post, _Url, [] = _Headers, _Body, []) -> | |
+ {ok, 200, 0, Response} | |
end. | |
%% output_test converts an output_test specifier into an eunit test generator | |
@@ -135,16 +135,16 @@ output_test(Fun, {Line, {Description, Response, Result}}) -> | |
{Description, | |
{Line, | |
fun() -> | |
- meck:expect(httpc, request, output_expect(Response)), | |
+ meck:expect(hackney, request, output_expect(Response)), | |
erlcloud_ec2:configure(string:copies("A", 20), string:copies("a", 40)), | |
Actual = Fun(), | |
?assertEqual(Result, Actual) | |
end}}. | |
%% output_test(Fun, {Line, {Response, Result}}) -> | |
%% output_test(Fun, {Line, {"", Response, Result}}). | |
- | |
+ | |
%% output_tests converts a list of output_test specifiers into an eunit test generator | |
--spec output_tests(fun(), [output_test_spec()]) -> [term()]. | |
+-spec output_tests(fun(), [output_test_spec()]) -> [term()]. | |
output_tests(Fun, Tests) -> | |
[output_test(Fun, Test) || Test <- Tests]. | |
@@ -210,7 +210,7 @@ describe_tags_input_tests(_) -> | |
input_tests(Response, Tests). | |
describe_tags_output_tests(_) -> | |
- Tests = | |
+ Tests = | |
[?_ec2_test( | |
{"This example describes all the tags in your account.", " | |
<DescribeTagsResponse xmlns=\"http://ec2.amazonaws.com/doc/2012-12-01/\"> | |
@@ -246,7 +246,7 @@ describe_tags_output_tests(_) -> | |
<key>database_server</key> | |
<value/> | |
</item> | |
- <item> | |
+ <item> | |
<resourceId>i-12345678</resourceId> | |
<resourceType>instance</resourceType> | |
<key>stack</key> | |
@@ -281,6 +281,6 @@ describe_tags_output_tests(_) -> | |
</DescribeTagsResponse>", | |
{ok, [#ec2_tag{resource_id="ami-1a2b3c4d", resource_type="image", key="webserver", value=""}, | |
#ec2_tag{resource_id="ami-1a2b3c4d", resource_type="image", key="stack", value="Production"}]}})], | |
- | |
+ | |
%% Remaining AWS API examples return subsets of the same data | |
output_tests(?_f(erlcloud_ec2:describe_tags()), Tests). | |
diff --git a/test/erlcloud_sdb_tests.erl b/test/erlcloud_sdb_tests.erl | |
index fa868c0..f366ee1 100644 | |
--- a/test/erlcloud_sdb_tests.erl | |
+++ b/test/erlcloud_sdb_tests.erl | |
@@ -7,15 +7,15 @@ | |
setup() -> | |
erlcloud_sdb:configure("fake", "fake-secret"), | |
- meck:new(httpc, [unstick]). | |
+ meck:new(hackney, [unstick]). | |
cleanup(_) -> | |
- meck:unload(httpc). | |
+ meck:unload(hackney). | |
%% Helpers | |
expect_chain([Response | Chain]) -> | |
- meck:expect(httpc, request, | |
+ meck:expect(hackney, request, | |
fun(_, _, _, _) -> | |
expect_chain(Chain), | |
Response | |
-- | |
1.8.3.2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment