diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5401b79 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_size = 4 +indent_style = space +trim_trailing_whitespace = true +max_line_length = 120 diff --git a/.env b/.env new file mode 100644 index 0000000..d471f87 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +OTP_VERSION=24.3.4 +REBAR_VERSION=3.18 +THRIFT_VERSION=0.14.2.3 diff --git a/.github/workflows/erlang-checks.yml b/.github/workflows/erlang-checks.yml new file mode 100644 index 0000000..d4fa15c --- /dev/null +++ b/.github/workflows/erlang-checks.yml @@ -0,0 +1,38 @@ +name: Erlang CI Checks + +on: + push: + branches: + - 'master' + - 'epic/**' + pull_request: + branches: ['**'] + +jobs: + setup: + name: Load .env + runs-on: ubuntu-latest + outputs: + otp-version: ${{ steps.otp-version.outputs.version }} + rebar-version: ${{ steps.rebar-version.outputs.version }} + thrift-version: ${{ steps.thrift-version.outputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - run: grep -v '^#' .env >> $GITHUB_ENV + - id: otp-version + run: echo "::set-output name=version::$OTP_VERSION" + - id: rebar-version + run: echo "::set-output name=version::$REBAR_VERSION" + - id: thrift-version + run: echo "::set-output name=version::$THRIFT_VERSION" + + run: + name: Run checks + needs: setup + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.1 + with: + otp-version: ${{ needs.setup.outputs.otp-version }} + rebar-version: ${{ needs.setup.outputs.rebar-version }} + use-thrift: true + thrift-version: ${{ needs.setup.outputs.thrift-version }} diff --git a/.gitignore b/.gitignore index f489b48..8b14b84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ -# general -log +# Build artifacts /_build/ -/.rebar3/ -/ebin/ -*~ +*.o +*.beam +*.plt + +# Run artifacts erl_crash.dump -.tags* -*.sublime-workspace -.DS_Store +log + +# make stuff +/.image.* +Makefile.env diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d2f53b2..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "builtils"] - path = builtils - url = git@github.com:rbkmoney/build_utils.git diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..4e47743 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,16 @@ +ARG OTP_VERSION + +FROM docker.io/library/erlang:${OTP_VERSION} + +# Install thrift compiler +ARG THRIFT_VERSION +ARG TARGETARCH +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${TARGETARCH}.tar.gz" \ + | tar -xvz -C /usr/local/bin/ + +# Set env +ENV CHARSET=UTF-8 +ENV LANG=C.UTF-8 + +# Set runtime +CMD ["/bin/bash"] diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index bf0dbd2..0000000 --- a/Jenkinsfile +++ /dev/null @@ -1,15 +0,0 @@ -#!groovy - -build('dmt_core', 'docker-host') { - checkoutRepo() - loadBuildUtils("builtils") - - def pipeErlangLib - runStage('load pipeline') { - env.JENKINS_LIB = "builtils/jenkins_lib" - env.SH_TOOLS = "builtils/sh" - pipeErlangLib = load("${env.JENKINS_LIB}/pipeErlangLib.groovy") - } - - pipeErlangLib.runPipe(false, true, 'test') -} diff --git a/Makefile b/Makefile index 3c34f8e..371b1a3 100644 --- a/Makefile +++ b/Makefile @@ -1,58 +1,94 @@ -REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -SUBMODULES = builtils -SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) +# HINT +# Use this file to override variables here. +# For example, to run with podman put `DOCKER=podman` there. +-include Makefile.env -UTILS_PATH := builtils -TEMPLATES_PATH := . +# NOTE +# Variables specified in `.env` file are used to pick and setup specific +# component versions, both when building a development image and when running +# CI workflows on GH Actions. This ensures that tasks run with `wc-` prefix +# (like `wc-dialyze`) are reproducible between local machine and CI runners. +DOTENV := $(shell grep -v '^\#' .env) -# Name of the service -SERVICE_NAME := dmt_core - -# Build image tag to be used -BUILD_IMAGE_TAG := 0c638a682f4735a65ef232b81ed872ba494574c3 - -CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze test clean distclean check_format format -CALL_W_CONTAINER := $(CALL_ANYWHERE) +DOCKER ?= docker +REBAR ?= rebar3 +TEST_CONTAINER_NAME ?= dmt-core-dev all: compile --include $(UTILS_PATH)/make_lib/utils_container.mk +# Development images -.PHONY: $(CALL_W_CONTAINER) +DEV_IMAGE_TAG = $(TEST_CONTAINER_NAME)-dev +DEV_IMAGE_ID = $(file < .image.dev) -$(SUBTARGETS): %/.git: % - git submodule update --init $< - touch $@ +.PHONY: dev-image clean-dev-image wc-shell test -submodules: $(SUBTARGETS) +dev-image: .image.dev -rebar-update: - $(REBAR) update +.image.dev: Dockerfile.dev .env + $(DOCKER) build . -f Dockerfile.dev --tag $(DEV_IMAGE_TAG) $(DOTENV:%=--build-arg %) + $(DOCKER) image ls -q -f "reference=$(DEV_IMAGE_TAG)" | head -n1 > $@ -compile: submodules rebar-update +clean-dev-image: +ifneq ($(DEV_IMAGE_ID),) + $(DOCKER) image rm -f $(DEV_IMAGE_TAG) + rm .image.dev +endif + +DOCKER_WC_OPTIONS := -v $(PWD):$(PWD) --workdir $(PWD) +DOCKER_WC_EXTRA_OPTIONS ?= --rm +DOCKER_RUN = $(DOCKER) run -t $(DOCKER_WC_OPTIONS) $(DOCKER_WC_EXTRA_OPTIONS) + +# Utility tasks + +wc-shell: dev-image + $(DOCKER_RUN) --interactive --tty $(DEV_IMAGE_TAG) + +wc-%: dev-image + $(DOCKER_RUN) $(DEV_IMAGE_TAG) make $* + +# Rebar tasks + +rebar-shell: + $(REBAR) shell + +compile: $(REBAR) compile -xref: submodules - $(REBAR) as test xref +xref: + $(REBAR) xref lint: - elvis rock + $(REBAR) lint -check_format: - $(REBAR) as test fmt -c - -format: - $(REBAR) fmt -w +check-format: + $(REBAR) fmt -c dialyze: $(REBAR) as test dialyzer -test: - $(REBAR) eunit - $(REBAR) ct +release: + $(REBAR) as prod release + +eunit: + $(REBAR) eunit --cover + +common-test: + $(REBAR) ct --cover + +cover: + $(REBAR) covertool generate + +format: + $(REBAR) fmt -w clean: $(REBAR) clean -distclean: +distclean: clean-build-image rm -rf _build + +test: eunit common-test + +cover-report: + $(REBAR) cover diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a40909 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# dmt-core + +Core mechanics of the domain config system. + +## Building + +To build the project, run the following command: + +```bash +$ make compile +``` + +## Running + +To enter the [Erlang shell][1] with the project running, run the following command: + +```bash +$ make rebar-shell +``` + +## Development environment + +### Run in a docker container + +You can run any of the tasks defined in the Makefile from inside of a docker container (defined in `Dockerfile.dev`) by prefixing the task name with `wc-`. To successfully build the dev container you need `Docker BuildKit` enabled. This can be accomplished by either installing [docker-buildx](https://docs.docker.com/buildx/working-with-buildx/) locally, or exporting the `DOCKER_BUILDKIT=1` environment variable. + +#### Example + +* This command will run the `compile` task in a docker container: +```bash +$ make wc-compile +``` +#### Example + +* This command will run the `compile` task in a docker container: +```bash +$ make wc-compile +``` + +## Documentation + +@TODO Please write a couple of words about what your project does and how it does it. + +[1]: http://erlang.org/doc/man/shell.html diff --git a/builtils b/builtils deleted file mode 160000 index f42e059..0000000 --- a/builtils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f42e059d9ec93826ba4ad23232eed8ce67bd5486 diff --git a/elvis.config b/elvis.config index 64e4892..6bc7df6 100644 --- a/elvis.config +++ b/elvis.config @@ -1,29 +1,27 @@ [ {elvis, [ + {verbose, true}, {config, [ #{ - dirs => ["src"], + dirs => ["src", "include"], filter => "*.erl", - ignore => ["_thrift.erl$"], + ruleset => erl_files, rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace}, - {elvis_style, macro_names}, - {elvis_style, macro_module_names}, - {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, + {elvis_text_style, line_length, #{limit => 120}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 25}}, - {elvis_style, no_if_expression}, - {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, - {elvis_style, used_ignored_variable}, - {elvis_style, no_behavior_info}, - {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, - {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, - {elvis_style, state_record_and_type}, - {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 10}}, - {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} + {elvis_style, no_if_expression, disable} + ] + }, + #{ + dirs => ["test"], + filter => "*.erl", + ruleset => erl_files, + rules => [ + {elvis_text_style, line_length, #{limit => 120}}, + {elvis_style, nesting_level, #{level => 3}}, + {elvis_style, no_if_expression, disable}, + % Tests are usually more comprehensible when a bit more verbose. + {elvis_style, dont_repeat_yourself, #{min_complexity => 50}} ] }, #{ @@ -39,28 +37,22 @@ #{ dirs => ["."], filter => "rebar.config", + ruleset => rebar_config, rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} - ] - }, - #{ - dirs => ["."], - filter => "rebar.config", - rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} + {elvis_text_style, line_length, #{limit => 120}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace}, + %% Temporarily disabled till regex pattern is available + {elvis_project, no_deps_master_rebar, disable} ] }, #{ dirs => ["src"], filter => "*.app.src", rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} + {elvis_text_style, line_length, #{limit => 120}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace} ] } ]} diff --git a/rebar.config b/rebar.config index 4dc128b..9e87ba1 100644 --- a/rebar.config +++ b/rebar.config @@ -1,6 +1,5 @@ %% Common project erlang options. {erl_opts, [ - % mandatory debug_info, warnings_as_errors, @@ -27,7 +26,7 @@ %% Common project dependencies. {deps, [ - {damsel, {git, "https://github.com/rbkmoney/damsel.git", {branch, "release/erlang/master"}}} + {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}} ]}. %% XRef checks @@ -37,7 +36,6 @@ deprecated_functions_calls, deprecated_functions ]}. - % at will % {xref_warnings, true}. @@ -50,23 +48,37 @@ race_conditions, unknown ]}, - {plt_apps, all_deps}, - {plt_extra_apps, [ - syntax_tools, - compiler + {plt_apps, all_deps} +]}. + +{profiles, [ + {test, [ + {cover_enabled, true}, + {deps, []}, + {dialyzer, [ + {plt_extra_apps, [eunit, common_test, syntax_tools, compiler]} + ]} ]} ]}. -{pre_hooks, [ - {thrift, "git submodule update --init"} +{project_plugins, [ + % {rebar3_bench, "0.2.1"}, + {rebar3_lint, "1.0.1"}, + {erlfmt, "1.0.0"}, + {covertool, "2.0.4"} ]}. -{plugins, [ - % {rebar3_bench, "0.2.1"}, - {erlfmt, "0.8.0"} -]}. +%% Linter config. +{elvis_output_format, colors}. {erlfmt, [ {print_width, 120}, - {files, "{src,include,test}/*.{hrl,erl}"} + {files, ["{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]} +]}. + +{covertool, [ + {coverdata_files, [ + "eunit.coverdata", + "ct.coverdata" + ]} ]}. diff --git a/rebar.lock b/rebar.lock index 5e17048..f8f0bd4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,6 +1,6 @@ [{<<"damsel">>, - {git,"https://github.com/rbkmoney/damsel.git", - {ref,"e3974a5e416169bc9d6e5d69fbff72b36ef8e677"}}, + {git,"https://github.com/valitydev/damsel.git", + {ref,"dac2cb599499cc0701e60856f4092c9ab283eedf"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", diff --git a/src/dmt_core.app.src b/src/dmt_core.app.src index 9dd11a5..dab2a1b 100644 --- a/src/dmt_core.app.src +++ b/src/dmt_core.app.src @@ -8,9 +8,5 @@ damsel ]}, {modules, []}, - {maintainers, [ - "Evgeny Levenets " - ]}, - {licenses, []}, - {links, ["https://github.com/rbkmoney/dmt_core"]} + {licenses, []} ]}. diff --git a/src/dmt_domain.erl b/src/dmt_domain.erl index 5b3c1ea..6c3d130 100644 --- a/src/dmt_domain.erl +++ b/src/dmt_domain.erl @@ -1,6 +1,6 @@ -module(dmt_domain). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). -compile({parse_transform, dmt_domain_pt}). @@ -19,7 +19,7 @@ %% --type operation() :: dmsl_domain_config_thrift:'Operation'(). +-type operation() :: dmsl_domain_conf_thrift:'Operation'(). -type object_ref() :: dmsl_domain_thrift:'Reference'(). -type domain() :: dmsl_domain_thrift:'Domain'(). -type domain_object() :: dmsl_domain_thrift:'DomainObject'(). @@ -66,11 +66,11 @@ apply_operations( ) -> {Result, Touch} = case Op of - {insert, #'InsertOp'{object = Object}} -> + {insert, #domain_conf_InsertOp{object = Object}} -> {insert(Object, Domain), {insert, Object}}; - {update, #'UpdateOp'{old_object = OldObject, new_object = NewObject}} -> + {update, #domain_conf_UpdateOp{old_object = OldObject, new_object = NewObject}} -> {update(OldObject, NewObject, Domain), {update, NewObject}}; - {remove, #'RemoveOp'{object = Object}} -> + {remove, #domain_conf_RemoveOp{object = Object}} -> {remove(Object, Domain), {remove, Object}} end, case Result of @@ -470,9 +470,9 @@ is_reference_type(Type, [{_, _, Type, Tag, _} | _Rest]) -> is_reference_type(Type, [_ | Rest]) -> is_reference_type(Type, Rest). -invert_operation({insert, #'InsertOp'{object = Object}}) -> - {remove, #'RemoveOp'{object = Object}}; -invert_operation({update, #'UpdateOp'{old_object = OldObject, new_object = NewObject}}) -> - {update, #'UpdateOp'{old_object = NewObject, new_object = OldObject}}; -invert_operation({remove, #'RemoveOp'{object = Object}}) -> - {insert, #'InsertOp'{object = Object}}. +invert_operation({insert, #domain_conf_InsertOp{object = Object}}) -> + {remove, #domain_conf_RemoveOp{object = Object}}; +invert_operation({update, #domain_conf_UpdateOp{old_object = OldObject, new_object = NewObject}}) -> + {update, #domain_conf_UpdateOp{old_object = NewObject, new_object = OldObject}}; +invert_operation({remove, #domain_conf_RemoveOp{object = Object}}) -> + {insert, #domain_conf_InsertOp{object = Object}}. diff --git a/src/dmt_domain_pt.erl b/src/dmt_domain_pt.erl index 27c9162..81c67bc 100644 --- a/src/dmt_domain_pt.erl +++ b/src/dmt_domain_pt.erl @@ -7,9 +7,9 @@ parse_transform(Forms, _Options) -> [ erl_syntax:revert(FormNext) - || Form <- Forms, - FormNext <- [erl_syntax_lib:map(fun transform/1, Form)], - FormNext /= delete + || Form <- Forms, + FormNext <- [erl_syntax_lib:map(fun transform/1, Form)], + FormNext /= delete ]. transform(Form) -> @@ -40,7 +40,7 @@ transform_function(Name = is_reference_type, 1, FormWas) -> none, [erl_syntax:abstract({true, Tag})] ) - || {_N, _Req, Type, Tag, _Default} <- StructInfo + || {_N, _Req, Type, Tag, _Default} <- StructInfo ] ++ [ erl_syntax:clause( diff --git a/src/dmt_history.erl b/src/dmt_history.erl index eb45c11..2707484 100644 --- a/src/dmt_history.erl +++ b/src/dmt_history.erl @@ -4,15 +4,15 @@ -export([head/2]). -export([travel/3]). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). --type history() :: dmsl_domain_config_thrift:'History'(). --type version() :: dmsl_domain_config_thrift:'Version'(). --type snapshot() :: dmsl_domain_config_thrift:'Snapshot'(). +-type history() :: dmsl_domain_conf_thrift:'History'(). +-type version() :: dmsl_domain_conf_thrift:'Version'(). +-type snapshot() :: dmsl_domain_conf_thrift:'Snapshot'(). -spec head(history()) -> {ok, snapshot()} | {error, dmt_domain:operation_error()}. head(History) -> - head(History, #'Snapshot'{version = 0, domain = dmt_domain:new()}). + head(History, #domain_conf_Snapshot{version = 0, domain = dmt_domain:new()}). -spec head(history(), snapshot()) -> {ok, snapshot()} | {error, dmt_domain:operation_error()}. head(History, Snapshot) when map_size(History) =:= 0 -> @@ -22,13 +22,13 @@ head(History, Snapshot) -> travel(Head, History, Snapshot). -spec travel(version(), history(), snapshot()) -> {ok, snapshot()} | {error, dmt_domain:operation_error()}. -travel(To, _History, #'Snapshot'{version = From} = Snapshot) when To =:= From -> +travel(To, _History, #domain_conf_Snapshot{version = From} = Snapshot) when To =:= From -> {ok, Snapshot}; -travel(To, History, #'Snapshot'{version = From, domain = Domain}) when To > From -> - #'Commit'{ops = Ops} = maps:get(From + 1, History), +travel(To, History, #domain_conf_Snapshot{version = From, domain = Domain}) when To > From -> + #domain_conf_Commit{ops = Ops} = maps:get(From + 1, History), case dmt_domain:apply_operations(Ops, Domain) of {ok, NewDomain} -> - NextSnapshot = #'Snapshot'{ + NextSnapshot = #domain_conf_Snapshot{ version = From + 1, domain = NewDomain }, @@ -36,11 +36,11 @@ travel(To, History, #'Snapshot'{version = From, domain = Domain}) when To > From {error, _} = Error -> Error end; -travel(To, History, #'Snapshot'{version = From, domain = Domain}) when To < From -> - #'Commit'{ops = Ops} = maps:get(From, History), +travel(To, History, #domain_conf_Snapshot{version = From, domain = Domain}) when To < From -> + #domain_conf_Commit{ops = Ops} = maps:get(From, History), case dmt_domain:revert_operations(Ops, Domain) of {ok, NewDomain} -> - PreviousSnapshot = #'Snapshot'{ + PreviousSnapshot = #domain_conf_Snapshot{ version = From - 1, domain = NewDomain }, diff --git a/test/bench_apply_operations.erl b/test/bench_apply_operations.erl index cea27ce..3760fa2 100644 --- a/test/bench_apply_operations.erl +++ b/test/bench_apply_operations.erl @@ -6,16 +6,18 @@ bench_apply_operations/2 ]). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). --type snapshot() :: dmsl_domain_config_thrift:'Snapshot'(). --type commit() :: dmsl_domain_config_thrift:'Commit'(). +-type snapshot() :: dmsl_domain_conf_thrift:'Snapshot'(). +-type commit() :: dmsl_domain_conf_thrift:'Commit'(). -record(st, { - snapshot = #'Snapshot'{version = 0, domain = dmt_domain:new()} :: snapshot(), + snapshot = #domain_conf_Snapshot{version = 0, domain = dmt_domain:new()} :: snapshot(), history = #{} :: #{_Version => commit()} }). +-type state() :: #st{}. + -spec repository_state() -> term(). repository_state() -> % NOTE @@ -39,21 +41,21 @@ compute_operation_stats(#st{snapshot = Snapshot, history = History}) -> _ = io:format(user, "~n", []), [ io:format(user, "~24.ts: ~p~n", Args) - || Args <- [ - ["Snapshot version", Snapshot#'Snapshot'.version], - ["Snapshot size", maps:size(Snapshot#'Snapshot'.domain)], - ["Number of commits", maps:size(History)], - ["Number of operations", NumInserts + NumUpdates + NumRemoves], - ["Number of insertions", NumInserts], - ["Number of updates", NumUpdates], - ["Number of removals", NumRemoves] - ] + || Args <- [ + ["Snapshot version", Snapshot#domain_conf_Snapshot.version], + ["Snapshot size", maps:size(Snapshot#domain_conf_Snapshot.domain)], + ["Number of commits", maps:size(History)], + ["Number of operations", NumInserts + NumUpdates + NumRemoves], + ["Number of insertions", NumInserts], + ["Number of updates", NumUpdates], + ["Number of removals", NumRemoves] + ] ], io:format(user, "~n", []). count_history_operations(Type, History = #{}) -> maps:fold( - fun(_, #'Commit'{ops = Ops}, N) -> + fun(_, #domain_conf_Commit{ops = Ops}, N) -> N + count_commit_operations(Type, Ops) end, 0, @@ -72,6 +74,6 @@ count_commit_operations(Type, Ops) -> Ops ). --spec bench_apply_operations(#st{}, _State) -> term(). +-spec bench_apply_operations(state(), _State) -> term(). bench_apply_operations(#st{snapshot = Snapshot, history = History}, _) -> dmt_history:head(History, Snapshot). diff --git a/test/dmt_domain_tests.erl b/test/dmt_domain_tests.erl index 2d380db..16023cb 100644 --- a/test/dmt_domain_tests.erl +++ b/test/dmt_domain_tests.erl @@ -4,16 +4,16 @@ -include("dmt_domain_tests_helper.hrl"). --type testcase() :: {_, fun()}. +-type testcase() :: {_, fun()} | {timeout, integer(), testcase()} | [testcase()]. -spec test() -> _. -spec basic_flow_test_() -> [testcase()]. -spec nested_links_test() -> _. -spec batch_link_test() -> _. -spec wrong_spec_order_test() -> _. --spec reference_cycle_test_() -> [testcase()]. --spec random_reference_cycle_test_() -> [testcase()]. --spec complete_reference_cycle_test_() -> [testcase()]. +-spec reference_cycle_test_() -> testcase(). +-spec random_reference_cycle_test_() -> testcase(). +-spec complete_reference_cycle_test_() -> testcase(). basic_flow_test_() -> Fixture = construct_fixture(), @@ -23,51 +23,59 @@ basic_flow_test_() -> dmt_domain:apply_operations([], Fixture) ), ?_assertEqual( - {error, {conflict, {object_already_exists, ?dummy_link_ref(1337)}}}, - dmt_domain:apply_operations([?insert(?dummy_link(1337, 43))], Fixture) + {error, {conflict, {object_already_exists, ?dummy_link_ref(<<"1337">>)}}}, + dmt_domain:apply_operations([?insert(?dummy_link(<<"1337">>, <<"43">>))], Fixture) ), ?_assertEqual( - {error, {invalid, {objects_not_exist, [{?dummy_ref(0), [?dummy_link_ref(1)]}]}}}, - dmt_domain:apply_operations([?insert(?dummy_link(1, 0))], Fixture) + {error, {invalid, {objects_not_exist, [{?dummy_ref(<<"0">>), [?dummy_link_ref(<<"1">>)]}]}}}, + dmt_domain:apply_operations([?insert(?dummy_link(<<"1">>, <<"0">>))], Fixture) ), ?_assertEqual( - {error, {invalid, {objects_not_exist, [{?dummy_ref(42), [?dummy_link_ref(1337)]}]}}}, - dmt_domain:apply_operations([?remove(?dummy(42))], Fixture) + {error, {invalid, {objects_not_exist, [{?dummy_ref(<<"42">>), [?dummy_link_ref(<<"1337">>)]}]}}}, + dmt_domain:apply_operations([?remove(?dummy(<<"42">>))], Fixture) ), ?_assertMatch( {ok, #{}}, dmt_domain:apply_operations( - [?remove(?dummy_link(1337, 42)), ?remove(?dummy(42)), ?remove(?dummy(44))], + [?remove(?dummy_link(<<"1337">>, <<"42">>)), ?remove(?dummy(<<"42">>)), ?remove(?dummy(<<"44">>))], Fixture ) ), ?_assertEqual( - {error, {conflict, {object_not_found, ?dummy_ref(1)}}}, - dmt_domain:apply_operations([?remove(?dummy(1))], Fixture) + {error, {conflict, {object_not_found, ?dummy_ref(<<"1">>)}}}, + dmt_domain:apply_operations([?remove(?dummy(<<"1">>))], Fixture) ), ?_assertEqual( - {error, {conflict, {object_not_found, ?dummy_ref(41)}}}, - dmt_domain:apply_operations([?remove(?dummy(41)), ?remove(?dummy(41))], Fixture) + {error, {conflict, {object_not_found, ?dummy_ref(<<"41">>)}}}, + dmt_domain:apply_operations([?remove(?dummy(<<"41">>)), ?remove(?dummy(<<"41">>))], Fixture) ), ?_assertEqual( - {error, {invalid, {objects_not_exist, [{?dummy_ref(0), [?dummy_link_ref(1337)]}]}}}, - dmt_domain:apply_operations([?update(?dummy_link(1337, 42), ?dummy_link(1337, 0))], Fixture) + {error, {invalid, {objects_not_exist, [{?dummy_ref(<<"0">>), [?dummy_link_ref(<<"1337">>)]}]}}}, + dmt_domain:apply_operations( + [?update(?dummy_link(<<"1337">>, <<"42">>), ?dummy_link(<<"1337">>, <<"0">>))], Fixture + ) ), ?_assertMatch( {ok, #{}}, - dmt_domain:apply_operations([?update(?dummy_link(1337, 42), ?dummy_link(1337, 44))], Fixture) + dmt_domain:apply_operations( + [?update(?dummy_link(<<"1337">>, <<"42">>), ?dummy_link(<<"1337">>, <<"44">>))], Fixture + ) ), ?_assertEqual( - {error, {conflict, {object_reference_mismatch, ?dummy_ref(1)}}}, - dmt_domain:apply_operations([?update(?dummy(42), ?dummy(1))], Fixture) + {error, {conflict, {object_reference_mismatch, ?dummy_ref(<<"1">>)}}}, + dmt_domain:apply_operations([?update(?dummy(<<"42">>), ?dummy(<<"1">>))], Fixture) ), ?_assertEqual( - {error, {conflict, {object_not_found, ?dummy_link_ref(1)}}}, - dmt_domain:apply_operations([?update(?dummy_link(1, 42), ?dummy_link(1, 44))], Fixture) + {error, {conflict, {object_not_found, ?dummy_link_ref(<<"1">>)}}}, + dmt_domain:apply_operations( + [?update(?dummy_link(<<"1">>, <<"42">>), ?dummy_link(<<"1">>, <<"44">>))], Fixture + ) ), ?_assertEqual( - {error, {conflict, {object_not_found, ?dummy_link_ref(1337)}}}, - dmt_domain:apply_operations([?update(?dummy_link(1337, 1), ?dummy_link(1337, 42))], Fixture) + {error, {conflict, {object_not_found, ?dummy_link_ref(<<"1337">>)}}}, + dmt_domain:apply_operations( + [?update(?dummy_link(<<"1337">>, <<"1">>), ?dummy_link(<<"1337">>, <<"42">>))], Fixture + ) ) ]. @@ -416,7 +424,7 @@ complete_reference_cycle_test_() -> end )} end - || N <- lists:seq(1, 9) + || N <- lists:seq(1, 9) ]. binom(N, K) -> @@ -433,13 +441,13 @@ criterion_w_refs(ID, Refs) -> construct_fixture() -> maps:from_list([ {{Type, Ref}, Object} - || Object = {Type, {_, Ref, _}} <- [ - ?dummy(41), - ?dummy(42), - ?dummy(43), - ?dummy(44), - ?dummy_link(1337, 42), - ?dummy_link(1338, 43), - ?category(1, <<"testCategory">>, <<"testDescription">>) - ] + || Object = {Type, {_, Ref, _}} <- [ + ?dummy(<<"41">>), + ?dummy(<<"42">>), + ?dummy(<<"43">>), + ?dummy(<<"44">>), + ?dummy_link(<<"1337">>, <<"42">>), + ?dummy_link(<<"1338">>, <<"43">>), + ?category(1, <<"testCategory">>, <<"testDescription">>) + ] ]). diff --git a/test/dmt_domain_tests_helper.hrl b/test/dmt_domain_tests_helper.hrl index 9585bf2..88a1ccc 100644 --- a/test/dmt_domain_tests_helper.hrl +++ b/test/dmt_domain_tests_helper.hrl @@ -2,7 +2,7 @@ -define(dmt_domain_tests_helper_included__, yeah). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). -define(dummy_ref(ID), {dummy, #domain_DummyRef{id = ID}}). -define(dummy_link_ref(ID), {dummy_link, #domain_DummyLinkRef{id = ID}}). @@ -54,9 +54,9 @@ }} ). --define(insert(O), {insert, #'InsertOp'{object = O}}). --define(remove(O), {remove, #'RemoveOp'{object = O}}). --define(update(O1, O2), {update, #'UpdateOp'{old_object = O1, new_object = O2}}). +-define(insert(O), {insert, #domain_conf_InsertOp{object = O}}). +-define(remove(O), {remove, #domain_conf_RemoveOp{object = O}}). +-define(update(O1, O2), {update, #domain_conf_UpdateOp{old_object = O1, new_object = O2}}). -define(set(L), (begin