1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2019-2020. 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%% This test suite is basically a "placeholder" for a proper test suite... 23%% Also we should really call prim_net directly, and not net (since that does 24%% not even reside here). 25%% 26 27%% Run the entire test suite: 28%% ts:run(emulator, net_SUITE, [batch]). 29%% 30%% Run a specific group: 31%% ts:run(emulator, net_SUITE, {group, foo}, [batch]). 32%% 33%% Run a specific test case: 34%% ts:run(emulator, net_SUITE, foo, [batch]). 35 36-module(net_SUITE). 37 38-include_lib("common_test/include/ct.hrl"). 39-include_lib("common_test/include/ct_event.hrl"). 40 41%% Suite exports 42-export([suite/0, all/0, groups/0]). 43-export([init_per_suite/1, end_per_suite/1, 44 init_per_group/2, end_per_group/2, 45 init_per_testcase/2, end_per_testcase/2]). 46 47%% Test cases 48-export([ 49 %% *** API Basic *** 50 api_b_gethostname/1, 51 api_b_getifaddrs/1, 52 api_b_name_and_addr_info/1, 53 54 api_b_name_and_index/1 55 56 %% Tickets 57 ]). 58 59 60%% -include("socket_test_evaluator.hrl"). 61 62%% Internal exports 63%% -export([]). 64 65 66%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 67 68-define(SLEEP(T), receive after T -> ok end). 69 70-define(FAIL(R), exit(R)). 71 72-define(MINS(M), timer:minutes(M)). 73-define(SECS(S), timer:seconds(S)). 74 75-define(TT(T), ct:timetrap(T)). 76 77 78%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 80suite() -> 81 [{ct_hooks,[ts_install_cth]}, 82 {timetrap,{minutes,1}}]. 83 84all() -> 85 Groups = [{api, "ENET_TEST_API", include}], 86 [use_group(Group, Env, Default) || {Group, Env, Default} <- Groups]. 87 88use_group(Group, Env, Default) -> 89 case os:getenv(Env) of 90 false when (Default =:= include) -> 91 [{group, Group}]; 92 false -> 93 []; 94 Val -> 95 case list_to_atom(string:to_lower(Val)) of 96 Use when (Use =:= include) orelse 97 (Use =:= enable) orelse 98 (Use =:= true) -> 99 [{group, Group}]; 100 _ -> 101 [] 102 end 103 end. 104 105 106groups() -> 107 [{api, [], api_cases()}, 108 {api_basic, [], api_basic_cases()} 109 110 %% {tickets, [], ticket_cases()} 111 ]. 112 113api_cases() -> 114 [ 115 {group, api_basic} 116 ]. 117 118api_basic_cases() -> 119 [ 120 api_b_gethostname, 121 api_b_getifaddrs, 122 api_b_name_and_addr_info, 123 api_b_name_and_index 124 ]. 125 126%% ticket_cases() -> 127%% []. 128 129 130 131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 132 133init_per_suite(Config) -> 134 %% We test on the socket module for simplicity 135 case lists:member(socket, erlang:loaded()) of 136 true -> 137 case os:type() of 138 {win32, _} -> 139 not_yet_implemented(); 140 _ -> 141 %% ?LOGGER:start(), 142 Config 143 end; 144 false -> 145 {skip, "esock disabled"} 146 end. 147 148end_per_suite(_) -> 149 %% ?LOGGER:stop(), 150 ok. 151 152init_per_group(_Group, Config) -> 153 Config. 154 155end_per_group(_Group, Config) -> 156 Config. 157 158 159init_per_testcase(_TC, Config) -> 160 Config. 161 162end_per_testcase(_TC, Config) -> 163 Config. 164 165 166 167%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 168%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 169%% %% 170%% API BASIC %% 171%% %% 172%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 174 175%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 176 177%% Get the hostname of the host. 178api_b_gethostname(suite) -> 179 []; 180api_b_gethostname(doc) -> 181 []; 182api_b_gethostname(_Config) when is_list(_Config) -> 183 ?TT(?SECS(5)), 184 tc_try(api_b_gethostname, 185 fun() -> 186 ok = api_b_gethostname() 187 end). 188 189 190api_b_gethostname() -> 191 case net:gethostname() of 192 {ok, Hostname} -> 193 i("hostname: ~s", [Hostname]), 194 ok; 195 {error, Reason} -> 196 ?FAIL(Reason) 197 end. 198 199 200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 201 202%% This is a *very* basic test. It simply calls the function and expect 203%% it to succeed... 204api_b_getifaddrs(suite) -> 205 []; 206api_b_getifaddrs(doc) -> 207 []; 208api_b_getifaddrs(_Config) when is_list(_Config) -> 209 ?TT(?SECS(5)), 210 tc_try(api_b_getifaddrs, 211 fun() -> 212 ok = api_b_getifaddrs() 213 end). 214 215 216api_b_getifaddrs() -> 217 case net:getifaddrs() of 218 {ok, IfAddrs} -> 219 i("IfAddrs: " 220 "~n ~p", [IfAddrs]), 221 ok; 222 {error, enotsup = Reason} -> 223 skip(Reason); 224 {error, Reason} -> 225 ?FAIL(Reason) 226 end. 227 228 229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 230 231%% Get name and address info. 232api_b_name_and_addr_info(suite) -> 233 []; 234api_b_name_and_addr_info(doc) -> 235 []; 236api_b_name_and_addr_info(_Config) when is_list(_Config) -> 237 ?TT(?SECS(5)), 238 tc_try(api_b_name_and_addr_info, 239 fun() -> 240 ok = api_b_name_and_addr_info() 241 end). 242 243 244api_b_name_and_addr_info() -> 245 Domain = inet, 246 Addr = which_local_addr(Domain), 247 SA = #{family => Domain, addr => Addr}, 248 Hostname = 249 case net:getnameinfo(SA) of 250 {ok, #{host := Name, service := Service} = NameInfo} 251 when is_list(Name) andalso is_list(Service) -> 252 i("getnameinfo: " 253 "~n ~p", [NameInfo]), 254 Name; 255 {ok, BadNameInfo} -> 256 ?FAIL({getnameinfo, SA, BadNameInfo}); 257 {error, Reason1} -> 258 ?FAIL({getnameinfo, SA, Reason1}) 259 end, 260 case net:getaddrinfo(Hostname) of 261 {ok, AddrInfos} when is_list(AddrInfos) -> 262 i("getaddrinfo: " 263 "~n ~p", [AddrInfos]), 264 verify_addr_info(AddrInfos, Domain); 265 {ok, BadAddrInfo} -> 266 ?FAIL({getaddrinfo, Hostname, BadAddrInfo}); 267 {error, Reason2} -> 268 ?FAIL({getaddrinfo, Hostname, Reason2}) 269 end. 270 271 272verify_addr_info(AddrInfos, Domain) when (AddrInfos =/= []) -> 273 verify_addr_info2(AddrInfos, Domain). 274 275verify_addr_info2([], _Domain) -> 276 ok; 277verify_addr_info2([#{addr := #{addr := Addr, 278 family := Domain, 279 port := Port}, 280 family := Domain, 281 type := _Type, 282 protocol := _Proto}|T], Domain) 283 when is_integer(Port) andalso 284 (((Domain =:= inet) andalso is_tuple(Addr) andalso (size(Addr) =:= 4)) orelse 285 ((Domain =:= inet6) andalso is_tuple(Addr) andalso (size(Addr) =:= 8))) -> 286 verify_addr_info2(T, Domain); 287verify_addr_info2([#{family := DomainA}|T], DomainB) 288 when (DomainA =/= DomainB) -> 289 %% Ignore entries for other domains 290 verify_addr_info2(T, DomainB); 291verify_addr_info2([BadAddrInfo|_], Domain) -> 292 ?FAIL({bad_address_info, BadAddrInfo, Domain}). 293 294 295 296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 297 298%% Verify (interface) name and index functions. 299%% if_names/0, 300%% if_name2index/1 301%% if_index2name/1 302api_b_name_and_index(suite) -> 303 []; 304api_b_name_and_index(doc) -> 305 []; 306api_b_name_and_index(_Config) when is_list(_Config) -> 307 ?TT(?SECS(5)), 308 tc_try(api_b_name_and_index, 309 fun() -> 310 ok = api_b_name_and_index() 311 end). 312 313 314api_b_name_and_index() -> 315 Names = 316 case net:if_names() of 317 {ok, N} when is_list(N) andalso (N =/= []) -> 318 N; 319 {error, Reason} -> 320 ?FAIL({if_names, Reason}) 321 end, 322 verify_if_names(Names). 323 324verify_if_names([]) -> 325 ok; 326verify_if_names([{Index, Name}|T]) -> 327 case net:if_name2index(Name) of 328 {ok, Index} -> 329 ok; 330 {ok, BadIndex} -> 331 ?FAIL({name2index, Name, Index, BadIndex}); 332 {error, ReasonN2I} -> 333 ?FAIL({name2index, Name, ReasonN2I}) 334 end, 335 case net:if_index2name(Index) of 336 {ok, Name} -> 337 ok; 338 {ok, BadName} -> 339 ?FAIL({index2name, Index, Name, BadName}); 340 {error, ReasonI2N} -> 341 ?FAIL({index2name, Index, ReasonI2N}) 342 end, 343 verify_if_names(T). 344 345 346 347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 348 349%% local_host() -> 350%% try net_adm:localhost() of 351%% Host when is_list(Host) -> 352%% %% Convert to shortname if long 353%% case string:tokens(Host, [$.]) of 354%% [H|_] -> 355%% list_to_atom(H) 356%% end 357%% catch 358%% C:E:S -> 359%% erlang:raise(C, E, S) 360%% end. 361 362 363%% This gets the local address (not 127.0...) 364%% We should really implement this using the (new) net module, 365%% but until that gets the necessary functionality... 366which_local_addr(Domain) -> 367 case inet:getifaddrs() of 368 {ok, IFL} -> 369 which_addr(Domain, IFL); 370 {error, Reason} -> 371 ?FAIL({inet, getifaddrs, Reason}) 372 end. 373 374which_addr(_Domain, []) -> 375 skip(no_address); 376which_addr(Domain, [{"lo" ++ _, _}|IFL]) -> 377 which_addr(Domain, IFL); 378which_addr(Domain, [{_Name, IFO}|IFL]) -> 379 case which_addr2(Domain, IFO) of 380 {ok, Addr} -> 381 Addr; 382 {error, no_address} -> 383 which_addr(Domain, IFL) 384 end; 385which_addr(Domain, [_|IFL]) -> 386 which_addr(Domain, IFL). 387 388which_addr2(_Domain, []) -> 389 {error, no_address}; 390which_addr2(inet = _Domain, [{addr, Addr}|_IFO]) when (size(Addr) =:= 4) -> 391 {ok, Addr}; 392which_addr2(inet6 = _Domain, [{addr, Addr}|_IFO]) when (size(Addr) =:= 8) -> 393 {ok, Addr}; 394which_addr2(Domain, [_|IFO]) -> 395 which_addr2(Domain, IFO). 396 397 398 399 400 401%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 402 403not_yet_implemented() -> 404 skip("not yet implemented"). 405 406skip(Reason) -> 407 throw({skip, Reason}). 408 409 410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 411 412%% t() -> 413%% os:timestamp(). 414 415 416%% tdiff({A1, B1, C1} = _T1x, {A2, B2, C2} = _T2x) -> 417%% T1 = A1*1000000000+B1*1000+(C1 div 1000), 418%% T2 = A2*1000000000+B2*1000+(C2 div 1000), 419%% T2 - T1. 420 421 422formated_timestamp() -> 423 format_timestamp(os:timestamp()). 424 425format_timestamp({_N1, _N2, _N3} = TS) -> 426 {_Date, Time} = calendar:now_to_local_time(TS), 427 %% {YYYY,MM,DD} = Date, 428 {Hour,Min,Sec} = Time, 429 %% FormatTS = 430 %% io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w.~w", 431 %% [YYYY, MM, DD, Hour, Min, Sec, N3]), 432 FormatTS = io_lib:format("~.2.0w:~.2.0w:~.2.0w", [Hour, Min, Sec]), 433 lists:flatten(FormatTS). 434 435 436%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 437 438set_tc_name(N) when is_atom(N) -> 439 set_tc_name(atom_to_list(N)); 440set_tc_name(N) when is_list(N) -> 441 put(tc_name, N). 442 443%% get_tc_name() -> 444%% get(tc_name). 445 446tc_begin(TC) -> 447 set_tc_name(TC), 448 tc_print("begin ***", 449 "~n----------------------------------------------------~n", ""). 450 451tc_end(Result) when is_list(Result) -> 452 tc_print("done: ~s", [Result], 453 "", "----------------------------------------------------~n~n"), 454 ok. 455 456 457tc_try(Case, Fun) when is_atom(Case) andalso is_function(Fun, 0) -> 458 tc_begin(Case), 459 try 460 begin 461 Fun(), 462 ?SLEEP(?SECS(1)), 463 tc_end("ok") 464 end 465 catch 466 throw:{skip, _} = SKIP -> 467 tc_end("skipping"), 468 SKIP; 469 Class:Error:Stack -> 470 tc_end("failed"), 471 erlang:raise(Class, Error, Stack) 472 end. 473 474 475tc_print(F, Before, After) -> 476 tc_print(F, [], Before, After). 477 478tc_print(F, A, Before, After) -> 479 Name = tc_which_name(), 480 FStr = f("*** [~s][~s][~p] " ++ F ++ "~n", 481 [formated_timestamp(),Name,self()|A]), 482 io:format(user, Before ++ FStr ++ After, []). 483 484tc_which_name() -> 485 case get(tc_name) of 486 undefined -> 487 case get(sname) of 488 undefined -> 489 ""; 490 SName when is_list(SName) -> 491 SName 492 end; 493 Name when is_list(Name) -> 494 Name 495 end. 496 497 498%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 499 500%% l2a(S) when is_list(S) -> 501%% list_to_atom(S). 502 503%% l2b(L) when is_list(L) -> 504%% list_to_binary(L). 505 506%% b2l(B) when is_binary(B) -> 507%% binary_to_list(B). 508 509f(F, A) -> 510 lists:flatten(io_lib:format(F, A)). 511 512 513%% i(F) -> 514%% i(F, []). 515 516i(F, A) -> 517 FStr = f("[~s] " ++ F, [formated_timestamp()|A]), 518 io:format(user, FStr ++ "~n", []), 519 io:format(FStr, []). 520 521