Newer
Older
/*
* Copyright (c) 2020 InterDigital Communications, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Simon Pastor
committed
"encoding/json"
Simon Pastor
committed
"github.com/ghodss/yaml"
gisClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-engine-client"
log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
platformCtrlClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-platform-ctrl-client"
sandboxCtrlClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client"
)
var httpReqBody []string
var platformCtrlAppClient *platformCtrlClient.APIClient
var sandboxCtrlAppClient *sandboxCtrlClient.APIClient
var gisAppClient *gisClient.APIClient
var sandboxName = "sandbox-system-test"
var hostUrlStr = ""
var httpListenerPort = "3333"
var run = false
func resetHttpReqBody() {
httpReqBody = []string{}
}
func printHttpReqBody() {
for index, body := range httpReqBody {
log.Info("Notification received: (" + strconv.Itoa(index) + "):" + body)
}
}
func printHttpReqBodyByIndex(index int) {
log.Info("Notification received: (" + strconv.Itoa(index) + "):" + httpReqBody[index])
}
hostUrl, _ := url.Parse(strings.TrimSpace(os.Getenv("MEEP_HOST_TEST_URL")))
hostUrlStr = hostUrl.String()
if hostUrlStr == "" {
hostUrlStr = "http://localhost"
}
// Create & store client for App REST API
platformCtrlAppClientCfg := platformCtrlClient.NewConfiguration()
Simon Pastor
committed
hostUrlStr = "http://localhost"
}
Simon Pastor
committed
platformCtrlAppClientCfg.BasePath = hostUrlStr + "/platform-ctrl/v1"
platformCtrlAppClient = platformCtrlClient.NewAPIClient(platformCtrlAppClientCfg)
if platformCtrlAppClient == nil {
log.Error("Failed to create Platform App REST API client: ", platformCtrlAppClientCfg.BasePath)
err := errors.New("Failed to create Platform App REST API client")
return err
}
return nil
}
func createSandboxClients(sandboxName string) error {
// Create & store client for App REST API
sandboxCtrlAppClientCfg := sandboxCtrlClient.NewConfiguration()
if hostUrlStr == "" {
Simon Pastor
committed
hostUrlStr = "http://localhost"
Simon Pastor
committed
sandboxCtrlAppClientCfg.BasePath = hostUrlStr + "/" + sandboxName + "/sandbox-ctrl/v1"
sandboxCtrlAppClient = sandboxCtrlClient.NewAPIClient(sandboxCtrlAppClientCfg)
if sandboxCtrlAppClient == nil {
log.Error("Failed to create Sandbox App REST API client: ", sandboxCtrlAppClientCfg.BasePath)
err := errors.New("Failed to create Sandbox App REST API client")
return err
}
gisAppClientCfg := gisClient.NewConfiguration()
Simon Pastor
committed
gisAppClientCfg.BasePath = hostUrlStr + "/" + sandboxName + "/gis/v1"
gisAppClient = gisClient.NewAPIClient(gisAppClientCfg)
if gisAppClient == nil {
log.Error("Failed to create GIS App REST API client: ", gisAppClientCfg.BasePath)
err := errors.New("Failed to create GIS App REST API client")
return err
}
return nil
}
func createSandbox(name string) error {
config := platformCtrlClient.SandboxConfig{""}
_, err := platformCtrlAppClient.SandboxControlApi.CreateSandboxWithName(context.TODO(), name, config)
if err != nil {
log.Error("Failed to create sandbox: ", err)
return err
}
}
func deleteSandbox(name string) error {
_, err := platformCtrlAppClient.SandboxControlApi.DeleteSandbox(context.TODO(), name)
if err != nil {
log.Error("Failed to delete sandbox: ", err)
return err
}
Simon Pastor
committed
func createScenario(name string, filepath string) error {
//get the content of the file, assuming yaml content
yamlContent, err := ioutil.ReadFile(filepath)
Simon Pastor
committed
if err != nil {
Simon Pastor
committed
return err
}
//converting to json since unmarshal with yaml directly not working well, while json does
jsonContent, err := yaml.YAMLToJSON(yamlContent)
if err != nil {
log.Error("Failed converting yaml to json: ", err)
return err
}
var scenario platformCtrlClient.Scenario
Simon Pastor
committed
err = json.Unmarshal([]byte(jsonContent), &scenario)
if err != nil {
log.Error("Failed to unmarshal: ", err)
return err
}
_, err = platformCtrlAppClient.ScenarioConfigurationApi.CreateScenario(context.TODO(), name, scenario)
if err != nil {
log.Error("Failed to create scenario: ", err)
return err
}
}
func deleteScenario(name string) error {
_, err := platformCtrlAppClient.ScenarioConfigurationApi.DeleteScenario(context.TODO(), name)
if err != nil {
log.Error("Failed to delete scenario: ", err)
return err
}
}
func activateScenario(name string) error {
_, err := sandboxCtrlAppClient.ActiveScenarioApi.ActivateScenario(context.TODO(), name, nil)
if err != nil {
log.Error("Failed to activate scenario: ", err)
return err
}
_, _, err = sandboxCtrlAppClient.ActiveScenarioApi.GetActiveScenario(context.TODO(), nil)
if err != nil {
log.Error("Scenario not active : ", err)
return err
}
//reinitialisation of http msg queue
resetHttpReqBody()
_, err := sandboxCtrlAppClient.ActiveScenarioApi.TerminateScenario(context.TODO())
if err != nil {
log.Error("Failed to terminate scenario: ", err)
return err
}
func createSystemTestReadyState() error {
log.Info("creating Clients")
err := createClients()
if err != nil {
return err
}
log.Info("creating Sandbox")
err = createSandbox(sandboxName)
if err != nil {
return err
} else {
time.Sleep(30000 * time.Millisecond)
log.Info("creating Sandbox Clients")
err = createSandboxClients(sandboxName)
if err != nil {
clearSystemTestReadyState()
return err
}
return nil
func clearSystemTestReadyState() {
log.Info("deleting Sandbox")
deleteSandbox(sandboxName)
func startSystemTest() error {
go systemTest()
err := createSystemTestReadyState()
if err != nil {
run = false
return err
}
clearSystemTestReadyState()
func systemTest() {
//create default route handler
http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
log.Info("http message received!")
defer req.Body.Close()
body, _ := ioutil.ReadAll(req.Body)
httpReqBody = append(httpReqBody, string(body))
})
log.Info(os.Args)
log.Info("Starting System Test")
run = true
//creating a server for graceful shutdown
listenerPort := ":" + httpListenerPort
server := &http.Server{Addr: listenerPort}
go func() {
sigchan := make(chan os.Signal, 10)
signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM)
<-sigchan
log.Info("Program killed !")
// do last actions and wait for all write operations to end
run = false
//graceful server shutdown
err := server.Shutdown(context.Background())
if err != nil {
log.Info("Error shuting down the server: ", err)
}
}()
go func() {
//create default route handler
if err := server.ListenAndServe(); err != http.ErrServerClosed {
// Error starting or closing listener
log.Fatal("HTTP server ListenAndServe: ", err)
}
//log.Fatal(http.ListenAndServe(":" + httpListenerPort, nil))
run = false
}()
count := 0
for {
if !run {
log.Info("Ran for ", count, " seconds")
clearSystemTestReadyState()
break
}
time.Sleep(time.Second)
count++
}
}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
func isAutomationReady(waitUntilReady bool, maxRetry int, initialWait int) bool {
if initialWait > 0 {
time.Sleep(time.Duration(initialWait) * time.Second)
}
var err error
if waitUntilReady {
retry := 0
for retry <= maxRetry {
_, _, err = gisAppClient.AutomationApi.GetAutomationState(context.TODO())
if err != nil {
retry++
log.Error("Failed to communicate with gis engine but retrying: ", err)
time.Sleep(time.Second)
} else {
return true
}
}
log.Error("Failed to communicate with gis engine: ", err)
return false
} else {
_, _, err = gisAppClient.AutomationApi.GetAutomationState(context.TODO())
if err != nil {
log.Error("Failed to communicate with gis engine: ", err)
return false
}
}
return true
}
func geAutomationUpdate(mobility bool, movement bool, poasInRange bool, netCharUpd bool) error {
_, err := gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "MOBILITY", mobility)
if err != nil {
log.Error("Failed to communicate with gis engine: ", err)
return err
}
_, err = gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "MOVEMENT", movement)
if err != nil {
log.Error("Failed to communicate with gis engine: ", err)
return err
}
_, err = gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "POAS-IN-RANGE", poasInRange)
if err != nil {
log.Error("Failed to communicate with gis engine: ", err)
return err
}
_, err = gisAppClient.AutomationApi.SetAutomationStateByName(context.TODO(), "NETWORK-CHARACTERISTICS-UPDATE", netCharUpd)
if err != nil {
log.Error("Failed to communicate with gis engine: ", err)
return err
}
return nil
}
func geMoveAssetCoordinates(assetName string, long float32, lat float32) error {
var geoData gisClient.GeoDataAsset
point := gisClient.Point{"Point", []float32{long, lat}}
geoData.Location = &point
geoData.AssetName = assetName
geoData.AssetType = "UE"
geoData.SubType = "UE"
err := geMoveAsset(assetName, geoData)
if err != nil {
log.Error("Failed to move asset: ", err)
return err
}
}
func geMoveAsset(assetName string, geoData gisClient.GeoDataAsset) error {
_, err := gisAppClient.GeospatialDataApi.UpdateGeoDataByName(context.TODO(), assetName, geoData)
if err != nil {
log.Error("Failed to communicate with gis engine: ", err)
return err
}