@@ -221,134 +221,41 @@ start_test_nodes(Testcase, NodeNumber, NodeCount, PeerOptions, Peers)
221221 when NodeNumber =< NodeCount ->
222222 PeerName0 = rabbit_misc :format (" ~s -~b " , [Testcase , NodeNumber ]),
223223 PeerOptions1 = PeerOptions #{name => PeerName0 },
224- ct :pal (" Starting peer with options: ~p " , [PeerOptions1 ]),
225- case catch peer :start (PeerOptions1 ) of
224+ PeerOptions2 = case PeerOptions1 of
225+ #{host := _ } ->
226+ PeerOptions1 ;
227+ #{longnames := true } ->
228+ % % To simulate Erlang long node names, we use a
229+ % % hard-coded IP address that is likely to exist.
230+ % %
231+ % % We can't rely on the host proper network
232+ % % configuration because it appears that several
233+ % % hosts are half-configured (at least some random
234+ % % GitHub workers and Broadcom-managed OSX laptops
235+ % % in the team).
236+ PeerOptions1 #{host => " 127.0.0.1" };
237+ _ ->
238+ PeerOptions1
239+ end ,
240+ ct :pal (" Starting peer with options: ~p " , [PeerOptions2 ]),
241+ case catch peer :start (PeerOptions2 ) of
226242 {ok , PeerPid , PeerName } ->
227243 ct :pal (" Configuring peer '~ts '" , [PeerName ]),
228- setup_test_node (PeerPid , PeerOptions1 ),
244+ setup_test_node (PeerPid , PeerOptions2 ),
229245 Peers1 = Peers #{PeerName => PeerPid },
230246 start_test_nodes (
231247 Testcase , NodeNumber + 1 , NodeCount , PeerOptions , Peers1 );
232- Error1 when not is_map_key (host , PeerOptions1 ) ->
233- ct :pal (" Failed to started peer node:~n "
234- " Options: ~p~n "
235- " Error: ~p " , [PeerOptions1 , Error1 ]),
236- % % At least when running from a Buildbuddy CI worker, the network
237- % % configuration is incomplete and the host lacks an FQDN. This
238- % % breaks the start of an Erlang node with long names.
239- % %
240- % % To work around that, we mess with the network configuration (the
241- % % Erlang node runs as root) and try to determine a hostname we can
242- % % use. We then try again to start the node.
243- case determine_hostname (PeerOptions1 ) of
244- {ok , Host } ->
245- PeerOptions2 = PeerOptions1 #{host => Host },
246- start_test_nodes (
247- Testcase , NodeNumber , NodeCount , PeerOptions2 , Peers );
248- {error , _ } = Error2 ->
249- ct :pal (" Failed to determine a usable hostname:~n "
250- " Options: ~p~n "
251- " Error: ~p " , [PeerOptions1 , Error2 ]),
252- stop_test_nodes (Peers ),
253- erlang :throw (Error2 )
254- end ;
255248 Error ->
256249 ct :pal (" Failed to started peer node:~n "
257250 " Options: ~p~n "
258- " Error: ~p " , [PeerOptions1 , Error ]),
251+ " Error: ~p " , [PeerOptions2 , Error ]),
259252 stop_test_nodes (Peers ),
260253 erlang :throw (Error )
261254 end ;
262255start_test_nodes (_Testcase , _NodeNumber , _Count , _PeerOptions , Peers ) ->
263256 ct :pal (" Peers: ~p " , [Peers ]),
264257 Peers .
265258
266- determine_hostname (PeerOptions ) ->
267- % % Please wear eye protection glasses to read what's next!
268- % %
269- % % The Buildbuddy CI worker network configuration lacks an FQDN and we need
270- % % one to start an Erlang node with a long name. To work around this, we
271- % % modify `/etc/hosts' to add an FQDN for 127.0.0.1 and ::1.
272- % %
273- % % 1. We read the existing file
274- % % 2. We modify it to add the FQDN
275- % % 3. We write the modified file
276- % % 4. We put a coin in the swear jar
277- HostsFilename = " /etc/hosts" ,
278- case file :read_file (HostsFilename ) of
279- {ok , HostsFile } ->
280- HostsFile1 = re :replace (
281- HostsFile ,
282- " ^(127\\ .0\\ .0\\ .1|::1)\\ s+.*" ,
283- " & localhost.my.domain" ,
284- [{return , binary }, multiline , global ]),
285- ct :pal (
286- " Changing ~s from:~n "
287- " ---8<---~n "
288- " ~s "
289- " ---8<---~n "
290- " to:~n "
291- " ---8<---~n "
292- " ~s "
293- " ---8<---~n " ,
294- [HostsFilename , HostsFile , HostsFile1 ]),
295- case file :write_file (HostsFilename , HostsFile1 ) of
296- ok -> determine_hostname1 (PeerOptions );
297- {error , _ } = Error -> Error
298- end ;
299- {error , _ } = Error ->
300- Error
301- end .
302-
303- determine_hostname1 (PeerOptions ) ->
304- % % Now that we proudly have an FQDN, we query the IP
305- % % addresses and get the hostname(s) associated with each.
306- % %
307- % % In the end, we return the first hostname that matches
308- % % the short/long name criteria.
309- case inet :getifaddrs () of
310- {ok , IFaces } ->
311- ct :pal (" Network interfaces: ~p " , [IFaces ]),
312- IPv4Addrs = [IPv4Addr
313- || {_Name , Props } <- IFaces ,
314- {addr , IPv4Addr } <- Props ,
315- is_tuple (IPv4Addr ) andalso size (IPv4Addr ) =:= 4 ],
316- ct :pal (" IPv4 addresses: ~p " , [IPv4Addrs ]),
317- determine_hostname2 (IPv4Addrs , PeerOptions );
318- {error , _ } = Error ->
319- Error
320- end .
321-
322- determine_hostname2 ([IPv4Addr | Rest ], PeerOptions ) ->
323- WantFQDN = maps :get (longnames , PeerOptions , false ),
324- case inet :gethostbyaddr (IPv4Addr ) of
325- {ok , # hostent {h_name = FQDN , h_aliases = ShortDNs }} ->
326- AllDNs = [FQDN | ShortDNs ],
327- ct :pal (
328- " All domain names for IPv4 address ~p : ~p " ,
329- [IPv4Addr , AllDNs ]),
330- ValidDNs = lists :filter (
331- fun (DN ) ->
332- lists :member ($. , DN ) =:= WantFQDN
333- end , AllDNs ),
334- ct :pal (
335- " Valid domain names for IPv4 address ~p : ~p " ,
336- [IPv4Addr , ValidDNs ]),
337- case ValidDNs of
338- [DN | _ ] ->
339- {ok , DN };
340- [] ->
341- ct :pal (
342- " No valid hostnames found for IPv4 ~p : ~p " ,
343- [IPv4Addr , AllDNs ]),
344- determine_hostname2 (Rest , PeerOptions )
345- end ;
346- {error , _ } = Error ->
347- Error
348- end ;
349- determine_hostname2 ([], _PeerOptions ) ->
350- {error , no_valid_hostnames_found }.
351-
352259setup_test_node (PeerPid , PeerOptions ) ->
353260 peer :call (PeerPid , ? MODULE , do_setup_test_node , [PeerOptions ]).
354261
0 commit comments