diff options
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | erlang.mk | 678 | ||||
-rw-r--r-- | include/cow_inline.hrl | 2 | ||||
-rw-r--r-- | src/cow_cookie.erl | 2 | ||||
-rw-r--r-- | src/cow_date.erl | 6 | ||||
-rw-r--r-- | src/cow_http.erl | 6 | ||||
-rw-r--r-- | src/cow_http_hd.erl | 66 | ||||
-rw-r--r-- | src/cow_http_te.erl | 7 | ||||
-rw-r--r-- | src/cow_mimetypes.erl | 2 | ||||
-rw-r--r-- | src/cow_multipart.erl | 12 | ||||
-rw-r--r-- | src/cow_qs.erl | 10 | ||||
-rw-r--r-- | src/cow_spdy.erl | 2 | ||||
-rw-r--r-- | src/cowlib.app.src | 2 | ||||
-rw-r--r-- | test/eunit_SUITE.erl | 31 |
15 files changed, 628 insertions, 214 deletions
@@ -1,4 +1,4 @@ -Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -1,8 +1,13 @@ # See LICENSE for licensing information. PROJECT = cowlib +#ERLC_OPTS += +bin_opt_info +TEST_ERLC_OPTS += +'{parse_transform, eunit_autoexport}' +'{parse_transform, horse_autoexport}' PLT_APPS = crypto +TEST_DEPS = triq +dep_triq = git https://github.com/krestenkrab/triq master + include erlang.mk .PHONY: gen perfs @@ -32,12 +37,15 @@ gen: # Performance testing. +ifeq ($(MAKECMDGOALS),perfs) +.NOTPARALLEL: +endif + deps/horse: git clone -n -- https://github.com/extend/horse $(DEPS_DIR)/horse cd $(DEPS_DIR)/horse ; git checkout -q master $(MAKE) -C $(DEPS_DIR)/horse -perfs: ERLC_OPTS += -DPERF=1 +'{parse_transform, horse_autoexport}' -DEXTRA=1 -perfs: clean deps deps/horse app +perfs: test-build $(gen_verbose) erl -noshell -pa ebin deps/horse/ebin \ - -eval 'horse:app_perf($(PROJECT)), init:stop().' + -eval 'horse:app_perf($(PROJECT)), erlang:halt().' @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -28,12 +28,30 @@ V ?= 0 gen_verbose_0 = @echo " GEN " $@; gen_verbose = $(gen_verbose_$(V)) +# "erl" command. + +ERL = erl +A0 -noinput -boot start_clean + # Core targets. -all:: deps app rel +ifneq ($(words $(MAKECMDGOALS)),1) +.NOTPARALLEL: +endif -clean:: +all:: deps + @$(MAKE) --no-print-directory app + @$(MAKE) --no-print-directory rel + +# Noop to avoid a Make warning when there's nothing to do. +rel:: + @echo -n + +clean:: clean-crashdump + +clean-crashdump: +ifneq ($(wildcard erl_crash.dump),) $(gen_verbose) rm -f erl_crash.dump +endif distclean:: clean @@ -42,7 +60,7 @@ help:: "erlang.mk (version $(ERLANG_MK_VERSION)) is distributed under the terms of the ISC License." \ "Copyright (c) 2013-2014 Loïc Hoguin <[email protected]>" \ "" \ - "Usage: [V=1] make [target]" \ + "Usage: [V=1] make [-jNUM] [target]" \ "" \ "Core targets:" \ " all Run deps, app and rel targets in that order" \ @@ -58,7 +76,8 @@ help:: "The target clean only removes files that are commonly removed." \ "Dependencies and releases are left untouched." \ "" \ - "Setting V=1 when calling make enables verbose mode." + "Setting V=1 when calling make enables verbose mode." \ + "Parallel execution is supported through the -j Make flag." # Core functions. @@ -68,7 +87,7 @@ define core_http_get endef else define core_http_get - erl -noshell -eval 'ssl:start(), inets:start(), case httpc:request(get, {"$(2)", []}, [{autoredirect, true}], []) of {ok, {{_, 200, _}, _, Body}} -> case file:write_file("$(1)", Body) of ok -> ok; {error, R1} -> halt(R1) end; {error, R2} -> halt(R2) end, halt(0).' + $(ERL) -eval 'ssl:start(), inets:start(), case httpc:request(get, {"$(2)", []}, [{autoredirect, true}], []) of {ok, {{_, 200, _}, _, Body}} -> case file:write_file("$(1)", Body) of ok -> ok; {error, R1} -> halt(R1) end; {error, R2} -> halt(R2) end, halt(0).' endef endif @@ -84,13 +103,16 @@ erlang-mk: cp $(ERLANG_MK_BUILD_DIR)/erlang.mk ./erlang.mk rm -rf $(ERLANG_MK_BUILD_DIR) -# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> # This file is part of erlang.mk and subject to the terms of the ISC License. .PHONY: distclean-deps distclean-pkg pkg-list pkg-search # Configuration. +AUTOPATCH ?= edown gen_leader gproc +export AUTOPATCH + DEPS_DIR ?= $(CURDIR)/deps export DEPS_DIR @@ -128,6 +150,41 @@ distclean:: distclean-deps distclean-pkg # Deps related targets. +define dep_autopatch + $(ERL) -eval " \ +DepDir = \"$(DEPS_DIR)/$(1)/\", \ +fun() -> \ + {ok, Conf} = file:consult(DepDir ++ \"rebar.config\"), \ + File = case lists:keyfind(deps, 1, Conf) of false -> []; {_, Deps} -> \ + [begin {Method, Repo, Commit} = case Repos of \ + {git, R} -> {git, R, master}; \ + {M, R, {branch, C}} -> {M, R, C}; \ + {M, R, {tag, C}} -> {M, R, C}; \ + {M, R, C} -> {M, R, C} \ + end, \ + io_lib:format(\"DEPS += ~s\ndep_~s = ~s ~s ~s~n\", [Name, Name, Method, Repo, Commit]) \ + end || {Name, _, Repos} <- Deps] \ + end, \ + ok = file:write_file(\"$(DEPS_DIR)/$(1)/Makefile\", [\"ERLC_OPTS = +debug_info\n\n\", File, \"\ninclude erlang.mk\"]) \ +end(), \ +AppSrcOut = \"$(DEPS_DIR)/$(1)/src/$(1).app.src\", \ +AppSrcIn = case filelib:is_regular(AppSrcOut) of false -> \"$(DEPS_DIR)/$(1)/ebin/$(1).app\"; true -> AppSrcOut end, \ +fun() -> \ + {ok, [{application, $(1), L}]} = file:consult(AppSrcIn), \ + L2 = case lists:keyfind(modules, 1, L) of {_, _} -> L; false -> [{modules, []}|L] end, \ + L3 = case lists:keyfind(vsn, 1, L2) of {vsn, git} -> lists:keyreplace(vsn, 1, L2, {vsn, \"git\"}); _ -> L2 end, \ + ok = file:write_file(AppSrcOut, io_lib:format(\"~p.~n\", [{application, $(1), L3}])) \ +end(), \ +case AppSrcOut of AppSrcIn -> ok; _ -> ok = file:delete(AppSrcIn) end, \ +halt()." +endef + +ifeq ($(V),0) +define dep_autopatch_verbose + @echo " PATCH " $(1); +endef +endif + define dep_fetch if [ "$$$$VS" = "git" ]; then \ git clone -n -- $$$$REPO $(DEPS_DIR)/$(1); \ @@ -135,6 +192,8 @@ define dep_fetch elif [ "$$$$VS" = "hg" ]; then \ hg clone -U $$$$REPO $(DEPS_DIR)/$(1); \ cd $(DEPS_DIR)/$(1) && hg update -q $$$$COMMIT; \ + elif [ "$$$$VS" = "svn" ]; then \ + svn checkout $$$$REPO $(DEPS_DIR)/$(1); \ else \ echo "Unknown or invalid dependency: $(1). Please consult the erlang.mk README for instructions." >&2; \ exit 78; \ @@ -157,6 +216,15 @@ else COMMIT=$(word 3,$(dep_$(1))); \ $(call dep_fetch,$(1)) endif +ifneq ($(filter $(1),$(AUTOPATCH)),) + $(call dep_autopatch_verbose,$(1)) if [ -f $(DEPS_DIR)/$(1)/rebar.config ]; then \ + $(call dep_autopatch,$(1)); \ + cd $(DEPS_DIR)/$(1)/ && ln -s ../../erlang.mk; \ + elif [ ! -f $(DEPS_DIR)/$(1)/Makefile ]; then \ + echo "ERLC_OPTS = +debug_info\ninclude erlang.mk" > $(DEPS_DIR)/$(1)/Makefile; \ + cd $(DEPS_DIR)/$(1)/ && ln -s ../../erlang.mk; \ + fi +endif endef $(foreach dep,$(DEPS),$(eval $(call dep_target,$(dep)))) @@ -199,32 +267,48 @@ help:: " pkg-list List all known packages" \ " pkg-search q=STRING Search for STRING in the package index" -# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> # This file is part of erlang.mk and subject to the terms of the ISC License. .PHONY: clean-app # Configuration. -ERLC_OPTS ?= -Werror +debug_info +warn_export_all +warn_export_vars \ - +warn_shadow_vars +warn_obsolete_guard # +bin_opt_info +warn_missing_spec +ERLC_OPTS ?= -Werror +debug_info +warn_export_vars +warn_shadow_vars \ + +warn_obsolete_guard # +bin_opt_info +warn_export_all +warn_missing_spec COMPILE_FIRST ?= COMPILE_FIRST_PATHS = $(addprefix src/,$(addsuffix .erl,$(COMPILE_FIRST))) +ERLC_EXCLUDE ?= +ERLC_EXCLUDE_PATHS = $(addprefix src/,$(addsuffix .erl,$(ERLC_EXCLUDE))) + +ERLC_MIB_OPTS ?= +COMPILE_MIB_FIRST ?= +COMPILE_MIB_FIRST_PATHS = $(addprefix mibs/,$(addsuffix .mib,$(COMPILE_MIB_FIRST))) # Verbosity. appsrc_verbose_0 = @echo " APP " $(PROJECT).app.src; appsrc_verbose = $(appsrc_verbose_$(V)) -erlc_verbose_0 = @echo " ERLC " $(filter %.erl %.core,$(?F)); +erlc_verbose_0 = @echo " ERLC " $(filter-out $(patsubst %,%.erl,$(ERLC_EXCLUDE)),\ + $(filter %.erl %.core,$(?F))); erlc_verbose = $(erlc_verbose_$(V)) xyrl_verbose_0 = @echo " XYRL " $(filter %.xrl %.yrl,$(?F)); xyrl_verbose = $(xyrl_verbose_$(V)) -# Core targets. +mib_verbose_0 = @echo " MIB " $(filter %.bin %.mib,$(?F)); +mib_verbose = $(mib_verbose_$(V)) + +# Targets. + +ifeq ($(wildcard ebin/test),) +app:: app-build +else +app:: clean app-build +endif -app:: erlc-include ebin/$(PROJECT).app +app-build: erlc-include ebin/$(PROJECT).app $(eval MODULES := $(shell find ebin -type f -name \*.beam \ | sed "s/ebin\//'/;s/\.beam/',/" | sed '$$s/.$$//')) @if [ -z "$$(grep -E '^[^%]*{modules,' src/$(PROJECT).app.src)" ]; then \ @@ -237,9 +321,15 @@ app:: erlc-include ebin/$(PROJECT).app | sed "s/{id,[[:space:]]*\"git\"}/{id, \"$(GITDESCRIBE)\"}/" \ > ebin/$(PROJECT).app +erlc-include: + -@if [ -d ebin/ ]; then \ + find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \ + fi + define compile_erl $(erlc_verbose) erlc -v $(ERLC_OPTS) -o ebin/ \ - -pa ebin/ -I include/ $(COMPILE_FIRST_PATHS) $(1) + -pa ebin/ -I include/ $(filter-out $(ERLC_EXCLUDE_PATHS),\ + $(COMPILE_FIRST_PATHS) $(1)) endef define compile_xyrl @@ -248,10 +338,22 @@ define compile_xyrl @rm ebin/*.erl endef +define compile_mib + $(mib_verbose) erlc -v $(ERLC_MIB_OPTS) -o priv/mibs/ \ + -I priv/mibs/ $(COMPILE_MIB_FIRST_PATHS) $(1) + $(mib_verbose) erlc -o include/ -- priv/mibs/*.bin +endef + ifneq ($(wildcard src/),) ebin/$(PROJECT).app:: @mkdir -p ebin/ +ifneq ($(wildcard mibs/),) +ebin/$(PROJECT).app:: $(shell find mibs -type f -name \*.mib) + @mkdir -p priv/mibs/ include + $(if $(strip $?),$(call compile_mib,$?)) +endif + ebin/$(PROJECT).app:: $(shell find src -type f -name \*.erl) \ $(shell find src -type f -name \*.core) $(if $(strip $?),$(call compile_erl,$?)) @@ -263,17 +365,56 @@ endif clean:: clean-app -# Extra targets. +clean-app: + $(gen_verbose) rm -rf ebin/ priv/mibs/ \ + $(addprefix include/,$(addsuffix .hrl,$(notdir $(basename $(wildcard mibs/*.mib))))) -erlc-include: - -@if [ -d ebin/ ]; then \ - find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \ - fi +# Copyright (c) 2015, Loïc Hoguin <[email protected]> +# This file is part of erlang.mk and subject to the terms of the ISC License. -clean-app: - $(gen_verbose) rm -rf ebin/ +.PHONY: test-deps test-dir test-build clean-test-dir + +# Configuration. + +TEST_DIR ?= test + +ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS)) + +TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard +TEST_ERLC_OPTS += -DTEST=1 + +# Targets. + +$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep)))) -# Copyright (c) 2014, Loïc Hoguin <[email protected]> +test-deps: $(ALL_TEST_DEPS_DIRS) + @for dep in $(ALL_TEST_DEPS_DIRS) ; do $(MAKE) -C $$dep; done + +ifneq ($(strip $(TEST_DIR)),) +test-dir: + $(gen_verbose) erlc -v $(TEST_ERLC_OPTS) -I include/ -o $(TEST_DIR) \ + $(wildcard $(TEST_DIR)/*.erl $(TEST_DIR)/*/*.erl) -pa ebin/ +endif + +ifeq ($(wildcard ebin/test),) +test-build: ERLC_OPTS=$(TEST_ERLC_OPTS) +test-build: clean deps test-deps + @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)" + $(gen_verbose) touch ebin/test +else +test-build: ERLC_OPTS=$(TEST_ERLC_OPTS) +test-build: deps test-deps + @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)" +endif + +clean:: clean-test-dir + +clean-test-dir: +ifneq ($(wildcard $(TEST_DIR)/*.beam),) + $(gen_verbose) rm -f $(TEST_DIR)/*.beam +endif + +# Copyright (c) 2014-2015, Loïc Hoguin <[email protected]> # This file is part of erlang.mk and subject to the terms of the ISC License. .PHONY: bootstrap bootstrap-lib bootstrap-rel new list-templates @@ -392,6 +533,56 @@ tpl_gen_server = "-module($(n))." \ "" \ "code_change(_OldVsn, State, _Extra) ->" \ " {ok, State}." +tpl_gen_fsm = "-module($(n))." \ + "-behaviour(gen_fsm)." \ + "" \ + "%% API." \ + "-export([start_link/0])." \ + "" \ + "%% gen_fsm." \ + "-export([init/1])." \ + "-export([state_name/2])." \ + "-export([handle_event/3])." \ + "-export([state_name/3])." \ + "-export([handle_sync_event/4])." \ + "-export([handle_info/3])." \ + "-export([terminate/3])." \ + "-export([code_change/4])." \ + "" \ + "-record(state, {" \ + "})." \ + "" \ + "%% API." \ + "" \ + "-spec start_link() -> {ok, pid()}." \ + "start_link() ->" \ + " gen_fsm:start_link(?MODULE, [], [])." \ + "" \ + "%% gen_fsm." \ + "" \ + "init([]) ->" \ + " {ok, state_name, \#state{}}." \ + "" \ + "state_name(_Event, StateData) ->" \ + " {next_state, state_name, StateData}." \ + "" \ + "handle_event(_Event, StateName, StateData) ->" \ + " {next_state, StateName, StateData}." \ + "" \ + "state_name(_Event, _From, StateData) ->" \ + " {reply, ignored, state_name, StateData}." \ + "" \ + "handle_sync_event(_Event, _From, StateName, StateData) ->" \ + " {reply, ignored, StateName, StateData}." \ + "" \ + "handle_info(_Info, StateName, StateData) ->" \ + " {next_state, StateName, StateData}." \ + "" \ + "terminate(_Reason, _StateName, _StateData) ->" \ + " ok." \ + "" \ + "code_change(_OldVsn, StateName, StateData, _Extra) ->" \ + " {ok, StateName, StateData}." tpl_cowboy_http = "-module($(n))." \ "-behaviour(cowboy_http_handler)." \ "" \ @@ -551,85 +742,169 @@ endif list-templates: @echo Available templates: $(sort $(patsubst tpl_%,%,$(filter tpl_%,$(.VARIABLES)))) -# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +# Copyright (c) 2014-2015, Loïc Hoguin <[email protected]> # This file is part of erlang.mk and subject to the terms of the ISC License. -.PHONY: build-ct-deps build-ct-suites tests-ct clean-ct distclean-ct +.PHONY: clean-c_src distclean-c_src-env +# todo + +# Configuration. + +C_SRC_DIR = $(CURDIR)/c_src +C_SRC_ENV ?= $(C_SRC_DIR)/env.mk +C_SRC_OUTPUT ?= $(CURDIR)/priv/$(PROJECT).so + +# System type and C compiler/flags. + +UNAME_SYS := $(shell uname -s) +ifeq ($(UNAME_SYS), Darwin) + CC ?= cc + CFLAGS ?= -O3 -std=c99 -arch x86_64 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -arch x86_64 -finline-functions -Wall + LDFLAGS ?= -arch x86_64 -flat_namespace -undefined suppress +else ifeq ($(UNAME_SYS), FreeBSD) + CC ?= cc + CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -finline-functions -Wall +else ifeq ($(UNAME_SYS), Linux) + CC ?= gcc + CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -finline-functions -Wall +endif + +CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) +CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) + +LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -lerl_interface -lei +LDFLAGS += -shared + +# Verbosity. + +c_verbose_0 = @echo " C " $(?F); +c_verbose = $(c_verbose_$(V)) + +cpp_verbose_0 = @echo " CPP " $(?F); +cpp_verbose = $(cpp_verbose_$(V)) + +link_verbose_0 = @echo " LD " $(@F); +link_verbose = $(link_verbose_$(V)) + +# Targets. + +ifeq ($(wildcard $(C_SRC_DIR)),) +else ifneq ($(wildcard $(C_SRC_DIR)/Makefile),) +app:: + $(MAKE) -C $(C_SRC_DIR) + +clean:: + $(MAKE) -C $(C_SRC_DIR) clean + +else +SOURCES := $(shell find $(C_SRC_DIR) -type f \( -name "*.c" -o -name "*.C" -o -name "*.cc" -o -name "*.cpp" \)) +OBJECTS = $(addsuffix .o, $(basename $(SOURCES))) + +COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c +COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c + +app:: $(C_SRC_ENV) $(C_SRC_OUTPUT) + +$(C_SRC_OUTPUT): $(OBJECTS) + @mkdir -p priv/ + $(link_verbose) $(CC) $(OBJECTS) $(LDFLAGS) $(LDLIBS) -o $(C_SRC_OUTPUT) + +%.o: %.c + $(COMPILE_C) $(OUTPUT_OPTION) $< + +%.o: %.cc + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +%.o: %.C + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +%.o: %.cpp + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +$(C_SRC_ENV): + @$(ERL) -eval "file:write_file(\"$(C_SRC_ENV)\", \ + io_lib:format( \ + \"ERTS_INCLUDE_DIR ?= ~s/erts-~s/include/~n\" \ + \"ERL_INTERFACE_INCLUDE_DIR ?= ~s~n\" \ + \"ERL_INTERFACE_LIB_DIR ?= ~s~n\", \ + [code:root_dir(), erlang:system_info(version), \ + code:lib_dir(erl_interface, include), \ + code:lib_dir(erl_interface, lib)])), \ + halt()." + +clean:: clean-c_src + +clean-c_src: + $(gen_verbose) rm -f $(C_SRC_OUTPUT) $(OBJECTS) + +distclean:: distclean-c_src-env + +distclean-c_src-env: + $(gen_verbose) rm -f $(C_SRC_ENV) + +-include $(C_SRC_ENV) +endif + +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: ct distclean-ct # Configuration. CT_OPTS ?= -ifneq ($(wildcard test/),) - CT_SUITES ?= $(sort $(subst _SUITE.erl,,$(shell find test -type f -name \*_SUITE.erl -exec basename {} \;))) +ifneq ($(wildcard $(TEST_DIR)),) + CT_SUITES ?= $(sort $(subst _SUITE.erl,,$(shell find $(TEST_DIR) -type f -name \*_SUITE.erl -exec basename {} \;))) else CT_SUITES ?= endif -TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard -TEST_ERLC_OPTS += -DTEST=1 -DEXTRA=1 +'{parse_transform, eunit_autoexport}' - # Core targets. -tests:: tests-ct - -clean:: clean-ct +tests:: ct distclean:: distclean-ct help:: @printf "%s\n" "" \ + "Common_test targets:" \ + " ct Run all the common_test suites for this project" \ + "" \ "All your common_test suites have their associated targets." \ "A suite named http_SUITE can be ran using the ct-http target." # Plugin-specific targets. -ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS)) - CT_RUN = ct_run \ -no_auto_compile \ - -noshell \ - -pa $(realpath ebin) $(DEPS_DIR)/*/ebin \ - -dir test \ + -noinput \ + -pa ebin $(DEPS_DIR)/*/ebin \ + -dir $(TEST_DIR) \ -logdir logs -$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep)))) - -build-ct-deps: $(ALL_TEST_DEPS_DIRS) - @for dep in $(ALL_TEST_DEPS_DIRS) ; do $(MAKE) -C $$dep; done - -build-ct-suites: build-ct-deps - $(gen_verbose) erlc -v $(TEST_ERLC_OPTS) -I include/ -o test/ \ - $(wildcard test/*.erl test/*/*.erl) -pa ebin/ - -tests-ct: ERLC_OPTS = $(TEST_ERLC_OPTS) -tests-ct: clean deps app build-ct-suites - @if [ -d "test" ] ; \ - then \ - mkdir -p logs/ ; \ - $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) ; \ - fi - $(gen_verbose) rm -f test/*.beam +ifeq ($(CT_SUITES),) +ct: +else +ct: test-build + @mkdir -p logs/ + $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) +endif define ct_suite_target -ct-$(1): ERLC_OPTS = $(TEST_ERLC_OPTS) -ct-$(1): clean deps app build-ct-suites - @if [ -d "test" ] ; \ - then \ - mkdir -p logs/ ; \ - $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_OPTS) ; \ - fi - $(gen_verbose) rm -f test/*.beam +ct-$(1): test-build + @mkdir -p logs/ + $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_OPTS) endef $(foreach test,$(CT_SUITES),$(eval $(call ct_suite_target,$(test)))) -clean-ct: - $(gen_verbose) rm -rf test/*.beam - distclean-ct: $(gen_verbose) rm -rf logs/ -# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> # This file is part of erlang.mk and subject to the terms of the ISC License. .PHONY: plt distclean-plt dialyze @@ -671,6 +946,35 @@ dialyze: $(DIALYZER_PLT) endif @dialyzer --no_native $(DIALYZER_DIRS) $(DIALYZER_OPTS) +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> +# Copyright (c) 2015, Viktor Söderqvist <[email protected]> +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-edoc build-doc-deps + +# Configuration. + +EDOC_OPTS ?= + +# Core targets. + +docs:: distclean-edoc build-doc-deps + $(gen_verbose) $(ERL) -eval 'edoc:application($(PROJECT), ".", [$(EDOC_OPTS)]), halt().' + +distclean:: distclean-edoc + +# Plugin-specific targets. + +DOC_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(DOC_DEPS)) + +$(foreach dep,$(DOC_DEPS),$(eval $(call dep_target,$(dep)))) + +build-doc-deps: $(DOC_DEPS_DIRS) + @for dep in $(DOC_DEPS_DIRS) ; do $(MAKE) -C $$dep; done + +distclean-edoc: + $(gen_verbose) rm -f doc/*.css doc/*.html doc/*.png doc/edoc-info + # Copyright (c) 2014, Juan Facorro <[email protected]> # This file is part of erlang.mk and subject to the terms of the ISC License. @@ -694,25 +998,221 @@ help:: "Elvis targets:" \ " elvis Run Elvis using the local elvis.config or download the default otherwise" -ifneq ($(wildcard $(ELVIS_CONFIG)),) -rel:: distclean-elvis -endif - distclean:: distclean-elvis # Plugin-specific targets. $(ELVIS): - @$(call core_http_get,$(ELVIS_CONFIG),$(ELVIS_CONFIG_URL)) @$(call core_http_get,$(ELVIS),$(ELVIS_URL)) @chmod +x $(ELVIS) -elvis: $(ELVIS) +$(ELVIS_CONFIG): + @$(call core_http_get,$(ELVIS_CONFIG),$(ELVIS_CONFIG_URL)) + +elvis: $(ELVIS) $(ELVIS_CONFIG) @$(ELVIS) rock -c $(ELVIS_CONFIG) $(ELVIS_OPTS) distclean-elvis: $(gen_verbose) rm -rf $(ELVIS) +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> +# This file is part of erlang.mk and subject to the terms of the ISC License. + +# Configuration. + +DTL_FULL_PATH ?= 0 + +# Verbosity. + +dtl_verbose_0 = @echo " DTL " $(filter %.dtl,$(?F)); +dtl_verbose = $(dtl_verbose_$(V)) + +# Core targets. + +define compile_erlydtl + $(dtl_verbose) $(ERL) -pa ebin/ $(DEPS_DIR)/erlydtl/ebin/ -eval ' \ + Compile = fun(F) -> \ + S = fun (1) -> re:replace(filename:rootname(string:sub_string(F, 11), ".dtl"), "/", "_", [{return, list}, global]); \ + (0) -> filename:basename(F, ".dtl") \ + end, \ + Module = list_to_atom(string:to_lower(S($(DTL_FULL_PATH))) ++ "_dtl"), \ + {ok, _} = erlydtl:compile(F, Module, [{out_dir, "ebin/"}, return_errors, {doc_root, "templates"}]) \ + end, \ + _ = [Compile(F) || F <- string:tokens("$(1)", " ")], \ + halt().' +endef + +ifneq ($(wildcard src/),) +ebin/$(PROJECT).app:: $(shell find templates -type f -name \*.dtl 2>/dev/null) + $(if $(strip $?),$(call compile_erlydtl,$?)) +endif + +# Copyright (c) 2014 Dave Cottlehuber <[email protected]> +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-escript escript + +# Configuration. + +ESCRIPT_NAME ?= $(PROJECT) +ESCRIPT_COMMENT ?= This is an -*- erlang -*- file + +ESCRIPT_BEAMS ?= "ebin/*", "deps/*/ebin/*" +ESCRIPT_SYS_CONFIG ?= "rel/sys.config" +ESCRIPT_EMU_ARGS ?= -pa . \ + -sasl errlog_type error \ + -escript main $(ESCRIPT_NAME) +ESCRIPT_SHEBANG ?= /usr/bin/env escript +ESCRIPT_STATIC ?= "deps/*/priv/**", "priv/**" + +# Core targets. + +distclean:: distclean-escript + +help:: + @printf "%s\n" "" \ + "Escript targets:" \ + " escript Build an executable escript archive" \ + +# Plugin-specific targets. + +# Based on https://github.com/synrc/mad/blob/master/src/mad_bundle.erl +# Copyright (c) 2013 Maxim Sokhatsky, Synrc Research Center +# Modified MIT License, https://github.com/synrc/mad/blob/master/LICENSE : +# Software may only be used for the great good and the true happiness of all +# sentient beings. + +define ESCRIPT_RAW +'Read = fun(F) -> {ok, B} = file:read_file(filename:absname(F)), B end,'\ +'Files = fun(L) -> A = lists:concat([filelib:wildcard(X)||X<- L ]),'\ +' [F || F <- A, not filelib:is_dir(F) ] end,'\ +'Squash = fun(L) -> [{filename:basename(F), Read(F) } || F <- L ] end,'\ +'Zip = fun(A, L) -> {ok,{_,Z}} = zip:create(A, L, [{compress,all},memory]), Z end,'\ +'Ez = fun(Escript) ->'\ +' Static = Files([$(ESCRIPT_STATIC)]),'\ +' Beams = Squash(Files([$(ESCRIPT_BEAMS), $(ESCRIPT_SYS_CONFIG)])),'\ +' Archive = Beams ++ [{ "static.gz", Zip("static.gz", Static)}],'\ +' escript:create(Escript, [ $(ESCRIPT_OPTIONS)'\ +' {archive, Archive, [memory]},'\ +' {shebang, "$(ESCRIPT_SHEBANG)"},'\ +' {comment, "$(ESCRIPT_COMMENT)"},'\ +' {emu_args, " $(ESCRIPT_EMU_ARGS)"}'\ +' ]),'\ +' file:change_mode(Escript, 8#755)'\ +'end,'\ +'Ez("$(ESCRIPT_NAME)"),'\ +'halt().' +endef + +ESCRIPT_COMMAND = $(subst ' ',,$(ESCRIPT_RAW)) + +escript:: distclean-escript deps app + $(gen_verbose) $(ERL) -eval $(ESCRIPT_COMMAND) + +distclean-escript: + $(gen_verbose) rm -f $(ESCRIPT_NAME) + +# Copyright (c) 2014, Enrique Fernandez <[email protected]> +# Copyright (c) 2015, Loïc Hoguin <[email protected]> +# This file is contributed to erlang.mk and subject to the terms of the ISC License. + +.PHONY: eunit + +# Configuration + +ifeq ($(strip $(TEST_DIR)),) +TAGGED_EUNIT_TESTS = {dir,"ebin"} +else +ifeq ($(wildcard $(TEST_DIR)),) +TAGGED_EUNIT_TESTS = {dir,"ebin"} +else +# All modules in TEST_DIR +TEST_DIR_MODS = $(notdir $(basename $(shell find $(TEST_DIR) -type f -name *.beam))) +# All modules in 'ebin' +EUNIT_EBIN_MODS = $(notdir $(basename $(shell find ebin -type f -name *.beam))) +# Only those modules in TEST_DIR with no matching module in 'ebin'. +# This is done to avoid some tests being executed twice. +EUNIT_MODS = $(filter-out $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(TEST_DIR_MODS)) +TAGGED_EUNIT_TESTS = {dir,"ebin"} $(foreach mod,$(EUNIT_MODS),$(shell echo $(mod) | sed -e 's/\(.*\)/{module,\1}/g')) +endif +endif + +EUNIT_OPTS ?= verbose + +# Utility functions + +define str-join + $(shell echo '$(strip $(1))' | sed -e "s/ /,/g") +endef + +# Core targets. + +tests:: eunit + +help:: + @printf "%s\n" "" \ + "EUnit targets:" \ + " eunit Run all the EUnit tests for this project" + +# Plugin-specific targets. + +EUNIT_RUN = $(ERL) \ + -pa $(TEST_DIR) $(DEPS_DIR)/*/ebin \ + -pz ebin \ + -eval 'case eunit:test([$(call str-join,$(TAGGED_EUNIT_TESTS))], [$(EUNIT_OPTS)]) of ok -> halt(0); error -> halt(1) end.' + +eunit: test-build + $(gen_verbose) $(EUNIT_RUN) + +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: relx-rel distclean-relx-rel distclean-relx + +# Configuration. + +RELX_CONFIG ?= $(CURDIR)/relx.config + +RELX ?= $(CURDIR)/relx +export RELX + +RELX_URL ?= https://github.com/erlware/relx/releases/download/v1.2.0/relx +RELX_OPTS ?= +RELX_OUTPUT_DIR ?= _rel + +ifeq ($(firstword $(RELX_OPTS)),-o) + RELX_OUTPUT_DIR = $(word 2,$(RELX_OPTS)) +else + RELX_OPTS += -o $(RELX_OUTPUT_DIR) +endif + +# Core targets. + +ifneq ($(wildcard $(RELX_CONFIG)),) +rel:: distclean-relx-rel relx-rel +endif + +distclean:: distclean-relx-rel distclean-relx + +# Plugin-specific targets. + +define relx_fetch + $(call core_http_get,$(RELX),$(RELX_URL)) + chmod +x $(RELX) +endef + +$(RELX): + @$(call relx_fetch) + +relx-rel: $(RELX) + @$(RELX) -c $(RELX_CONFIG) $(RELX_OPTS) + +distclean-relx-rel: + $(gen_verbose) rm -rf $(RELX_OUTPUT_DIR) + +distclean-relx: + $(gen_verbose) rm -rf $(RELX) + # Copyright (c) 2014, M Robert Martin <[email protected]> # This file is contributed to erlang.mk and subject to the terms of the ISC License. @@ -720,7 +1220,7 @@ distclean-elvis: # Configuration. -SHELL_PATH ?= -pa ../$(PROJECT)/ebin $(DEPS_DIR)/*/ebin +SHELL_PATH ?= -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin SHELL_OPTS ?= ALL_SHELL_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(SHELL_DEPS)) @@ -741,3 +1241,35 @@ build-shell-deps: $(ALL_SHELL_DEPS_DIRS) shell: build-shell-deps $(gen_verbose) erl $(SHELL_PATH) $(SHELL_OPTS) + +# Copyright (c) 2015, Loïc Hoguin <[email protected]> +# This file is part of erlang.mk and subject to the terms of the ISC License. + +ifneq ($(wildcard $(DEPS_DIR)/triq),) +.PHONY: triq + +# Targets. + +tests:: triq + +define triq_run +$(ERL) -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin \ + -eval "try $(1) of true -> halt(0); _ -> halt(1) catch error:undef -> io:format(\"Undefined property or module~n\"), halt() end." +endef + +ifdef t +ifeq (,$(findstring :,$(t))) +triq: test-build + @$(call triq_run,triq:check($(t))) +else +triq: test-build + @echo Testing $(t)/0 + @$(call triq_run,triq:check($(t)())) +endif +else +triq: test-build + $(eval MODULES := $(shell find ebin -type f -name \*.beam \ + | sed "s/ebin\//'/;s/\.beam/',/" | sed '$$s/.$$//')) + $(gen_verbose) $(call triq_run,[true] =:= lists:usort([triq:check(M) || M <- [$(MODULES)]])) +endif +endif diff --git a/include/cow_inline.hrl b/include/cow_inline.hrl index 458e011..5c43a5a 100644 --- a/include/cow_inline.hrl +++ b/include/cow_inline.hrl @@ -1,4 +1,4 @@ -%% Copyright (c) 2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2014-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above diff --git a/src/cow_cookie.erl b/src/cow_cookie.erl index 02df65e..150efeb 100644 --- a/src/cow_cookie.erl +++ b/src/cow_cookie.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above diff --git a/src/cow_date.erl b/src/cow_date.erl index 1e54090..b805aec 100644 --- a/src/cow_date.erl +++ b/src/cow_date.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above @@ -182,9 +182,7 @@ http_date_test_() -> {<<"Sun Nov 6 08:49:37 1994">>, {{1994, 11, 6}, {8, 49, 37}}} ], [{V, fun() -> R = http_date(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_http_date_fixdate() -> horse:repeat(200000, http_date(<<"Sun, 06 Nov 1994 08:49:37 GMT">>) @@ -221,9 +219,7 @@ rfc2109_test_() -> {<<"Sun, 01-Jan-2012 00:00:00 GMT">>, {{2012, 1, 1}, { 0, 0, 0}}} ], [{R, fun() -> R = rfc2109(D) end} || {R, D} <- Tests]. --endif. --ifdef(PERF). horse_rfc2019_20130101_000000() -> horse:repeat(100000, rfc2109({{2013, 1, 1}, {0, 0, 0}}) diff --git a/src/cow_http.erl b/src/cow_http.erl index 60f3faa..8f2ae92 100644 --- a/src/cow_http.erl +++ b/src/cow_http.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above @@ -82,9 +82,7 @@ parse_status_line_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_status_line(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_status_line_200() -> horse:repeat(200000, parse_status_line(<<"HTTP/1.1 200 OK\r\n">>) @@ -184,9 +182,7 @@ parse_headers_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_headers(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_headers() -> horse:repeat(50000, parse_headers(<<"Server: Erlang/R17\r\n" diff --git a/src/cow_http_hd.erl b/src/cow_http_hd.erl index b54ade6..e47d80d 100644 --- a/src/cow_http_hd.erl +++ b/src/cow_http_hd.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2014-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above @@ -386,9 +386,7 @@ parse_accept_error_test_() -> <<"audio/basic;t=\"zero \\", 0, " woo\"">> ], [{V, fun() -> {'EXIT', _} = (catch parse_accept(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_accept() -> horse:repeat(20000, parse_accept(<<"text/*;q=0.3, text/html;q=0.7, text/html;level=1, " @@ -480,9 +478,7 @@ parse_accept_charset_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_accept_charset(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_accept_charset() -> horse:repeat(20000, parse_accept_charset(<<"iso-8859-5, unicode-1-1;q=0.8">>) @@ -538,9 +534,7 @@ parse_accept_encoding_test_() -> ]} ], [{V, fun() -> R = parse_accept_encoding(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_accept_encoding() -> horse:repeat(20000, parse_accept_encoding(<<"gzip;q=1.0, identity; q=0.5, *;q=0">>) @@ -657,9 +651,7 @@ parse_accept_language_error_test_() -> <<"419-en-us">> ], [{V, fun() -> {'EXIT', _} = (catch parse_accept_language(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_accept_language() -> horse:repeat(20000, parse_accept_language(<<"da, en-gb;q=0.8, en;q=0.7">>) @@ -688,9 +680,7 @@ parse_accept_ranges_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_accept_ranges(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_accept_ranges_none() -> horse:repeat(200000, parse_accept_ranges(<<"none">>) @@ -764,9 +754,7 @@ parse_allow_test_() -> {<<"GET, HEAD, PUT">>, [<<"GET">>, <<"HEAD">>, <<"PUT">>]} ], [{V, fun() -> R = parse_allow(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_allow() -> horse:repeat(200000, parse_allow(<<"GET, HEAD, PUT">>) @@ -863,9 +851,7 @@ parse_authorization_test_() -> {<<"opaque">>, <<"5ccc069c403ebaf9f0171e9517f40e41">>}]}} ], [{V, fun() -> R = parse_authorization(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_authorization_basic() -> horse:repeat(20000, parse_authorization(<<"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==">>) @@ -1014,9 +1000,7 @@ parse_cache_control_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_cache_control(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_cache_control_no_cache() -> horse:repeat(200000, parse_cache_control(<<"no-cache">>) @@ -1078,9 +1062,7 @@ parse_connection_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_connection(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_connection_close() -> horse:repeat(200000, parse_connection(<<"close">>) @@ -1115,9 +1097,7 @@ parse_content_encoding_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_content_encoding(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_content_encoding() -> horse:repeat(200000, parse_content_encoding(<<"gzip">>) @@ -1403,9 +1383,7 @@ parse_content_language_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_content_language(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_content_language() -> horse:repeat(100000, parse_content_language(<<"fr, en-US, es-419, az-Arab, x-pig-latin, man-Nkoo-GN">>) @@ -1449,9 +1427,7 @@ parse_content_length_error_test_() -> <<"4.17">> ], [{V, fun() -> {'EXIT', _} = (catch parse_content_length(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_content_length_zero() -> horse:repeat(100000, parse_content_length(<<"0">>) @@ -1551,9 +1527,7 @@ parse_content_range_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_content_range(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_content_range_bytes() -> horse:repeat(200000, parse_content_range(<<"bytes 21010-47021/47022">>) @@ -1666,9 +1640,7 @@ parse_content_type_test_() -> ]}} ], [{V, fun() -> R = parse_content_type(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_content_type() -> horse:repeat(200000, parse_content_type(<<"text/html;charset=utf-8">>) @@ -1739,9 +1711,7 @@ parse_etag_error_test_() -> <<"W/">> ], [{V, fun() -> {'EXIT', _} = (catch parse_etag(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_etag() -> horse:repeat(200000, parse_etag(<<"W/\"xyzzy\"">>) @@ -1789,9 +1759,7 @@ parse_expect_error_test_() -> <<"Cookies">> ], [{V, fun() -> {'EXIT', _} = (catch parse_expect(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_expect() -> horse:repeat(200000, parse_expect(<<"100-continue">>) @@ -1821,9 +1789,7 @@ parse_expires_test_() -> {<<"Thu, 01 Dec 1994 16:00:00 GMT">>, {{1994, 12, 1}, {16, 0, 0}}} ], [{V, fun() -> R = parse_expires(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_expires_0() -> horse:repeat(200000, parse_expires(<<"0">>) @@ -1897,9 +1863,7 @@ parse_host_test_() -> {<<"[::ffff:192.0.2.1]">>, {<<"[::ffff:192.0.2.1]">>, undefined}} ], [{V, fun() -> R = parse_host(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_host_blue_example_org() -> horse:repeat(200000, parse_host(<<"blue.example.org:8080">>) @@ -1966,9 +1930,7 @@ parse_if_match_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_if_match(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_if_match() -> horse:repeat(200000, parse_if_match(<<"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\"">>) @@ -2015,9 +1977,7 @@ parse_if_none_match_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_if_none_match(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_if_none_match() -> horse:repeat(200000, parse_if_none_match(<<"W/\"xyzzy\", W/\"r2d2xxxx\", W/\"c3piozzzz\"">>) @@ -2048,9 +2008,7 @@ parse_if_range_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_if_range(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_if_range_etag() -> horse:repeat(200000, parse_if_range(<<"\"xyzzy\"">>) @@ -2255,9 +2213,7 @@ parse_range_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_range(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_range_first_last() -> horse:repeat(200000, parse_range(<<"bytes=500-999">>) @@ -2307,9 +2263,7 @@ parse_retry_after_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_retry_after(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_retry_after_date() -> horse:repeat(200000, parse_retry_after(<<"Fri, 31 Dec 1999 23:59:59 GMT">>) @@ -2417,9 +2371,7 @@ parse_sec_websocket_extensions_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_extensions(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_sec_websocket_extensions() -> horse:repeat(200000, parse_sec_websocket_extensions(<<"mux; max-channels=4; flow-control, deflate-stream">>) @@ -2456,9 +2408,7 @@ parse_sec_websocket_protocol_req_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_protocol_req(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_sec_websocket_protocol_req() -> horse:repeat(200000, parse_sec_websocket_protocol_req(<<"chat, superchat">>) @@ -2494,9 +2444,7 @@ parse_sec_websocket_protocol_resp_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_protocol_resp(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_sec_websocket_protocol_resp() -> horse:repeat(200000, parse_sec_websocket_protocol_resp(<<"chat">>) @@ -2533,9 +2481,7 @@ parse_sec_websocket_version_req_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_version_req(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_sec_websocket_version_req_13() -> horse:repeat(200000, parse_sec_websocket_version_req(<<"13">>) @@ -2591,9 +2537,7 @@ parse_sec_websocket_version_resp_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_version_resp(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_sec_websocket_version_resp() -> horse:repeat(200000, parse_sec_websocket_version_resp(<<"13, 8, 7">>) @@ -2691,9 +2635,7 @@ parse_te_test_() -> {<<"trailers, deflate;q=0.5">>, {trailers, [{<<"deflate">>, 500}]}} ], [{V, fun() -> R = parse_te(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_te() -> horse:repeat(200000, parse_te(<<"trailers, deflate;q=0.5">>) @@ -2718,9 +2660,7 @@ parse_trailer_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_trailer(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_trailer() -> horse:repeat(200000, parse_trailer(<<"Date, Content-MD5">>) @@ -2769,9 +2709,7 @@ parse_transfer_encoding_error_test_() -> ], [{V, fun() -> {'EXIT', _} = (catch parse_transfer_encoding(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_transfer_encoding_chunked() -> horse:repeat(200000, parse_transfer_encoding(<<"chunked">>) @@ -3018,9 +2956,7 @@ parse_www_authenticate_error_test_() -> <<>> ], [{V, fun() -> {'EXIT', _} = (catch parse_www_authenticate(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_www_authenticate() -> horse:repeat(200000, parse_www_authenticate(<<"Newauth realm=\"apps\", type=1, title=\"Login to \\\"apps\\\"\", Basic realm=\"simple\"">>) diff --git a/src/cow_http_te.erl b/src/cow_http_te.erl index 5ab71f4..1e7b43f 100644 --- a/src/cow_http_te.erl +++ b/src/cow_http_te.erl @@ -34,7 +34,7 @@ | {done, Data::binary(), TotalLen::non_neg_integer(), Rest::binary()}. -export_type([decode_ret/0]). --ifdef(EXTRA). +-ifdef(TEST). dripfeed(<< C, Rest/bits >>, Acc, State, F) -> case F(<< Acc/binary, C >>, State) of more -> @@ -92,11 +92,8 @@ stream_identity_parts_test() -> {done, << 0:7992 >>, 2999, <<>>} = stream_identity(<< 0:7992 >>, S2), ok. --endif. --ifdef(PERF). %% Using the same data as the chunked one for comparison. - horse_stream_identity() -> horse:repeat(10000, stream_identity(<< @@ -296,9 +293,7 @@ stream_chunked_error_test_() -> [{lists:flatten(io_lib:format("value ~p state ~p", [V, S])), fun() -> {'EXIT', _} = (catch stream_chunked(V, S)) end} || {V, S} <- Tests]. --endif. --ifdef(PERF). horse_stream_chunked() -> horse:repeat(10000, stream_chunked(<< diff --git a/src/cow_mimetypes.erl b/src/cow_mimetypes.erl index 69284e1..58585b9 100644 --- a/src/cow_mimetypes.erl +++ b/src/cow_mimetypes.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above diff --git a/src/cow_multipart.erl b/src/cow_multipart.erl index c53cdb4..d37a7e1 100644 --- a/src/cow_multipart.erl +++ b/src/cow_multipart.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2014-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above @@ -362,9 +362,7 @@ parse_partial_test() -> {ok, <<"boundary">>, <<"\r\n--">>} = parse_body(<<"boundary\r\n--">>, <<"boundary">>), ok. --endif. --ifdef(PERF). perf_parse_multipart(Stream, Boundary) -> case parse_headers(Stream, Boundary) of {ok, _, Rest} -> @@ -461,9 +459,7 @@ identity_test() -> {done, Body2, M6} = parse_body(M5, B), {done, Epilogue} = parse_headers(M6, B), ok. --endif. --ifdef(PERF). perf_build_multipart() -> B = boundary(), [ @@ -575,9 +571,7 @@ parse_content_disposition_test_() -> {<<"file">>, [{<<"filename">>, <<"file2.gif">>}]}} ], [{V, fun() -> R = parse_content_disposition(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_content_disposition_attachment() -> horse:repeat(100000, parse_content_disposition(<<"attachment; filename=genome.jpeg;" @@ -617,9 +611,7 @@ parse_content_transfer_encoding_test_() -> ], [{V, fun() -> R = parse_content_transfer_encoding(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_content_transfer_encoding() -> horse:repeat(100000, parse_content_transfer_encoding(<<"QUOTED-PRINTABLE">>) @@ -680,9 +672,7 @@ parse_content_type_test_() -> ], [{V, fun() -> R = parse_content_type(V) end} || {V, R} <- Tests]. --endif. --ifdef(PERF). horse_parse_content_type_zero() -> horse:repeat(100000, parse_content_type(<<"text/plain">>) diff --git a/src/cow_qs.erl b/src/cow_qs.erl index 413562b..33d385b 100644 --- a/src/cow_qs.erl +++ b/src/cow_qs.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above @@ -126,9 +126,7 @@ parse_qs_identity_test_() -> "b-sid=521732&ortb-xt=IAB3&ortb-ugc=">> ], [{V, fun() -> V = qs(parse_qs(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_parse_qs_shorter() -> horse:repeat(20000, parse_qs(<<"hl=en&q=erlang%20cowboy">>) @@ -310,9 +308,7 @@ qs_identity_test_() -> [{lists:flatten(io_lib:format("~p", [V])), fun() -> V = parse_qs(qs(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_qs_shorter() -> horse:repeat(20000, qs(?QS_SHORTER)). @@ -395,9 +391,7 @@ urldecode_identity_test_() -> "%BE%8B%E3%80%9C">> ], [{V, fun() -> V = urlencode(urldecode(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_urldecode() -> horse:repeat(100000, urldecode(<<"nothingnothingnothingnothing">>) @@ -544,9 +538,7 @@ urlencode_identity_test_() -> 129,153,227,130,139,230,151,139,229,190,139,227,128,156>> ], [{V, fun() -> V = urldecode(urlencode(V)) end} || V <- Tests]. --endif. --ifdef(PERF). horse_urlencode() -> horse:repeat(100000, urlencode(<<"nothingnothingnothingnothing">>) diff --git a/src/cow_spdy.erl b/src/cow_spdy.erl index 59c1ba4..ac7f0fc 100644 --- a/src/cow_spdy.erl +++ b/src/cow_spdy.erl @@ -1,4 +1,4 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above diff --git a/src/cowlib.app.src b/src/cowlib.app.src index 2172075..5d358c2 100644 --- a/src/cowlib.app.src +++ b/src/cowlib.app.src @@ -1,4 +1,4 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above diff --git a/test/eunit_SUITE.erl b/test/eunit_SUITE.erl deleted file mode 100644 index dddfdd3..0000000 --- a/test/eunit_SUITE.erl +++ /dev/null @@ -1,31 +0,0 @@ -%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> -%% -%% 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(eunit_SUITE). - --include_lib("common_test/include/ct.hrl"). - -%% ct. --export([all/0]). - -%% Tests. --export([eunit/1]). - -%% ct. - -all() -> - [eunit]. - -eunit(_) -> - ok = eunit:test({application, cowlib}). |