1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2013-2015. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%% 22%% Test service and transport config. In particular, of the detection 23%% of config errors. 24%% 25 26-module(diameter_config_SUITE). 27 28-export([suite/0, 29 all/0]). 30 31%% testcases 32-export([start/1, 33 start_service/1, 34 add_transport/1, 35 stop/1]). 36 37-define(util, diameter_util). 38 39%% Lists of {Key, GoodConfigList, BadConfigList} with which to 40%% configure. 41 42-define(SERVICE_CONFIG, 43 [{application, 44 [[[{dictionary, diameter_gen_base_rfc6733}, 45 {module, ?MODULE}]] 46 | [[[{dictionary, D}, 47 {module, M}, 48 {alias, A}, 49 {state, S}, 50 {answer_errors, AE}, 51 {request_errors, RE}, 52 {call_mutates_state, C}]] 53 || D <- [diameter_gen_base_rfc3588, diameter_gen_base_rfc6733], 54 M <- [?MODULE, [?MODULE, diameter_lib:now()]], 55 A <- [0, common, make_ref()], 56 S <- [[], make_ref()], 57 AE <- [report, callback, discard], 58 RE <- [answer_3xxx, answer, callback], 59 C <- [true, false]]], 60 [[x], 61 [[]], 62 [[{dictionary, diameter_gen_base_rfc3588}]], 63 [[{module, ?MODULE}]] 64 | [[[{dictionary, diameter_gen_base_rfc6733}, 65 {module, ?MODULE}, 66 {K,x}]] 67 || K <- [answer_errors, 68 request_errors, 69 call_mutates_state]]]}, 70 {restrict_connections, 71 [[false], [node], [nodes], [[node(), node()]]], 72 []}, 73 {sequence, 74 [[{0,32}], [{1,31}]], 75 [[{2,31}]]}, 76 {share_peers, 77 [[true], 78 [false], 79 [[node()]]], 80 [[x]]}, 81 {use_shared_peers, 82 [[true], 83 [false], 84 [[node(), node()]]], 85 [[x]]}, 86 {string_decode, 87 [[true], [false]], 88 [[0], [x]]}, 89 {incoming_maxlen, 90 [[0], [65536], [16#FFFFFF]], 91 [[-1], [1 bsl 24], [infinity], [false]]}, 92 {spawn_opt, 93 [[[]], [[monitor, link]]], 94 [[false]]}, 95 {invalid_option, %% invalid service options are rejected 96 [], 97 [[x], 98 [x,x]]}]). 99 100-define(TRANSPORT_CONFIG, 101 [{transport_module, 102 [[?MODULE]], 103 [[[?MODULE]]]}, 104 {transport_config, 105 [[{}, 3000], 106 [{}, infinity]], 107 [[{}, x]]}, 108 {applications, 109 [[[1, a, [x]]]], 110 [[x]]}, 111 {capabilities, 112 [[[{'Origin-Host', "diameter.erlang.org"}]], 113 [[{'Origin-Realm', "erlang.org"}]]] 114 ++ [[[{'Host-IP-Address', L}]] 115 || L <- [[{127,0,0,1}], 116 ["127.0.0.1"], 117 ["127.0.0.1", "FFFF::1", "::1", {1,2,3,4,5,6,7,8}]]] 118 ++ [[[{'Product-Name', N}]] 119 || N <- [["Product", $-, ["Name"]], 120 "Norðurálfa", 121 "ᚠᚢᚦᚨᚱᚲ"]] 122 ++ [[[{K,V}]] 123 || K <- ['Vendor-Id', 124 'Origin-State-Id', 125 'Firmware-Revision'], 126 V <- [0, 256, 16#FFFF]] 127 ++ [[[{K,V}]] 128 || K <- ['Supported-Vendor-Id', 129 'Auth-Application-Id', 130 'Acct-Application-Id', 131 'Inband-Security-Id'], 132 V <- [[17], [0, 256, 16#FFFF]]] 133 ++ [[[{'Vendor-Specific-Application-Id', 134 [[{'Vendor-Id', V}, 135 {'Auth-Application-Id', [0]}, 136 {'Acct-Application-Id', [4]}]]}]] 137 || V <- [1, [1]]], 138 [[x], [[{'Origin-Host', "ᚠᚢᚦᚨᚱᚲ"}]]] 139 ++ [[[{'Host-IP-Address', A}]] 140 || A <- [{127,0,0,1}]] 141 ++ [[[{'Product-Name', N}]] 142 || N <- [x, 1]] 143 ++ [[[{K,V}]] 144 || K <- ['Vendor-Id', 145 'Origin-State-Id', 146 'Firmware-Revision'], 147 V <- [x, [0], -1, 1 bsl 32]] 148 ++ [[[{K,V}]] 149 || K <- ['Supported-Vendor-Id', 150 'Auth-Application-Id', 151 'Acct-Application-Id', 152 'Inband-Security-Id'], 153 V <- [x, 17, [-1], [1 bsl 32]]] 154 ++ [[[{'Vendor-Specific-Application-Id', V}]] 155 || V <- [x, 156 [[{'Vendor-Id', 1 bsl 32}]], 157 [[{'Auth-Application-Id', 1}]]]]}, 158 {capabilities_cb, 159 [[x]], 160 []}, 161 {capx_timeout, 162 [[3000]], 163 [[{?MODULE, tmo, []}]]}, 164 {disconnect_cb, 165 [[x]], 166 []}, 167 {length_errors, 168 [[exit], [handle], [discard]], 169 [[x]]}, 170 {dpr_timeout, 171 [[0], [3000], [16#FFFFFFFF]], 172 [[infinity], [-1], [1 bsl 32], [x]]}, 173 {dpa_timeout, 174 [[0], [3000], [16#FFFFFFFF]], 175 [[infinity], [-1], [1 bsl 32], [x]]}, 176 {connect_timer, 177 [[3000]], 178 [[infinity]]}, 179 {watchdog_timer, 180 [[3000], 181 [{?MODULE, tmo, []}]], 182 [[infinity], 183 [-1]]}, 184 {watchdog_config, 185 [[[{okay, 0}, {suspect, 0}]], 186 [[{okay, 1}]], 187 [[{suspect, 2}]]], 188 [[x], 189 [[{open, 0}]]]}, 190 {pool_size, 191 [[1], [100]], 192 [[0], [infinity], [-1], [x]]}, 193 {private, 194 [[x]], 195 []}, 196 {spawn_opt, 197 [[[]], [[monitor, link]]], 198 [[false]]}, 199 {invalid_option, %% invalid transport options are silently ignored 200 [[x], 201 [x,x]], 202 []}]). 203 204%% =========================================================================== 205 206suite() -> 207 [{timetrap, {seconds, 60}}]. 208 209all() -> 210 [start, 211 start_service, 212 add_transport, 213 stop]. 214 215%% =========================================================================== 216 217start(_) -> 218 ok = diameter:start(). 219 220start_service(T) 221 when is_tuple(T) -> 222 do(fun start/3, T); 223 224start_service(_) -> 225 [] = ?util:run([{?MODULE, start_service, [T]} 226 || T <- [lists:keyfind(capabilities, 1, ?TRANSPORT_CONFIG) 227 | ?SERVICE_CONFIG]]). 228 229add_transport(T) 230 when is_tuple(T) -> 231 do(fun add/3, T); 232 233add_transport(_) -> 234 [] = ?util:run([{?MODULE, add_transport, [T]} 235 || T <- ?TRANSPORT_CONFIG]). 236 237stop(_) -> 238 ok = diameter:stop(). 239 240%% =========================================================================== 241 242%% do/2 243 244do(F, {Key, Good, Bad}) -> 245 F(Key, Good, Bad). 246 247%% add/3 248 249add(Key, Good, Bad) -> 250 {[],[]} = {[{Vs,T} || Vs <- Good, 251 T <- [add(Key, Vs)], 252 [T] /= [T || {ok,_} <- [T]]], 253 [{Vs,T} || Vs <- Bad, 254 T <- [add(Key, Vs)], 255 [T] /= [T || {error,_} <- [T]]]}. 256 257add(Key, Vs) -> 258 T = list_to_tuple([Key | Vs]), 259 diameter:add_transport(make_ref(), {connect, [T]}). 260 261%% start/3 262 263start(Key, Good, Bad) -> 264 {[],[]} = {[{Vs,T} || Vs <- Good, 265 T <- [start(Key, Vs)], 266 T /= ok], 267 [{Vs,T} || Vs <- Bad, 268 T <- [start(Key, Vs)], 269 [T] /= [T || {error,_} <- [T]]]}. 270 271start(capabilities = K, [Vs]) -> 272 if is_list(Vs) -> 273 start(make_ref(), Vs ++ apps(K)); 274 true -> 275 {error, Vs} 276 end; 277 278start(Key, Vs) 279 when is_atom(Key) -> 280 start(make_ref(), [list_to_tuple([Key | Vs]) | apps(Key)]); 281 282start(SvcName, Opts) -> 283 try 284 diameter:start_service(SvcName, Opts) 285 after 286 diameter:stop_service(SvcName) 287 end. 288 289apps(application) -> 290 []; 291apps(_) -> 292 [{application, [{dictionary, diameter_gen_base_rfc6733}, 293 {module, ?MODULE}]}]. 294