Skip to content

Commit

Permalink
Simplify and extend unit tests
Browse files Browse the repository at this point in the history
* Use a single unified eunit test generator for each module's tests, to reduce repetition.
* Leverage the `setup/0` function for storing common test parameters.
* Add tests of invalid tokens in `pot:valid_hotp` and `pot:valid_totp` to achieve full line coverage in unit tests.
* extend hotp_generation_tests to reason about 0 and negative/very large interval (counter) values.
  • Loading branch information
nalundgaard committed Oct 16, 2019
1 parent 2991d88 commit d7abe97
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 56 deletions.
61 changes: 31 additions & 30 deletions test/hotp_generation_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,51 @@
-include_lib("eunit/include/eunit.hrl").


hotp_generation_from_secret_test_() ->
{setup, fun start/0,
fun stop/1,
fun hotp_generation_from_secret/1}.


hotp_generation_for_different_intervals_test_() ->
{setup, fun start/0,
fun stop/1,
fun hotp_generation_for_different_intervals/1}.

hotp_generation_with_padding_test_() ->
{setup, fun start/0,
fun stop/1,
fun hotp_generation_with_padding/1}.

hotp_generation_with_multiple_padding_test_() ->
{setup, fun start/0,
fun stop/1,
fun hotp_generation_with_multiple_padding/1}.
all_test_() ->
{foreach,
fun start/0,
fun stop/1,
[fun hotp_generation_from_secret/1,
fun hotp_generation_for_different_intervals/1,
fun hotp_generation_with_padding/1,
fun hotp_generation_with_multiple_padding/1,
fun hotp_generation_unsigned_interval/1]}.


start() ->
ok.
#{secret1 => <<"MFRGGZDFMZTWQ2LK">>,
secret2 => <<"RWLMFU237M4RJIFA">>}.


stop(_) ->
ok.


