124 lines
3.8 KiB
Erlang
124 lines
3.8 KiB
Erlang
%%--------------------------------------------------------------------
|
|
%% Copyright (c) 2020-2021 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_lib("emqx/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]).
|