diff --git a/dev_env_data/docker-compose/integration-test_docker-compose.yml b/dev_env_data/docker-compose/integration-test_docker-compose.yml index 1a4eb087eaf8b4a6b23bb32c55d968a92e0cd524..daa0080ea70c58853229dfd78c3369c0c6e72da6 100644 --- a/dev_env_data/docker-compose/integration-test_docker-compose.yml +++ b/dev_env_data/docker-compose/integration-test_docker-compose.yml @@ -21,6 +21,7 @@ services: image: rabbitmq:3-management ports: - 127.0.0.1:5672:5672 + - 127.0.0.1:15672:15672 healthcheck: test: rabbitmq-diagnostics -q ping interval: 30s diff --git a/integration-tests/application_tests/appUtility_test.go b/integration-tests/application_tests/appUtility_test.go index d27369612d4d1fbc3a169648132f434c48282a21..a9cd6a726c4fbe7f3b5e9f5ac330bd0aa25f76c5 100644 --- a/integration-tests/application_tests/appUtility_test.go +++ b/integration-tests/application_tests/appUtility_test.go @@ -34,8 +34,6 @@ func NewApplication(ctx context.Context, grpcClientConn *grpc.ClientConn, contro queueCredentials = strings.ReplaceAll(queueCredentials, localhost, rabbitMQAddress) } - logrus.Infof("QUEUE CREDENTIALS: %v", queueCredentials) - eventService, err := event.NewEventService( queueCredentials, topics, @@ -78,5 +76,6 @@ func (a *Application) Run(eventTypeCallbackTuples []event.TypeToCallbackTuple) { } func (a *Application) callback(event *event.Event) { + logrus.Infof("Incoming Event: EntityID: %v, ID: %v, PathsAndValues: %v, Type: %v", event.EntityID, event.ID, event.PathsAndValuesMap, event.Type) a.eventChannel <- *event } diff --git a/integration-tests/application_tests/application_test.go b/integration-tests/application_tests/application_test.go index a0ce732a7f34d22e5af2be871d0a8d7e208aed23..1c5855d1bd2cbfbb4b143c338ac2b52ca96534d2 100644 --- a/integration-tests/application_tests/application_test.go +++ b/integration-tests/application_tests/application_test.go @@ -4,21 +4,35 @@ import ( "context" "fmt" "os" + "reflect" "testing" + "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict" mnepb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement" + apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac" tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport" "code.fbi.h-da.de/danet/gosdn/application-framework/event" integration_test_utils "code.fbi.h-da.de/danet/gosdn/integration-tests/integrationTestUtils" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "google.golang.org/grpc" ) +// Notes: +//When adding tests take into account all the messages that get added to the message +// queue during test setups. So make sure to read from the eventChannel of the application accordingly! +// +// Do not reset test setup in this because it causes weird interactions with the test cases that are hard +// to deal with when writing actual test cases. + const targetAAdress = "gnmi-target_A:7030" const targetUserAndPW = "admin" const pndID = "5f20f34b-cbd0-4511-9ddc-c50cf6a3b49d" const pluginID = "d1c269a2-6482-4010-b0d8-679dff73153b" +const mneID = "9ee7bf15-15ff-44b8-aafa-035487d1e97f" + +const userID = "23224223-aeb6-433b-a797-2d671d7424f0" +const roleID = "679f7982-d740-452e-b78d-c1d133233694" // The connection to the controller to use in each test. var conn *grpc.ClientConn @@ -45,7 +59,8 @@ func TestMain(m *testing.M) { fmt.Println(err.Error()) } - integration_test_utils.ApplySDNConfig(conn, ctx, defaultSDNConfig) + // integration_test_utils.ApplySDNConfig(conn, ctx, defaultSDNConfig) + // integration_test_utils.CleanUserAndRolesExceptAdmin(conn, ctx) topics := []event.Topic{event.ManagedNetworkElement, event.User} @@ -77,16 +92,22 @@ func TestMain(m *testing.M) { } go application.Run(eventTypeCallbackTuples) - asdf := <-application.eventChannel - logrus.Info(asdf) + // This is needed to clear the go channel of the messages sent by RabbitMQ when creating + // and logging in with the admin user. + // Important note: only works once after starting the setup, because first time use creates + // a user and updates it because of the login. After then only logins are done, no user creations. + // This means that this will block after trying once, because the two attempts to read from eventChannel. + _ = <-application.eventChannel + _ = <-application.eventChannel m.Run() } -func TestAddEvent(t *testing.T) { - defer integration_test_utils.ApplySDNConfig(conn, ctx, defaultSDNConfig) - +func TestNetworkElementAddAndSubscribeEvent(t *testing.T) { // setup required parameters + const hostnamePath = "/system/config/hostname" + const domainNamePath = "/system/config/domain-name" + opt := &tpb.TransportOption{ Address: targetAAdress, Username: targetUserAndPW, @@ -101,6 +122,7 @@ func TestAddEvent(t *testing.T) { Timestamp: integration_test_utils.GetTimestamp(), Mne: []*mnepb.SetMne{ { + MneId: mneID, Address: "gnmi-target_A:7030", Pid: pndID, PluginId: pluginID, @@ -121,8 +143,118 @@ func TestAddEvent(t *testing.T) { t.FailNow() } + // check if events are available and correct type and content + addEvent := <-application.eventChannel + assert.Equal(t, event.Add.String(), addEvent.Type) + assert.Equal(t, mneID, addEvent.EntityID.String()) + + subscribeEvent := <-application.eventChannel + assert.Equal(t, event.Subscribe.String(), subscribeEvent.Type) + assert.Equal(t, hostnamePath, reflect.ValueOf(subscribeEvent.PathsAndValuesMap).MapKeys()[0].String(), "Should be hostname path.") + + subscribeEvent = <-application.eventChannel + assert.Equal(t, event.Subscribe.String(), subscribeEvent.Type) + assert.Equal(t, domainNamePath, reflect.ValueOf(subscribeEvent.PathsAndValuesMap).MapKeys()[0].String(), "Should be domain-name path.") +} + +func TestUserAddAndUpdateEvent(t *testing.T) { + // setup required parameters + addUserRequest := &apb.CreateUsersRequest{ + Timestamp: integration_test_utils.GetTimestamp(), + User: []*apb.User{ + { + Id: userID, + Name: "user", + Roles: map[string]string{pndID: "admin"}, + Password: targetUserAndPW, + Metadata: &conflict.Metadata{ + ResourceVersion: 0, + }, + }, + }, + } + + updateUserRequest := &apb.UpdateUsersRequest{ + Timestamp: integration_test_utils.GetTimestamp(), + User: []*apb.UpdateUser{ + { + Id: userID, + Name: "new name", + Metadata: &conflict.Metadata{}, + }, + }, + } + + // setup gRPC services + userService := apb.NewUserServiceClient(conn) + + // add one device to the controller + _, err := userService.CreateUsers(ctx, addUserRequest) + if err != nil { + t.Error(err) + t.FailNow() + } + // check if event is available and correct type addEvent := <-application.eventChannel + assert.Equal(t, event.Add.String(), addEvent.Type) + assert.Equal(t, userID, addEvent.EntityID.String()) + + // update user and check for event + _, err = userService.UpdateUsers(ctx, updateUserRequest) + if err != nil { + t.Error(err) + t.FailNow() + } + + updateEvent := <-application.eventChannel + assert.Equal(t, event.Update.String(), updateEvent.Type) + assert.Equal(t, userID, updateEvent.EntityID.String()) +} + +func TestRoleAddAndDeleteEvent(t *testing.T) { + // setup required parameters + const roleName = "new role" + + addRoleRequest := &apb.CreateRolesRequest{ + Timestamp: integration_test_utils.GetTimestamp(), + Roles: []*apb.Role{ + { + Id: roleID, + Name: roleName, + Description: "well, not much to see here", + Permissions: []string{"some permission"}, + }, + }, + } + + deleteRoleRequest := &apb.DeleteRolesRequest{ + Timestamp: integration_test_utils.GetTimestamp(), + RoleName: []string{roleName}, + } + + // setup gRPC services + roleService := apb.NewRoleServiceClient(conn) + + // add role and check add event + _, err := roleService.CreateRoles(ctx, addRoleRequest) + if err != nil { + t.Error(err) + t.FailNow() + } + + // addEvent := <-application.eventChannel + // assert.Equal(t, event.Add.String(), addEvent.Type) + // assert.Equal(t, roleID, addEvent.EntityID.String()) + + // delete new role and check for event + _, err = roleService.DeleteRoles(ctx, deleteRoleRequest) + if err != nil { + t.Error(err) + t.FailNow() + } - assert.IsType(t, event.Add.String(), addEvent.Type) + // deleteEvent := <-application.eventChannel + // assert.Equal(t, event.Delete.String(), deleteEvent.Type) + // assert.Equal(t, roleID, addEvent.EntityID.String()) } diff --git a/integration-tests/integrationTestUtils/integrationTestUtils.go b/integration-tests/integrationTestUtils/integrationTestUtils.go index 271be882d7ec1a226bf05c206238262fb3407eec..daf272f74c1cd1d30c9dd68bc76f2bf8a8f5cbef 100644 --- a/integration-tests/integrationTestUtils/integrationTestUtils.go +++ b/integration-tests/integrationTestUtils/integrationTestUtils.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "os" - "os/exec" "time" configMgmtPb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/configurationmanagement" @@ -193,57 +192,3 @@ func cleanRolesExceptAdmin(resp *apb.GetRolesResponse, roleService apb.RoleServi return nil } - -func ClearRabbitMQQueues() { - rabbitMQAddress := "localhost" - envVarRabbitmq := os.Getenv("RABBITMQ") - if envVarRabbitmq != "" { - rabbitMQAddress = envVarRabbitmq - } - - // add more queue names if necessary - queues := []string{ - "user", - "role", - "managedNetworkElement", - } - - // for _, queue := range queues { - // args := []string{ - // "-X", "DELETE", - // "-u", "guest:guest", - // "http://" + rabbitMQAddress + ":15672/api/queues/%2f/" + queue, - // "--write-out", "%{http_code}", - // } - - // cmd := exec.Command("curl", args...) - // cmd.Stdout = os.Stdout - // cmd.Stderr = os.Stderr - // err := cmd.Run() - // if err != nil { - // logrus.Info(err) - // } - // } - - // -i -u guest:guest -H "content-type:application/json" -X POST http://127.0.0.1:15672/api/queues/foo/get -d '{"count":5,"requeue":true,"encoding":"auto","truncate":50000}' - - for _, queue := range queues { - args := []string{ - "-i", - "-u", "guest:guest", - "-H", "\"content-type:application/json\"", - "-X", "POST", - "http://" + rabbitMQAddress + ":15672/api/queues/%2f/" + queue + "/get", - "-d", "{\"count\":10,\"encoding\":\"auto\",\"truncate\":50000,\"ackmode\":\"ack_requeue_true\"}", - } - - cmd := exec.Command("curl", args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - err := cmd.Run() - if err != nil { - logrus.Info(err) - } - } -}