hotp_generation_from_secret(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,
hotp_generation_from_secret(#{secret1 := Secret}) ->
[?_assertEqual(pot:hotp(Secret, 1), <<"765705">>)].


hotp_generation_for_different_intervals(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,
[?_assertEqual(pot:hotp(Secret, 1), <<"765705">>),
hotp_generation_for_different_intervals(#{secret1 := Secret}) ->
[?_assertEqual(pot:hotp(Secret, 0), <<"462371">>),
?_assertEqual(pot:hotp(Secret, 1), <<"765705">>),
?_assertEqual(pot:hotp(Secret, 2), <<"816065">>)].

hotp_generation_with_padding(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,

hotp_generation_with_padding(#{secret1 := Secret}) ->
[?_assertEqual(pot:hotp(Secret, 19), <<"088239">>)].

hotp_generation_with_multiple_padding(_) ->
Secret = <<"RWLMFU237M4RJIFA">>,

hotp_generation_with_multiple_padding(#{secret2 := Secret}) ->
[?_assertEqual(pot:hotp(Secret, 48930987), <<"000371">>)].


hotp_generation_unsigned_interval(#{secret1 := Secret}) ->
[{"negative intervals are equivalent to 64-bit unsigned representations (2^64 - 1)",
?_assertEqual(pot:hotp(Secret, 18446744073709551615),
pot:hotp(Secret, -1))},
{"negative intervals are equivalent to 64-bit unsigned representations (2^63 - 1)",
?_assertEqual(pot:hotp(Secret, 9223372036854775808),
pot:hotp(Secret, -9223372036854775808))},
{"large intervals are equivalent to 64-bit truncated representations (2^64 + 1)",
?_assertEqual(pot:hotp(Secret, 18446744073709551617),
pot:hotp(Secret, 1))}].
5 changes: 5 additions & 0 deletions test/hotp_validity_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ checking_hotp_validity_without_range_test_() ->
[fun checking_hotp_validity_without_range/1,
fun checking_hotp_validity_max_default_range/1,
fun checking_hotp_validity_past_max_default_range/1,
fun validatinging_invalid_token_hotp/1,
fun validating_correct_hotp_after_exhaustion/1,
fun validating_correct_totp_as_hotp/1,
fun retrieving_proper_interval_from_validator/1,
Expand Down Expand Up @@ -40,6 +41,10 @@ checking_hotp_validity_past_max_default_range(Secret) ->
?_assertNot(pot:valid_hotp(pot:hotp(Secret, 1002), Secret))}].


validatinging_invalid_token_hotp(Secret) ->
[?_assertNot(pot:valid_hotp(<<"abcdef">>, Secret))].


validating_correct_hotp_after_exhaustion(Secret) ->
[?_assertNot(pot:valid_hotp(pot:hotp(Secret, 123), Secret, [{last, 123}]))].

Expand Down
26 changes: 11 additions & 15 deletions test/preliminary_check_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@
-include_lib("eunit/include/eunit.hrl").


valid_token_test_() ->
{setup, fun start/0,
fun stop/1,
fun valid_token/1}.


variable_length_in_possible_token_test_() ->
{setup, fun start/0,
fun stop/1,
fun variable_length_in_possible_token/1}.
all_test_() ->
{foreach,
fun start/0,
fun stop/1,
[fun valid_token/1,
fun variable_length_in_possible_token/1]}.


start() ->
Expand All @@ -24,11 +20,11 @@ stop(_) ->


valid_token(_) ->
[?_assertEqual(pot:valid_token(<<"123456">>), true),
?_assertEqual(pot:valid_token(<<"abcdef">>), false),
?_assertEqual(pot:valid_token(<<"12345678">>), false)].
[?_assert(pot:valid_token(<<"123456">>)),
?_assertNot(pot:valid_token(<<"abcdef">>)),
?_assertNot(pot:valid_token(<<"12345678">>))].


variable_length_in_possible_token(_) ->
[?_assertEqual(pot:valid_token(<<"1234567">>), false),
?_assertEqual(pot:valid_token(<<"1234567">>, [{token_length, 7}]), true)].
[?_assertNot(pot:valid_token(<<"1234567">>)),
?_assert(pot:valid_token(<<"1234567">>, [{token_length, 7}]))].
22 changes: 11 additions & 11 deletions test/totp_validity_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,37 @@ totp_validity_test_() ->
fun stop/1,
[fun validating_totp_for_same_secret/1,
fun validating_invalid_totp_for_same_secret/1,
fun validatinging_invalid_token_hotp/1,
fun validating_correct_hotp_as_totp/1,
fun validating_past_future_totp_too_small_window/1,
fun validating_past_future_totp_with_window/1]}.


start() ->
ok.
_Secret = <<"MFRGGZDFMZTWQ2LK">>.


stop(_) ->
ok.


validating_totp_for_same_secret(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,
validating_totp_for_same_secret(Secret) ->
[?_assert(pot:valid_totp(pot:totp(Secret), Secret))].


validating_invalid_totp_for_same_secret(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,
validating_invalid_totp_for_same_secret(Secret) ->
[?_assertNot(pot:valid_totp(<<"123456">>, Secret))].


validating_correct_hotp_as_totp(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,
validatinging_invalid_token_hotp(Secret) ->
[?_assertNot(pot:valid_totp(<<"abcdef">>, Secret))].


validating_correct_hotp_as_totp(Secret) ->
[?_assertNot(pot:valid_totp(pot:hotp(Secret, 1), Secret))].


validating_past_future_totp_too_small_window(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,
validating_past_future_totp_too_small_window(Secret) ->
IntervalOpts = [{timestamp, os:timestamp()}],
N = 5,
[?_assertNot(pot:valid_totp(pot:totp(Secret, [{addwindow, AW} | IntervalOpts]),
Expand All @@ -47,8 +48,7 @@ validating_past_future_totp_too_small_window(_) ->
|| W <- lists:seq(0, N), AW <- lists:seq(-N, N), W < abs(AW)].


validating_past_future_totp_with_window(_) ->
Secret = <<"MFRGGZDFMZTWQ2LK">>,
validating_past_future_totp_with_window(Secret) ->
IntervalOpts = [{timestamp, os:timestamp()}],
N = 5,
[?_assert(pot:valid_totp(pot:totp(Secret, [{addwindow, AW} | IntervalOpts]),
Expand Down

0 comments on commit d7abe97

Please sign in to comment.