Additional test coverage

This commit is contained in:
Gavin M. Roy 2016-04-15 00:32:25 -04:00
parent b4aef6f3ea
commit 58365970b5
7 changed files with 350 additions and 432 deletions

View File

@ -5,5 +5,6 @@
{eunit_exclude_deps, true}. {eunit_exclude_deps, true}.
{eunit_opts, [verbose, {skip_deps, true}]}. {eunit_opts, [verbose, {skip_deps, true}]}.
{deps, [ {deps, [
{jsx, ".*", {git, "https://github.com/talentdeficit/jsx.git", {tag, "v2.8.0"}}} {jsx, ".*", {git, "https://github.com/talentdeficit/jsx.git", {tag, "v2.8.0"}}},
{meck, ".*", {git, "https://github.com/eproxus/meck.git", {tag, "0.8.4"}}}
]}. ]}.

View File

@ -9,7 +9,8 @@
-behavior(gen_server). -behavior(gen_server).
%% API exports %% API exports
-export([set_credentials/2]). -export([get_credentials/0,
set_credentials/2]).
%% gen-server exports %% gen-server exports
-export([start_link/0, -export([start_link/0,
@ -31,6 +32,11 @@
%% exported wrapper functions %% exported wrapper functions
%%==================================================================== %%====================================================================
-spec get_credentials() -> {ok, access_key(), secret_access_key()}.
get_credentials() ->
gen_server:call(httpc_aws, get_credentials).
-spec set_credentials(access_key(), secret_access_key()) -> ok. -spec set_credentials(access_key(), secret_access_key()) -> ok.
%% @spec set_credentials(AccessKey, SecretAccessKey) -> ok %% @spec set_credentials(AccessKey, SecretAccessKey) -> ok
%% where %% where
@ -79,6 +85,9 @@ handle_call({set_credentials, AccessKey, SecretAccessKey}, _, State) ->
{reply, ok, State#state{access_key = AccessKey, {reply, ok, State#state{access_key = AccessKey,
secret_access_key = SecretAccessKey}}; secret_access_key = SecretAccessKey}};
handle_call(get_credentials, _, State) ->
{reply, {ok, State#state.access_key, State#state.secret_access_key}, State};
handle_call(_Request, _From, State) -> handle_call(_Request, _From, State) ->
{noreply, State}. {noreply, State}.

View File

@ -438,8 +438,6 @@ lookup_credentials(_, AccessKey, SecretKey) ->
%% @end %% @end
lookup_credentials_from_config(Profile, {error,_}, _) -> lookup_credentials_from_config(Profile, {error,_}, _) ->
lookup_credentials_from_file(Profile, credentials_file_data()); lookup_credentials_from_file(Profile, credentials_file_data());
lookup_credentials_from_config(Profile, _, {error,_}) ->
lookup_credentials_from_file(Profile, credentials_file_data());
lookup_credentials_from_config(_, AccessKey, SecretKey) -> lookup_credentials_from_config(_, AccessKey, SecretKey) ->
{ok, AccessKey, SecretKey, undefined, undefined}. {ok, AccessKey, SecretKey, undefined, undefined}.

View File

@ -2,11 +2,27 @@
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
%% Return the parsed configuration file data -include("httpc_aws.hrl").
config_file_data_test() ->
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test", config_file_test_() ->
"test_aws_config.ini"])), [
{"from environment variable", fun() ->
os:putenv("AWS_CONFIG_FILE", "/etc/aws/config"),
?assertEqual("/etc/aws/config", httpc_aws_config:config_file())
end},
{"default without environment variable", fun() ->
os:unsetenv("AWS_CONFIG_FILE"),
os:putenv("HOME", "/home/gavinr"),
?assertEqual("/home/gavinr/.aws/config",
httpc_aws_config:config_file())
end}
].
config_file_data_test_() ->
[
{"successfully parses ini", fun() ->
setup_test_config_env_var(),
Expectation = [ Expectation = [
{"default", {"default",
[{aws_access_key_id, "default-key"}, [{aws_access_key_id, "default-key"},
@ -29,420 +45,274 @@ config_file_data_test() ->
[{aws_secret_access, "foo5"}]} [{aws_secret_access, "foo5"}]}
], ],
?assertEqual(Expectation, ?assertEqual(Expectation,
httpc_aws_config:config_file_data()). httpc_aws_config:config_file_data())
end},
%% Return the default configuration when the environment variable is set {"file does not exist", fun() ->
config_file_test() -> ?assertEqual({error, enoent},
os:putenv("AWS_CONFIG_FILE", "/etc/aws/config"), httpc_aws_config:ini_file_data(filename:join([filename:absname("."), "bad_path"]), false))
?assertEqual("/etc/aws/config", end
httpc_aws_config:config_file()). },
{"file exists but path is invalid", fun() ->
%% Return the default configuration path based upon the user's home directory ?assertEqual({error, enoent},
config_file_no_env_var_test() -> httpc_aws_config:ini_file_data(filename:join([filename:absname("."), "bad_path"]), true))
os:unsetenv("AWS_CONFIG_FILE"), end
os:putenv("HOME", "/home/gavinr"), }
?assertEqual("/home/gavinr/.aws/config", ].
httpc_aws_config:config_file()).
%% Return the parsed configuration file data
credentials_file_data_test() ->
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = [
{"default",
[{aws_access_key_id, "foo1"},
{aws_secret_access_key, "bar1"}]},
{"development",
[{aws_access_key_id, "foo2"},
{aws_secret_access_key, "bar2"}]},
{"only-key",
[{aws_access_key_id, "foo3"}]},
{"only-secret",
[{aws_secret_access_key, "foo4"}]},
{"bad-entry",
[{aws_secret_access, "foo5"}]}
],
?assertEqual(Expectation,
httpc_aws_config:credentials_file_data()).
%% Return the default configuration when the environment variable is set credentials_file_test_() ->
credentials_file_test() -> [
{"from environment variable", fun() ->
os:putenv("AWS_SHARED_CREDENTIALS_FILE", "/etc/aws/credentials"), os:putenv("AWS_SHARED_CREDENTIALS_FILE", "/etc/aws/credentials"),
?assertEqual("/etc/aws/credentials", ?assertEqual("/etc/aws/credentials", httpc_aws_config:credentials_file())
httpc_aws_config:credentials_file()). end},
{"default without environment variable", fun() ->
%% Return the default configuration path based upon the user's home directory
credentials_no_env_var_test() ->
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"), os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
os:putenv("HOME", "/home/gavinr"), os:putenv("HOME", "/home/gavinr"),
?assertEqual("/home/gavinr/.aws/credentials", ?assertEqual("/home/gavinr/.aws/credentials",
httpc_aws_config:credentials_file()). httpc_aws_config:credentials_file())
end}
].
%% Return the home directory path based upon the HOME shell environment variable credentials_test_() ->
home_path_test() -> {
foreach,
fun () ->
meck:new(httpc),
reset_environment(),
[httpc]
end,
fun meck:unload/1,
[
{"from environment variables", fun() ->
os:putenv("AWS_ACCESS_KEY_ID", "Sésame"),
os:putenv("AWS_SECRET_ACCESS_KEY", "ouvre-toi"),
?assertEqual({ok, "Sésame", "ouvre-toi", undefined, undefined},
httpc_aws_config:credentials())
end},
{"from config file with default profile", fun() ->
setup_test_config_env_var(),
?assertEqual({ok, "default-key", "default-access-key", undefined, undefined},
httpc_aws_config:credentials())
end},
{"with missing environment variable", fun() ->
os:putenv("AWS_ACCESS_KEY_ID", "Sésame"),
?assertEqual({error, undefined},
httpc_aws_config:credentials())
end},
{"from config file with default profile", fun() ->
setup_test_config_env_var(),
?assertEqual({ok, "default-key", "default-access-key", undefined, undefined},
httpc_aws_config:credentials())
end},
{"from config file with profile", fun() ->
setup_test_config_env_var(),
?assertEqual({ok, "foo1", "bar2", undefined, undefined},
httpc_aws_config:credentials("testing"))
end},
{"from config file with bad profile", fun() ->
setup_test_config_env_var(),
?assertEqual({error, undefined},
httpc_aws_config:credentials("bad-profile-name"))
end},
{"from credentials file with default profile", fun() ->
setup_test_credentials_env_var(),
?assertEqual({ok, "foo1", "bar1", undefined, undefined},
httpc_aws_config:credentials())
end},
{"from credentials file with profile", fun() ->
setup_test_credentials_env_var(),
?assertEqual({ok, "foo2", "bar2", undefined, undefined},
httpc_aws_config:credentials("development"))
end},
{"from credentials file with bad profile", fun() ->
setup_test_credentials_env_var(),
?assertEqual({error, undefined},
httpc_aws_config:credentials("bad-profile-name"))
end},
{"from credentials file with only the key in profile", fun() ->
setup_test_credentials_env_var(),
?assertEqual({error, undefined},
httpc_aws_config:credentials("only-key"))
end},
{"from credentials file with only the value in profile", fun() ->
setup_test_credentials_env_var(),
?assertEqual({error, undefined},
httpc_aws_config:credentials("only-value"))
end},
{"from credentials file with missing keys in profile", fun() ->
setup_test_credentials_env_var(),
?assertEqual({error, undefined},
httpc_aws_config:credentials("bad-entry"))
end},
{"from instance metadata service", fun() ->
CredsBody = "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2016-03-31T21:51:49Z\",\n \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"ASIAIMAFAKEACCESSKEY\",\n \"SecretAccessKey\" : \"2+t64tZZVaz0yp0x1G23ZRYn+FAKEyVALUEs/4qh\",\n \"Token\" : \"FAKE//////////wEAK/TOKEN/VALUE=\",\n \"Expiration\" : \"2016-04-01T04:13:28Z\"\n}",
meck:sequence(httpc, request, 4,
[{ok, {{protocol, 200, message}, headers, "Bob"}},
{ok, {{protocol, 200, message}, headers, CredsBody}}]),
Expectation = {ok, "ASIAIMAFAKEACCESSKEY", "2+t64tZZVaz0yp0x1G23ZRYn+FAKEyVALUEs/4qh", "2016-04-01T04:13:28Z", "FAKE//////////wEAK/TOKEN/VALUE="},
?assertEqual(Expectation, httpc_aws_config:credentials())
end
},
{"with instance metadata service role error", fun() ->
meck:expect(httpc, request, 4, {error, timeout}),
?assertEqual({error, undefined}, httpc_aws_config:credentials())
end
},
{"with instance metadata service role http error", fun() ->
meck:expect(httpc, request, 4,
{ok, {{protocol, 500, message}, headers, "Internal Server Error"}}),
?assertEqual({error, undefined}, httpc_aws_config:credentials())
end
},
{"with instance metadata service credentials error", fun() ->
meck:sequence(httpc, request, 4,
[{ok, {{protocol, 200, message}, headers, "Bob"}},
{error, timeout}]),
?assertEqual({error, undefined}, httpc_aws_config:credentials())
end
},
{"with instance metadata service credentials not found", fun() ->
meck:sequence(httpc, request, 4,
[{ok, {{protocol, 200, message}, headers, "Bob"}},
{ok, {{protocol, 404, message}, headers, "File Not Found"}}]),
?assertEqual({error, undefined}, httpc_aws_config:credentials())
end
}
]}.
home_path_test_() ->
[
{"with HOME", fun() ->
os:putenv("HOME", "/home/gavinr"), os:putenv("HOME", "/home/gavinr"),
?assertEqual("/home/gavinr", ?assertEqual("/home/gavinr",
httpc_aws_config:home_path()). httpc_aws_config:home_path())
end},
%% Test that the cwd is returned if HOME is not set in the shell environment {"without HOME", fun() ->
home_path_no_env_var_test() ->
os:unsetenv("HOME"), os:unsetenv("HOME"),
?assertEqual(filename:absname("."), ?assertEqual(filename:absname("."),
httpc_aws_config:home_path()). httpc_aws_config:home_path())
end}
].
%% Test that an atom is returned when passing in a list ini_format_key_test_() ->
ini_format_key_when_list_test() -> [
?assertEqual(test_key, httpc_aws_config:ini_format_key("test_key")). {"when value is list", fun() ->
?assertEqual(test_key, httpc_aws_config:ini_format_key("test_key"))
end},
{"when value is binary", fun() ->
?assertEqual({error, type}, httpc_aws_config:ini_format_key(<<"test_key">>))
end}
].
%% Test that an error is returned when passing in a binary
ini_format_key_when_binary_test() ->
?assertEqual({error, type}, httpc_aws_config:ini_format_key(<<"test_key">>)).
%% Test that a string value with an integer returns the proper value maybe_convert_number_test_() ->
maybe_convert_number_test() -> [
?assertEqual(123, httpc_aws_config:maybe_convert_number("123")). {"when string contains an integer", fun() ->
?assertEqual(123, httpc_aws_config:maybe_convert_number("123"))
end},
{"when string contains a float", fun() ->
?assertEqual(123.456, httpc_aws_config:maybe_convert_number("123.456"))
end},
{"when string does not contain a number", fun() ->
?assertEqual("hello, world", httpc_aws_config:maybe_convert_number("hello, world"))
end}
].
%% Test that a string value with an float returns the proper value
maybe_convert_number_float_test() ->
?assertEqual(123.456, httpc_aws_config:maybe_convert_number("123.456")).
%% Test that a string value with an float returns the proper value profile_test_() ->
maybe_convert_number_no_number_test() -> [
?assertEqual("hello, world", httpc_aws_config:maybe_convert_number("hello, world")). {"from environment variable", fun() ->
os:putenv("AWS_DEFAULT_PROFILE", "httpc-aws test"),
?assertEqual("httpc-aws test", httpc_aws_config:profile())
end},
{"default without environment variable", fun() ->
os:unsetenv("AWS_DEFAULT_PROFILE"),
?assertEqual("default", httpc_aws_config:profile())
end}
].
%% Test that the appropriate error is raised when the specified path does not exist and the file is not found
ini_file_data_file_doesnt_exist_test() ->
?assertEqual({error, enoent}, httpc_aws_config:ini_file_data(filename:join([filename:absname("."), "bad_path"]), false)).
%% Test that the appropriate error is raised when the specified path does not exist and the file is found read_file_test_() ->
ini_file_data_bad_path_test() -> [
?assertEqual({error, enoent}, httpc_aws_config:ini_file_data(filename:join([filename:absname("."), "bad_path"]), true)). {"file does not exist", fun() ->
?assertEqual({error, enoent}, httpc_aws_config:read_file(filename:join([filename:absname("."), "bad_path"])))
%% Test that the appropriate error is raised when trying to read a file that doesn't exist end},
read_file_bad_path_test() -> {"file handle is closed", fun() ->
?assertEqual({error, enoent}, httpc_aws_config:read_file(filename:join([filename:absname("."), "bad_path"]))).
%% Test that the appropriate error is raised when trying to read a file that errors out when reading the line
read_file_bad_handle_test() ->
{MegaSecs, Secs, MicroSecs} = now(), {MegaSecs, Secs, MicroSecs} = now(),
Name = lists:flatten(io_lib:format("~p-~p-~p.tmp", [MegaSecs, Secs, MicroSecs])), Name = lists:flatten(io_lib:format("~p-~p-~p.tmp", [MegaSecs, Secs, MicroSecs])),
{ok, Handle} = file:open(Name, [write]), {ok, Handle} = file:open(Name, [write]),
file:close(Handle), file:close(Handle),
?assertEqual({error,terminated}, httpc_aws_config:read_file(Handle, [])), ?assertEqual({error,terminated}, httpc_aws_config:read_file(Handle, [])),
file:delete(Name). file:delete(Name)
end}
%% Test the profile value set in an environment variable is returned ].
profile_from_env_var_test() ->
os:putenv("AWS_DEFAULT_PROFILE", "httpc-aws test"),
?assertEqual("httpc-aws test",
httpc_aws_config:profile()).
%% Test the default profile value is returned when no environment variable is set
profile_no_env_var_test() ->
os:unsetenv("AWS_DEFAULT_PROFILE"),
?assertEqual("default",
httpc_aws_config:profile()).
%% Test that the proper config section is returned for the default profile
values_with_default_profile_test() ->
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
Expectation = [{aws_access_key_id, "default-key"},
{aws_secret_access_key, "default-access-key"},
{region, "us-east-1"}],
?assertEqual(Expectation, httpc_aws_config:values("default")).
%% Test that the proper config section is returned for the unprefixed testing profile region_test_() ->
values_with_unprefixed_testing_profile_test() -> {
os:putenv("AWS_CONFIG_FILE", foreach,
filename:join([filename:absname("."), "test", fun () ->
"test_aws_config.ini"])), meck:new(httpc),
Expectation = [{aws_access_key_id, "foo1"}, reset_environment(),
{aws_secret_access_key, "bar2"}, [httpc]
{s3, [{max_concurrent_requests, 10}, end,
{max_queue_size, 1000}]}, fun meck:unload/1,
{region, "us-west-2"}], [
?assertEqual(Expectation, httpc_aws_config:values("testing")). {"with environment variable", fun() ->
%% Test that an error is returned
config_data_with_no_config_file_test() ->
os:unsetenv("AWS_CONFIG_FILE"),
?assertEqual({error, enoent}, httpc_aws_config:values("testing")).
%% Test that the correct region is returned from an environment variable
region_with_env_var_test() ->
os:putenv("AWS_DEFAULT_REGION", "us-west-1"), os:putenv("AWS_DEFAULT_REGION", "us-west-1"),
?assertEqual({ok, "us-west-1"}, httpc_aws_config:region()). ?assertEqual({ok, "us-west-1"}, httpc_aws_config:region())
end},
{"with config file and specified profile", fun() ->
setup_test_config_env_var(),
?assertEqual({ok, "us-west-2"}, httpc_aws_config:region("testing"))
end},
{"with config file using default profile", fun() ->
setup_test_config_env_var(),
?assertEqual({ok, "us-east-1"}, httpc_aws_config:region())
end},
{"missing profile in config", fun() ->
setup_test_config_env_var(),
?assertEqual({error, undefined}, httpc_aws_config:region("no-region"))
end},
{"from instance metadata service", fun() ->
meck:expect(httpc, request, 4,
{ok, {{protocol, 200, message}, headers, "us-west-1a"}}),
?assertEqual({ok, "us-west-1"}, httpc_aws_config:region())
end},
{"full lookup failure", fun() ->
?assertEqual({error, undefined}, httpc_aws_config:region())
end},
{"http error failure", fun() ->
meck:expect(httpc, request, 4,
{ok, {{protocol, 500, message}, headers, "Internal Server Error"}}),
?assertEqual({error, undefined}, httpc_aws_config:region())
end}
]}.
%% Test that the correct region is returned from the config file for the default profile
region_with_config_file_and_default_profile_test() -> reset_environment() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_DEFAULT_REGION"), os:unsetenv("AWS_DEFAULT_REGION"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
?assertEqual({ok, "us-east-1"}, httpc_aws_config:region()).
%% Test that the correct region is returned from the config file for the specified profile
region_with_config_file_test() ->
os:unsetenv("AWS_DEFAULT_REGION"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
?assertEqual({ok, "us-west-2"}, httpc_aws_config:region("testing")).
%% Test that an error is returned when there is no config file, region, or EC2 instance metadata service
region_without_config_file_test() ->
os:unsetenv("AWS_DEFAULT_REGION"),
os:unsetenv("AWS_CONFIG_FILE"),
?assertEqual({error, undefined}, httpc_aws_config:region()).
%% Test that an error is returned when the config for the specified profile doesnt have a region
region_with_profile_without_region_test() ->
os:unsetenv("AWS_DEFAULT_REGION"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
?assertEqual({error, undefined}, httpc_aws_config:region("no-region")).
%% Test stripping the az designation from the region
region_from_availability_zone_test() ->
?assertEqual("us-east-1", httpc_aws_config:region_from_availability_zone("us-east-1a")).
%% Test that the availability-zone URL is constructed correctly
instance_availability_zone_url_test() ->
?assertEqual("http://169.254.169.254/latest/meta-data/placement/availability-zone",
httpc_aws_config:instance_availability_zone_url()).
%% Test the return an individual value from the AWS config file for the specified profile
value_found_test() ->
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
?assertEqual("default-key",
httpc_aws_config:value("default", aws_access_key_id)).
%% Test the error return an unset value from the AWS config file for the specified profile
value_not_set_test() ->
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
?assertEqual({error, undefined},
httpc_aws_config:value("default", bad_key_name)).
%% Test the error return when the config file is not valid
value_no_config_file_test() ->
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"invalid-test-data.ini"])),
?assertEqual({error, enoent},
httpc_aws_config:value("default", bad_key_name)).
%% Test values when a requested profile is not configured
values_unset_profile_test() ->
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
?assertEqual({error, undefined},
httpc_aws_config:values("invalid-profile")).
%% Test credential values from environment variables
credentials_env_var_test() ->
os:putenv("AWS_ACCESS_KEY_ID", "Sésame"),
os:putenv("AWS_SECRET_ACCESS_KEY", "ouvre-toi"),
os:unsetenv("AWS_CONFIG_FILE"),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {ok, "Sésame", "ouvre-toi", undefined, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials()).
%% Test credential values from default profile in config
credentials_config_file_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"), os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:putenv("AWS_CONFIG_FILE", setup_test_file_with_env_var("AWS_CONFIG_FILE", "bad_config.ini"),
setup_test_file_with_env_var("AWS_SHARED_CREDENTIALS_FILE",
"bad_credentials.ini"),
meck:expect(httpc, request, 4, {error, timeout}).
setup_test_config_env_var() ->
setup_test_file_with_env_var("AWS_CONFIG_FILE", "test_aws_config.ini").
setup_test_file_with_env_var(EnvVar, Filename) ->
os:putenv(EnvVar,
filename:join([filename:absname("."), "test", filename:join([filename:absname("."), "test",
"test_aws_config.ini"])), Filename])).
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {ok, "default-key", "default-access-key", undefined, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials()).
%% Test credential values from environment variables setup_test_credentials_env_var() ->
credentials_partial_env_var_access_key_test() -> setup_test_file_with_env_var("AWS_SHARED_CREDENTIALS_FILE",
os:putenv("AWS_ACCESS_KEY_ID", "Sésame"), "test_aws_credentials.ini").
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:unsetenv("AWS_CONFIG_FILE"),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials()).
%% Test credential values from environment variables
credentials_partial_env_var_secret_key_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:putenv("AWS_SECRET_ACCESS_KEY", "ouvre-toi"),
os:unsetenv("AWS_CONFIG_FILE"),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials()).
%% Test credential values from default profile in config with credentials file
credentials_config_file_with_credentials_file_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = {ok, "default-key", "default-access-key", undefined, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials()).
%% Test credential values when they cant be resolved
credentials_config_file_only_with_key_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("only-key")).
%% Test credential values when they cant be resolved
credentials_config_file_only_with_secret_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("only-secret")).
%% Test credential values when they cant be resolved
credentials_config_file_only_with_bad_profile_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("bad-profile!")).
%% Test credential values when they cant be resolved
credentials_config_file_only_with_bad_entry_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("bad-entry")).
%% Test credential values from default profile in config with credentials file
credentials_credentials_file_with_config_file_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:putenv("AWS_CONFIG_FILE",
filename:join([filename:absname("."), "test",
"test_aws_config.ini"])),
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = {ok, "foo2", "bar2", undefined, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("development")).
%% Test credential values from default profile in config with credentials file
credentials_credentials_file_without_config_file_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:unsetenv("AWS_CONFIG_FILE"),
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = {ok, "foo1", "bar1", undefined, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials()).
%% Test credential values when they cant be resolved
credentials_credentials_file_only_with_key_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:unsetenv("AWS_CONFIG_FILE"),
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("only-key")).
%% Test credential values when they cant be resolved
credentials_credentials_file_only_with_secret_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:unsetenv("AWS_CONFIG_FILE"),
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("only-secret")).
%% Test credential values when they cant be resolved
credentials_credentials_file_only_with_bad_profile_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:unsetenv("AWS_CONFIG_FILE"),
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("bad-profile!")).
%% Test credential values when they cant be resolved
credentials_credentials_file_only_with_bad_entry_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:unsetenv("AWS_CONFIG_FILE"),
os:putenv("AWS_SHARED_CREDENTIALS_FILE",
filename:join([filename:absname("."), "test",
"test_aws_credentials.ini"])),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials("bad-entry")).
%% Test credential values when they cant be resolved
credentials_unresolved_test() ->
os:unsetenv("AWS_ACCESS_KEY_ID"),
os:unsetenv("AWS_SECRET_ACCESS_KEY"),
os:unsetenv("AWS_CONFIG_FILE"),
os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"),
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:credentials()).
%% Test that the credentials URL is constructed correctly
instance_credentials_url_test() ->
?assertEqual("http://169.254.169.254/latest/meta-data/iam/security-credentials/bob",
httpc_aws_config:instance_credentials_url("bob")).
%% Test that the role URL is constructed correctly
instance_role_url_test() ->
?assertEqual("http://169.254.169.254/latest/meta-data/iam/security-credentials",
httpc_aws_config:instance_role_url()).
parse_credentials_response_ok_test() ->
Value = "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2016-03-31T21:51:49Z\",\n \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"ASIAIMAFAKEACCESSKEY\",\n \"SecretAccessKey\" : \"2+t64tZZVaz0yp0x1G23ZRYn+FAKEyVALUEs/4qh\",\n \"Token\" : \"FAKE//////////wEAK/TOKEN/VALUE=\",\n \"Expiration\" : \"2016-04-01T04:13:28Z\"\n}",
Expectation = {ok, "ASIAIMAFAKEACCESSKEY", "2+t64tZZVaz0yp0x1G23ZRYn+FAKEyVALUEs/4qh", "2016-04-01T04:13:28Z", "FAKE//////////wEAK/TOKEN/VALUE="},
?assertEqual(Expectation, httpc_aws_config:parse_credentials_response({ok, {{protocol, 200, message}, headers, Value}})).
parse_credentials_404_error_test() ->
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:parse_credentials_response({ok, {{protocol, 404, message}, headers, body}})).
parse_credentials_response_error_test() ->
Expectation = {error, undefined},
?assertEqual(Expectation, httpc_aws_config:parse_credentials_response({error, bad_request})).

View File

@ -0,0 +1,10 @@
-module(httpc_aws_sup_tests).
-include_lib("eunit/include/eunit.hrl").
init_test() ->
?assertEqual({ok, {{one_for_one, 5, 10},
[{httpc_aws, {httpc_aws, start_link, []},
permanent, 5, worker, [httpc_aws]}]}},
httpc_aws_sup:init([])).

View File

@ -0,0 +1,30 @@
-module(httpc_aws_tests).
-include_lib("eunit/include/eunit.hrl").
-include("httpc_aws.hrl").
api_test_() ->
{
foreach,
fun setup/0,
fun cleanup/1,
[
{"set_credentials values assigned",
fun() ->
AccessKey = "foo",
SecretKey = "bar",
ok = httpc_aws:set_credentials(AccessKey, SecretKey),
?assertEqual({ok, AccessKey, SecretKey},
httpc_aws:get_credentials())
end
}
]
}.
setup() ->
{ok, _Pid} = httpc_aws:start_link(),
httpc_aws.
cleanup(Name) ->
gen_server:stop(Name).