// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //nolint: testpackage package reg import ( "context" "fmt" "io/ioutil" "net" "os" "testing" "github.com/golang/protobuf/ptypes/empty" "github.com/stretchr/testify/suite" "golang.org/x/sys/unix" "google.golang.org/grpc" "github.com/talos-systems/talos/internal/app/networkd/pkg/networkd" "github.com/talos-systems/talos/pkg/grpc/dialer" "github.com/talos-systems/talos/pkg/grpc/factory" healthapi "github.com/talos-systems/talos/pkg/machinery/api/health" networkapi "github.com/talos-systems/talos/pkg/machinery/api/network" ) type NetworkdSuite struct { suite.Suite } func TestNetworkdSuite(t *testing.T) { suite.Run(t, new(NetworkdSuite)) } // nolint: dupl func (suite *NetworkdSuite) TestRoutes() { _, server, listener := suite.fakeNetworkdRPC() // nolint: errcheck defer os.Remove(listener.Addr().String()) defer server.Stop() // nolint: errcheck go server.Serve(listener) conn, err := grpc.Dial( fmt.Sprintf("%s://%s", "unix", listener.Addr().String()), grpc.WithInsecure(), grpc.WithContextDialer(dialer.DialUnix()), ) suite.Assert().NoError(err) nClient := networkapi.NewNetworkServiceClient(conn) resp, err := nClient.Routes(context.Background(), &empty.Empty{}) suite.Assert().NoError(err) suite.Assert().Greater(len(resp.Messages[0].Routes), 0) } // nolint: dupl func (suite *NetworkdSuite) TestInterfaces() { _, server, listener := suite.fakeNetworkdRPC() // nolint: errcheck defer os.Remove(listener.Addr().String()) defer server.Stop() // nolint: errcheck go server.Serve(listener) conn, err := grpc.Dial( fmt.Sprintf("%s://%s", "unix", listener.Addr().String()), grpc.WithInsecure(), grpc.WithContextDialer(dialer.DialUnix()), ) suite.Assert().NoError(err) nClient := networkapi.NewNetworkServiceClient(conn) resp, err := nClient.Interfaces(context.Background(), &empty.Empty{}) suite.Assert().NoError(err) suite.Assert().Greater(len(resp.Messages[0].Interfaces), 0) } func (suite *NetworkdSuite) fakeNetworkdRPC() (*networkd.Networkd, *grpc.Server, net.Listener) { // Create networkd instance n, err := networkd.New(nil) suite.Assert().NoError(err) // Create gRPC server api := NewRegistrator(n) server := factory.NewServer(api) tmpfile, err := ioutil.TempFile("", "networkd") suite.Assert().NoError(err) listener, err := factory.NewListener( factory.Network("unix"), factory.SocketPath(tmpfile.Name()), ) suite.Assert().NoError(err) return n, server, listener } func (suite *NetworkdSuite) TestToCIDR() { suite.Assert().Equal(toCIDR(unix.AF_INET, net.ParseIP("192.168.254.0"), 24), "192.168.254.0/24") suite.Assert().Equal(toCIDR(unix.AF_INET6, net.ParseIP("2001:db8::"), 16), "2001:db8::/16") suite.Assert().Equal(toCIDR(unix.AF_INET, nil, 0), "0.0.0.0/0") suite.Assert().Equal(toCIDR(unix.AF_INET6, nil, 0), "::/0") } func (suite *NetworkdSuite) TestHealthAPI() { nwd, server, listener := suite.fakeNetworkdRPC() // nolint: errcheck defer os.Remove(listener.Addr().String()) defer server.Stop() // nolint: errcheck go server.Serve(listener) conn, err := grpc.Dial( fmt.Sprintf("%s://%s", "unix", listener.Addr().String()), grpc.WithInsecure(), grpc.WithContextDialer(dialer.DialUnix()), ) suite.Assert().NoError(err) // Verify base state nClient := healthapi.NewHealthClient(conn) hcResp, err := nClient.Check(context.Background(), &empty.Empty{}) suite.Assert().NoError(err) // Can only check against unknown since its not guaranteed that // the host the tests will run on will have an arp table populated. suite.Assert().NotEqual(healthapi.HealthCheck_UNKNOWN, hcResp.Messages[0].Status) rResp, err := nClient.Ready(context.Background(), &empty.Empty{}) suite.Assert().NoError(err) suite.Assert().Equal(healthapi.ReadyCheck_NOT_READY, rResp.Messages[0].Status) // Trigger ready condition nwd.SetReady() suite.Assert().NoError(err) rResp, err = nClient.Ready(context.Background(), &empty.Empty{}) suite.Assert().NoError(err) suite.Assert().Equal(healthapi.ReadyCheck_READY, rResp.Messages[0].Status) // Test watch ctx, cancel := context.WithCancel(context.Background()) stream, err := nClient.Watch(ctx, &healthapi.HealthWatchRequest{IntervalSeconds: 1}) suite.Require().NoError(err) for i := 0; i < 2; i++ { hcResp, err = stream.Recv() suite.Assert().NoError(err) suite.Assert().NotEqual(healthapi.HealthCheck_UNKNOWN, hcResp.Messages[0].Status) } cancel() _, err = stream.Recv() suite.Assert().Error(err) }