mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
WIP: add license statement to new files, implement addResultFile and deleteResultFile endpoints, implement delete method for Result; first draft for test
This commit is contained in:
parent
6689c858d6
commit
3f45e286f9
5 changed files with 323 additions and 48 deletions
|
@ -1,8 +1,32 @@
|
||||||
|
/** Result package, endpoints.
|
||||||
|
*
|
||||||
|
* @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 result
|
package result
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/file"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -15,7 +39,6 @@ func RegisterResultEndpoints(r *gin.RouterGroup) {
|
||||||
r.GET("/:resultID", getResult)
|
r.GET("/:resultID", getResult)
|
||||||
r.DELETE("/:resultID", deleteResult)
|
r.DELETE("/:resultID", deleteResult)
|
||||||
r.POST("/:resultID/file", addResultFile)
|
r.POST("/:resultID/file", addResultFile)
|
||||||
r.GET("/:resultID/file/:fileID", getResultFile)
|
|
||||||
r.DELETE("/:resultID/file/:fileID", deleteResultFile)
|
r.DELETE("/:resultID/file/:fileID", deleteResultFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,16 +56,16 @@ func RegisterResultEndpoints(r *gin.RouterGroup) {
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func getResults(c *gin.Context) {
|
func getResults(c *gin.Context) {
|
||||||
|
|
||||||
ok, scenario := scenario.CheckPermissions(c, database.Read, "query", -1)
|
ok, sco := scenario.CheckPermissions(c, database.Read, "query", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var result []database.Result
|
var results []database.Result
|
||||||
err := db.Order("ID asc").Model(scenario).Related(&result, "Results").Error
|
err := db.Order("ID asc").Model(sco).Related(&results, "Results").Error
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"result": result})
|
c.JSON(http.StatusOK, gin.H{"results": results})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +132,7 @@ func addResult(c *gin.Context) {
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func updateResult(c *gin.Context) {
|
func updateResult(c *gin.Context) {
|
||||||
|
|
||||||
ok, oldResult := CheckPermissions(c, database.Update, "path", -1)
|
ok, oldResult := checkPermissions(c, database.Update, "path", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -151,7 +174,7 @@ func updateResult(c *gin.Context) {
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func getResult(c *gin.Context) {
|
func getResult(c *gin.Context) {
|
||||||
|
|
||||||
ok, result := CheckPermissions(c, database.Read, "path", -1)
|
ok, result := checkPermissions(c, database.Read, "path", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -160,7 +183,7 @@ func getResult(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteResult godoc
|
// deleteResult godoc
|
||||||
// @Summary Delete a Result
|
// @Summary Delete a Result incl. all result files
|
||||||
// @ID deleteResult
|
// @ID deleteResult
|
||||||
// @Tags results
|
// @Tags results
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
@ -173,7 +196,13 @@ func getResult(c *gin.Context) {
|
||||||
// @Router /results/{resultID} [delete]
|
// @Router /results/{resultID} [delete]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func deleteResult(c *gin.Context) {
|
func deleteResult(c *gin.Context) {
|
||||||
ok, result := CheckPermissions(c, database.Delete, "path", -1)
|
ok, result := checkPermissions(c, database.Delete, "path", -1)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is allowed to modify scenario associated with result
|
||||||
|
ok, _ = scenario.CheckPermissions(c, database.Update, "body", int(result.ScenarioID))
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -210,49 +239,37 @@ func deleteResult(c *gin.Context) {
|
||||||
// @Router /results/{resultID}/file [post]
|
// @Router /results/{resultID}/file [post]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func addResultFile(c *gin.Context) {
|
func addResultFile(c *gin.Context) {
|
||||||
ok, _ := CheckPermissions(c, database.Update, "path", -1)
|
ok, result := checkPermissions(c, database.Update, "path", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check permissions of scenario first (file will be added to scenario)
|
// Check if user is allowed to modify scenario associated with result
|
||||||
|
ok, sco := scenario.CheckPermissions(c, database.Update, "body", int(result.ScenarioID))
|
||||||
// TODO add file to DB, associate with scenario and add file ID to result
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// getResultFile godoc
|
|
||||||
// @Summary Download a result file
|
|
||||||
// @ID getResultFile
|
|
||||||
// @Tags results
|
|
||||||
// @Produce text/plain
|
|
||||||
// @Produce text/csv
|
|
||||||
// @Produce application/gzip
|
|
||||||
// @Produce application/x-gtar
|
|
||||||
// @Produce application/x-tar
|
|
||||||
// @Produce application/x-ustar
|
|
||||||
// @Produce application/zip
|
|
||||||
// @Produce application/msexcel
|
|
||||||
// @Produce application/xml
|
|
||||||
// @Produce application/x-bag
|
|
||||||
// @Success 200 {object} docs.ResponseFile "File that was requested"
|
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
|
||||||
// @Param resultID path int true "Result ID"
|
|
||||||
// @Param fileID path int true "ID of the file to download"
|
|
||||||
// @Router /results/{resultID}/file/{fileID} [get]
|
|
||||||
// @Security Bearer
|
|
||||||
func getResultFile(c *gin.Context) {
|
|
||||||
|
|
||||||
// check access
|
|
||||||
ok, _ := CheckPermissions(c, database.Read, "path", -1)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO download result file
|
// Extract file from POST request form
|
||||||
|
file_header, err := c.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequestError(c, fmt.Sprintf("Get form error: %s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// save result file to DB and associate it with scenario
|
||||||
|
var newFile file.File
|
||||||
|
err = newFile.Register(file_header, sco.ID)
|
||||||
|
if helper.DBError(c, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// add file ID to ResultFileIDs of Result
|
||||||
|
err = result.addResultFileID(newFile.File.ID)
|
||||||
|
if !helper.DBError(c, err) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"result": result.Result})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteResultFile godoc
|
// deleteResultFile godoc
|
||||||
|
@ -270,12 +287,34 @@ func getResultFile(c *gin.Context) {
|
||||||
// @Router /results/{resultID}/file/{fileID} [delete]
|
// @Router /results/{resultID}/file/{fileID} [delete]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func deleteResultFile(c *gin.Context) {
|
func deleteResultFile(c *gin.Context) {
|
||||||
// TODO check access to scenario (file deletion) first
|
|
||||||
|
|
||||||
// check access
|
// check access
|
||||||
ok, _ := CheckPermissions(c, database.Update, "path", -1)
|
ok, result := checkPermissions(c, database.Update, "path", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok, f := file.CheckPermissions(c, database.Delete)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is allowed to modify scenario associated with result
|
||||||
|
ok, _ = scenario.CheckPermissions(c, database.Update, "body", int(result.ScenarioID))
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove file ID from ResultFileIDs of Result
|
||||||
|
err := result.removeResultFileID(f.ID)
|
||||||
|
if helper.DBError(c, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the file
|
||||||
|
err = f.Delete()
|
||||||
|
if !helper.DBError(c, err) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"result": result.Result})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,32 @@
|
||||||
|
/** Result package, methods.
|
||||||
|
*
|
||||||
|
* @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 result
|
package result
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/file"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
|
@ -69,7 +93,56 @@ func (r *Result) delete() error {
|
||||||
// remove association between Result and Scenario
|
// remove association between Result and Scenario
|
||||||
err = db.Model(&sco).Association("Results").Delete(r).Error
|
err = db.Model(&sco).Association("Results").Delete(r).Error
|
||||||
|
|
||||||
// TODO delete Result + files (if any)
|
// Delete result files
|
||||||
|
for id, _ := range r.ResultFileIDs {
|
||||||
|
var f file.File
|
||||||
|
err := f.ByID(uint(id))
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Unable to delete file with ID ", id, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err = f.Delete()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete result
|
||||||
|
err = db.Delete(r).Error
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) addResultFileID(fileID uint) error {
|
||||||
|
|
||||||
|
oldResultFileIDs := r.ResultFileIDs
|
||||||
|
newResultFileIDs := append(oldResultFileIDs, int64(fileID))
|
||||||
|
|
||||||
|
db := database.GetDB()
|
||||||
|
|
||||||
|
err := db.Model(r).Updates(map[string]interface{}{
|
||||||
|
"ResultFileIDs": newResultFileIDs,
|
||||||
|
}).Error
|
||||||
|
|
||||||
|
return err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) removeResultFileID(fileID uint) error {
|
||||||
|
oldResultFileIDs := r.ResultFileIDs
|
||||||
|
var newResultFileIDs []int64
|
||||||
|
|
||||||
|
for _, id := range oldResultFileIDs {
|
||||||
|
if id != int64(fileID) {
|
||||||
|
newResultFileIDs = append(newResultFileIDs, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db := database.GetDB()
|
||||||
|
|
||||||
|
err := db.Model(r).Updates(map[string]interface{}{
|
||||||
|
"ResultFileIDs": newResultFileIDs,
|
||||||
|
}).Error
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,25 @@
|
||||||
|
/** Result package, middleware.
|
||||||
|
*
|
||||||
|
* @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 result
|
package result
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -8,7 +30,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckPermissions(c *gin.Context, operation database.CRUD, resultIDSource string, resultIDBody int) (bool, Result) {
|
func checkPermissions(c *gin.Context, operation database.CRUD, resultIDSource string, resultIDBody int) (bool, Result) {
|
||||||
|
|
||||||
var result Result
|
var result Result
|
||||||
|
|
||||||
|
|
|
@ -1 +1,120 @@
|
||||||
|
/** Result 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 result
|
package result
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/file"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/jinzhu/gorm/dialects/postgres"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var router *gin.Engine
|
||||||
|
|
||||||
|
type ScenarioRequest struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Running bool `json:"running,omitempty"`
|
||||||
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func addScenario() (scenarioID uint) {
|
||||||
|
|
||||||
|
// authenticate as admin
|
||||||
|
token, _ := helper.AuthenticateForTest(router,
|
||||||
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
|
|
||||||
|
// authenticate as normal user
|
||||||
|
token, _ = helper.AuthenticateForTest(router,
|
||||||
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
|
|
||||||
|
// POST $newScenario
|
||||||
|
newScenario := ScenarioRequest{
|
||||||
|
Name: helper.ScenarioA.Name,
|
||||||
|
Running: helper.ScenarioA.Running,
|
||||||
|
StartParameters: helper.ScenarioA.StartParameters,
|
||||||
|
}
|
||||||
|
_, resp, _ := helper.TestEndpoint(router, token,
|
||||||
|
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
|
||||||
|
|
||||||
|
// Read newScenario's ID from the response
|
||||||
|
newScenarioID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
|
// add the guest user to the new scenario
|
||||||
|
_, resp, _ = helper.TestEndpoint(router, token,
|
||||||
|
fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil)
|
||||||
|
|
||||||
|
return uint(newScenarioID)
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
api := router.Group("/api")
|
||||||
|
|
||||||
|
user.RegisterAuthenticate(api.Group("/authenticate"))
|
||||||
|
api.Use(user.Authentication(true))
|
||||||
|
// scenario endpoints required here to first add a scenario to the DB
|
||||||
|
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
||||||
|
// file endpoints required to download result file
|
||||||
|
file.RegisterFileEndpoints(api.Group("/files"))
|
||||||
|
|
||||||
|
RegisterResultEndpoints(api.Group("/results"))
|
||||||
|
|
||||||
|
os.Exit(m.Run())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetAllResultsOfScenario(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddGetUpdateResult(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteResult(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddResultFile(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteResultFile(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,25 @@
|
||||||
|
/** Result package, validators.
|
||||||
|
*
|
||||||
|
* @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 result
|
package result
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
Loading…
Add table
Reference in a new issue