Просмотр исходного кода

test(bpapi): Run verification in CI

k32 4 лет назад
Родитель
Сommit
26f4b2495b

+ 3 - 0
.github/workflows/build_slim_packages.yaml

@@ -52,6 +52,9 @@ jobs:
       run: |
         make ${EMQX_NAME}-zip
         .ci/build_packages/tests.sh "$EMQX_PKG_NAME" zip
+    - name: run static checks
+      run: |
+        make static_checks
     - name: build and test deb/rpm packages
       run: |
         make ${EMQX_NAME}-pkg

+ 4 - 0
Makefile

@@ -55,6 +55,10 @@ proper: $(REBAR)
 ct: $(REBAR) conf-segs
 	@ENABLE_COVER_COMPILE=1 $(REBAR) ct --name $(CT_NODE_NAME) -c -v
 
+.PHONY: static_checks
+static_checks: dialyzer xref
+	@$(REBAR) ct --suite apps/emqx/test/emqx_bpapi_suite --readable false
+
 APPS=$(shell $(CURDIR)/scripts/find-apps.sh)
 
 ## app/name-ct targets are intended for local tests hence cover is not enabled

+ 0 - 0
apps/emqx/priv/.gitkeep


+ 33 - 5
apps/emqx/src/bpapi/emqx_bpapi_static_checks.erl

@@ -16,7 +16,7 @@
 
 -module(emqx_bpapi_static_checks).
 
--export([dump/1, dump/0, check_compat/1]).
+-export([run/0, dump/1, dump/0, check_compat/1]).
 
 -include_lib("emqx/include/logger.hrl").
 
@@ -34,6 +34,10 @@
                      , release    => string()
                      }.
 
+-type dump_options() :: #{ reldir := file:name()
+                         , plt    := file:name()
+                         }.
+
 -type param_types() :: #{emqx_bpapi:var_name() => _Type}.
 
 %% Applications and modules we wish to ignore in the analysis:
@@ -50,6 +54,19 @@
 %% Functions related to BPAPI compatibility checking
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+-spec run() -> boolean().
+run() ->
+    dump(), %% TODO: check return value
+    Dumps = filelib:wildcard(dumps_dir() ++ "/*.bpapi"),
+    case Dumps of
+        [] ->
+            ?ERROR("No BPAPI dumps are found in ~s, abort", [dumps_dir()]),
+            false;
+        _ ->
+            ?NOTICE("Running API compatibility checks for ~p", [Dumps]),
+            check_compat(Dumps)
+    end.
+
 -spec check_compat([file:filename()]) -> boolean().
 check_compat(DumpFilenames) ->
     put(bpapi_ok, true),
@@ -143,15 +160,19 @@ get_param_types(Signatures, {M, F, A}) ->
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 dump() ->
-    case {filelib:wildcard("*_plt"), filelib:wildcard("_build/emqx*/lib")} of
+    case { filelib:wildcard(project_root_dir() ++ "/*_plt")
+         , filelib:wildcard(project_root_dir() ++ "/_build/emqx*/lib")
+         } of
         {[PLT|_], [RelDir|_]} ->
-            dump(#{plt => PLT, reldir => RelDir});
+            dump(#{ plt => PLT
+                  , reldir => RelDir
+                  });
         _ ->
             error("failed to guess run options")
     end.
 
 %% Collect the local BPAPI modules to a dump file
--spec dump(map()) -> boolean().
+-spec dump(dump_options()) -> boolean().
 dump(Opts) ->
     put(bpapi_ok, true),
     PLT = prepare(Opts),
@@ -207,7 +228,8 @@ is_bpapi_call({Module, _Function, _Arity}) ->
 
 -spec dump_api(fulldump()) -> ok.
 dump_api(Term = #{api := _, signatures := _, release := Release}) ->
-    Filename = filename:join(code:priv_dir(emqx), Release ++ ".bpapi"),
+    Filename = filename:join(dumps_dir(), Release ++ ".bpapi"),
+    ok = filelib:ensure_dir(Filename),
     file:write_file(Filename, io_lib:format("~0p.", [Term])).
 
 -spec collect_bpapis([mfa()]) -> api_dump().
@@ -263,3 +285,9 @@ format_call({M, F, A}) ->
 
 setnok() ->
     put(bpapi_ok, false).
+
+dumps_dir() ->
+    filename:join(project_root_dir(), "apps/emqx/test/emqx_bpapi_suite_data").
+
+project_root_dir() ->
+    string:trim(os:cmd("git rev-parse --show-toplevel")).

+ 34 - 0
apps/emqx/test/emqx_bpapi_suite.erl

@@ -0,0 +1,34 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2022 EMQ Technologies Co., Ltd. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%--------------------------------------------------------------------
+
+-module(emqx_bpapi_suite).
+
+-compile(export_all).
+-compile(nowarn_export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("stdlib/include/assert.hrl").
+
+all() -> emqx_common_test_helpers:all(?MODULE).
+
+init_per_suite(Config) ->
+    Config.
+
+end_per_suite(_Config) ->
+    ok.
+
+t_run_check(_) ->
+    ?assertMatch(true, emqx_bpapi_static_checks:run()).