emqx/test/props/prop_emqx_reason_codes.erl

124 lines
3.8 KiB
Erlang

%%--------------------------------------------------------------------
%% Copyright (c) 2020 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(prop_emqx_reason_codes).
-include("emqx_mqtt.hrl").
-include_lib("proper/include/proper.hrl").
%%--------------------------------------------------------------------
%% Properties
%%--------------------------------------------------------------------
prop_name_text() ->
?FORALL(UnionArgs, union_args(),
is_atom(apply_fun(name, UnionArgs)) andalso
is_binary(apply_fun(text, UnionArgs))).
prop_compat() ->
?FORALL(CompatArgs, compat_args(),
begin
Result = apply_fun(compat, CompatArgs),
is_number(Result) orelse Result =:= undefined
end).
prop_connack_error() ->
?FORALL(CONNACK_ERROR_ARGS, connack_error_args(),
is_integer(apply_fun(connack_error, CONNACK_ERROR_ARGS))).
%%--------------------------------------------------------------------
%% Helper
%%--------------------------------------------------------------------
apply_fun(Fun, Args) ->
apply(emqx_reason_codes, Fun, Args).
%%--------------------------------------------------------------------
%% Generator
%%--------------------------------------------------------------------
union_args() ->
frequency([{6, [real_mqttv3_rc(), mqttv3_version()]},
{43, [real_mqttv5_rc(), mqttv5_version()]}]).
compat_args() ->
frequency([{18, [connack, compat_rc()]},
{2, [suback, compat_rc()]},
{1, [unsuback, compat_rc()]}]).
connack_error_args() ->
[frequency([{10, connack_error()},
{1, unexpected_connack_error()}])].
connack_error() ->
oneof([client_identifier_not_valid,
bad_username_or_password,
bad_clientid_or_password,
username_or_password_undefined,
password_error,
not_authorized,
server_unavailable,
server_busy,
banned,
bad_authentication_method]).
unexpected_connack_error() ->
oneof([who_knows]).
real_mqttv3_rc() ->
frequency([{6, mqttv3_rc()},
{1, unexpected_rc()}]).
real_mqttv5_rc() ->
frequency([{43, mqttv5_rc()},
{2, unexpected_rc()}]).
compat_rc() ->
frequency([{95, ?SUCHTHAT(RC , mqttv5_rc(), RC >= 16#80 orelse RC =< 2)},
{5, unexpected_rc()}]).
mqttv3_rc() ->
oneof(mqttv3_rcs()).
mqttv5_rc() ->
oneof(mqttv5_rcs()).
unexpected_rc() ->
oneof(unexpected_rcs()).
mqttv3_rcs() ->
[0, 1, 2, 3, 4, 5].
mqttv5_rcs() ->
[16#00, 16#01, 16#02, 16#04, 16#10, 16#11, 16#18, 16#19,
16#80, 16#81, 16#82, 16#83, 16#84, 16#85, 16#86, 16#87,
16#88, 16#89, 16#8A, 16#8B, 16#8C, 16#8D, 16#8E, 16#8F,
16#90, 16#91, 16#92, 16#93, 16#94, 16#95, 16#96, 16#97,
16#98, 16#99, 16#9A, 16#9B, 16#9C, 16#9D, 16#9E, 16#9F,
16#A0, 16#A1, 16#A2].
unexpected_rcs() ->
ReasonCodes = mqttv3_rcs() ++ mqttv5_rcs(),
Unexpected = lists:seq(0, 16#FF) -- ReasonCodes,
lists:sublist(Unexpected, 5).
mqttv5_version() ->
?MQTT_PROTO_V5.
mqttv3_version() ->
oneof([?MQTT_PROTO_V3, ?MQTT_PROTO_V4]).