diff --git a/Makefile b/Makefile index 60edb9118fa..fcdf6a27736 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,12 @@ compile: clean: $(REBAR) clean -cover: test +cover: + $(REBAR) eunit --cover $(REBAR) cover test: compile - $(REBAR) as test do eunit + $(REBAR) eunit dialyzer: $(REBAR) dialyzer diff --git a/eqc/pbkdf2_eqc.erl b/eqc/pbkdf2_eqc.erl index ce4762a738f..0e72bac5575 100644 --- a/eqc/pbkdf2_eqc.erl +++ b/eqc/pbkdf2_eqc.erl @@ -1,5 +1,7 @@ -module(pbkdf2_eqc). +%% Compile C code and compare C code execution with Erlang code. + -export([prop_equivalent/0]). -include_lib("eqc/include/eqc.hrl"). @@ -9,60 +11,72 @@ eqc:on_output(fun(Str, Args) -> io:format(user, Str, Args) end, P)). eqc_test_() -> - {timeout, 30, - [ - {timeout, 30, ?_assertEqual(true, eqc:quickcheck(eqc:testing_time(14, ?QC_OUT(prop_equivalent()))))} - ] - }. + {timeout, 30, + [ + {timeout, 30, ?_assertEqual(true, eqc:quickcheck(eqc:testing_time(14, ?QC_OUT(prop_equivalent()))))} + ] + }. prop_equivalent() -> - %% try to compile the openssl port we need to compare the erlang version against: - case code:lib_dir(erl_interface) of - {error, Reason} -> - {error, Reason}; - EIDir -> - %% we assume the ebin of this file is in .eunit, where rebar puts it - PortSrcDir = "eqc", - %% yeeehaw - [] = os:cmd("gcc -Wno-format -Wno-pointer-sign -Wno-implicit-function-declaration "++PortSrcDir++"/pbkdf2-port.c -o pbkdf2-port -I"++EIDir++"/include -L"++EIDir++"/lib -lei -lssl -lcrypto"), - ?FORALL({Password, Salt, Iterations, KeySize}, {gen_print_bin(), gen_salt(), gen_iterations(), gen_keysize()}, - begin - Port = open_port({spawn, "./pbkdf2-port"}, [{packet, 4}]), - Hash = sha, %% only hash openssl supports for PBKDF2 is SHA1 :( - {ok, Bin} = pbkdf2:pbkdf2(Hash, Password, Salt, Iterations, KeySize), - Result = pbkdf2:to_hex(Bin), - port_command(Port, term_to_binary({Hash, Password, Salt, Iterations, KeySize})), - Expected = receive - {Port, {data, E}} -> - list_to_binary(E) - after - 5000 -> - timeout - end, - port_close(Port), - ?WHENFAIL(begin - io:format(user, "Password ~p~n", [Password]), - io:format(user, "Salt ~p~n", [Salt]), - io:format(user, "Iterations ~p~n", [Iterations]), - io:format(user, "KeySize ~p~n", [KeySize]), - io:format(user, "Expected ~p~n", [Expected]), - io:format(user, "Result ~p~n", [Result]) - end, - Expected == Result) - end) - end. + ?SETUP(fun() -> + ok = compile_c_code(), + fun(_) -> ok end + end, + ?FORALL({Password, Salt, Iterations, KeySize}, {gen_print_bin(), gen_salt(), gen_iterations(), gen_keysize()}, + begin + Port = open_port({spawn, "./pbkdf2-port"}, [{packet, 4}]), + Hash = sha, %% only hash openssl supports for PBKDF2 is SHA1 :( + {ok, Bin} = pbkdf2:pbkdf2(Hash, Password, Salt, Iterations, KeySize), + Result = pbkdf2:to_hex(Bin), + port_command(Port, term_to_binary({Hash, Password, Salt, Iterations, KeySize})), + Expected = receive + {Port, {data, E}} -> + list_to_binary(E) + after + 5000 -> + timeout + end, + port_close(Port), + ?WHENFAIL(begin + io:format(user, "Password ~p~n", [Password]), + io:format(user, "Salt ~p~n", [Salt]), + io:format(user, "Iterations ~p~n", [Iterations]), + io:format(user, "KeySize ~p~n", [KeySize]), + io:format(user, "Expected ~p~n", [Expected]), + io:format(user, "Result ~p~n", [Result]) + end, + Expected == Result) + end)). + +compile_c_code() -> + %% try to compile the openssl port we need to compare the erlang version against: + case code:lib_dir(erl_interface) of + {error, Reason} -> + {error, Reason}; + EIDir -> + %% EIDir is the erl_interface dir which contains lib and include for erl_interface C code + PortSrcDir = "./eqc", + %% yeeehaw + case os:cmd("gcc -Wno-format -Wno-pointer-sign -Wno-implicit-function-declaration "++PortSrcDir++"/pbkdf2-port.c -o pbkdf2-port -I"++EIDir++"/include -L"++EIDir++"/lib -lei -lssl -lcrypto") of + [] -> + ok; + Error -> + %% We need access to include files like openssl/evp.h + {error, {compiling_c_code, Error}} + end + end. gen_print_str() -> - ?LET(Xs, list(char()), [X || X <- Xs, io_lib:printable_list([X]), X /= $~, X < 255]). + ?LET(Xs, list(char()), [X || X <- Xs, io_lib:printable_list([X]), X /= $~, X < 255]). gen_print_bin() -> - ?SUCHTHAT(B, ?LET(Xs, gen_print_str(), list_to_binary(Xs)), B/= <<>>). + ?SUCHTHAT(B, ?LET(Xs, gen_print_str(), list_to_binary(Xs)), B/= <<>>). gen_salt() -> - ?SUCHTHAT(S, binary(), S /= <<>>). + ?SUCHTHAT(S, binary(), S /= <<>>). gen_keysize() -> - ?LET(Xs, nat(), Xs+5). + ?LET(Xs, nat(), Xs+5). gen_iterations() -> - ?LET(X, ?SUCHTHAT(I, nat(), I > 0), X*X). + ?LET(X, ?SUCHTHAT(I, nat(), I > 0), X*X). diff --git a/rebar.config b/rebar.config index 4188f1a664a..fae6139f6d2 100644 --- a/rebar.config +++ b/rebar.config @@ -7,9 +7,7 @@ {eunit_opts, [verbose]}. - {plugins, [{eqc_rebar, {git, "https://github.com/Quviq/eqc-rebar", {branch, "master"}}}]}. - {xref_checks,[undefined_function_calls,undefined_functions,locals_not_used, deprecated_function_calls, deprecated_functions]}.