emqx_reason_codes_SUITE.erl 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2019 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_reason_codes_SUITE).
  17. -compile(export_all).
  18. -compile(nowarn_export_all).
  19. -include("emqx_mqtt.hrl").
  20. -include_lib("proper/include/proper.hrl").
  21. -include_lib("eunit/include/eunit.hrl").
  22. all() -> emqx_ct:all(?MODULE).
  23. t_prop_name_text(_) ->
  24. ?assert(proper:quickcheck(prop_name_text(), prop_name_text(opts))).
  25. t_prop_compat(_) ->
  26. ?assert(proper:quickcheck(prop_compat(), prop_compat(opts))).
  27. t_prop_connack_error(_) ->
  28. ?assert(proper:quickcheck(prop_connack_error(), default_opts([]))).
  29. prop_name_text(opts) ->
  30. default_opts([{numtests, 1000}]).
  31. prop_name_text() ->
  32. ?FORALL(UnionArgs, union_args(),
  33. is_atom(apply_fun(name, UnionArgs)) andalso
  34. is_binary(apply_fun(text, UnionArgs))).
  35. prop_compat(opts) ->
  36. default_opts([{numtests, 512}]).
  37. prop_compat() ->
  38. ?FORALL(CompatArgs, compat_args(),
  39. begin
  40. Result = apply_fun(compat, CompatArgs),
  41. is_number(Result) orelse Result =:= undefined
  42. end).
  43. prop_connack_error() ->
  44. ?FORALL(CONNACK_ERROR_ARGS, connack_error_args(),
  45. is_integer(apply_fun(connack_error, CONNACK_ERROR_ARGS))).
  46. %%--------------------------------------------------------------------
  47. %% Helper
  48. %%--------------------------------------------------------------------
  49. default_opts() ->
  50. default_opts([]).
  51. default_opts(AdditionalOpts) ->
  52. [{to_file, user} | AdditionalOpts].
  53. apply_fun(Fun, Args) ->
  54. apply(emqx_reason_codes, Fun, Args).
  55. %%--------------------------------------------------------------------
  56. %% Generator
  57. %%--------------------------------------------------------------------
  58. union_args() ->
  59. frequency([{6, [real_mqttv3_rc(), mqttv3_version()]},
  60. {43, [real_mqttv5_rc(), mqttv5_version()]}]).
  61. compat_args() ->
  62. frequency([{18, [connack, compat_rc()]},
  63. {2, [suback, compat_rc()]},
  64. {1, [unsuback, compat_rc()]}]).
  65. connack_error_args() ->
  66. [frequency([{10, connack_error()},
  67. {1, unexpected_connack_error()}])].
  68. connack_error() ->
  69. oneof([client_identifier_not_valid,
  70. bad_username_or_password,
  71. bad_clientid_or_password,
  72. username_or_password_undefined,
  73. password_error,
  74. not_authorized,
  75. server_unavailable,
  76. server_busy,
  77. banned,
  78. bad_authentication_method]).
  79. unexpected_connack_error() ->
  80. oneof([who_knows]).
  81. real_mqttv3_rc() ->
  82. frequency([{6, mqttv3_rc()},
  83. {1, unexpected_rc()}]).
  84. real_mqttv5_rc() ->
  85. frequency([{43, mqttv5_rc()},
  86. {2, unexpected_rc()}]).
  87. compat_rc() ->
  88. frequency([{95, ?SUCHTHAT(RC , mqttv5_rc(), RC >= 16#80 orelse RC =< 2)},
  89. {5, unexpected_rc()}]).
  90. mqttv3_rc() ->
  91. oneof(mqttv3_rcs()).
  92. mqttv5_rc() ->
  93. oneof(mqttv5_rcs()).
  94. unexpected_rc() ->
  95. oneof(unexpected_rcs()).
  96. mqttv3_rcs() ->
  97. [0, 1, 2, 3, 4, 5].
  98. mqttv5_rcs() ->
  99. [16#00, 16#01, 16#02, 16#04, 16#10, 16#11, 16#18, 16#19,
  100. 16#80, 16#81, 16#82, 16#83, 16#84, 16#85, 16#86, 16#87,
  101. 16#88, 16#89, 16#8A, 16#8B, 16#8C, 16#8D, 16#8E, 16#8F,
  102. 16#90, 16#91, 16#92, 16#93, 16#94, 16#95, 16#96, 16#97,
  103. 16#98, 16#99, 16#9A, 16#9B, 16#9C, 16#9D, 16#9E, 16#9F,
  104. 16#A0, 16#A1, 16#A2].
  105. unexpected_rcs() ->
  106. ReasonCodes = mqttv3_rcs() ++ mqttv5_rcs(),
  107. Unexpected = lists:seq(0, 16#FF) -- ReasonCodes,
  108. lists:sublist(Unexpected, 5).
  109. mqttv5_version() ->
  110. ?MQTT_PROTO_V5.
  111. mqttv3_version() ->
  112. oneof([?MQTT_PROTO_V3, ?MQTT_PROTO_V4]).