From 58365970b5366d50e57b704aa6a2c50740956f36 Mon Sep 17 00:00:00 2001 From: "Gavin M. Roy" Date: Fri, 15 Apr 2016 00:32:25 -0400 Subject: [PATCH] Additional test coverage --- deps/rabbitmq_aws/rebar.config | 3 +- deps/rabbitmq_aws/src/httpc_aws.erl | 11 +- deps/rabbitmq_aws/src/httpc_aws_config.erl | 2 - deps/rabbitmq_aws/src/httpc_aws_sup.erl | 4 +- .../test/httpc_aws_config_tests.erl | 722 +++++++----------- .../rabbitmq_aws/test/httpc_aws_sup_tests.erl | 10 + deps/rabbitmq_aws/test/httpc_aws_tests.erl | 30 + 7 files changed, 350 insertions(+), 432 deletions(-) create mode 100644 deps/rabbitmq_aws/test/httpc_aws_sup_tests.erl create mode 100644 deps/rabbitmq_aws/test/httpc_aws_tests.erl diff --git a/deps/rabbitmq_aws/rebar.config b/deps/rabbitmq_aws/rebar.config index 336e6f5902..f15438cd35 100644 --- a/deps/rabbitmq_aws/rebar.config +++ b/deps/rabbitmq_aws/rebar.config @@ -5,5 +5,6 @@ {eunit_exclude_deps, true}. {eunit_opts, [verbose, {skip_deps, true}]}. {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"}}} ]}. diff --git a/deps/rabbitmq_aws/src/httpc_aws.erl b/deps/rabbitmq_aws/src/httpc_aws.erl index 6aa5c9d109..69f18c41c6 100644 --- a/deps/rabbitmq_aws/src/httpc_aws.erl +++ b/deps/rabbitmq_aws/src/httpc_aws.erl @@ -9,7 +9,8 @@ -behavior(gen_server). %% API exports --export([set_credentials/2]). +-export([get_credentials/0, + set_credentials/2]). %% gen-server exports -export([start_link/0, @@ -31,6 +32,11 @@ %% 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(AccessKey, SecretAccessKey) -> ok %% where @@ -79,6 +85,9 @@ handle_call({set_credentials, AccessKey, SecretAccessKey}, _, State) -> {reply, ok, State#state{access_key = AccessKey, 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) -> {noreply, State}. diff --git a/deps/rabbitmq_aws/src/httpc_aws_config.erl b/deps/rabbitmq_aws/src/httpc_aws_config.erl index 1e638cee07..e5494c771c 100644 --- a/deps/rabbitmq_aws/src/httpc_aws_config.erl +++ b/deps/rabbitmq_aws/src/httpc_aws_config.erl @@ -438,8 +438,6 @@ lookup_credentials(_, AccessKey, SecretKey) -> %% @end lookup_credentials_from_config(Profile, {error,_}, _) -> 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) -> {ok, AccessKey, SecretKey, undefined, undefined}. diff --git a/deps/rabbitmq_aws/src/httpc_aws_sup.erl b/deps/rabbitmq_aws/src/httpc_aws_sup.erl index 30629b237d..4996e9e592 100644 --- a/deps/rabbitmq_aws/src/httpc_aws_sup.erl +++ b/deps/rabbitmq_aws/src/httpc_aws_sup.erl @@ -14,7 +14,7 @@ -define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5, Type, [I]}). start_link() -> - supervisor:start_link({local, ?MODULE}, ?MODULE, []). + supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> - {ok, {{one_for_one, 5, 10}, [?CHILD(httpc_aws, worker)]}}. + {ok, {{one_for_one, 5, 10}, [?CHILD(httpc_aws, worker)]}}. diff --git a/deps/rabbitmq_aws/test/httpc_aws_config_tests.erl b/deps/rabbitmq_aws/test/httpc_aws_config_tests.erl index 69ea83be46..44ea613fa9 100644 --- a/deps/rabbitmq_aws/test/httpc_aws_config_tests.erl +++ b/deps/rabbitmq_aws/test/httpc_aws_config_tests.erl @@ -2,447 +2,317 @@ -include_lib("eunit/include/eunit.hrl"). -%% Return the parsed configuration file data -config_file_data_test() -> - os:putenv("AWS_CONFIG_FILE", - filename:join([filename:absname("."), "test", - "test_aws_config.ini"])), - Expectation = [ - {"default", - [{aws_access_key_id, "default-key"}, - {aws_secret_access_key, "default-access-key"}, - {region, "us-east-1"}]}, - {"profile testing", - [{aws_access_key_id, "foo1"}, - {aws_secret_access_key, "bar2"}, - {s3, [{max_concurrent_requests, 10}, - {max_queue_size, 1000}]}, - {region, "us-west-2"}]}, - {"profile no-region", - [{aws_access_key_id, "foo2"}, - {aws_secret_access_key, "bar3"}]}, - {"profile only-key", - [{aws_access_key_id, "foo3"}]}, - {"profile only-secret", - [{aws_secret_access_key, "foo4"}]}, - {"profile bad-entry", - [{aws_secret_access, "foo5"}]} - ], - ?assertEqual(Expectation, - httpc_aws_config:config_file_data()). - -%% Return the default configuration when the environment variable is set -config_file_test() -> - os:putenv("AWS_CONFIG_FILE", "/etc/aws/config"), - ?assertEqual("/etc/aws/config", - httpc_aws_config:config_file()). - -%% Return the default configuration path based upon the user's home directory -config_file_no_env_var_test() -> - os:unsetenv("AWS_CONFIG_FILE"), - os:putenv("HOME", "/home/gavinr"), - ?assertEqual("/home/gavinr/.aws/config", - httpc_aws_config:config_file()). +-include("httpc_aws.hrl"). -%% 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()). +config_file_test_() -> + [ + {"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} + ]. -%% Return the default configuration when the environment variable is set -credentials_file_test() -> - os:putenv("AWS_SHARED_CREDENTIALS_FILE", "/etc/aws/credentials"), - ?assertEqual("/etc/aws/credentials", - httpc_aws_config:credentials_file()). - -%% Return the default configuration path based upon the user's home directory -credentials_no_env_var_test() -> - os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"), - os:putenv("HOME", "/home/gavinr"), - ?assertEqual("/home/gavinr/.aws/credentials", - httpc_aws_config:credentials_file()). +config_file_data_test_() -> + [ + {"successfully parses ini", fun() -> + setup_test_config_env_var(), + Expectation = [ + {"default", + [{aws_access_key_id, "default-key"}, + {aws_secret_access_key, "default-access-key"}, + {region, "us-east-1"}]}, + {"profile testing", + [{aws_access_key_id, "foo1"}, + {aws_secret_access_key, "bar2"}, + {s3, [{max_concurrent_requests, 10}, + {max_queue_size, 1000}]}, + {region, "us-west-2"}]}, + {"profile no-region", + [{aws_access_key_id, "foo2"}, + {aws_secret_access_key, "bar3"}]}, + {"profile only-key", + [{aws_access_key_id, "foo3"}]}, + {"profile only-secret", + [{aws_secret_access_key, "foo4"}]}, + {"profile bad-entry", + [{aws_secret_access, "foo5"}]} + ], + ?assertEqual(Expectation, + httpc_aws_config:config_file_data()) + end}, + {"file does not exist", fun() -> + ?assertEqual({error, enoent}, + httpc_aws_config:ini_file_data(filename:join([filename:absname("."), "bad_path"]), false)) + end + }, + {"file exists but path is invalid", fun() -> + ?assertEqual({error, enoent}, + httpc_aws_config:ini_file_data(filename:join([filename:absname("."), "bad_path"]), true)) + end + } + ]. -%% Return the home directory path based upon the HOME shell environment variable -home_path_test() -> - os:putenv("HOME", "/home/gavinr"), - ?assertEqual("/home/gavinr", - httpc_aws_config:home_path()). -%% Test that the cwd is returned if HOME is not set in the shell environment -home_path_no_env_var_test() -> - os:unsetenv("HOME"), - ?assertEqual(filename:absname("."), - httpc_aws_config:home_path()). +credentials_file_test_() -> + [ + {"from environment variable", fun() -> + os:putenv("AWS_SHARED_CREDENTIALS_FILE", "/etc/aws/credentials"), + ?assertEqual("/etc/aws/credentials", httpc_aws_config:credentials_file()) + end}, + {"default without environment variable", fun() -> + os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"), + os:putenv("HOME", "/home/gavinr"), + ?assertEqual("/home/gavinr/.aws/credentials", + httpc_aws_config:credentials_file()) + end} + ]. -%% Test that an atom is returned when passing in a list -ini_format_key_when_list_test() -> - ?assertEqual(test_key, httpc_aws_config:ini_format_key("test_key")). +credentials_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 + } -%% 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() -> - ?assertEqual(123, httpc_aws_config:maybe_convert_number("123")). - -%% 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 -maybe_convert_number_no_number_test() -> - ?assertEqual("hello, world", httpc_aws_config:maybe_convert_number("hello, world")). - -%% 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 -ini_file_data_bad_path_test() -> - ?assertEqual({error, enoent}, httpc_aws_config:ini_file_data(filename:join([filename:absname("."), "bad_path"]), true)). - -%% Test that the appropriate error is raised when trying to read a file that doesn't exist -read_file_bad_path_test() -> - ?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(), - Name = lists:flatten(io_lib:format("~p-~p-~p.tmp", [MegaSecs, Secs, MicroSecs])), - {ok, Handle} = file:open(Name, [write]), - file:close(Handle), - ?assertEqual({error,terminated}, httpc_aws_config:read_file(Handle, [])), - file:delete(Name). - -%% 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 -values_with_unprefixed_testing_profile_test() -> - os:putenv("AWS_CONFIG_FILE", - filename:join([filename:absname("."), "test", - "test_aws_config.ini"])), - Expectation = [{aws_access_key_id, "foo1"}, - {aws_secret_access_key, "bar2"}, - {s3, [{max_concurrent_requests, 10}, - {max_queue_size, 1000}]}, - {region, "us-west-2"}], - ?assertEqual(Expectation, httpc_aws_config:values("testing")). +home_path_test_() -> + [ + {"with HOME", fun() -> + os:putenv("HOME", "/home/gavinr"), + ?assertEqual("/home/gavinr", + httpc_aws_config:home_path()) + end}, + {"without HOME", fun() -> + os:unsetenv("HOME"), + ?assertEqual(filename:absname("."), + httpc_aws_config:home_path()) + end} + ]. -%% 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"), - ?assertEqual({ok, "us-west-1"}, httpc_aws_config:region()). +ini_format_key_test_() -> + [ + {"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 the correct region is returned from the config file for the default profile -region_with_config_file_and_default_profile_test() -> + +maybe_convert_number_test_() -> + [ + {"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} + ]. + + +profile_test_() -> + [ + {"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} + ]. + + +read_file_test_() -> + [ + {"file does not exist", fun() -> + ?assertEqual({error, enoent}, httpc_aws_config:read_file(filename:join([filename:absname("."), "bad_path"]))) + end}, + {"file handle is closed", fun() -> + {MegaSecs, Secs, MicroSecs} = now(), + Name = lists:flatten(io_lib:format("~p-~p-~p.tmp", [MegaSecs, Secs, MicroSecs])), + {ok, Handle} = file:open(Name, [write]), + file:close(Handle), + ?assertEqual({error,terminated}, httpc_aws_config:read_file(Handle, [])), + file:delete(Name) + end} + ]. + + +region_test_() -> + { + foreach, + fun () -> + meck:new(httpc), + reset_environment(), + [httpc] + end, + fun meck:unload/1, + [ + {"with environment variable", fun() -> + os:putenv("AWS_DEFAULT_REGION", "us-west-1"), + ?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} + ]}. + + +reset_environment() -> + os:unsetenv("AWS_ACCESS_KEY_ID"), 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: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", - "test_aws_config.ini"])), - os:unsetenv("AWS_SHARED_CREDENTIALS_FILE"), - Expectation = {ok, "default-key", "default-access-key", undefined, undefined}, - ?assertEqual(Expectation, httpc_aws_config:credentials()). + Filename])). -%% Test credential values from environment variables -credentials_partial_env_var_access_key_test() -> - os:putenv("AWS_ACCESS_KEY_ID", "Sésame"), - 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})). +setup_test_credentials_env_var() -> + setup_test_file_with_env_var("AWS_SHARED_CREDENTIALS_FILE", + "test_aws_credentials.ini"). diff --git a/deps/rabbitmq_aws/test/httpc_aws_sup_tests.erl b/deps/rabbitmq_aws/test/httpc_aws_sup_tests.erl new file mode 100644 index 0000000000..713ded6a83 --- /dev/null +++ b/deps/rabbitmq_aws/test/httpc_aws_sup_tests.erl @@ -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([])). diff --git a/deps/rabbitmq_aws/test/httpc_aws_tests.erl b/deps/rabbitmq_aws/test/httpc_aws_tests.erl new file mode 100644 index 0000000000..05bb6355b1 --- /dev/null +++ b/deps/rabbitmq_aws/test/httpc_aws_tests.erl @@ -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).