Code base refactoring: no functional changes, improving test coverage

This commit is contained in:
Sonja Happ 2020-03-27 11:53:26 +01:00
parent eb10488c1f
commit 1de4d9c9c2
17 changed files with 1206 additions and 1103 deletions

View file

@ -25,6 +25,7 @@ import (
"encoding/json"
"fmt"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"github.com/gin-gonic/gin"
"github.com/streadway/amqp"
"github.com/tidwall/gjson"
"log"
@ -203,3 +204,37 @@ func CheckConnection() error {
return nil
}
func StartAMQP(AMQPurl string, api *gin.RouterGroup) error {
if AMQPurl != "" {
log.Println("Starting AMQP client")
err := ConnectAMQP(AMQPurl)
if err != nil {
return err
}
// register IC action endpoint only if AMQP client is used
RegisterAMQPEndpoint(api.Group("/ic"))
// Periodically call the Ping function to check which ICs are still there
ticker := time.NewTicker(10 * time.Second)
go func() {
for {
select {
case <-ticker.C:
err = PingAMQP()
if err != nil {
log.Println("AMQP Error: ", err.Error())
}
}
}
}()
log.Printf("Connected AMQP client to %s", AMQPurl)
}
return nil
}

View file

@ -23,10 +23,9 @@ package configuration
import (
"flag"
"github.com/zpatrick/go-config"
"log"
"os"
"github.com/zpatrick/go-config"
)
// Global configuration
@ -109,9 +108,48 @@ func InitConfig() error {
settings, _ := GolbalConfig.Settings()
log.Print("All settings:")
for key, val := range settings {
// TODO password settings should be excluded!
log.Printf(" %s = %s \n", key, val)
}
}
return nil
}
func ConfigureBackend() (string, string, string, string, string, string, string, error) {
err := InitConfig()
if err != nil {
log.Printf("Error during initialization of global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
mode, err := GolbalConfig.String("mode")
if err != nil {
log.Printf("Error reading mode from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
baseHost, err := GolbalConfig.String("base.host")
if err != nil {
log.Printf("Error reading base.host from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
basePath, err := GolbalConfig.String("base.path")
if err != nil {
log.Printf("Error reading base.path from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
port, err := GolbalConfig.String("port")
if err != nil {
log.Printf("Error reading port from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
AMQPhost, _ := GolbalConfig.String("amqp.host")
AMQPuser, _ := GolbalConfig.String("amqp.user")
AMQPpass, _ := GolbalConfig.String("amqp.pass")
return mode, baseHost, basePath, port, AMQPhost, AMQPuser, AMQPpass, nil
}

View file

@ -23,7 +23,7 @@ package database
import (
"fmt"
"log"
"github.com/zpatrick/go-config"
"os"
"testing"
@ -32,40 +32,77 @@ import (
)
func TestMain(m *testing.M) {
err := configuration.InitConfig()
if err != nil {
panic(m)
}
err = InitDB(configuration.GolbalConfig)
if err != nil {
panic(m)
}
// Verify that you can connect to the database
err = DBpool.DB().Ping()
if err != nil {
log.Panic("Error: DB must ping to run tests")
}
defer DBpool.Close()
os.Exit(m.Run())
}
func TestInitDB(t *testing.T) {
err := configuration.InitConfig()
assert.NoError(t, err)
static := map[string]string{}
mappings := map[string]string{}
defaults := config.NewStatic(static)
env := config.NewEnvironment(mappings)
ownconfig := config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbname, err := configuration.GolbalConfig.String("db.name")
assert.NoError(t, err)
static["db.name"] = dbname
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbhost, err := configuration.GolbalConfig.String("db.host")
assert.NoError(t, err)
static["db.host"] = dbhost
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbuser, err := configuration.GolbalConfig.String("db.user")
static["db.user"] = dbuser
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbpass, err := configuration.GolbalConfig.String("db.pass")
static["db.pass"] = dbpass
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbssl, err := configuration.GolbalConfig.String("db.ssl")
assert.NoError(t, err)
static["db.ssl"] = dbssl
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.NoError(t, err)
// Verify that you can connect to the database
db := GetDB()
err = db.DB().Ping()
assert.NoError(t, err)
}
func TestUserAssociations(t *testing.T) {
DropTables()
MigrateModels()
// create copies of global test data
scenarioA := ScenarioA
scenarioB := ScenarioB
user0 := User0
userA := UserA
userB := UserB
scenarioA := Scenario{}
scenarioB := Scenario{}
userA := User{Username: "abcdef"}
userB := User{Username: "ghijkl"}
// add three users to DB
assert.NoError(t, DBpool.Create(&user0).Error) // Admin
// add users to DB
assert.NoError(t, DBpool.Create(&userA).Error) // Normal User
assert.NoError(t, DBpool.Create(&userB).Error) // Normal User
@ -78,11 +115,9 @@ func TestUserAssociations(t *testing.T) {
assert.NoError(t, DBpool.Model(&userA).Association("Scenarios").Append(&scenarioA).Error)
assert.NoError(t, DBpool.Model(&userA).Association("Scenarios").Append(&scenarioB).Error)
assert.NoError(t, DBpool.Model(&userB).Association("Scenarios").Append(&scenarioA).Error)
assert.NoError(t, DBpool.Model(&userB).Association("Scenarios").Append(&scenarioB).Error)
var usr1 User
assert.NoError(t, DBpool.Find(&usr1, "ID = ?", 2).Error, fmt.Sprintf("Find User with ID=2"))
assert.EqualValues(t, "User_A", usr1.Username)
assert.NoError(t, DBpool.Find(&usr1, "ID = ?", 1).Error, fmt.Sprintf("Find User with ID=1"))
// Get scenarios of usr1
var scenarios []Scenario
@ -99,22 +134,20 @@ func TestScenarioAssociations(t *testing.T) {
MigrateModels()
// create copies of global test data
scenarioA := ScenarioA
scenarioB := ScenarioB
user0 := User0
userA := UserA
userB := UserB
configA := ConfigA
configB := ConfigB
dashboardA := DashboardA
dashboardB := DashboardB
scenarioA := Scenario{}
scenarioB := Scenario{}
userA := User{Username: "abcdef"}
userB := User{Username: "ghijkl"}
configA := ComponentConfiguration{}
configB := ComponentConfiguration{}
dashboardA := Dashboard{}
dashboardB := Dashboard{}
// add scenarios to DB
assert.NoError(t, DBpool.Create(&scenarioA).Error)
assert.NoError(t, DBpool.Create(&scenarioB).Error)
// add users to DB
assert.NoError(t, DBpool.Create(&user0).Error) // Admin
assert.NoError(t, DBpool.Create(&userA).Error) // Normal User
assert.NoError(t, DBpool.Create(&userB).Error) // Normal User
@ -143,7 +176,6 @@ func TestScenarioAssociations(t *testing.T) {
var scenario1 Scenario
assert.NoError(t, DBpool.Find(&scenario1, 1).Error, fmt.Sprintf("Find Scenario with ID=1"))
assert.EqualValues(t, "Scenario_A", scenario1.Name)
// Get users of scenario1
var users []User
@ -176,10 +208,10 @@ func TestICAssociations(t *testing.T) {
MigrateModels()
// create copies of global test data
icA := ICA
icB := ICB
configA := ConfigA
configB := ConfigB
icA := InfrastructureComponent{}
icB := InfrastructureComponent{}
configA := ComponentConfiguration{}
configB := ComponentConfiguration{}
// add ICs to DB
assert.NoError(t, DBpool.Create(&icA).Error)
@ -195,7 +227,6 @@ func TestICAssociations(t *testing.T) {
var ic1 InfrastructureComponent
assert.NoError(t, DBpool.Find(&ic1, 1).Error, fmt.Sprintf("Find InfrastructureComponent with ID=1"))
assert.EqualValues(t, "xxx.yyy.zzz.aaa", ic1.Host)
// Get Component Configurations of ic1
var configs []ComponentConfiguration
@ -212,18 +243,18 @@ func TestComponentConfigurationAssociations(t *testing.T) {
MigrateModels()
// create copies of global test data
configA := ConfigA
configB := ConfigB
outSignalA := OutSignalA
outSignalB := OutSignalB
inSignalA := InSignalA
inSignalB := InSignalB
fileA := FileA
fileB := FileB
fileC := FileC
fileD := FileD
icA := ICA
icB := ICB
configA := ComponentConfiguration{}
configB := ComponentConfiguration{}
outSignalA := Signal{Direction: "out"}
outSignalB := Signal{Direction: "out"}
inSignalA := Signal{Direction: "in"}
inSignalB := Signal{Direction: "in"}
fileA := File{}
fileB := File{}
fileC := File{}
fileD := File{}
icA := InfrastructureComponent{}
icB := InfrastructureComponent{}
// add Component Configurations to DB
assert.NoError(t, DBpool.Create(&configA).Error)
@ -261,7 +292,6 @@ func TestComponentConfigurationAssociations(t *testing.T) {
var config1 ComponentConfiguration
assert.NoError(t, DBpool.Find(&config1, 1).Error, fmt.Sprintf("Find ComponentConfiguration with ID=1"))
assert.EqualValues(t, ConfigA.Name, config1.Name)
// Check IC ID
if config1.ICID != 1 {
@ -291,10 +321,10 @@ func TestDashboardAssociations(t *testing.T) {
MigrateModels()
// create copies of global test data
dashboardA := DashboardA
dashboardB := DashboardB
widgetA := WidgetA
widgetB := WidgetB
dashboardA := Dashboard{}
dashboardB := Dashboard{}
widgetA := Widget{}
widgetB := Widget{}
// add dashboards to DB
assert.NoError(t, DBpool.Create(&dashboardA).Error)
@ -310,7 +340,6 @@ func TestDashboardAssociations(t *testing.T) {
var dashboard1 Dashboard
assert.NoError(t, DBpool.Find(&dashboard1, 1).Error, fmt.Sprintf("Find Dashboard with ID=1"))
assert.EqualValues(t, "Dashboard_A", dashboard1.Name)
//Get widgets of dashboard1
var widgets []Widget
@ -327,12 +356,12 @@ func TestWidgetAssociations(t *testing.T) {
MigrateModels()
// create copies of global test data
widgetA := WidgetA
widgetB := WidgetB
fileA := FileA
fileB := FileB
fileC := FileC
fileD := FileD
widgetA := Widget{}
widgetB := Widget{}
fileA := File{}
fileB := File{}
fileC := File{}
fileD := File{}
// add widgets to DB
assert.NoError(t, DBpool.Create(&widgetA).Error)
@ -350,7 +379,6 @@ func TestWidgetAssociations(t *testing.T) {
var widget1 Widget
assert.NoError(t, DBpool.Find(&widget1, 1).Error, fmt.Sprintf("Find Widget with ID=1"))
assert.EqualValues(t, widgetA.Name, widget1.Name)
// Get files of widget
var files []File
@ -367,10 +395,10 @@ func TestFileAssociations(t *testing.T) {
MigrateModels()
// create copies of global test data
fileA := FileA
fileB := FileB
fileC := FileC
fileD := FileD
fileA := File{}
fileB := File{}
fileC := File{}
fileD := File{}
// add files to DB
assert.NoError(t, DBpool.Create(&fileA).Error)
@ -380,19 +408,4 @@ func TestFileAssociations(t *testing.T) {
var file1 File
assert.NoError(t, DBpool.Find(&file1, 1).Error, fmt.Sprintf("Find File with ID=1"))
assert.EqualValues(t, "File_A", file1.Name)
}
func TestAddAdmin(t *testing.T) {
DropTables()
MigrateModels()
assert.NoError(t, DBAddAdminUser())
}
func TestAddAdminAndUsers(t *testing.T) {
DropTables()
MigrateModels()
assert.NoError(t, DBAddAdminAndUserAndGuest())
}

View file

@ -1,548 +0,0 @@
/** Database package, test data.
*
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLASweb-backend-go
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
package database
import (
"bytes"
"encoding/json"
"fmt"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm/dialects/postgres"
"golang.org/x/crypto/bcrypt"
"io"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"time"
)
// #######################################################################
// #################### Data used for testing ############################
// #######################################################################
// Users
var StrPassword0 = "xyz789"
var StrPasswordA = "abc123"
var StrPasswordB = "bcd234"
var StrPasswordC = "guestpw"
// Hash passwords with bcrypt algorithm
var bcryptCost = 10
var pw0, _ = bcrypt.GenerateFromPassword([]byte(StrPassword0), bcryptCost)
var pwA, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordA), bcryptCost)
var pwB, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordB), bcryptCost)
var pwC, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordC), bcryptCost)
var User0 = User{Username: "User_0", Password: string(pw0),
Role: "Admin", Mail: "User_0@example.com", Active: true}
var UserA = User{Username: "User_A", Password: string(pwA),
Role: "User", Mail: "User_A@example.com", Active: true}
var UserB = User{Username: "User_B", Password: string(pwB),
Role: "User", Mail: "User_B@example.com", Active: true}
var UserC = User{Username: "User_C", Password: string(pwC),
Role: "Guest", Mail: "User_C@example.com", Active: true}
type UserRequest struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
OldPassword string `json:"oldPassword,omitempty"`
Mail string `json:"mail,omitempty"`
Role string `json:"role,omitempty"`
Active string `json:"active,omitempty"`
}
var newUserA = UserRequest{
Username: UserA.Username,
Password: StrPasswordA,
Role: UserA.Role,
Mail: UserA.Mail,
}
var newUserB = UserRequest{
Username: UserB.Username,
Password: StrPasswordB,
Role: UserB.Role,
Mail: UserB.Mail,
}
var newUserC = UserRequest{
Username: UserC.Username,
Password: StrPasswordC,
Role: UserC.Role,
Mail: UserC.Mail,
}
// Infrastructure components
var propertiesA = json.RawMessage(`{"location" : "ACSlab"}`)
var propertiesB = json.RawMessage(`{"location" : "ACSlab"}`)
var ICA = InfrastructureComponent{
UUID: "4854af30-325f-44a5-ad59-b67b2597de68",
Host: "xxx.yyy.zzz.aaa",
Type: "DPsim",
Category: "Simulator",
Name: "Test DPsim Simulator",
Uptime: 0,
State: "running",
StateUpdateAt: time.Now().String(),
Properties: postgres.Jsonb{propertiesA},
RawProperties: postgres.Jsonb{propertiesA},
}
var ICB = InfrastructureComponent{
UUID: "7be0322d-354e-431e-84bd-ae4c9633138b",
Host: "xxx.yyy.zzz.bbb",
Type: "VILLASnode",
Category: "Gateway",
Name: "Test VILLASnode Gateway",
Uptime: 0,
State: "idle",
StateUpdateAt: time.Now().String(),
Properties: postgres.Jsonb{propertiesB},
RawProperties: postgres.Jsonb{propertiesB},
}
// Scenarios
var startParametersA = json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)
var startParametersB = json.RawMessage(`{"parameter1" : "testValue1B", "parameter2" : "testValue2B", "parameter3" : 43}`)
var ScenarioA = Scenario{
Name: "Scenario_A",
Running: true,
StartParameters: postgres.Jsonb{startParametersA},
}
var ScenarioB = Scenario{
Name: "Scenario_B",
Running: false,
StartParameters: postgres.Jsonb{startParametersB},
}
// Component Configuration
var ConfigA = ComponentConfiguration{
Name: "Example simulation",
StartParameters: postgres.Jsonb{startParametersA},
SelectedFileID: 3,
}
var ConfigB = ComponentConfiguration{
Name: "VILLASnode gateway X",
StartParameters: postgres.Jsonb{startParametersB},
SelectedFileID: 4,
}
// Signals
var OutSignalA = Signal{
Name: "outSignal_A",
Direction: "out",
Index: 1,
Unit: "V",
}
var OutSignalB = Signal{
Name: "outSignal_B",
Direction: "out",
Index: 2,
Unit: "V",
}
var InSignalA = Signal{
Name: "inSignal_A",
Direction: "in",
Index: 1,
Unit: "A",
}
var InSignalB = Signal{
Name: "inSignal_B",
Direction: "in",
Index: 2,
Unit: "A",
}
// Dashboards
var DashboardA = Dashboard{
Name: "Dashboard_A",
Grid: 15,
}
var DashboardB = Dashboard{
Name: "Dashboard_B",
Grid: 10,
}
// Files
var FileA = File{
Name: "File_A",
Type: "text/plain",
Size: 42,
Date: time.Now().String(),
}
var FileB = File{
Name: "File_B",
Type: "text/plain",
Size: 1234,
Date: time.Now().String(),
}
var FileC = File{
Name: "File_C",
Type: "text/plain",
Size: 32,
Date: time.Now().String(),
}
var FileD = File{
Name: "File_D",
Type: "text/plain",
Size: 5000,
Date: time.Now().String(),
}
// Widgets
var customPropertiesA = json.RawMessage(`{"property1" : "testValue1A", "property2" : "testValue2A", "property3" : 42}`)
var customPropertiesBox = json.RawMessage(`{"border_color" : "18", "background_color" : "2", "background_color_opacity" : 0.3}`)
var customPropertiesSlider = json.RawMessage(`{"default_value" : 10, "orientation" : 0, "rangeMin" : 0, "rangeMax": 500, "step" : 1}`)
var customPropertiesLabel = json.RawMessage(`{"textSize" : "20", "fontColor" : 5}`)
var customPropertiesButton = json.RawMessage(`{"toggle" : "Value1", "on_value" : "Value2", "off_value" : Value3}`)
var customPropertiesCustomActions = json.RawMessage(`{"actions" : "Value1", "icon" : "Value2"}`)
var customPropertiesGauge = json.RawMessage(`{ "valueMin": 0, "valueMax": 1}`)
var customPropertiesLamp = json.RawMessage(`{"signal" : 0, "on_color" : 4, "off_color": 2 , "threshold" : 0.5}`)
var WidgetA = Widget{
Name: "Label",
Type: "Label",
Width: 100,
Height: 50,
MinHeight: 40,
MinWidth: 80,
X: 10,
Y: 10,
Z: 200,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesLabel},
SignalIDs: []int64{1},
}
var WidgetB = Widget{
Name: "Slider",
Type: "Slider",
Width: 200,
Height: 20,
MinHeight: 10,
MinWidth: 50,
X: 70,
Y: 10,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesSlider},
SignalIDs: []int64{1},
}
var WidgetC = Widget{
Name: "Box",
Type: "Box",
Width: 200,
Height: 200,
MinHeight: 10,
MinWidth: 50,
X: 300,
Y: 10,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesBox},
SignalIDs: []int64{3},
}
var WidgetD = Widget{
Name: "Action",
Type: "Action",
Width: 20,
Height: 20,
MinHeight: 10,
MinWidth: 50,
X: 10,
Y: 50,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesCustomActions},
SignalIDs: []int64{2},
}
var WidgetE = Widget{
Name: "Lamp",
Type: "Lamp",
Width: 200,
Height: 20,
MinHeight: 10,
MinWidth: 50,
X: 50,
Y: 300,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesLamp},
SignalIDs: []int64{4},
}
func DBAddAdminUser() error {
DBpool.AutoMigrate(&User{})
// Check if admin user exists in DB
var users []User
err := DBpool.Where("Role = ?", "Admin").Find(&users).Error
if len(users) == 0 {
fmt.Println("No admin user found in DB, adding default admin user.")
//create a copy of global test data
user0 := User0
// add admin user to DB
err = DBpool.Create(&user0).Error
}
return err
}
func DBAddAdminAndUserAndGuest() error {
DBpool.AutoMigrate(&User{})
//create a copy of global test data
user0 := User0
userA := UserA
userB := UserB
userC := UserC
// add admin user to DB
err := DBpool.Create(&user0).Error
// add normal users to DB
err = DBpool.Create(&userA).Error
err = DBpool.Create(&userB).Error
// add guest user to DB
err = DBpool.Create(&userC).Error
return err
}
// Populates DB with test data
func DBAddTestData(basePath string, router *gin.Engine) error {
MigrateModels()
// Create entries of each model (data defined in testdata.go)
// add Admin user
err := DBAddAdminUser()
if err != nil {
return err
}
// authenticate as admin
token, err := helper.AuthenticateForTest(router, basePath+"/authenticate", "POST", helper.AdminCredentials)
if err != nil {
return err
}
// add 2 normal and 1 guest user
code, _, err := helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": newUserA})
if code != http.StatusOK {
return fmt.Errorf("error adding User_A")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": newUserB})
if code != http.StatusOK {
return fmt.Errorf("error adding User_B")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": newUserC})
if code != http.StatusOK {
return fmt.Errorf("error adding User_C")
}
// add infrastructure components
code, _, err = helper.TestEndpoint(router, token, basePath+"/ic", "POST", helper.KeyModels{"ic": ICA})
if code != http.StatusOK {
return fmt.Errorf("error adding IC A")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/ic", "POST", helper.KeyModels{"ic": ICB})
if code != http.StatusOK {
return fmt.Errorf("error adding IC B")
}
// add scenarios
code, _, err = helper.TestEndpoint(router, token, basePath+"/scenarios", "POST", helper.KeyModels{"scenario": ScenarioA})
if code != http.StatusOK {
return fmt.Errorf("error adding Scenario A")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/scenarios", "POST", helper.KeyModels{"scenario": ScenarioB})
if code != http.StatusOK {
return fmt.Errorf("error adding Scenario B")
}
// add users to scenario
code, _, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/1/user?username=User_A", basePath), "PUT", nil)
if code != http.StatusOK {
return fmt.Errorf("error adding User_A to Scenario A")
}
code, _, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/2/user?username=User_A", basePath), "PUT", nil)
if code != http.StatusOK {
return fmt.Errorf("error adding User_A to Scenario B")
}
code, _, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/2/user?username=User_B", basePath), "PUT", nil)
if code != http.StatusOK {
return fmt.Errorf("error adding User_B to Scenario B")
}
code, _, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/1/user?username=User_C", basePath), "PUT", nil)
if code != http.StatusOK {
return fmt.Errorf("error adding User_C to Scenario A")
}
// add component configurations
configA := ConfigA
configB := ConfigB
configA.ScenarioID = 1
configB.ScenarioID = 1
configA.ICID = 1
configB.ICID = 2
code, _, err = helper.TestEndpoint(router, token, basePath+"/configs", "POST", helper.KeyModels{"config": configA})
if code != http.StatusOK {
return fmt.Errorf("error adding Config A")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/configs", "POST", helper.KeyModels{"config": configB})
if code != http.StatusOK {
return fmt.Errorf("error adding Config B")
}
// add dashboards
dashboardA := DashboardA
dashboardB := DashboardB
dashboardA.ScenarioID = 1
dashboardB.ScenarioID = 1
code, _, err = helper.TestEndpoint(router, token, basePath+"/dashboards", "POST", helper.KeyModels{"dashboard": dashboardA})
if code != http.StatusOK {
return fmt.Errorf("error adding Dashboard B")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/dashboards", "POST", helper.KeyModels{"dashboard": dashboardB})
if code != http.StatusOK {
return fmt.Errorf("error adding Dashboard B")
}
// add widgets
widgetA := WidgetA
widgetB := WidgetB
widgetC := WidgetC
widgetD := WidgetD
widgetE := WidgetE
widgetA.DashboardID = 1
widgetB.DashboardID = 1
widgetC.DashboardID = 1
widgetD.DashboardID = 1
widgetE.DashboardID = 1
code, _, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetA})
if code != http.StatusOK {
return fmt.Errorf("error adding Widget A")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetB})
if code != http.StatusOK {
return fmt.Errorf("error adding Widget B")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetC})
if code != http.StatusOK {
return fmt.Errorf("error adding Widget C")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetD})
if code != http.StatusOK {
return fmt.Errorf("error adding Widget D")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetE})
if code != http.StatusOK {
return fmt.Errorf("error adding Widget E")
}
// add signals
outSignalA := OutSignalA
outSignalB := OutSignalB
inSignalA := InSignalA
inSignalB := InSignalB
outSignalA.ConfigID = 1
outSignalB.ConfigID = 1
inSignalA.ConfigID = 1
inSignalB.ConfigID = 1
code, _, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": outSignalB})
if code != http.StatusOK {
return fmt.Errorf("error adding outSignalB")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": outSignalA})
if code != http.StatusOK {
return fmt.Errorf("error adding outSignalA")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": inSignalA})
if code != http.StatusOK {
return fmt.Errorf("error adding inSignalA")
}
code, _, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": inSignalB})
if code != http.StatusOK {
return fmt.Errorf("error adding inSignalB")
}
// upload files
// upload readme file
bodyBuf := &bytes.Buffer{}
bodyWriter := multipart.NewWriter(bodyBuf)
fileWriter, _ := bodyWriter.CreateFormFile("file", "Readme.md")
fh, _ := os.Open("README.md")
defer fh.Close()
// io copy
_, err = io.Copy(fileWriter, fh)
contentType := bodyWriter.FormDataContentType()
bodyWriter.Close()
// Create the request and add file to component config
w1 := httptest.NewRecorder()
req1, _ := http.NewRequest("POST", basePath+"/files?objectID=1&objectType=config", bodyBuf)
req1.Header.Set("Content-Type", contentType)
req1.Header.Add("Authorization", "Bearer "+token)
router.ServeHTTP(w1, req1)
// upload image file
bodyBuf = &bytes.Buffer{}
bodyWriter = multipart.NewWriter(bodyBuf)
fileWriter, _ = bodyWriter.CreateFormFile("file", "logo.png")
fh, _ = os.Open("doc/pictures/villas_web.png")
defer fh.Close()
// io copy
_, err = io.Copy(fileWriter, fh)
contentType = bodyWriter.FormDataContentType()
bodyWriter.Close()
// Create the request and add file to widget
w2 := httptest.NewRecorder()
req2, _ := http.NewRequest("POST", basePath+"/files?objectID=1&objectType=widget", bodyBuf)
req2.Header.Set("Content-Type", contentType)
req2.Header.Add("Authorization", "Bearer "+token)
router.ServeHTTP(w2, req2)
return nil
}

342
helper/test_data.go Normal file
View file

@ -0,0 +1,342 @@
/** Helper package, test data.
*
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLASweb-backend-go
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
package helper
import (
"encoding/json"
"fmt"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"github.com/jinzhu/gorm/dialects/postgres"
"golang.org/x/crypto/bcrypt"
"time"
)
// #######################################################################
// #################### Data used for testing ############################
// #######################################################################
// Credentials
var StrPassword0 = "xyz789"
var StrPasswordA = "abc123"
var StrPasswordB = "bcd234"
var StrPasswordC = "guestpw"
// Hash passwords with bcrypt algorithm
var bcryptCost = 10
var pw0, _ = bcrypt.GenerateFromPassword([]byte(StrPassword0), bcryptCost)
var pwA, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordA), bcryptCost)
var pwB, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordB), bcryptCost)
var pwC, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordC), bcryptCost)
var User0 = database.User{Username: "User_0", Password: string(pw0),
Role: "Admin", Mail: "User_0@example.com", Active: true}
var UserA = database.User{Username: "User_A", Password: string(pwA),
Role: "User", Mail: "User_A@example.com", Active: true}
var UserB = database.User{Username: "User_B", Password: string(pwB),
Role: "User", Mail: "User_B@example.com", Active: true}
var UserC = database.User{Username: "User_C", Password: string(pwC),
Role: "Guest", Mail: "User_C@example.com", Active: true}
type UserRequest struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
OldPassword string `json:"oldPassword,omitempty"`
Mail string `json:"mail,omitempty"`
Role string `json:"role,omitempty"`
Active string `json:"active,omitempty"`
}
var NewUserA = UserRequest{
Username: UserA.Username,
Password: StrPasswordA,
Role: UserA.Role,
Mail: UserA.Mail,
}
var NewUserB = UserRequest{
Username: UserB.Username,
Password: StrPasswordB,
Role: UserB.Role,
Mail: UserB.Mail,
}
var NewUserC = UserRequest{
Username: UserC.Username,
Password: StrPasswordC,
Role: UserC.Role,
Mail: UserC.Mail,
}
// Infrastructure components
var propertiesA = json.RawMessage(`{"location" : "ACSlab"}`)
var propertiesB = json.RawMessage(`{"location" : "ACSlab"}`)
var ICA = database.InfrastructureComponent{
UUID: "4854af30-325f-44a5-ad59-b67b2597de68",
Host: "xxx.yyy.zzz.aaa",
Type: "DPsim",
Category: "Simulator",
Name: "Test DPsim Simulator",
Uptime: 0,
State: "running",
StateUpdateAt: time.Now().String(),
Properties: postgres.Jsonb{propertiesA},
RawProperties: postgres.Jsonb{propertiesA},
}
var ICB = database.InfrastructureComponent{
UUID: "7be0322d-354e-431e-84bd-ae4c9633138b",
Host: "xxx.yyy.zzz.bbb",
Type: "VILLASnode",
Category: "Gateway",
Name: "Test VILLASnode Gateway",
Uptime: 0,
State: "idle",
StateUpdateAt: time.Now().String(),
Properties: postgres.Jsonb{propertiesB},
RawProperties: postgres.Jsonb{propertiesB},
}
// Scenarios
var startParametersA = json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)
var startParametersB = json.RawMessage(`{"parameter1" : "testValue1B", "parameter2" : "testValue2B", "parameter3" : 43}`)
var ScenarioA = database.Scenario{
Name: "Scenario_A",
Running: true,
StartParameters: postgres.Jsonb{startParametersA},
}
var ScenarioB = database.Scenario{
Name: "Scenario_B",
Running: false,
StartParameters: postgres.Jsonb{startParametersB},
}
// Component Configuration
var ConfigA = database.ComponentConfiguration{
Name: "Example simulation",
StartParameters: postgres.Jsonb{startParametersA},
SelectedFileID: 3,
}
var ConfigB = database.ComponentConfiguration{
Name: "VILLASnode gateway X",
StartParameters: postgres.Jsonb{startParametersB},
SelectedFileID: 4,
}
// Signals
var OutSignalA = database.Signal{
Name: "outSignal_A",
Direction: "out",
Index: 1,
Unit: "V",
}
var OutSignalB = database.Signal{
Name: "outSignal_B",
Direction: "out",
Index: 2,
Unit: "V",
}
var InSignalA = database.Signal{
Name: "inSignal_A",
Direction: "in",
Index: 1,
Unit: "A",
}
var InSignalB = database.Signal{
Name: "inSignal_B",
Direction: "in",
Index: 2,
Unit: "A",
}
// Dashboards
var DashboardA = database.Dashboard{
Name: "Dashboard_A",
Grid: 15,
}
var DashboardB = database.Dashboard{
Name: "Dashboard_B",
Grid: 10,
}
// Files
var FileA = database.File{
Name: "File_A",
Type: "text/plain",
Size: 42,
Date: time.Now().String(),
}
var FileB = database.File{
Name: "File_B",
Type: "text/plain",
Size: 1234,
Date: time.Now().String(),
}
var FileC = database.File{
Name: "File_C",
Type: "text/plain",
Size: 32,
Date: time.Now().String(),
}
var FileD = database.File{
Name: "File_D",
Type: "text/plain",
Size: 5000,
Date: time.Now().String(),
}
// Widgets
var customPropertiesA = json.RawMessage(`{"property1" : "testValue1A", "property2" : "testValue2A", "property3" : 42}`)
var customPropertiesBox = json.RawMessage(`{"border_color" : "18", "background_color" : "2", "background_color_opacity" : 0.3}`)
var customPropertiesSlider = json.RawMessage(`{"default_value" : 10, "orientation" : 0, "rangeMin" : 0, "rangeMax": 500, "step" : 1}`)
var customPropertiesLabel = json.RawMessage(`{"textSize" : "20", "fontColor" : 5}`)
var customPropertiesButton = json.RawMessage(`{"toggle" : "Value1", "on_value" : "Value2", "off_value" : Value3}`)
var customPropertiesCustomActions = json.RawMessage(`{"actions" : "Value1", "icon" : "Value2"}`)
var customPropertiesGauge = json.RawMessage(`{ "valueMin": 0, "valueMax": 1}`)
var customPropertiesLamp = json.RawMessage(`{"signal" : 0, "on_color" : 4, "off_color": 2 , "threshold" : 0.5}`)
var WidgetA = database.Widget{
Name: "Label",
Type: "Label",
Width: 100,
Height: 50,
MinHeight: 40,
MinWidth: 80,
X: 10,
Y: 10,
Z: 200,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesLabel},
SignalIDs: []int64{1},
}
var WidgetB = database.Widget{
Name: "Slider",
Type: "Slider",
Width: 200,
Height: 20,
MinHeight: 10,
MinWidth: 50,
X: 70,
Y: 10,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesSlider},
SignalIDs: []int64{1},
}
var WidgetC = database.Widget{
Name: "Box",
Type: "Box",
Width: 200,
Height: 200,
MinHeight: 10,
MinWidth: 50,
X: 300,
Y: 10,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesBox},
SignalIDs: []int64{3},
}
var WidgetD = database.Widget{
Name: "Action",
Type: "Action",
Width: 20,
Height: 20,
MinHeight: 10,
MinWidth: 50,
X: 10,
Y: 50,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesCustomActions},
SignalIDs: []int64{2},
}
var WidgetE = database.Widget{
Name: "Lamp",
Type: "Lamp",
Width: 200,
Height: 20,
MinHeight: 10,
MinWidth: 50,
X: 50,
Y: 300,
Z: 0,
IsLocked: false,
CustomProperties: postgres.Jsonb{customPropertiesLamp},
SignalIDs: []int64{4},
}
// add a default admin user to the DB
func DBAddAdminUser() error {
database.DBpool.AutoMigrate(&database.User{})
// Check if admin user exists in DB
var users []database.User
err := database.DBpool.Where("Role = ?", "Admin").Find(&users).Error
if len(users) == 0 {
fmt.Println("No admin user found in DB, adding default admin user.")
//create a copy of global test data
user0 := User0
// add admin user to DB
err = database.DBpool.Create(&user0).Error
}
return err
}
// add default admin user, normal users and a guest to the DB
func DBAddAdminAndUserAndGuest() error {
database.DBpool.AutoMigrate(&database.User{})
//create a copy of global test data
user0 := User0
userA := UserA
userB := UserB
userC := UserC
// add admin user to DB
err := database.DBpool.Create(&user0).Error
// add normal users to DB
err = database.DBpool.Create(&userA).Error
err = database.DBpool.Create(&userB).Error
// add guest user to DB
err = database.DBpool.Create(&userC).Error
return err
}

View file

@ -39,12 +39,6 @@ type KeyModels map[string]interface{}
// #################### User data used for testing #######################
// #######################################################################
// Credentials
var StrPassword0 = "xyz789"
var StrPasswordA = "abc123"
var StrPasswordB = "bcd234"
var StrPasswordC = "guestpw"
type Credentials struct {
Username string
Password string

View file

@ -72,13 +72,13 @@ func addScenarioAndIC() (scenarioID uint, ICID uint) {
// POST $newICA
newICA := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
_, resp, _ := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
@ -88,13 +88,13 @@ func addScenarioAndIC() (scenarioID uint, ICID uint) {
// POST a second IC to change to that IC during testing
newICB := ICRequest{
UUID: database.ICB.UUID,
Host: database.ICB.Host,
Type: database.ICB.Type,
Name: database.ICB.Name,
Category: database.ICB.Category,
State: database.ICB.State,
Properties: database.ICB.Properties,
UUID: helper.ICB.UUID,
Host: helper.ICB.Host,
Type: helper.ICB.Type,
Name: helper.ICB.Name,
Category: helper.ICB.Category,
State: helper.ICB.State,
Properties: helper.ICB.Properties,
}
_, resp, _ = helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newICB})
@ -105,9 +105,9 @@ func addScenarioAndIC() (scenarioID uint, ICID uint) {
// POST $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
_, resp, _ = helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -153,7 +153,7 @@ func TestMain(m *testing.M) {
func TestAddConfig(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -161,11 +161,11 @@ func TestAddConfig(t *testing.T) {
scenarioID, ICID := addScenarioAndIC()
newConfig := ConfigRequest{
Name: database.ConfigA.Name,
Name: helper.ConfigA.Name,
ScenarioID: scenarioID,
ICID: ICID,
StartParameters: database.ConfigA.StartParameters,
SelectedFileID: database.ConfigA.SelectedFileID,
StartParameters: helper.ConfigA.StartParameters,
SelectedFileID: helper.ConfigA.SelectedFileID,
}
// authenticate as normal userB who has no access to new scenario
@ -249,7 +249,7 @@ func TestUpdateConfig(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -263,11 +263,11 @@ func TestUpdateConfig(t *testing.T) {
// test POST newConfig
newConfig := ConfigRequest{
Name: database.ConfigA.Name,
Name: helper.ConfigA.Name,
ScenarioID: scenarioID,
ICID: ICID,
StartParameters: database.ConfigA.StartParameters,
SelectedFileID: database.ConfigA.SelectedFileID,
StartParameters: helper.ConfigA.StartParameters,
SelectedFileID: helper.ConfigA.SelectedFileID,
}
code, resp, err := helper.TestEndpoint(router, token,
base_api_configs, "POST", helper.KeyModels{"config": newConfig})
@ -279,8 +279,8 @@ func TestUpdateConfig(t *testing.T) {
assert.NoError(t, err)
updatedConfig := ConfigRequest{
Name: database.ConfigB.Name,
StartParameters: database.ConfigB.StartParameters,
Name: helper.ConfigB.Name,
StartParameters: helper.ConfigB.StartParameters,
}
// authenticate as normal userB who has no access to new scenario
@ -361,7 +361,7 @@ func TestUpdateConfig(t *testing.T) {
func TestDeleteConfig(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -369,11 +369,11 @@ func TestDeleteConfig(t *testing.T) {
scenarioID, ICID := addScenarioAndIC()
newConfig := ConfigRequest{
Name: database.ConfigA.Name,
Name: helper.ConfigA.Name,
ScenarioID: scenarioID,
ICID: ICID,
StartParameters: database.ConfigA.StartParameters,
SelectedFileID: database.ConfigA.SelectedFileID,
StartParameters: helper.ConfigA.StartParameters,
SelectedFileID: helper.ConfigA.SelectedFileID,
}
// authenticate as normal user
@ -434,7 +434,7 @@ func TestDeleteConfig(t *testing.T) {
func TestGetAllConfigsOfScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -448,11 +448,11 @@ func TestGetAllConfigsOfScenario(t *testing.T) {
// test POST newConfig
newConfig := ConfigRequest{
Name: database.ConfigA.Name,
Name: helper.ConfigA.Name,
ScenarioID: scenarioID,
ICID: ICID,
StartParameters: database.ConfigA.StartParameters,
SelectedFileID: database.ConfigA.SelectedFileID,
StartParameters: helper.ConfigA.StartParameters,
SelectedFileID: helper.ConfigA.SelectedFileID,
}
code, resp, err := helper.TestEndpoint(router, token,
base_api_configs, "POST", helper.KeyModels{"config": newConfig})

View file

@ -54,9 +54,9 @@ func addScenario(token string) (scenarioID uint) {
// POST $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
_, resp, err := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -101,7 +101,7 @@ func TestMain(m *testing.M) {
func TestAddDashboard(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -112,8 +112,8 @@ func TestAddDashboard(t *testing.T) {
// test POST dashboards/ $newDashboard
newDashboard := DashboardRequest{
Name: database.DashboardA.Name,
Grid: database.DashboardA.Grid,
Name: helper.DashboardA.Name,
Grid: helper.DashboardA.Grid,
ScenarioID: scenarioID,
}
code, resp, err := helper.TestEndpoint(router, token,
@ -187,7 +187,7 @@ func TestAddDashboard(t *testing.T) {
func TestUpdateDashboard(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -198,8 +198,8 @@ func TestUpdateDashboard(t *testing.T) {
// test POST dashboards/ $newDashboard
newDashboard := DashboardRequest{
Name: database.DashboardA.Name,
Grid: database.DashboardA.Grid,
Name: helper.DashboardA.Name,
Grid: helper.DashboardA.Grid,
ScenarioID: scenarioID,
}
code, resp, err := helper.TestEndpoint(router, token,
@ -212,8 +212,8 @@ func TestUpdateDashboard(t *testing.T) {
assert.NoError(t, err)
updatedDashboard := DashboardRequest{
Name: database.DashboardB.Name,
Grid: database.DashboardB.Grid,
Name: helper.DashboardB.Name,
Grid: helper.DashboardB.Grid,
}
// authenticate as guest user
@ -268,7 +268,7 @@ func TestUpdateDashboard(t *testing.T) {
func TestDeleteDashboard(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -279,8 +279,8 @@ func TestDeleteDashboard(t *testing.T) {
// test POST dashboards/ $newDashboard
newDashboard := DashboardRequest{
Name: database.DashboardA.Name,
Grid: database.DashboardA.Grid,
Name: helper.DashboardA.Name,
Grid: helper.DashboardA.Grid,
ScenarioID: scenarioID,
}
code, resp, err := helper.TestEndpoint(router, token,
@ -341,7 +341,7 @@ func TestDeleteDashboard(t *testing.T) {
func TestGetAllDashboardsOfScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -357,8 +357,8 @@ func TestGetAllDashboardsOfScenario(t *testing.T) {
// test POST dashboards/ $newDashboard
newDashboardA := DashboardRequest{
Name: database.DashboardA.Name,
Grid: database.DashboardA.Grid,
Name: helper.DashboardA.Name,
Grid: helper.DashboardA.Grid,
ScenarioID: scenarioID,
}
code, resp, err := helper.TestEndpoint(router, token,
@ -368,8 +368,8 @@ func TestGetAllDashboardsOfScenario(t *testing.T) {
// POST a second dashboard for the same scenario
newDashboardB := DashboardRequest{
Name: database.DashboardB.Name,
Grid: database.DashboardB.Grid,
Name: helper.DashboardB.Name,
Grid: helper.DashboardB.Grid,
ScenarioID: scenarioID,
}
code, resp, err = helper.TestEndpoint(router, token,

View file

@ -99,13 +99,13 @@ func addScenarioAndICAndConfigAndDashboardAndWidget() (scenarioID uint, ICID uin
// POST $newICA
newICA := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
_, resp, _ := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
@ -119,9 +119,9 @@ func addScenarioAndICAndConfigAndDashboardAndWidget() (scenarioID uint, ICID uin
// POST $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
_, resp, _ = helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -131,10 +131,10 @@ func addScenarioAndICAndConfigAndDashboardAndWidget() (scenarioID uint, ICID uin
// POST new component config
newConfig := ConfigRequest{
Name: database.ConfigA.Name,
Name: helper.ConfigA.Name,
ScenarioID: uint(newScenarioID),
ICID: uint(newICID),
StartParameters: database.ConfigA.StartParameters,
StartParameters: helper.ConfigA.StartParameters,
}
_, resp, _ = helper.TestEndpoint(router, token,
"/api/configs", "POST", helper.KeyModels{"config": newConfig})
@ -144,8 +144,8 @@ func addScenarioAndICAndConfigAndDashboardAndWidget() (scenarioID uint, ICID uin
// POST new dashboard
newDashboard := DashboardRequest{
Name: database.DashboardA.Name,
Grid: database.DashboardA.Grid,
Name: helper.DashboardA.Name,
Grid: helper.DashboardA.Grid,
ScenarioID: uint(newScenarioID),
}
_, resp, _ = helper.TestEndpoint(router, token,
@ -156,17 +156,17 @@ func addScenarioAndICAndConfigAndDashboardAndWidget() (scenarioID uint, ICID uin
// POST new widget
newWidget := WidgetRequest{
Name: database.WidgetA.Name,
Type: database.WidgetA.Type,
Width: database.WidgetA.Width,
Height: database.WidgetA.Height,
MinWidth: database.WidgetA.MinWidth,
MinHeight: database.WidgetA.MinHeight,
X: database.WidgetA.X,
Y: database.WidgetA.Y,
Z: database.WidgetA.Z,
IsLocked: database.WidgetA.IsLocked,
CustomProperties: database.WidgetA.CustomProperties,
Name: helper.WidgetA.Name,
Type: helper.WidgetA.Type,
Width: helper.WidgetA.Width,
Height: helper.WidgetA.Height,
MinWidth: helper.WidgetA.MinWidth,
MinHeight: helper.WidgetA.MinHeight,
X: helper.WidgetA.X,
Y: helper.WidgetA.Y,
Z: helper.WidgetA.Z,
IsLocked: helper.WidgetA.IsLocked,
CustomProperties: helper.WidgetA.CustomProperties,
DashboardID: uint(newDashboardID),
}
_, resp, _ = helper.TestEndpoint(router, token,
@ -222,7 +222,7 @@ func TestMain(m *testing.M) {
func TestAddFile(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// using the respective endpoints of the API
@ -338,7 +338,7 @@ func TestUpdateFile(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// using the respective endpoints of the API
@ -472,7 +472,7 @@ func TestUpdateFile(t *testing.T) {
func TestDeleteFile(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// using the respective endpoints of the API
@ -623,7 +623,7 @@ func TestGetAllFilesOfConfig(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// using the respective endpoints of the API

View file

@ -73,7 +73,7 @@ func TestMain(m *testing.M) {
func TestAddICAsAdmin(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -90,7 +90,7 @@ func TestAddICAsAdmin(t *testing.T) {
// try to POST malformed IC (required fields missing, validation should fail)
// should result in an unprocessable entity
newMalformedIC := ICRequest{
UUID: database.ICB.UUID,
UUID: helper.ICB.UUID,
}
code, resp, err = helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newMalformedIC})
@ -99,13 +99,13 @@ func TestAddICAsAdmin(t *testing.T) {
// test POST ic/ $newIC
newIC := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
code, resp, err = helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
@ -142,7 +142,7 @@ func TestAddICAsAdmin(t *testing.T) {
func TestAddICAsUser(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as user
token, err := helper.AuthenticateForTest(router,
@ -151,13 +151,13 @@ func TestAddICAsUser(t *testing.T) {
// test POST ic/ $newIC
newIC := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
// This should fail with unprocessable entity 422 error code
@ -171,7 +171,7 @@ func TestAddICAsUser(t *testing.T) {
func TestUpdateICAsAdmin(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -180,13 +180,13 @@ func TestUpdateICAsAdmin(t *testing.T) {
// test POST ic/ $newIC
newIC := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
@ -235,7 +235,7 @@ func TestUpdateICAsAdmin(t *testing.T) {
func TestUpdateICAsUser(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -244,13 +244,13 @@ func TestUpdateICAsUser(t *testing.T) {
// test POST ic/ $newIC
newIC := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
@ -279,7 +279,7 @@ func TestUpdateICAsUser(t *testing.T) {
func TestDeleteICAsAdmin(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -288,13 +288,13 @@ func TestDeleteICAsAdmin(t *testing.T) {
// test POST ic/ $newIC
newIC := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
@ -331,7 +331,7 @@ func TestDeleteICAsAdmin(t *testing.T) {
func TestDeleteICAsUser(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -340,13 +340,13 @@ func TestDeleteICAsUser(t *testing.T) {
// test POST ic/ $newIC
newIC := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
@ -374,7 +374,7 @@ func TestDeleteICAsUser(t *testing.T) {
func TestGetAllICs(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -388,13 +388,13 @@ func TestGetAllICs(t *testing.T) {
// test POST ic/ $newICA
newICA := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
@ -403,13 +403,13 @@ func TestGetAllICs(t *testing.T) {
// test POST ic/ $newICB
newICB := ICRequest{
UUID: database.ICB.UUID,
Host: database.ICB.Host,
Type: database.ICB.Type,
Name: database.ICB.Name,
Category: database.ICB.Category,
State: database.ICB.State,
Properties: database.ICB.Properties,
UUID: helper.ICB.UUID,
Host: helper.ICB.Host,
Type: helper.ICB.Type,
Name: helper.ICB.Name,
Category: helper.ICB.Category,
State: helper.ICB.State,
Properties: helper.ICB.Properties,
}
code, resp, err = helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newICB})
@ -439,7 +439,7 @@ func TestGetAllICs(t *testing.T) {
func TestGetConfigsOfIC(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -448,13 +448,13 @@ func TestGetConfigsOfIC(t *testing.T) {
// test POST ic/ $newICA
newICA := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newICA})

275
routes/register.go Normal file
View file

@ -0,0 +1,275 @@
/** Routes package, registration function
*
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLASweb-backend-go
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
package routes
import (
"bytes"
"fmt"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
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/dashboard"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/file"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/healthz"
infrastructure_component "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/metrics"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/signal"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
"github.com/gin-gonic/gin"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"io"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
)
// register all backend endpoints; to be called after DB is initialized
func RegisterEndpoints(router *gin.Engine, api *gin.RouterGroup) {
healthz.RegisterHealthzEndpoint(api.Group("/healthz"))
metrics.RegisterMetricsEndpoint(api.Group("/metrics"))
// All endpoints (except for /healthz and /metrics) require authentication except when someone wants to
// login (POST /authenticate)
user.RegisterAuthenticate(api.Group("/authenticate"))
api.Use(user.Authentication(true))
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
component_configuration.RegisterComponentConfigurationEndpoints(api.Group("/configs"))
signal.RegisterSignalEndpoints(api.Group("/signals"))
dashboard.RegisterDashboardEndpoints(api.Group("/dashboards"))
widget.RegisterWidgetEndpoints(api.Group("/widgets"))
file.RegisterFileEndpoints(api.Group("/files"))
user.RegisterUserEndpoints(api.Group("/users"))
infrastructure_component.RegisterICEndpoints(api.Group("/ic"))
router.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
metrics.InitCounters()
}
// Uses API endpoints to add test data to the backend; All endpoints have to be registered before invoking this function.
func AddTestData(basePath string, router *gin.Engine) (*bytes.Buffer, error) {
database.MigrateModels()
// Create entries of each model (data defined in test_data.go)
// add Admin user
err := helper.DBAddAdminUser()
if err != nil {
return nil, err
}
// authenticate as admin
token, err := helper.AuthenticateForTest(router, basePath+"/authenticate", "POST", helper.AdminCredentials)
if err != nil {
return nil, err
}
// add 2 normal and 1 guest user
code, resp, err := helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": helper.NewUserA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding User_A")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": helper.NewUserB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding User_B")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": helper.NewUserC})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding User_C")
}
// add infrastructure components
code, resp, err = helper.TestEndpoint(router, token, basePath+"/ic", "POST", helper.KeyModels{"ic": helper.ICA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding IC A")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/ic", "POST", helper.KeyModels{"ic": helper.ICB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding IC B")
}
// add scenarios
code, resp, err = helper.TestEndpoint(router, token, basePath+"/scenarios", "POST", helper.KeyModels{"scenario": helper.ScenarioA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Scenario A")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/scenarios", "POST", helper.KeyModels{"scenario": helper.ScenarioB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Scenario B")
}
// add users to scenario
code, resp, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/1/user?username=User_A", basePath), "PUT", nil)
if code != http.StatusOK {
return resp, fmt.Errorf("error adding User_A to Scenario A")
}
code, resp, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/2/user?username=User_A", basePath), "PUT", nil)
if code != http.StatusOK {
return resp, fmt.Errorf("error adding User_A to Scenario B")
}
code, resp, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/2/user?username=User_B", basePath), "PUT", nil)
if code != http.StatusOK {
return resp, fmt.Errorf("error adding User_B to Scenario B")
}
code, resp, err = helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/1/user?username=User_C", basePath), "PUT", nil)
if code != http.StatusOK {
return resp, fmt.Errorf("error adding User_C to Scenario A")
}
// add component configurations
configA := helper.ConfigA
configB := helper.ConfigB
configA.ScenarioID = 1
configB.ScenarioID = 1
configA.ICID = 1
configB.ICID = 2
code, resp, err = helper.TestEndpoint(router, token, basePath+"/configs", "POST", helper.KeyModels{"config": configA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Config A")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/configs", "POST", helper.KeyModels{"config": configB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Config B")
}
// add dashboards
dashboardA := helper.DashboardA
dashboardB := helper.DashboardB
dashboardA.ScenarioID = 1
dashboardB.ScenarioID = 1
code, resp, err = helper.TestEndpoint(router, token, basePath+"/dashboards", "POST", helper.KeyModels{"dashboard": dashboardA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Dashboard B")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/dashboards", "POST", helper.KeyModels{"dashboard": dashboardB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Dashboard B")
}
// add widgets
widgetA := helper.WidgetA
widgetB := helper.WidgetB
widgetC := helper.WidgetC
widgetD := helper.WidgetD
widgetE := helper.WidgetE
widgetA.DashboardID = 1
widgetB.DashboardID = 1
widgetC.DashboardID = 1
widgetD.DashboardID = 1
widgetE.DashboardID = 1
code, resp, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Widget A")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Widget B")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetC})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Widget C")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetD})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Widget D")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": widgetE})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding Widget E")
}
// add signals
outSignalA := helper.OutSignalA
outSignalB := helper.OutSignalB
inSignalA := helper.InSignalA
inSignalB := helper.InSignalB
outSignalA.ConfigID = 1
outSignalB.ConfigID = 1
inSignalA.ConfigID = 1
inSignalB.ConfigID = 1
code, resp, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": outSignalB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding outSignalB")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": outSignalA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding outSignalA")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": inSignalA})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding inSignalA")
}
code, resp, err = helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": inSignalB})
if code != http.StatusOK {
return resp, fmt.Errorf("error adding inSignalB")
}
// upload files
// upload readme file
bodyBuf := &bytes.Buffer{}
bodyWriter := multipart.NewWriter(bodyBuf)
fileWriter, _ := bodyWriter.CreateFormFile("file", "Readme.md")
fh, _ := os.Open("README.md")
defer fh.Close()
// io copy
_, err = io.Copy(fileWriter, fh)
contentType := bodyWriter.FormDataContentType()
bodyWriter.Close()
// Create the request and add file to component config
w1 := httptest.NewRecorder()
req1, _ := http.NewRequest("POST", basePath+"/files?objectID=1&objectType=config", bodyBuf)
req1.Header.Set("Content-Type", contentType)
req1.Header.Add("Authorization", "Bearer "+token)
router.ServeHTTP(w1, req1)
// upload image file
bodyBuf = &bytes.Buffer{}
bodyWriter = multipart.NewWriter(bodyBuf)
fileWriter, _ = bodyWriter.CreateFormFile("file", "logo.png")
fh, _ = os.Open("doc/pictures/villas_web.png")
defer fh.Close()
// io copy
_, err = io.Copy(fileWriter, fh)
contentType = bodyWriter.FormDataContentType()
bodyWriter.Close()
// Create the request and add file to widget
w2 := httptest.NewRecorder()
req2, _ := http.NewRequest("POST", basePath+"/files?objectID=1&objectType=widget", bodyBuf)
req2.Header.Set("Content-Type", contentType)
req2.Header.Add("Authorization", "Bearer "+token)
router.ServeHTTP(w2, req2)
return nil, nil
}

64
routes/register_test.go Normal file
View file

@ -0,0 +1,64 @@
/** Routes package, testing
*
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLASweb-backend-go
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
package routes
import (
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"os"
"testing"
)
var router *gin.Engine
func TestMain(m *testing.M) {
err := configuration.InitConfig()
if err != nil {
panic(m)
}
err = database.InitDB(configuration.GolbalConfig)
if err != nil {
panic(m)
}
defer database.DBpool.Close()
router = gin.Default()
os.Exit(m.Run())
}
func TestRegisterEndpoints(t *testing.T) {
database.DropTables()
database.MigrateModels()
api := router.Group("/api")
RegisterEndpoints(router, api)
}
func TestAddTestData(t *testing.T) {
resp, err := AddTestData("/api", router)
assert.NoError(t, err, "Response body: %v", resp)
}

View file

@ -79,12 +79,12 @@ func TestAddScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
// authenticate as normal user
@ -181,7 +181,7 @@ func TestUpdateScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -190,9 +190,9 @@ func TestUpdateScenario(t *testing.T) {
// test POST scenarios/ $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -209,8 +209,8 @@ func TestUpdateScenario(t *testing.T) {
updatedScenario := ScenarioRequest{
Name: "Updated name",
Running: !database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Running: !helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
// try to update with non JSON body
@ -251,7 +251,7 @@ func TestGetAllScenariosAsAdmin(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -270,9 +270,9 @@ func TestGetAllScenariosAsAdmin(t *testing.T) {
// test POST scenarios/ $newScenarioB
newScenarioB := ScenarioRequest{
Name: database.ScenarioB.Name,
Running: database.ScenarioB.Running,
StartParameters: database.ScenarioB.StartParameters,
Name: helper.ScenarioB.Name,
Running: helper.ScenarioB.Running,
StartParameters: helper.ScenarioB.StartParameters,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenarioB})
@ -286,9 +286,9 @@ func TestGetAllScenariosAsAdmin(t *testing.T) {
// test POST scenarios/ $newScenarioA
newScenarioA := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
code, resp, err = helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenarioA})
@ -312,7 +312,7 @@ func TestGetAllScenariosAsUser(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal userB
token, err := helper.AuthenticateForTest(router,
@ -326,9 +326,9 @@ func TestGetAllScenariosAsUser(t *testing.T) {
// test POST scenarios/ $newScenarioB
newScenarioB := ScenarioRequest{
Name: database.ScenarioB.Name,
Running: database.ScenarioB.Running,
StartParameters: database.ScenarioB.StartParameters,
Name: helper.ScenarioB.Name,
Running: helper.ScenarioB.Running,
StartParameters: helper.ScenarioB.StartParameters,
}
code, resp, err := helper.TestEndpoint(router, token,
@ -343,9 +343,9 @@ func TestGetAllScenariosAsUser(t *testing.T) {
// test POST scenarios/ $newScenarioA
newScenarioA := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
code, resp, err = helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenarioA})
@ -369,7 +369,7 @@ func TestDeleteScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -378,9 +378,9 @@ func TestDeleteScenario(t *testing.T) {
// test POST scenarios/ $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -441,7 +441,7 @@ func TestAddUserToScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -450,9 +450,9 @@ func TestAddUserToScenario(t *testing.T) {
// test POST scenarios/ $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -500,7 +500,7 @@ func TestAddUserToScenario(t *testing.T) {
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
// Compare resp to userB
err = helper.CompareResponse(resp, helper.KeyModels{"user": database.UserB})
err = helper.CompareResponse(resp, helper.KeyModels{"user": helper.UserB})
assert.NoError(t, err)
// Count AGAIN the number of all the users returned for newScenario
@ -521,7 +521,7 @@ func TestGetAllUsersOfScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -530,9 +530,9 @@ func TestGetAllUsersOfScenario(t *testing.T) {
// test POST scenarios/ $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -606,7 +606,7 @@ func TestRemoveUserFromScenario(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -615,9 +615,9 @@ func TestRemoveUserFromScenario(t *testing.T) {
// test POST scenarios/ $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -664,7 +664,7 @@ func TestRemoveUserFromScenario(t *testing.T) {
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
// Compare DELETE's response with UserB
err = helper.CompareResponse(resp, helper.KeyModels{"user": database.UserC})
err = helper.CompareResponse(resp, helper.KeyModels{"user": helper.UserC})
assert.NoError(t, err)
// Count AGAIN the number of all the users returned for newScenario

View file

@ -78,13 +78,13 @@ func addScenarioAndICAndConfig() (scenarioID uint, ICID uint, configID uint) {
// POST $newICA
newICA := ICRequest{
UUID: database.ICA.UUID,
Host: database.ICA.Host,
Type: database.ICA.Type,
Name: database.ICA.Name,
Category: database.ICA.Category,
State: database.ICA.State,
Properties: database.ICA.Properties,
UUID: helper.ICA.UUID,
Host: helper.ICA.Host,
Type: helper.ICA.Type,
Name: helper.ICA.Name,
Category: helper.ICA.Category,
State: helper.ICA.State,
Properties: helper.ICA.Properties,
}
_, resp, _ := helper.TestEndpoint(router, token,
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
@ -98,9 +98,9 @@ func addScenarioAndICAndConfig() (scenarioID uint, ICID uint, configID uint) {
// POST $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
_, resp, _ = helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -110,10 +110,10 @@ func addScenarioAndICAndConfig() (scenarioID uint, ICID uint, configID uint) {
// test POST newConfig
newConfig := ConfigRequest{
Name: database.ConfigA.Name,
Name: helper.ConfigA.Name,
ScenarioID: uint(newScenarioID),
ICID: uint(newICID),
StartParameters: database.ConfigA.StartParameters,
StartParameters: helper.ConfigA.StartParameters,
}
_, resp, _ = helper.TestEndpoint(router, token,
"/api/configs", "POST", helper.KeyModels{"config": newConfig})
@ -162,7 +162,7 @@ func TestMain(m *testing.M) {
func TestAddSignal(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -175,9 +175,9 @@ func TestAddSignal(t *testing.T) {
assert.NoError(t, err)
newSignal := SignalRequest{
Name: database.InSignalA.Name,
Unit: database.InSignalA.Unit,
Direction: database.InSignalA.Direction,
Name: helper.InSignalA.Name,
Unit: helper.InSignalA.Unit,
Direction: helper.InSignalA.Direction,
Index: 1,
ConfigID: configID,
}
@ -257,7 +257,7 @@ func TestAddSignal(t *testing.T) {
func TestUpdateSignal(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -271,9 +271,9 @@ func TestUpdateSignal(t *testing.T) {
// test POST signals/ $newSignal
newSignal := SignalRequest{
Name: database.InSignalA.Name,
Unit: database.InSignalA.Unit,
Direction: database.InSignalA.Direction,
Name: helper.InSignalA.Name,
Unit: helper.InSignalA.Unit,
Direction: helper.InSignalA.Direction,
Index: 1,
ConfigID: configID,
}
@ -287,8 +287,8 @@ func TestUpdateSignal(t *testing.T) {
assert.NoError(t, err)
updatedSignal := SignalRequest{
Name: database.InSignalB.Name,
Unit: database.InSignalB.Unit,
Name: helper.InSignalB.Name,
Unit: helper.InSignalB.Unit,
Index: 1,
}
@ -359,7 +359,7 @@ func TestUpdateSignal(t *testing.T) {
func TestDeleteSignal(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -373,9 +373,9 @@ func TestDeleteSignal(t *testing.T) {
// test POST signals/ $newSignal
newSignal := SignalRequest{
Name: database.InSignalA.Name,
Unit: database.InSignalA.Unit,
Direction: database.InSignalA.Direction,
Name: helper.InSignalA.Name,
Unit: helper.InSignalA.Unit,
Direction: helper.InSignalA.Direction,
Index: 1,
ConfigID: configID,
}
@ -412,9 +412,9 @@ func TestDeleteSignal(t *testing.T) {
// add an output signal to make sure that counting of input signals works
newSignalout := SignalRequest{
Name: database.OutSignalA.Name,
Unit: database.OutSignalA.Unit,
Direction: database.OutSignalA.Direction,
Name: helper.OutSignalA.Name,
Unit: helper.OutSignalA.Unit,
Direction: helper.OutSignalA.Direction,
Index: 1,
ConfigID: configID,
}
@ -454,7 +454,7 @@ func TestDeleteSignal(t *testing.T) {
func TestGetAllInputSignalsOfConfig(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
@ -473,9 +473,9 @@ func TestGetAllInputSignalsOfConfig(t *testing.T) {
// test POST signals/ $newSignal
newSignalA := SignalRequest{
Name: database.InSignalA.Name,
Unit: database.InSignalA.Unit,
Direction: database.InSignalA.Direction,
Name: helper.InSignalA.Name,
Unit: helper.InSignalA.Unit,
Direction: helper.InSignalA.Direction,
Index: 1,
ConfigID: configID,
}
@ -486,9 +486,9 @@ func TestGetAllInputSignalsOfConfig(t *testing.T) {
// add a second input signal
newSignalB := SignalRequest{
Name: database.InSignalB.Name,
Unit: database.InSignalB.Unit,
Direction: database.InSignalB.Direction,
Name: helper.InSignalB.Name,
Unit: helper.InSignalB.Unit,
Direction: helper.InSignalB.Direction,
Index: 2,
ConfigID: configID,
}
@ -499,9 +499,9 @@ func TestGetAllInputSignalsOfConfig(t *testing.T) {
// add an output signal
newSignalAout := SignalRequest{
Name: database.OutSignalA.Name,
Unit: database.OutSignalA.Unit,
Direction: database.OutSignalA.Direction,
Name: helper.OutSignalA.Name,
Unit: helper.OutSignalA.Unit,
Direction: helper.OutSignalA.Direction,
Index: 1,
ConfigID: configID,
}
@ -512,9 +512,9 @@ func TestGetAllInputSignalsOfConfig(t *testing.T) {
// add a second output signal
newSignalBout := SignalRequest{
Name: database.OutSignalB.Name,
Unit: database.OutSignalB.Unit,
Direction: database.OutSignalB.Direction,
Name: helper.OutSignalB.Name,
Unit: helper.OutSignalB.Unit,
Direction: helper.OutSignalB.Direction,
Index: 1,
ConfigID: configID,
}

View file

@ -74,7 +74,7 @@ func TestMain(m *testing.M) {
func TestAuthenticate(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// try to authenticate with non JSON body
// should result in unauthorized
@ -134,7 +134,7 @@ func TestAddGetUser(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -258,7 +258,7 @@ func TestUsersNotAllowedActions(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -318,7 +318,7 @@ func TestGetAllUsers(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -367,7 +367,7 @@ func TestModifyAddedUserAsUser(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -524,7 +524,7 @@ func TestInvalidUserUpdate(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -597,7 +597,7 @@ func TestModifyAddedUserAsAdmin(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,
@ -671,7 +671,7 @@ func TestModifyAddedUserAsAdmin(t *testing.T) {
// modify newUser's password, requires admin password
modRequest = UserRequest{
Password: "4_g00d_pw!",
OldPassword: database.StrPassword0,
OldPassword: helper.StrPassword0,
}
code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/users/%v", newUserID), "PUT",
@ -716,7 +716,7 @@ func TestDeleteUser(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as admin
token, err := helper.AuthenticateForTest(router,

View file

@ -70,9 +70,9 @@ func addScenarioAndDashboard(token string) (scenarioID uint, dashboardID uint) {
// POST $newScenario
newScenario := ScenarioRequest{
Name: database.ScenarioA.Name,
Running: database.ScenarioA.Running,
StartParameters: database.ScenarioA.StartParameters,
Name: helper.ScenarioA.Name,
Running: helper.ScenarioA.Running,
StartParameters: helper.ScenarioA.StartParameters,
}
_, resp, _ := helper.TestEndpoint(router, token,
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
@ -82,8 +82,8 @@ func addScenarioAndDashboard(token string) (scenarioID uint, dashboardID uint) {
// test POST dashboards/ $newDashboard
newDashboard := DashboardRequest{
Name: database.DashboardA.Name,
Grid: database.DashboardA.Grid,
Name: helper.DashboardA.Name,
Grid: helper.DashboardA.Grid,
ScenarioID: uint(newScenarioID),
}
_, resp, _ = helper.TestEndpoint(router, token,
@ -130,7 +130,7 @@ func TestMain(m *testing.M) {
func TestAddWidget(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -140,19 +140,19 @@ func TestAddWidget(t *testing.T) {
_, dashboardID := addScenarioAndDashboard(token)
newWidget := WidgetRequest{
Name: database.WidgetA.Name,
Type: database.WidgetA.Type,
Width: database.WidgetA.Width,
Height: database.WidgetA.Height,
MinWidth: database.WidgetA.MinWidth,
MinHeight: database.WidgetA.MinHeight,
X: database.WidgetA.X,
Y: database.WidgetA.Y,
Z: database.WidgetA.Z,
IsLocked: database.WidgetA.IsLocked,
CustomProperties: database.WidgetA.CustomProperties,
Name: helper.WidgetA.Name,
Type: helper.WidgetA.Type,
Width: helper.WidgetA.Width,
Height: helper.WidgetA.Height,
MinWidth: helper.WidgetA.MinWidth,
MinHeight: helper.WidgetA.MinHeight,
X: helper.WidgetA.X,
Y: helper.WidgetA.Y,
Z: helper.WidgetA.Z,
IsLocked: helper.WidgetA.IsLocked,
CustomProperties: helper.WidgetA.CustomProperties,
DashboardID: dashboardID,
SignalIDs: database.WidgetA.SignalIDs,
SignalIDs: helper.WidgetA.SignalIDs,
}
// authenticate as userB who has no access to scenario
@ -230,7 +230,7 @@ func TestAddWidget(t *testing.T) {
func TestUpdateWidget(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -241,19 +241,19 @@ func TestUpdateWidget(t *testing.T) {
// test POST widgets/ $newWidget
newWidget := WidgetRequest{
Name: database.WidgetA.Name,
Type: database.WidgetA.Type,
Width: database.WidgetA.Width,
Height: database.WidgetA.Height,
MinWidth: database.WidgetA.MinWidth,
MinHeight: database.WidgetA.MinHeight,
X: database.WidgetA.X,
Y: database.WidgetA.Y,
Z: database.WidgetA.Z,
IsLocked: database.WidgetA.IsLocked,
CustomProperties: database.WidgetA.CustomProperties,
Name: helper.WidgetA.Name,
Type: helper.WidgetA.Type,
Width: helper.WidgetA.Width,
Height: helper.WidgetA.Height,
MinWidth: helper.WidgetA.MinWidth,
MinHeight: helper.WidgetA.MinHeight,
X: helper.WidgetA.X,
Y: helper.WidgetA.Y,
Z: helper.WidgetA.Z,
IsLocked: helper.WidgetA.IsLocked,
CustomProperties: helper.WidgetA.CustomProperties,
DashboardID: dashboardID,
SignalIDs: database.WidgetA.SignalIDs,
SignalIDs: helper.WidgetA.SignalIDs,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/widgets", "POST", helper.KeyModels{"widget": newWidget})
@ -265,14 +265,14 @@ func TestUpdateWidget(t *testing.T) {
assert.NoError(t, err)
updatedWidget := WidgetRequest{
Name: database.WidgetB.Name,
Type: database.WidgetB.Type,
Width: database.WidgetB.Width,
Height: database.WidgetB.Height,
MinWidth: database.WidgetB.MinWidth,
MinHeight: database.WidgetB.MinHeight,
CustomProperties: database.WidgetA.CustomProperties,
SignalIDs: database.WidgetB.SignalIDs,
Name: helper.WidgetB.Name,
Type: helper.WidgetB.Type,
Width: helper.WidgetB.Width,
Height: helper.WidgetB.Height,
MinWidth: helper.WidgetB.MinWidth,
MinHeight: helper.WidgetB.MinHeight,
CustomProperties: helper.WidgetA.CustomProperties,
SignalIDs: helper.WidgetB.SignalIDs,
}
// authenticate as userB who has no access to scenario
@ -342,7 +342,7 @@ func TestUpdateWidget(t *testing.T) {
func TestDeleteWidget(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -353,19 +353,19 @@ func TestDeleteWidget(t *testing.T) {
// test POST widgets/ $newWidget
newWidget := WidgetRequest{
Name: database.WidgetA.Name,
Type: database.WidgetA.Type,
Width: database.WidgetA.Width,
Height: database.WidgetA.Height,
MinWidth: database.WidgetA.MinWidth,
MinHeight: database.WidgetA.MinHeight,
X: database.WidgetA.X,
Y: database.WidgetA.Y,
Z: database.WidgetA.Z,
IsLocked: database.WidgetA.IsLocked,
CustomProperties: database.WidgetA.CustomProperties,
Name: helper.WidgetA.Name,
Type: helper.WidgetA.Type,
Width: helper.WidgetA.Width,
Height: helper.WidgetA.Height,
MinWidth: helper.WidgetA.MinWidth,
MinHeight: helper.WidgetA.MinHeight,
X: helper.WidgetA.X,
Y: helper.WidgetA.Y,
Z: helper.WidgetA.Z,
IsLocked: helper.WidgetA.IsLocked,
CustomProperties: helper.WidgetA.CustomProperties,
DashboardID: dashboardID,
SignalIDs: database.WidgetA.SignalIDs,
SignalIDs: helper.WidgetA.SignalIDs,
}
code, resp, err := helper.TestEndpoint(router, token,
"/api/widgets", "POST", helper.KeyModels{"widget": newWidget})
@ -419,7 +419,7 @@ func TestDeleteWidget(t *testing.T) {
func TestGetAllWidgetsOfDashboard(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, database.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
// authenticate as normal user
token, err := helper.AuthenticateForTest(router,
@ -452,19 +452,19 @@ func TestGetAllWidgetsOfDashboard(t *testing.T) {
// test POST widgets/ $newWidget
newWidgetA := WidgetRequest{
Name: database.WidgetA.Name,
Type: database.WidgetA.Type,
Width: database.WidgetA.Width,
Height: database.WidgetA.Height,
MinWidth: database.WidgetA.MinWidth,
MinHeight: database.WidgetA.MinHeight,
X: database.WidgetA.X,
Y: database.WidgetA.Y,
Z: database.WidgetA.Z,
IsLocked: database.WidgetA.IsLocked,
CustomProperties: database.WidgetA.CustomProperties,
Name: helper.WidgetA.Name,
Type: helper.WidgetA.Type,
Width: helper.WidgetA.Width,
Height: helper.WidgetA.Height,
MinWidth: helper.WidgetA.MinWidth,
MinHeight: helper.WidgetA.MinHeight,
X: helper.WidgetA.X,
Y: helper.WidgetA.Y,
Z: helper.WidgetA.Z,
IsLocked: helper.WidgetA.IsLocked,
CustomProperties: helper.WidgetA.CustomProperties,
DashboardID: dashboardID,
SignalIDs: database.WidgetA.SignalIDs,
SignalIDs: helper.WidgetA.SignalIDs,
}
code, resp, err = helper.TestEndpoint(router, token,
"/api/widgets", "POST", helper.KeyModels{"widget": newWidgetA})
@ -472,19 +472,19 @@ func TestGetAllWidgetsOfDashboard(t *testing.T) {
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
newWidgetB := WidgetRequest{
Name: database.WidgetB.Name,
Type: database.WidgetB.Type,
Width: database.WidgetB.Width,
Height: database.WidgetB.Height,
MinWidth: database.WidgetB.MinWidth,
MinHeight: database.WidgetB.MinHeight,
X: database.WidgetB.X,
Y: database.WidgetB.Y,
Z: database.WidgetB.Z,
IsLocked: database.WidgetB.IsLocked,
CustomProperties: database.WidgetB.CustomProperties,
Name: helper.WidgetB.Name,
Type: helper.WidgetB.Type,
Width: helper.WidgetB.Width,
Height: helper.WidgetB.Height,
MinWidth: helper.WidgetB.MinWidth,
MinHeight: helper.WidgetB.MinHeight,
X: helper.WidgetB.X,
Y: helper.WidgetB.Y,
Z: helper.WidgetB.Z,
IsLocked: helper.WidgetB.IsLocked,
CustomProperties: helper.WidgetB.CustomProperties,
DashboardID: dashboardID,
SignalIDs: database.WidgetB.SignalIDs,
SignalIDs: helper.WidgetB.SignalIDs,
}
code, resp, err = helper.TestEndpoint(router, token,
"/api/widgets", "POST", helper.KeyModels{"widget": newWidgetB})

162
start.go
View file

@ -23,163 +23,38 @@ package main
import (
"fmt"
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/dashboard"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/file"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/healthz"
infrastructure_component "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/signal"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"log"
"time"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/amqp"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
apidocs "git.rwth-aachen.de/acs/public/villas/web-backend-go/doc/api" // doc/api folder is used by Swag CLI, you have to import it
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/metrics"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes"
"github.com/gin-gonic/gin"
"log"
)
func configureBackend() (string, string, string, string, string, string, string, error) {
err := configuration.InitConfig()
if err != nil {
log.Printf("Error during initialization of global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
err = database.InitDB(configuration.GolbalConfig)
if err != nil {
log.Printf("Error during initialization of database: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
mode, err := configuration.GolbalConfig.String("mode")
if err != nil {
log.Printf("Error reading mode from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
if mode == "release" {
gin.SetMode(gin.ReleaseMode)
}
baseHost, err := configuration.GolbalConfig.String("base.host")
if err != nil {
log.Printf("Error reading base.host from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
basePath, err := configuration.GolbalConfig.String("base.path")
if err != nil {
log.Printf("Error reading base.path from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
port, err := configuration.GolbalConfig.String("port")
if err != nil {
log.Printf("Error reading port from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
apidocs.SwaggerInfo.Host = baseHost
apidocs.SwaggerInfo.BasePath = basePath
metrics.InitCounters()
AMQPhost, _ := configuration.GolbalConfig.String("amqp.host")
AMQPuser, _ := configuration.GolbalConfig.String("amqp.user")
AMQPpass, _ := configuration.GolbalConfig.String("amqp.pass")
return mode, baseHost, basePath, port, AMQPhost, AMQPuser, AMQPpass, nil
}
func registerEndpoints(router *gin.Engine, api *gin.RouterGroup) {
healthz.RegisterHealthzEndpoint(api.Group("/healthz"))
metrics.RegisterMetricsEndpoint(api.Group("/metrics"))
// All endpoints (except for /healthz and /metrics) require authentication except when someone wants to
// login (POST /authenticate)
user.RegisterAuthenticate(api.Group("/authenticate"))
api.Use(user.Authentication(true))
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
component_configuration.RegisterComponentConfigurationEndpoints(api.Group("/configs"))
signal.RegisterSignalEndpoints(api.Group("/signals"))
dashboard.RegisterDashboardEndpoints(api.Group("/dashboards"))
widget.RegisterWidgetEndpoints(api.Group("/widgets"))
file.RegisterFileEndpoints(api.Group("/files"))
user.RegisterUserEndpoints(api.Group("/users"))
infrastructure_component.RegisterICEndpoints(api.Group("/ic"))
router.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}
func addData(router *gin.Engine, mode string, basePath string) error {
if mode == "test" {
// test mode: drop all tables and add test data to DB
database.DropTables()
log.Println("Database tables dropped, adding test data to DB")
err := database.DBAddTestData(basePath, router)
log.Println("Database tables dropped, using API to add test data")
resp, err := routes.AddTestData(basePath, router)
if err != nil {
fmt.Println(err.Error())
fmt.Println("error: testdata could not be added to DB, aborting")
fmt.Println("error: testdata could not be added to DB:", err.Error(), "Response body: ", resp)
return err
}
log.Println("Database initialized with test data")
} else {
// release mode: make sure that at least one admin user exists in DB
err := database.DBAddAdminUser()
err := helper.DBAddAdminUser()
if err != nil {
fmt.Println(err.Error())
fmt.Println("error: adding admin user failed, aborting")
fmt.Println("error: adding admin user failed:", err.Error())
return err
}
}
return nil
}
func connectAMQP(AMQPurl string, api *gin.RouterGroup) error {
if AMQPurl != "" {
log.Println("Starting AMQP client")
err := amqp.ConnectAMQP(AMQPurl)
if err != nil {
return err
}
// register IC action endpoint only if AMQP client is used
amqp.RegisterAMQPEndpoint(api.Group("/ic"))
// Periodically call the Ping function to check which ICs are still there
ticker := time.NewTicker(10 * time.Second)
go func() {
for {
select {
case <-ticker.C:
err = amqp.PingAMQP()
if err != nil {
log.Println("AMQP Error: ", err.Error())
}
}
}
}()
log.Printf("Connected AMQP client to %s", AMQPurl)
}
return nil
}
// @title VILLASweb Backend API
// @version 2.0
// @description This is the VILLASweb Backend API v2.0.
@ -193,25 +68,40 @@ func connectAMQP(AMQPurl string, api *gin.RouterGroup) error {
func main() {
log.Println("Starting VILLASweb-backend-go")
mode, _, basePath, port, amqphost, amqpuser, amqppass, err := configureBackend()
mode, baseHost, basePath, port, amqphost, amqpuser, amqppass, err := configuration.ConfigureBackend()
if err != nil {
panic(err)
}
//init database
err = database.InitDB(configuration.GolbalConfig)
if err != nil {
log.Printf("Error during initialization of database: %v, aborting.", err.Error())
panic(err)
}
defer database.DBpool.Close()
// init endpoints
if mode == "release" {
gin.SetMode(gin.ReleaseMode)
}
r := gin.Default()
api := r.Group(basePath)
registerEndpoints(r, api)
routes.RegisterEndpoints(r, api)
apidocs.SwaggerInfo.Host = baseHost
apidocs.SwaggerInfo.BasePath = basePath
// add data to DB (if any)
err = addData(r, mode, basePath)
if err != nil {
panic(err)
}
//Start AMQP client
if amqphost != "" {
// create amqp URL based on username, password and host
amqpurl := "amqp://" + amqpuser + ":" + amqppass + "@" + amqphost
err = connectAMQP(amqpurl, api)
err = amqp.StartAMQP(amqpurl, api)
if err != nil {
panic(err)
}