@@ -414,3 +414,64 @@ func TestGRPCHealthCheckUnimplemented(t *testing.T) {
414414
415415 checkRegistryResults (expectedResults , mfs , t )
416416}
417+
418+ func TestGrpcSourceIPAddress (t * testing.T ) {
419+
420+ ln , err := net .Listen ("tcp" , "localhost:0" )
421+ if err != nil {
422+ t .Fatalf ("Error listening on socket: %s" , err )
423+ }
424+ defer ln .Close ()
425+
426+ _ , port , err := net .SplitHostPort (ln .Addr ().String ())
427+ if err != nil {
428+ t .Fatalf ("Error retrieving port for socket: %s" , err )
429+ }
430+ s := grpc .NewServer ()
431+ healthServer := health .NewServer ()
432+ healthServer .SetServingStatus ("service" , grpc_health_v1 .HealthCheckResponse_SERVING )
433+ grpc_health_v1 .RegisterHealthServer (s , healthServer )
434+
435+ go func () {
436+ if err := s .Serve (ln ); err != nil {
437+ t .Errorf ("failed to serve: %v" , err )
438+ return
439+ }
440+ }()
441+ defer s .GracefulStop ()
442+
443+ ifaces , err := net .Interfaces ()
444+ if err != nil {
445+ t .Fatalf ("Error retrieving network interfaces: %s" , err )
446+ }
447+ for _ , iface := range ifaces {
448+ addrs , err := iface .Addrs ()
449+ if err != nil {
450+ t .Fatalf ("Error retrieving addrs from iface %s: %s" , iface .Name , err )
451+ }
452+ for _ , addr := range addrs {
453+ var ip net.IP
454+ switch v := addr .(type ) {
455+ case * net.IPNet :
456+ ip = v .IP
457+ case * net.IPAddr :
458+ ip = v .IP
459+ }
460+ // Skipping IPv6 addrs
461+ if ip .To4 () == nil {
462+ continue
463+ }
464+ registry := prometheus .NewRegistry ()
465+ testCTX , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
466+ defer cancel ()
467+ result := ProbeGRPC (testCTX , "localhost:" + port ,
468+ config.Module {Timeout : time .Second , GRPC : config.GRPCProbe {
469+ IPProtocolFallback : false ,
470+ SourceIPAddress : ip .String (),
471+ }}, registry , log .NewNopLogger ())
472+ if result != true {
473+ t .Fatalf ("Test %s had unexpected result" , ip .String ())
474+ }
475+ }
476+ }
477+ }
0 commit comments