github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/routing/routing_unix_test.go (about)

     1  //go:build !windows
     2  
     3  package routing
     4  
     5  import (
     6  	"net"
     7  	"runtime"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/datawire/dlib/dlog"
    14  	"github.com/telepresenceio/telepresence/v2/pkg/iputil"
    15  )
    16  
    17  func TestGetRouteConsistency(t *testing.T) {
    18  	ctx := dlog.NewTestContext(t, true)
    19  	addresses := map[string]struct{}{
    20  		"192.168.1.23": {},
    21  		"10.0.5.3":     {},
    22  		"127.0.0.1":    {},
    23  		"8.8.8.8":      {},
    24  	}
    25  	table, err := GetRoutingTable(ctx)
    26  	assert.NoError(t, err)
    27  	for _, route := range table {
    28  		if ip := route.RoutedNet.IP.To4(); ip != nil {
    29  			if ip.String() == "0.0.0.0" || ip.IsMulticast() {
    30  				// Don't test 0.0.0.0 or any multicast addresses.
    31  				continue
    32  			}
    33  			dlog.Debugf(ctx, "Adding route %s", route)
    34  			addresses[ip.String()] = struct{}{}
    35  			if n, _ := route.RoutedNet.Mask.Size(); n < 32 {
    36  				ip2 := make(net.IP, len(ip))
    37  				copy(ip2, ip)
    38  				ip2[3]++
    39  				addresses[ip2.String()] = struct{}{}
    40  				dlog.Debugf(ctx, "Adding IP %s", ip2)
    41  			}
    42  		}
    43  	}
    44  	for addr := range addresses {
    45  		t.Run(addr, func(t *testing.T) {
    46  			testNet := &net.IPNet{
    47  				IP:   iputil.Parse(addr),
    48  				Mask: net.CIDRMask(32, 32),
    49  			}
    50  			osRoute, err := getOsRoute(ctx, testNet)
    51  			require.NoError(t, err)
    52  			route, err := GetRoute(ctx, testNet)
    53  			require.NoError(t, err)
    54  			// This is about as much as we can actually assert, because OSs tend to create
    55  			// routes on the fly when, for example, a default route is hit. So there's no guarantee
    56  			// that the matching "original" route in the table will be identical to the route returned on the fly.
    57  			if runtime.GOOS == "linux" && osRoute.Interface.Flags&net.FlagLoopback != 0 && osRoute.LocalIP.Equal(osRoute.RoutedNet.IP) {
    58  				addrs, err := route.Interface.Addrs()
    59  				assert.NoError(t, err)
    60  				assert.True(t, func() bool {
    61  					for _, addr := range addrs {
    62  						if addr.(*net.IPNet).IP.Equal(osRoute.LocalIP) {
    63  							return true
    64  						}
    65  					}
    66  					return false
    67  				}(), "Interface addresses %v don't include route's local IP %s", addrs, osRoute.LocalIP)
    68  			} else {
    69  				require.Equal(t, osRoute.Interface.Index, route.Interface.Index, "Routes %s and %s differ", osRoute, route)
    70  			}
    71  			require.True(t, route.RoutedNet.Contains(osRoute.RoutedNet.IP) || route.Default, "Route %s doesn't route requested IP %s", route, osRoute.RoutedNet.IP)
    72  		})
    73  	}
    74  }