package api import ( "context" "net" "os" "testing" "time" cpb "code.fbi.h-da.de/danet/api/go/gosdn/core" ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" "code.fbi.h-da.de/danet/gosdn/mocks" nbi "code.fbi.h-da.de/danet/gosdn/northbound/server" "code.fbi.h-da.de/danet/gosdn/nucleus" "code.fbi.h-da.de/danet/gosdn/nucleus/util/proto" "code.fbi.h-da.de/danet/yang-models/generated/openconfig" "github.com/google/uuid" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/mock" "google.golang.org/grpc" "google.golang.org/grpc/test/bufconn" gpb "github.com/openconfig/gnmi/proto/gnmi" pb "google.golang.org/protobuf/proto" ) /* Based on this StackOverflow answer: https://stackoverflow.com/a/52080545/4378176 */ const bufSize = 1024 * 1024 const bufnet = "bufnet" const pndID = "2043519e-46d1-4963-9a8e-d99007e104b8" const changeID = "0992d600-f7d4-4906-9559-409b04d59a5f" const sbiID = "f6fd4b35-f039-4111-9156-5e4501bb8a5a" const ondID = "7e0ed8cc-ebf5-46fa-9794-741494914883" var pndStore *nucleus.PndStore var sbiStore *nucleus.SbiStore var lis *bufconn.Listener var pndUUID uuid.UUID var sbiUUID uuid.UUID func bootstrapUnitTest() { dialOptions = []grpc.DialOption{ grpc.WithContextDialer(bufDialer), grpc.WithInsecure(), } lis = bufconn.Listen(bufSize) s := grpc.NewServer() pndStore = nucleus.NewPndStore() sbiStore = nucleus.NewSbiStore() changeUUID, err := uuid.Parse(changeID) if err != nil { log.Fatal(err) } pndUUID, err = uuid.Parse(pndID) if err != nil { log.Fatal(err) } sbiUUID, err = uuid.Parse(sbiID) if err != nil { log.Fatal(err) } deviceUUID, err := uuid.Parse(ondID) if err != nil { log.Fatal(err) } mockChange := &mocks.Change{} mockChange.On("Age").Return(time.Hour) mockChange.On("State").Return(ppb.Change_INCONSISTENT) mockPnd := mocks.NetworkDomain{} mockPnd.On("ID").Return(pndUUID) mockPnd.On("GetName").Return("test") mockPnd.On("GetDescription").Return("test") mockPnd.On("PendingChanges").Return([]uuid.UUID{changeUUID}) mockPnd.On("CommittedChanges").Return([]uuid.UUID{changeUUID}) mockPnd.On("GetChange", mock.Anything).Return(mockChange, nil) mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil) mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.CommonDevice{ UUID: deviceUUID, GoStruct: &openconfig.Device{}, }, nil) mockPnd.On("Commit", mock.Anything).Return(nil) mockPnd.On("Confirm", mock.Anything).Return(nil) mockPnd.On("Devices").Return([]uuid.UUID{deviceUUID}) mockPnd.On("GetSBIs").Return(sbiStore) mockPnd.On("ChangeOND", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(uuid.Nil, nil) if err := pndStore.Add(&mockPnd); err != nil { log.Fatal(err) } northbound := nbi.NewNBI(pndStore) cpb.RegisterCoreServer(s, northbound.Core) ppb.RegisterPndServer(s, northbound.Pnd) go func() { if err := s.Serve(lis); err != nil { log.Fatalf("Server exited with error: %v", err) } }() } func bufDialer(context.Context, string) (net.Conn, error) { return lis.Dial() } const unreachable = "203.0.113.10:6030" const testPath = "/system/config/hostname" var testAddress = "141.100.70.170:6030" var testAPIEndpoint = "gosdn-latest.apps.ocp.fbi.h-da.de" var testUsername = "admin" var testPassword = "arista" var opt *tpb.TransportOption var gnmiMessages map[string]pb.Message func TestMain(m *testing.M) { bootstrapUnitTest() bootstrapIntegrationTest() os.Exit(m.Run()) } func bootstrapIntegrationTest() { if os.Getenv("GOSDN_LOG") == "nolog" { log.SetLevel(log.PanicLevel) } addr := os.Getenv("GOSDN_TEST_ENDPOINT") if addr != "" { testAddress = addr log.Infof("GOSDN_TEST_ENDPOINT set to %v", testAddress) } api := os.Getenv("GOSDN_TEST_API_ENDPOINT") if api != "" { testAPIEndpoint = api log.Infof("GOSDN_TEST_API_ENDPOINT set to %v", testAPIEndpoint) } u := os.Getenv("GOSDN_TEST_USER") if u != "" { testUsername = u log.Infof("GOSDN_TEST_USER set to %v", testUsername) } p := os.Getenv("GOSDN_TEST_PASSWORD") if p != "" { testPassword = p log.Infof("GOSDN_TEST_PASSWORD set to %v", testPassword) } gnmiMessages = map[string]pb.Message{ "../test/proto/cap-resp-arista-ceos": &gpb.CapabilityResponse{}, "../test/proto/req-full-node": &gpb.GetRequest{}, "../test/proto/req-full-node-arista-ceos": &gpb.GetRequest{}, "../test/proto/req-interfaces-arista-ceos": &gpb.GetRequest{}, "../test/proto/req-interfaces-interface-arista-ceos": &gpb.GetRequest{}, "../test/proto/req-interfaces-wildcard": &gpb.GetRequest{}, "../test/proto/resp-full-node": &gpb.GetResponse{}, "../test/proto/resp-full-node-arista-ceos": &gpb.GetResponse{}, "../test/proto/resp-interfaces-arista-ceos": &gpb.GetResponse{}, "../test/proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{}, "../test/proto/resp-interfaces-wildcard": &gpb.GetResponse{}, "../test/proto/resp-set-system-config-hostname": &gpb.SetResponse{}, } for k, v := range gnmiMessages { if err := proto.Read(k, v); err != nil { log.Fatalf("error parsing %v: %v", k, err) } } opt = &tpb.TransportOption{ Address: testAddress, Username: testUsername, Password: testPassword, } }