Merge pull request #6691 from k32/bpapi-run-check

test(bpapi): Run static checks in CI
This commit is contained in:
k32 2022-01-11 13:25:06 +01:00 committed by GitHub
commit 6a1ada8623
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 45 deletions

View File

@ -71,6 +71,10 @@ jobs:
run: |
make ${EMQX_NAME}-zip
.ci/build_packages/tests.sh "$EMQX_PKG_NAME" zip
- name: run static checks
if: contains(matrix.os, 'ubuntu')
run: |
make static_checks
- name: build and test deb/rpm packages
run: |
make ${EMQX_NAME}-pkg

View File

@ -1,39 +0,0 @@
name: Run static checks
concurrency:
group: static-check-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: true
on:
schedule:
- cron: '0 */6 * * *'
push:
tags:
- v*
- e*
workflow_dispatch:
jobs:
run_static_analysis:
runs-on: self-hosted
strategy:
fail-fast: false
matrix:
include:
- branch: "master"
container: "ghcr.io/emqx/emqx-builder/5.0-3:24.1.5-3-alpine3.14"
- branch: "main-v4.4"
container: "ghcr.io/emqx/emqx-builder/4.4-4:24.1.5-3-ubuntu20.04"
- branch: "main-v4.3"
container: "emqx/build-env:erl23.2.7.2-emqx-3-ubuntu20.04"
container: ${{ matrix.container }}
steps:
- uses: actions/checkout@v2
with:
ref: ${{ matrix.branch }}
- name: xref
run: make xref
- name: dialyzer
run: make dialyzer

View File

@ -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

View File

@ -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")).

View File

@ -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()).

View File

@ -27,7 +27,7 @@
]}.
{dialyzer, [
{warnings, [unmatched_returns, error_handling, race_conditions]},
{warnings, [unmatched_returns, error_handling]},
{plt_location, "."},
{plt_prefix, "emqx_dialyzer"},
{plt_apps, all_apps},