From e5d4c1f22f29d2ab9e7fb8b5bdd298d02ffaec1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 26 Jul 2011 10:46:06 +0200 Subject: Add a PropEr test for cowboy_dispatcher:split_host/1 Mostly thanks to Magnus Klaar as it took me a while to figure out how PropEr tests had to be written. --- Makefile | 2 +- rebar.config | 4 ++- test/dispatcher_prop.erl | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ test/proper_SUITE.erl | 37 ++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 test/dispatcher_prop.erl create mode 100644 test/proper_SUITE.erl diff --git a/Makefile b/Makefile index 2a3a8c0..0cf2950 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ clean: tests: clean app eunit ct eunit: - @$(REBAR) eunit + @$(REBAR) eunit skip_deps=true ct: @$(REBAR) ct diff --git a/rebar.config b/rebar.config index 476ddd6..af656ef 100644 --- a/rebar.config +++ b/rebar.config @@ -1,7 +1,9 @@ {cover_enabled, true}. {deps, [ {quoted, "1.0.0", - {git, "git://github.com/klaar/quoted.erl.git", {tag, "1.0.1"}}} + {git, "git://github.com/klaar/quoted.erl.git", {tag, "1.0.1"}}}, + {proper, "1.0", + {git, "git://github.com/manopapad/proper.git", {tag, "v1.0"}}} ]}. {erl_opts, [ %% bin_opt_info, diff --git a/test/dispatcher_prop.erl b/test/dispatcher_prop.erl new file mode 100644 index 0000000..b6a1c92 --- /dev/null +++ b/test/dispatcher_prop.erl @@ -0,0 +1,68 @@ +%% Copyright (c) 2011, Magnus Klaar +%% Copyright (c) 2011, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(dispatcher_prop). +-include_lib("proper/include/proper.hrl"). + +%% Generators. + +hostname_head_char() -> + oneof([choose($a, $z), choose($A, $Z), choose($0, $9)]). + +hostname_char() -> + oneof([choose($a, $z), choose($A, $Z), choose($0, $9), $-]). + +hostname_label() -> + ?SUCHTHAT(Label, [hostname_head_char()|list(hostname_char())], + length(Label) < 64). + +hostname() -> + ?SUCHTHAT(Hostname, + ?LET(Labels, list(hostname_label()), string:join(Labels, ".")), + length(Hostname) > 0 andalso length(Hostname) =< 255). + +port_number() -> + choose(1, 16#ffff). + +port_str() -> + oneof(["", ?LET(Port, port_number(), ":" ++ integer_to_list(Port))]). + +server() -> + ?LET({Hostname, PortStr}, {hostname(), port_str()}, + list_to_binary(Hostname ++ PortStr)). + +%% Properties. + +prop_split_host_symmetric() -> + ?FORALL(Server, server(), + begin case cowboy_dispatcher:split_host(Server) of + {Tokens, RawHost, undefined} -> + (Server == RawHost) and (Server == binary_join(Tokens, ".")); + {Tokens, RawHost, Port} -> + PortBin = (list_to_binary(":" ++ integer_to_list(Port))), + (Server == << RawHost/binary, PortBin/binary >>) + and (Server == << (binary_join(Tokens, "."))/binary, + PortBin/binary >>) + end end). + +%% Internal. + +%% Contributed by MononcQc on #erlounge. +binary_join(Flowers, Leaf) -> + case Flowers of + [] -> <<>>; + [Petal|Pot] -> iolist_to_binary( + [Petal | [[Leaf | Pollen] || Pollen <- Pot]]) + end. diff --git a/test/proper_SUITE.erl b/test/proper_SUITE.erl new file mode 100644 index 0000000..440aa5f --- /dev/null +++ b/test/proper_SUITE.erl @@ -0,0 +1,37 @@ +%% Copyright (c) 2011, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(proper_SUITE). + +-include_lib("common_test/include/ct.hrl"). + +-export([all/0, groups/0]). %% ct. +-export([dispatcher_split_host/1]). %% cowboy_dispatcher. + +%% ct. + +all() -> + [{group, dispatcher}]. + +groups() -> + [{dispatcher, [], [dispatcher_split_host]}]. + +%% cowboy_dispatcher. + +dispatcher_split_host(_Config) -> + true = proper:quickcheck(dispatcher_prop:prop_split_host_symmetric(), + [{on_output, fun(Format, Data) -> + io:format(user, Format, Data), %% Console. + io:format(Format, Data) %% Logs. + end}]). -- cgit v1.2.3