prop_emqx_reason_codes.erl 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020-2024 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(prop_emqx_reason_codes).
  17. -include_lib("emqx/include/emqx_mqtt.hrl").
  18. -include_lib("proper/include/proper.hrl").
  19. %%--------------------------------------------------------------------
  20. %% Properties
  21. %%--------------------------------------------------------------------
  22. prop_name_text() ->
  23. ?FORALL(
  24. UnionArgs,
  25. union_args(),
  26. is_atom(apply_fun(name, UnionArgs)) andalso
  27. is_binary(apply_fun(text, UnionArgs))
  28. ).
  29. prop_compat() ->
  30. ?FORALL(
  31. CompatArgs,
  32. compat_args(),
  33. begin
  34. Result = apply_fun(compat, CompatArgs),
  35. is_number(Result) orelse Result =:= undefined
  36. end
  37. ).
  38. prop_connack_error() ->
  39. ?FORALL(
  40. CONNACK_ERROR_ARGS,
  41. connack_error_args(),
  42. is_integer(apply_fun(connack_error, CONNACK_ERROR_ARGS))
  43. ).
  44. %%--------------------------------------------------------------------
  45. %% Helper
  46. %%--------------------------------------------------------------------
  47. apply_fun(Fun, Args) ->
  48. apply(emqx_reason_codes, Fun, Args).
  49. %%--------------------------------------------------------------------
  50. %% Generator
  51. %%--------------------------------------------------------------------
  52. union_args() ->
  53. frequency([
  54. {6, [real_mqttv3_rc(), mqttv3_version()]},
  55. {43, [real_mqttv5_rc(), mqttv5_version()]}
  56. ]).
  57. compat_args() ->
  58. frequency([
  59. {18, [connack, compat_rc()]},
  60. {2, [suback, compat_rc()]},
  61. {1, [unsuback, compat_rc()]}
  62. ]).
  63. connack_error_args() ->
  64. [
  65. frequency([
  66. {10, connack_error()},
  67. {1, unexpected_connack_error()}
  68. ])
  69. ].
  70. connack_error() ->
  71. oneof([
  72. client_identifier_not_valid,
  73. bad_username_or_password,
  74. bad_clientid_or_password,
  75. username_or_password_undefined,
  76. password_error,
  77. not_authorized,
  78. server_unavailable,
  79. server_busy,
  80. banned,
  81. bad_authentication_method
  82. ]).
  83. unexpected_connack_error() ->
  84. oneof([who_knows]).
  85. real_mqttv3_rc() ->
  86. frequency([
  87. {6, mqttv3_rc()},
  88. {1, unexpected_rc()}
  89. ]).
  90. real_mqttv5_rc() ->
  91. frequency([
  92. {43, mqttv5_rc()},
  93. {2, unexpected_rc()}
  94. ]).
  95. compat_rc() ->
  96. frequency([
  97. {95, ?SUCHTHAT(RC, mqttv5_rc(), RC >= 16#80 orelse RC =< 2)},
  98. {5, unexpected_rc()}
  99. ]).
  100. mqttv3_rc() ->
  101. oneof(mqttv3_rcs()).
  102. mqttv5_rc() ->
  103. oneof(mqttv5_rcs()).
  104. unexpected_rc() ->
  105. oneof(unexpected_rcs()).
  106. mqttv3_rcs() ->
  107. [0, 1, 2, 3, 4, 5].
  108. mqttv5_rcs() ->
  109. [
  110. 16#00,
  111. 16#01,
  112. 16#02,
  113. 16#04,
  114. 16#10,
  115. 16#11,
  116. 16#18,
  117. 16#19,
  118. 16#80,
  119. 16#81,
  120. 16#82,
  121. 16#83,
  122. 16#84,
  123. 16#85,
  124. 16#86,
  125. 16#87,
  126. 16#88,
  127. 16#89,
  128. 16#8A,
  129. 16#8B,
  130. 16#8C,
  131. 16#8D,
  132. 16#8E,
  133. 16#8F,
  134. 16#90,
  135. 16#91,
  136. 16#92,
  137. 16#93,
  138. 16#94,
  139. 16#95,
  140. 16#96,
  141. 16#97,
  142. 16#98,
  143. 16#99,
  144. 16#9A,
  145. 16#9B,
  146. 16#9C,
  147. 16#9D,
  148. 16#9E,
  149. 16#9F,
  150. 16#A0,
  151. 16#A1,
  152. 16#A2
  153. ].
  154. unexpected_rcs() ->
  155. ReasonCodes = mqttv3_rcs() ++ mqttv5_rcs(),
  156. Unexpected = lists:seq(0, 16#FF) -- ReasonCodes,
  157. lists:sublist(Unexpected, 5).
  158. mqttv5_version() ->
  159. ?MQTT_PROTO_V5.
  160. mqttv3_version() ->
  161. oneof([?MQTT_PROTO_V3, ?MQTT_PROTO_V4]).