package controller import ( "context" "os" "testing" "github.com/gravitl/netmaker/db" "github.com/gravitl/netmaker/orchestrator" "github.com/gravitl/netmaker/pro/orchestrator/extensions" "github.com/gravitl/netmaker/schema" "github.com/gravitl/netmaker/scope" "gorm.io/gorm" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" "github.com/stretchr/testify/assert" ) type NetworkValidationTestCase struct { testname string network schema.Network errMessage string } var defaultTenantID string func TestMain(m *testing.M) { db.InitializeDB(schema.ListModels()...) defer db.CloseDB() defaultOrg := schema.Organization{} if err := defaultOrg.CreateDefault(db.WithContext(context.TODO())); err != nil { // CreateDefault sets ID before the failed insert; GetDefault must run // on a fresh struct or gorm.First will AND in the stale ID and never match. defaultOrg = schema.Organization{} _ = defaultOrg.GetDefault(db.WithContext(context.TODO())) } defaultTenant := schema.Tenant{ OrganizationID: defaultOrg.ID, } if err := defaultTenant.CreateDefault(db.WithContext(context.TODO())); err != nil { defaultTenant = schema.Tenant{} _ = defaultTenant.GetDefault(db.WithContext(context.TODO())) } orchestrator.InitializeRepository(extensions.NewProFactory()) defaultTenantID = defaultTenant.ID ctx := scope.WithContext(db.WithContext(context.TODO()), scope.TenantScope, defaultTenant.ID) _ = orchestrator.GetRepository().UserOrchestrator().CreateUser(ctx, &schema.User{ Username: "admin", Password: "password", PlatformRoleID: schema.SuperAdminRole, }) peerUpdate := make(chan *models.Node) go logic.ManageZombies(context.Background()) go func() { for update := range peerUpdate { //do nothing logger.Log(3, "received node update", update.Action) } }() os.Exit(m.Run()) } func TestCreateNetwork(t *testing.T) { deleteAllNetworks() var network schema.Network network.Name = "skynet1" network.TenantID = defaultTenantID network.AddressRange = "10.10.0.1/24" // if tests break - check here (removed displayname) //network.DisplayName = "mynetwork" ctx := scope.WithContext(db.WithContext(context.TODO()), scope.TenantScope, defaultTenantID) err := logic.CreateNetwork(ctx, &network) assert.Nil(t, err) } func TestGetNetwork(t *testing.T) { createNet() ctx := scope.WithContext(db.WithContext(context.TODO()), scope.TenantScope, defaultTenantID) t.Run("GetExistingNetwork", func(t *testing.T) { network := &schema.Network{Name: "skynet"} err := network.Get(ctx) assert.Nil(t, err) assert.Equal(t, "skynet", network.Name) }) t.Run("GetNonExistantNetwork", func(t *testing.T) { network := &schema.Network{Name: "doesnotexist"} err := network.Get(ctx) assert.EqualError(t, err, gorm.ErrRecordNotFound.Error()) assert.Equal(t, "", network.ID) }) } func TestDeleteNetwork(t *testing.T) { createNet() //create nodes t.Run("NetworkwithNodes", func(t *testing.T) { }) t.Run("DeleteExistingNetwork", func(t *testing.T) { doneCh := make(chan struct{}, 1) err := logic.DeleteNetwork(scope.WithContext(db.WithContext(context.Background()), scope.TenantScope, defaultTenantID), "skynet", false, doneCh) assert.Nil(t, err) }) t.Run("NonExistentNetwork", func(t *testing.T) { doneCh := make(chan struct{}, 1) err := logic.DeleteNetwork(scope.WithContext(db.WithContext(context.Background()), scope.TenantScope, defaultTenantID), "skynet", false, doneCh) assert.Nil(t, err) }) createNetv1("test") t.Run("ForceDeleteNetwork", func(t *testing.T) { doneCh := make(chan struct{}, 1) err := logic.DeleteNetwork(scope.WithContext(db.WithContext(context.Background()), scope.TenantScope, defaultTenantID), "test", true, doneCh) assert.Nil(t, err) }) } func TestValidateNetwork(t *testing.T) { //t.Skip() //This functions is not called by anyone //it panics as validation function 'display_name_valid' is not defined //yes := true //no := false //deleteNet(t) //DeleteNetworks cases := []NetworkValidationTestCase{ { testname: "InvalidAddress", network: schema.Network{ Name: "skynet", AddressRange: "10.0.0.256", }, errMessage: "invalid CIDR address: 10.0.0.256", }, { testname: "InvalidAddress6", network: schema.Network{ Name: "skynet1", AddressRange6: "2607::ffff/130", }, errMessage: "invalid CIDR address: 2607::ffff/130", }, { testname: "InvalidNetID", network: schema.Network{ Name: "with spaces", }, errMessage: "invalid character(s) in network name", }, { testname: "NetIDTooLong", network: schema.Network{ Name: "LongNetIDNameForMaxCharactersTest", }, errMessage: "network name cannot be longer than 32 characters", }, { testname: "KeepAliveTooBig", network: schema.Network{ Name: "skynet", DefaultKeepAlive: 1010, }, errMessage: "default keep alive must be less than 1000", }, } ctx := scope.WithContext(db.WithContext(context.TODO()), scope.TenantScope, defaultTenantID) for _, tc := range cases { t.Run(tc.testname, func(t *testing.T) { t.Log(tc.testname) network := tc.network err := logic.ValidateNetwork(ctx, &network, false) assert.NotNil(t, err) assert.Contains(t, err.Error(), tc.errMessage) // test passes if err.Error() contains the expected errMessage. }) } } func deleteAllNetworks() { deleteAllNodes() ctx := scope.WithContext(db.WithContext(context.TODO()), scope.TenantScope, defaultTenantID) _networks, _ := (&schema.Network{}).ListAll(ctx) for _, _network := range _networks { _ = _network.Delete(ctx) } } func createNet() { ctx := scope.WithContext(db.WithContext(context.TODO()), scope.TenantScope, defaultTenantID) var network schema.Network network.Name = "skynet" network.AddressRange = "10.0.0.1/24" network.TenantID = defaultTenantID err := (&schema.Network{Name: "skynet"}).Get(ctx) if err != nil { logic.CreateNetwork(ctx, &network) } } func createNetv1(netId string) { ctx := scope.WithContext(db.WithContext(context.TODO()), scope.TenantScope, defaultTenantID) var network schema.Network network.Name = netId network.TenantID = defaultTenantID network.AddressRange = "100.0.0.1/24" err := (&schema.Network{Name: netId}).Get(ctx) if err != nil { logic.CreateNetwork(ctx, &network) } }