Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ACS
Public
VILLASframework
VILLASweb-backend-go
Commits
616a1c74
Commit
616a1c74
authored
Jan 26, 2021
by
Sonja Happ
Browse files
WIP: adding test data via JSON file
#44
parent
d99b7691
Changes
16
Hide whitespace changes
Inline
Side-by-side
configuration/config.go
View file @
616a1c74
...
...
@@ -61,6 +61,7 @@ func InitConfig() error {
s3PathStyle
=
flag
.
Bool
(
"s3-pathstyle"
,
false
,
"Use path-style S3 API"
)
jwtSecret
=
flag
.
String
(
"jwt-secret"
,
"This should NOT be here!!@33$8&"
,
"The JSON Web Token secret"
)
jwtExpiresAfter
=
flag
.
String
(
"jwt-expires-after"
,
"168h"
/* 1 week */
,
"The time after which the JSON Web Token expires"
)
testDataPath
=
flag
.
String
(
"test-data-path"
,
"database/testdata.json"
,
"The path to the test data json file (used in test mode)"
)
)
flag
.
Parse
()
...
...
@@ -85,6 +86,7 @@ func InitConfig() error {
"s3.region"
:
*
s3Region
,
"jwt.secret"
:
*
jwtSecret
,
"jwt.expires-after"
:
*
jwtExpiresAfter
,
"test.datapath"
:
*
testDataPath
,
}
if
*
s3NoSSL
==
true
{
...
...
@@ -122,6 +124,7 @@ func InitConfig() error {
"S3_PATHSTYLE"
:
"s3.pathstyle"
,
"JWT_SECRET"
:
"jwt.secret"
,
"JWT_EXPIRES_AFTER"
:
"jwt.expires-after"
,
"TEST_DATA_PATH"
:
"test.datapath"
,
}
defaults
:=
config
.
NewStatic
(
static
)
...
...
database/database.go
View file @
616a1c74
...
...
@@ -23,8 +23,11 @@ package database
import
(
"fmt"
"golang.org/x/crypto/bcrypt"
"log"
"math/rand"
"strings"
"time"
"github.com/jinzhu/gorm"
_
"github.com/jinzhu/gorm/dialects/postgres"
...
...
@@ -110,3 +113,58 @@ func MigrateModels() {
DBpool
.
AutoMigrate
(
&
Widget
{})
DBpool
.
AutoMigrate
(
&
Result
{})
}
// DBAddAdminUser adds a default admin user to the DB
func
DBAddAdminUser
(
cfg
*
config
.
Config
)
(
error
,
string
)
{
DBpool
.
AutoMigrate
(
User
{})
// Check if admin user exists in DB
var
users
[]
User
err
:=
DBpool
.
Where
(
"Role = ?"
,
"Admin"
)
.
Find
(
&
users
)
.
Error
adminPW
:=
""
if
len
(
users
)
==
0
{
fmt
.
Println
(
"No admin user found in DB, adding default admin user."
)
name
,
err
:=
cfg
.
String
(
"admin.user"
)
if
err
!=
nil
||
name
==
""
{
name
=
"admin"
}
adminPW
,
err
=
cfg
.
String
(
"admin.pass"
)
if
err
!=
nil
||
adminPW
==
""
{
adminPW
=
generatePassword
(
16
)
fmt
.
Printf
(
" Generated admin password: %s
\n
"
,
adminPW
)
}
mail
,
err
:=
cfg
.
String
(
"admin.mail"
)
if
err
==
nil
||
mail
==
""
{
mail
=
"admin@example.com"
}
pwEnc
,
_
:=
bcrypt
.
GenerateFromPassword
([]
byte
(
adminPW
),
10
)
// create a copy of global test data
user
:=
User
{
Username
:
name
,
Password
:
string
(
pwEnc
),
Role
:
"Admin"
,
Mail
:
mail
,
Active
:
true
}
// add admin user to DB
err
=
DBpool
.
Create
(
&
user
)
.
Error
}
return
err
,
adminPW
}
func
generatePassword
(
Len
int
)
string
{
rand
.
Seed
(
time
.
Now
()
.
UnixNano
())
chars
:=
[]
rune
(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
"abcdefghijklmnopqrstuvwxyz"
+
"0123456789"
)
var
b
strings
.
Builder
for
i
:=
0
;
i
<
Len
;
i
++
{
b
.
WriteRune
(
chars
[
rand
.
Intn
(
len
(
chars
))])
}
return
b
.
String
()
}
database/testdata.json
0 → 100644
View file @
616a1c74
{
"users"
:
[
{
"username"
:
"User_0"
,
"password"
:
"xyz789"
,
"role"
:
"Admin"
,
"mail"
:
"User_0@example.com"
},
{
"username"
:
"User_A"
,
"password"
:
"abc123"
,
"role"
:
"User"
,
"mail"
:
"User_A@example.com"
},
{
"username"
:
"User_B"
,
"password"
:
"bcd234"
,
"role"
:
"User"
,
"mail"
:
"User_B@example.com"
},
{
"username"
:
"User_C"
,
"password"
:
"guestpw"
,
"role"
:
"Guest"
,
"mail"
:
"User_C@example.com"
}
],
"ics"
:
[
{
"uuid"
:
"7be0322d-354e-431e-84bd-ae4c9633138b"
,
"name"
:
"ACS Demo Signals"
,
"type"
:
"villas-node"
,
"category"
:
"gateway"
,
"websocketurl"
:
"https://villas.k8s.eonerc.rwth-aachen.de/ws/ws_sig"
,
"apiurl"
:
"https://villas.k8s.eonerc.rwth-aachen.de/ws/api/v2"
,
"location"
:
"K8S"
,
"description"
:
"A signal generator for testing purposes"
,
"state"
:
"idle"
,
"managedexternally"
:
false
,
"startparameterscheme"
:
{
"param1"
:
42
,
"param2"
:
"testvalue"
}
},
{
"uuid"
:
"4854af30-325f-44a5-ad59-b67b2597de68"
,
"name"
:
"Test DPsim Simulator"
,
"type"
:
"dpsim"
,
"category"
:
"simulator"
,
"location"
:
"acs lab"
,
"description"
:
"DPsim simulator"
,
"state"
:
"running"
,
"managedexternally"
:
true
,
"startparameterscheme"
:
{
"param1"
:
55
,
"param2"
:
"testvalue2"
}
}
],
"scenarios"
:
[
{
"name"
:
"Scenario_A"
,
"startParameters"
:
{
"param1"
:
"a nice param"
,
"param2"
:
"a not so nice param"
}
},
{
"name"
:
"Scenario_B"
,
"startParameters"
:
{
"param1"
:
"another nice param"
,
"param2"
:
"another not so nice param"
}
}
],
"configs"
:
[
{
"name"
:
"Example for Signal generator"
,
"startParameters"
:
{
"param1"
:
"nice param"
,
"param2"
:
"not so nice"
},
"fileIDs"
:
[]
},
{
"name"
:
"Example for DPsim simulator"
,
"startParameters"
:
{
"param1"
:
"cool thing"
,
"param2"
:
"who needs this"
},
"fileIDs"
:
[]
}
],
"dashboards"
:
[
{
"name"
:
"Dashboard_A"
,
"grid"
:
15
},
{
"name"
:
"Dashboard_B"
,
"grid"
:
10
}
],
"results"
:
[
{
"description"
:
"Test run 1"
},
{
"description"
:
"Test run 2"
}
],
"widgets"
:
[
{
"name"
:
"MyLabel"
,
"type"
:
"Label"
,
"width"
:
100
,
"height"
:
50
,
"minWidth"
:
40
,
"minHeight"
:
80
,
"x"
:
10
,
"y"
:
10
,
"z"
:
200
,
"isLocked"
:
false
,
"signalIDs"
:
[],
"customProperties"
:
{
"textSize"
:
"20"
,
"fontColor"
:
"#4287f5"
,
"fontColor_opacity"
:
1
}
},
{
"name"
:
"MySlider"
,
"type"
:
"Slider"
,
"width"
:
400
,
"height"
:
50
,
"minWidth"
:
30
,
"minHeight"
:
380
,
"x"
:
70
,
"y"
:
400
,
"z"
:
0
,
"isLocked"
:
false
,
"signalIDs"
:
[],
"customProperties"
:
{
"default_value"
:
0
,
"orientation"
:
0
,
"rangeMin"
:
0
,
"rangeMax"
:
200
,
"rangeUseMinMax"
:
true
,
"showUnit"
:
true
,
"continous_update"
:
false
,
"value"
:
""
,
"resizeLeftRightLock"
:
false
,
"resizeTopBottomLock"
:
true
,
"step"
:
0.1
}
},
{
"name"
:
"MyBox"
,
"type"
:
"Box"
,
"width"
:
200
,
"height"
:
200
,
"minWidth"
:
10
,
"minHeight"
:
50
,
"x"
:
300
,
"y"
:
10
,
"z"
:
0
,
"isLocked"
:
false
,
"signalIDs"
:
[],
"customProperties"
:
{
"border_color"
:
"#4287f5"
,
"border_color_opacity"
:
1
,
"background_color"
:
"#961520"
,
"background_color_opacity"
:
1
}
},
{
"name"
:
"MyButton"
,
"type"
:
"Button"
,
"width"
:
100
,
"height"
:
100
,
"minWidth"
:
50
,
"minHeight"
:
100
,
"x"
:
10
,
"y"
:
50
,
"z"
:
0
,
"isLocked"
:
false
,
"signalIDs"
:
[],
"customProperties"
:
{
"pressed"
:
false
,
"toggle"
:
false
,
"on_value"
:
1
,
"off_value"
:
0
,
"background_color"
:
"#961520"
,
"font_color"
:
"#4287f5"
,
"border_color"
:
"#4287f5"
,
"background_color_opacity"
:
1
}
},
{
"name"
:
"MyLamp"
,
"type"
:
"Lamp"
,
"width"
:
200
,
"height"
:
20
,
"minWidth"
:
10
,
"minHeight"
:
50
,
"x"
:
50
,
"y"
:
300
,
"z"
:
0
,
"isLocked"
:
false
,
"signalIDs"
:
[],
"customProperties"
:
{
"on_color"
:
"#4287f5"
,
"off_color"
:
"#961520"
,
"threshold"
:
0.5
,
"on_color_opacity"
:
1
,
"off_color_opacity"
:
1
}
}
],
"signals"
:
[
{
"name"
:
"outSignal_A"
,
"direction"
:
"out"
,
"unit"
:
"V"
,
"index"
:
1
},
{
"name"
:
"outSignal_B"
,
"direction"
:
"out"
,
"unit"
:
"V"
,
"index"
:
2
},
{
"name"
:
"outSignal_C"
,
"direction"
:
"out"
,
"unit"
:
"---"
,
"index"
:
3
},
{
"name"
:
"outSignal_D"
,
"direction"
:
"out"
,
"unit"
:
"---"
,
"index"
:
4
},
{
"name"
:
"outSignal_E"
,
"direction"
:
"out"
,
"unit"
:
"---"
,
"index"
:
5
},
{
"name"
:
"inSignal_A"
,
"direction"
:
"in"
,
"unit"
:
"---"
,
"index"
:
1
},
{
"name"
:
"inSignal_B"
,
"direction"
:
"in"
,
"unit"
:
"---"
,
"index"
:
2
}
]
}
\ No newline at end of file
helper/test_data.go
View file @
616a1c74
...
...
@@ -24,20 +24,37 @@ package helper
import
(
"encoding/json"
"fmt"
"math/rand"
"strings"
"time"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"github.com/jinzhu/gorm/dialects/postgres"
"github.com/zpatrick/go-config"
"golang.org/x/crypto/bcrypt"
"io/ioutil"
"log"
"os"
)
// #######################################################################
// #################### Data used for testing ############################
// #######################################################################
type
jsonUser
struct
{
Username
string
Password
string
Mail
string
Role
string
}
var
GlobalTestData
struct
{
Users
[]
jsonUser
ICs
[]
database
.
InfrastructureComponent
Scenarios
[]
database
.
Scenario
Results
[]
database
.
Result
Configs
[]
database
.
ComponentConfiguration
Dashboards
[]
database
.
Dashboard
Widgets
[]
database
.
Widget
Signals
[]
database
.
Signal
}
// Credentials
var
StrPassword0
=
"xyz789"
var
StrPasswordA
=
"abc123"
...
...
@@ -46,13 +63,10 @@ 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
),
...
...
@@ -216,35 +230,6 @@ var DashboardB = database.Dashboard{
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
customPropertiesBox
=
json
.
RawMessage
(
`{"border_color" : "#4287f5", "border_color_opacity": 1, "background_color" : "#961520", "background_color_opacity" : 1}`
)
var
customPropertiesSlider
=
json
.
RawMessage
(
`{"default_value" : 0, "orientation" : 0, "rangeUseMinMax": false, "rangeMin" : 0, "rangeMax": 200, "rangeUseMinMax" : true, "showUnit": true, "continous_update": false, "value": "", "resizeLeftRightLock": false, "resizeTopBottomLock": true, "step": 0.1 }`
)
...
...
@@ -327,84 +312,63 @@ var WidgetE = database.Widget{
SignalIDs
:
[]
int64
{},
}
func
generatePassword
(
Len
int
)
string
{
rand
.
Seed
(
time
.
Now
()
.
UnixNano
())
chars
:=
[]
rune
(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
"abcdefghijklmnopqrstuvwxyz"
+
"0123456789"
)
func
ReadTestDataFromJson
(
path
string
)
error
{
var
b
strings
.
Builder
for
i
:=
0
;
i
<
Len
;
i
++
{
b
.
WriteRune
(
chars
[
rand
.
Intn
(
len
(
chars
))]
)
jsonFile
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error opening json file: %v"
,
err
)
}
log
.
Println
(
"Successfully opened json data file"
,
path
)
return
b
.
String
()
}
// DBAddAdminUser adds a default admin user to the DB
func
DBAddAdminUser
(
cfg
*
config
.
Config
)
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
defer
jsonFile
.
Close
()
if
len
(
users
)
==
0
{
fmt
.
Println
(
"No admin user found in DB, adding default admin user."
)
byteValue
,
_
:=
ioutil
.
ReadAll
(
jsonFile
)
mode
,
err
:=
cfg
.
String
(
"mode"
)
err
=
json
.
Unmarshal
(
byteValue
,
&
GlobalTestData
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error unmarshalling json: %v"
,
err
)
}
name
,
err
:=
cfg
.
String
(
"admin.user"
)
if
(
err
!=
nil
||
name
==
""
)
&&
mode
!=
"test"
{
name
=
"admin"
}
else
if
mode
==
"test"
{
name
=
User0
.
Username
}
log
.
Println
(
len
(
GlobalTestData
.
Users
))
pw
,
err
:=
cfg
.
String
(
"admin.pass"
)
if
(
err
!=
nil
||
pw
==
""
)
&&
mode
!=
"test"
{
pw
=
generatePassword
(
16
)
fmt
.
Printf
(
" Generated admin password: %s
\n
"
,
pw
)
}
else
if
mode
==
"test"
{
pw
=
StrPassword0
}
mail
,
err
:=
cfg
.
String
(
"admin.mail"
)
if
(
err
==
nil
||
mail
==
""
)
&&
mode
!=
"test"
{
mail
=
"admin@example.com"
}
else
if
mode
==
"test"
{
mail
=
User0
.
Mail
}
pwEnc
,
_
:=
bcrypt
.
GenerateFromPassword
([]
byte
(
pw
),
bcryptCost
)
return
nil
}
// create a copy of global test data
user
:=
database
.
User
{
Username
:
name
,
Password
:
string
(
pwEnc
),
Role
:
"Admin"
,
Mail
:
mail
,
Active
:
true
}
// add default admin user, normal users and a guest to the DB
func
AddTestUsers
()
error
{
// add admin user to DB
err
=
database
.
DBpool
.
Create
(
&
user
)
.
Error
err
:=
ReadTestDataFromJson
(
"../../testdata/testdata.json"
)
if
err
!=
nil
{
return
err
}
return
err
}
//create a copy of global test data
if
len
(
GlobalTestData
.
Users
)
==
0
{
return
fmt
.
Errorf
(
"no users in test data"
)
}
// add default admin user, normal users and a guest to the DB
func
DBAddAdminAndUserAndGuest
()
error
{
database
.
DBpool
.
AutoMigrate
(
&
database
.
User
{})
err
,
_
=
database
.
DBAddAdminUser
(
configuration
.
GlobalConfig
)
if
err
!=
nil
{
return
err
}
//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
for
_
,
user
:=
range
GlobalTestData
.
Users
{
if
user
.
Role
!=
"Admin"
{
// add users to DB that are not admin users
var
newUser
database
.
User
newUser
.
Username
=
user
.
Username
newUser
.
Role
=
user
.
Role
newUser
.
Mail
=
user
.
Mail
pwEnc
,
_
:=
bcrypt
.
GenerateFromPassword
([]
byte
(
user
.
Password
),
10
)
newUser
.
Password
=
string
(
pwEnc
)
err
=
database
.
DBpool
.
Create
(
&
newUser
)
.
Error
if
err
!=
nil
{
return
err
}
}
}
return
nil
}
helper/test_utilities.go
View file @
616a1c74
...
...
@@ -41,13 +41,13 @@ type KeyModels map[string]interface{}
// #######################################################################
type
Credentials
struct
{
Username
string
Password
string
Username
string
`json:"username,required"`
Password
string
`json:"password,required"`
}
var
AdminCredentials
=
Credentials
{
Username
:
"
User_0
"
,
Password
:
StrPassword0
,
Username
:
"
admin
"
,
Password
:
"xyz789"
,
}
var
UserACredentials
=
Credentials
{
...
...
routes/component-configuration/config_test.go
View file @
616a1c74
...
...
@@ -172,7 +172,7 @@ func TestMain(m *testing.M) {
func
TestAddConfig
(
t
*
testing
.
T
)
{
database
.
DropTables
()
database
.
MigrateModels
()
assert
.
NoError
(
t
,
helper
.
DB
Add
AdminAndUserAndGuest
())
assert
.
NoError
(
t
,
helper
.
Add
TestUsers
())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
...
...
@@ -268,7 +268,7 @@ func TestUpdateConfig(t *testing.T) {