From ae4436be6d236da9ce716458e7129a5b44d1810b Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Thu, 28 Jan 2021 12:23:00 +0100 Subject: [PATCH] fix IC and register tests --- .../infrastructure-component/ic_amqpclient.go | 106 +++++++------- routes/infrastructure-component/ic_test.go | 131 ++++++++++-------- routes/register_test.go | 36 +++-- 3 files changed, 153 insertions(+), 120 deletions(-) diff --git a/routes/infrastructure-component/ic_amqpclient.go b/routes/infrastructure-component/ic_amqpclient.go index f1af181..22fb8f8 100644 --- a/routes/infrastructure-component/ic_amqpclient.go +++ b/routes/infrastructure-component/ic_amqpclient.go @@ -304,6 +304,10 @@ func processMessage(message amqp.Delivery) error { func createExternalIC(payload ICUpdate, ICUUID string) error { + if payload.Properties == nil { + return fmt.Errorf("AMQP: Cannot create new IC, Propertie field missing") + } + var newICReq AddICRequest newICReq.InfrastructureComponent.UUID = ICUUID if payload.Properties.Name == nil || @@ -317,15 +321,21 @@ func createExternalIC(payload ICUpdate, ICUUID string) error { newICReq.InfrastructureComponent.Type = *payload.Properties.Type // add optional params - if payload.Status.State != nil { - newICReq.InfrastructureComponent.State = *payload.Status.State - } else { - newICReq.InfrastructureComponent.State = "unknown" - } - if newICReq.InfrastructureComponent.State == "gone" { - // Check if state is "gone" and abort creation of IC in this case - log.Println("AMQP: Aborting creation of IC with state gone") - return nil + if payload.Status != nil { + if payload.Status.State != nil { + newICReq.InfrastructureComponent.State = *payload.Status.State + } else { + newICReq.InfrastructureComponent.State = "unknown" + } + if newICReq.InfrastructureComponent.State == "gone" { + // Check if state is "gone" and abort creation of IC in this case + log.Println("AMQP: Aborting creation of IC with state gone") + return nil + } + + if payload.Status.Uptime != nil { + newICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime + } } if payload.Properties.WS_url != nil { @@ -340,9 +350,7 @@ func createExternalIC(payload ICUpdate, ICUUID string) error { if payload.Properties.Description != nil { newICReq.InfrastructureComponent.Description = *payload.Properties.Description } - if payload.Status.Uptime != nil { - newICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime - } + // TODO add JSON start parameter scheme // set managed externally to true because this IC is created via AMQP @@ -380,47 +388,51 @@ func createExternalIC(payload ICUpdate, ICUUID string) error { func (s *InfrastructureComponent) updateExternalIC(payload ICUpdate) error { var updatedICReq UpdateICRequest - if payload.Status.State != nil { - updatedICReq.InfrastructureComponent.State = *payload.Status.State - if *payload.Status.State == "gone" { - // remove IC from DB - log.Println("AMQP: Deleting IC with state gone") - err := s.delete(true) - if err != nil { - // if component could not be deleted there are still configurations using it in the DB - // continue with the update to save the new state of the component and get back to the deletion later - log.Println("AMQP: Deletion of IC postponed (config(s) associated to it)") + if payload.Status != nil { + if payload.Status.State != nil { + updatedICReq.InfrastructureComponent.State = *payload.Status.State + + if *payload.Status.State == "gone" { + // remove IC from DB + log.Println("AMQP: Deleting IC with state gone") + err := s.delete(true) + if err != nil { + // if component could not be deleted there are still configurations using it in the DB + // continue with the update to save the new state of the component and get back to the deletion later + log.Println("AMQP: Deletion of IC postponed (config(s) associated to it)") + } + } + } + if payload.Status.Uptime != nil { + updatedICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime } } - if payload.Status.Uptime != nil { - updatedICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime - } - - if payload.Properties.Type != nil { - updatedICReq.InfrastructureComponent.Type = *payload.Properties.Type - } - if payload.Properties.Category != nil { - updatedICReq.InfrastructureComponent.Category = *payload.Properties.Category - } - if payload.Properties.Name != nil { - updatedICReq.InfrastructureComponent.Name = *payload.Properties.Name - } - if payload.Properties.WS_url != nil { - updatedICReq.InfrastructureComponent.WebsocketURL = *payload.Properties.WS_url - } - if payload.Properties.API_url != nil { - updatedICReq.InfrastructureComponent.APIURL = *payload.Properties.API_url - } - if payload.Properties.Location != nil { - //postgres.Jsonb{json.RawMessage(`{"location" : " ` + *payload.Status.Location + `"}`)} - updatedICReq.InfrastructureComponent.Location = *payload.Properties.Location - } - if payload.Properties.Description != nil { - updatedICReq.InfrastructureComponent.Description = *payload.Properties.Description + if payload.Properties != nil { + if payload.Properties.Type != nil { + updatedICReq.InfrastructureComponent.Type = *payload.Properties.Type + } + if payload.Properties.Category != nil { + updatedICReq.InfrastructureComponent.Category = *payload.Properties.Category + } + if payload.Properties.Name != nil { + updatedICReq.InfrastructureComponent.Name = *payload.Properties.Name + } + if payload.Properties.WS_url != nil { + updatedICReq.InfrastructureComponent.WebsocketURL = *payload.Properties.WS_url + } + if payload.Properties.API_url != nil { + updatedICReq.InfrastructureComponent.APIURL = *payload.Properties.API_url + } + if payload.Properties.Location != nil { + updatedICReq.InfrastructureComponent.Location = *payload.Properties.Location + } + if payload.Properties.Description != nil { + updatedICReq.InfrastructureComponent.Description = *payload.Properties.Description + } } // set raw status update if IC diff --git a/routes/infrastructure-component/ic_test.go b/routes/infrastructure-component/ic_test.go index bdd2676..5b30bc2 100644 --- a/routes/infrastructure-component/ic_test.go +++ b/routes/infrastructure-component/ic_test.go @@ -24,6 +24,8 @@ package infrastructure_component import ( "encoding/json" "fmt" + "github.com/streadway/amqp" + "log" "os" "testing" "time" @@ -32,7 +34,6 @@ import ( component_configuration "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration" "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario" "github.com/jinzhu/gorm/dialects/postgres" - "github.com/streadway/amqp" "github.com/stretchr/testify/assert" "github.com/gin-gonic/gin" @@ -141,6 +142,27 @@ func TestMain(m *testing.M) { // that can be associated with a new component configuration scenario.RegisterScenarioEndpoints(api.Group("/scenarios")) + // check AMQP connection + err = CheckConnection() + if err.Error() != "connection is nil" { + return + } + + // connect AMQP client + // Make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set + host, err := configuration.GlobalConfig.String("amqp.host") + usr, err := configuration.GlobalConfig.String("amqp.user") + pass, err := configuration.GlobalConfig.String("amqp.pass") + amqpURI := "amqp://" + usr + ":" + pass + "@" + host + + // AMQP Connection startup is tested here + // Not repeated in other tests because it is only needed once + err = StartAMQP(amqpURI, api) + if err != nil { + log.Println("unable to connect to AMQP") + return + } + os.Exit(m.Run()) } @@ -149,22 +171,6 @@ func TestAddICAsAdmin(t *testing.T) { database.MigrateModels() assert.NoError(t, helper.AddTestUsers()) - // check AMQP connection - err := CheckConnection() - assert.Errorf(t, err, "connection is nil") - - // connect AMQP client - // Make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set - host, err := configuration.GlobalConfig.String("amqp.host") - user, err := configuration.GlobalConfig.String("amqp.user") - pass, err := configuration.GlobalConfig.String("amqp.pass") - amqpURI := "amqp://" + user + ":" + pass + "@" + host - - // AMQP Connection startup is tested here - // Not repeated in other tests because it is only needed once - err = StartAMQP(amqpURI, api) - assert.NoError(t, err) - // authenticate as admin token, err := helper.AuthenticateForTest(router, "/api/authenticate", "POST", helper.AdminCredentials) @@ -228,6 +234,9 @@ func TestAddICAsAdmin(t *testing.T) { // Compare POST's response with the newExternalIC err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC2}) assert.NoError(t, err) + + // wait to have async operation be completed + time.Sleep(waitingTime * time.Second) } func TestAddICAsUser(t *testing.T) { @@ -243,6 +252,7 @@ func TestAddICAsUser(t *testing.T) { // test POST ic/ $newIC // This should fail with unprocessable entity 422 error code // Normal users are not allowed to add ICs + newIC1.ManagedExternally = newFalse() code, resp, err := helper.TestEndpoint(router, token, "/api/ic", "POST", helper.KeyModels{"ic": newIC1}) assert.NoError(t, err) @@ -305,14 +315,15 @@ func TestUpdateICAsAdmin(t *testing.T) { // fake an IC update (create) message var update ICUpdate update.Status = new(ICStatus) + update.Properties = new(ICProperties) update.Status.State = new(string) *update.Status.State = "idle" - update.Status.Name = new(string) - *update.Status.Name = newIC2.Name - update.Status.Category = new(string) - *update.Status.Category = newIC2.Category - update.Status.Type = new(string) - *update.Status.Type = newIC2.Type + update.Properties.Name = new(string) + *update.Properties.Name = newIC2.Name + update.Properties.Category = new(string) + *update.Properties.Category = newIC2.Category + update.Properties.Type = new(string) + *update.Properties.Type = newIC2.Type payload, err := json.Marshal(update) assert.NoError(t, err) @@ -435,14 +446,15 @@ func TestDeleteICAsAdmin(t *testing.T) { // fake an IC update (create) message var update ICUpdate update.Status = new(ICStatus) + update.Properties = new(ICProperties) update.Status.State = new(string) *update.Status.State = "idle" - update.Status.Name = new(string) - *update.Status.Name = newIC2.Name - update.Status.Category = new(string) - *update.Status.Category = newIC2.Category - update.Status.Type = new(string) - *update.Status.Type = newIC2.Type + update.Properties.Name = new(string) + *update.Properties.Name = newIC2.Name + update.Properties.Category = new(string) + *update.Properties.Category = newIC2.Category + update.Properties.Type = new(string) + *update.Properties.Type = newIC2.Type payload, err := json.Marshal(update) assert.NoError(t, err) @@ -676,6 +688,7 @@ func TestCreateUpdateViaAMQPRecv(t *testing.T) { // fake an IC update message var update ICUpdate update.Status = new(ICStatus) + update.Properties = new(ICProperties) update.Status.State = new(string) *update.Status.State = "idle" @@ -715,22 +728,22 @@ func TestCreateUpdateViaAMQPRecv(t *testing.T) { assert.Equal(t, 0, number) // complete the (required) data of an IC - update.Status.Name = new(string) - *update.Status.Name = newIC1.Name - update.Status.Category = new(string) - *update.Status.Category = newIC1.Category - update.Status.Type = new(string) - *update.Status.Type = newIC1.Type + update.Properties.Name = new(string) + *update.Properties.Name = newIC1.Name + update.Properties.Category = new(string) + *update.Properties.Category = newIC1.Category + update.Properties.Type = new(string) + *update.Properties.Type = newIC1.Type update.Status.Uptime = new(float64) *update.Status.Uptime = -1.0 - update.Status.WS_url = new(string) - *update.Status.WS_url = newIC1.WebsocketURL - update.Status.API_url = new(string) - *update.Status.API_url = newIC1.APIURL - update.Status.Description = new(string) - *update.Status.Description = newIC1.Description - update.Status.Location = new(string) - *update.Status.Location = newIC1.Location + update.Properties.WS_url = new(string) + *update.Properties.WS_url = newIC1.WebsocketURL + update.Properties.API_url = new(string) + *update.Properties.API_url = newIC1.APIURL + update.Properties.Description = new(string) + *update.Properties.Description = newIC1.Description + update.Properties.Location = new(string) + *update.Properties.Location = newIC1.Location payload, err = json.Marshal(update) assert.NoError(t, err) @@ -765,7 +778,7 @@ func TestCreateUpdateViaAMQPRecv(t *testing.T) { assert.Equal(t, 1, number) // modify status update - *update.Status.Name = "This is the new name" + *update.Properties.Name = "This is the new name" payload, err = json.Marshal(update) assert.NoError(t, err) @@ -809,26 +822,26 @@ func TestDeleteICViaAMQPRecv(t *testing.T) { // fake an IC update message var update ICUpdate update.Status = new(ICStatus) - + update.Properties = new(ICProperties) update.Status.State = new(string) *update.Status.State = "idle" // complete the (required) data of an IC - update.Status.Name = new(string) - *update.Status.Name = newIC1.Name - update.Status.Category = new(string) - *update.Status.Category = newIC1.Category - update.Status.Type = new(string) - *update.Status.Type = newIC1.Type + update.Properties.Name = new(string) + *update.Properties.Name = newIC1.Name + update.Properties.Category = new(string) + *update.Properties.Category = newIC1.Category + update.Properties.Type = new(string) + *update.Properties.Type = newIC1.Type update.Status.Uptime = new(float64) *update.Status.Uptime = -1.0 - update.Status.WS_url = new(string) - *update.Status.WS_url = newIC1.WebsocketURL - update.Status.API_url = new(string) - *update.Status.API_url = newIC1.APIURL - update.Status.Description = new(string) - *update.Status.Description = newIC1.Description - update.Status.Location = new(string) - *update.Status.Location = newIC1.Location + update.Properties.WS_url = new(string) + *update.Properties.WS_url = newIC1.WebsocketURL + update.Properties.API_url = new(string) + *update.Properties.API_url = newIC1.APIURL + update.Properties.Description = new(string) + *update.Properties.Description = newIC1.Description + update.Properties.Location = new(string) + *update.Properties.Location = newIC1.Location payload, err := json.Marshal(update) assert.NoError(t, err) diff --git a/routes/register_test.go b/routes/register_test.go index c712576..671c5fa 100644 --- a/routes/register_test.go +++ b/routes/register_test.go @@ -23,17 +23,18 @@ package routes import ( + infrastructure_component "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component" "os" "testing" "git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration" "git.rwth-aachen.de/acs/public/villas/web-backend-go/database" - infrastructure_component "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" ) var router *gin.Engine +var api *gin.RouterGroup func TestMain(m *testing.M) { err := configuration.InitConfig() @@ -49,35 +50,42 @@ func TestMain(m *testing.M) { router = gin.Default() - // connect AMQP client (make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set via command line parameters) + basePath, _ := configuration.GlobalConfig.String("base.path") + api = router.Group(basePath) + os.Exit(m.Run()) +} + +/* + * The order of test functions is important here + * 1. Start and connect AMQP + * 2. Register endpoints + * 3. Add test data + */ + +func TestStartAMQP(t *testing.T) { + // connect AMQP client + // Make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set host, err := configuration.GlobalConfig.String("amqp.host") user, err := configuration.GlobalConfig.String("amqp.user") pass, err := configuration.GlobalConfig.String("amqp.pass") - amqpURI := "amqp://" + user + ":" + pass + "@" + host - err = infrastructure_component.ConnectAMQP(amqpURI) - - os.Exit(m.Run()) + // AMQP Connection startup is tested here + // Not repeated in other tests because it is only needed once + err = infrastructure_component.StartAMQP(amqpURI, api) + assert.NoError(t, err) } func TestRegisterEndpoints(t *testing.T) { database.DropTables() database.MigrateModels() - basePath, err := configuration.GlobalConfig.String("base.path") - assert.NoError(t, err) - api := router.Group(basePath) RegisterEndpoints(router, api) } func TestAddTestData(t *testing.T) { - err := configuration.InitConfig() - if err != nil { - panic(t) - } - err = ReadTestDataFromJson("../database/testdata.json") + err := ReadTestDataFromJson("../database/testdata.json") assert.NoError(t, err) resp, err := AddTestData(configuration.GlobalConfig, router)