From bcf76a2c86d15ca4885350823c1de5eeb89af63e Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 5 Mar 2023 18:16:38 +0100 Subject: [PATCH] New route to stop all running/pending tests for a given work --- repositories.go | 57 +++++++++++++++++++ ui/src/lib/works.js | 14 +++++ ui/src/routes/works/[wid]/rendus/+page.svelte | 7 +++ works.go | 12 ++++ 4 files changed, 90 insertions(+) diff --git a/repositories.go b/repositories.go index 49e8d48..221991c 100644 --- a/repositories.go +++ b/repositories.go @@ -603,6 +603,42 @@ func TriggerTests(c *gin.Context, work *Work, repo *Repository, u *User) { c.JSON(http.StatusOK, repo) } +func (w *Work) stopTests() error { + repos, err := w.GetRepositories() + if err != nil { + return err + } + + client := drone.NewClient(droneEndpoint, droneConfig) + for _, repo := range repos { + slug := strings.Split(repo.TestsRef, "/") + if len(slug) < 3 { + continue + } + + buildn, err := strconv.ParseInt(slug[2], 10, 32) + if err != nil { + continue + } + + build, err := client.Build(slug[0], slug[1], int(buildn)) + if err != nil { + log.Println("Unable to communicate with Drone:", err.Error()) + continue + } + + if build.Status == "pending" { + err := client.BuildCancel(slug[0], slug[1], int(buildn)) + if err != nil { + log.Println("Unable to cancel the build:", err.Error()) + continue + } + } + } + + return nil +} + type Repository struct { Id int64 `json:"id"` IdUser int64 `json:"id_user"` @@ -637,6 +673,27 @@ func (u *User) GetRepositories() (repositories []*Repository, err error) { } } +func (w *Work) GetRepositories() (repositories []*Repository, err error) { + if rows, errr := DBQuery("SELECT id_repository, id_user, id_work, uri, secret, last_check, droneref, last_tests, testsref FROM user_work_repositories WHERE id_work=?", w.Id); errr != nil { + return nil, errr + } else { + defer rows.Close() + + for rows.Next() { + var repo Repository + if err = rows.Scan(&repo.Id, &repo.IdUser, &repo.IdWork, &repo.URI, &repo.Secret, &repo.LastCheck, &repo.DroneRef, &repo.LastTests, &repo.TestsRef); err != nil { + return + } + repositories = append(repositories, &repo) + } + if err = rows.Err(); err != nil { + return + } + + return + } +} + func getRepositoriesByURI(uri string) (repositories []*Repository, err error) { if rows, errr := DBQuery("SELECT id_repository, id_user, id_work, uri, secret, last_check, droneref, last_tests, testsref FROM user_work_repositories WHERE uri=?", uri); errr != nil { return nil, errr diff --git a/ui/src/lib/works.js b/ui/src/lib/works.js index 9d83b98..1d5976c 100644 --- a/ui/src/lib/works.js +++ b/ui/src/lib/works.js @@ -95,6 +95,20 @@ export class Work { } } + async stopTests() { + if (this.id) { + const res = await fetch(`api/works/${this.id}/tests`, { + method: 'DELETE', + headers: {'Accept': 'application/json'}, + }); + if (res.status == 200) { + return true; + } else { + throw new Error((await res.json()).errmsg); + } + } + } + async getSubmission(uid) { const res = await fetch(uid?`api/users/${uid}/works/${this.id}/submission`:`api/works/${this.id}/submission`, { headers: {'Accept': 'application/json'} diff --git a/ui/src/routes/works/[wid]/rendus/+page.svelte b/ui/src/routes/works/[wid]/rendus/+page.svelte index 818735d..a7d0574 100644 --- a/ui/src/routes/works/[wid]/rendus/+page.svelte +++ b/ui/src/routes/works/[wid]/rendus/+page.svelte @@ -79,6 +79,13 @@ {/if} + diff --git a/works.go b/works.go index e3c4940..1ce2e81 100644 --- a/works.go +++ b/works.go @@ -153,6 +153,18 @@ func declareAPIAdminWorksRoutes(router *gin.RouterGroup) { c.JSON(http.StatusOK, nil) }) + worksRoutes.DELETE("/tests", func(c *gin.Context) { + w := c.MustGet("work").(*Work) + + err := w.stopTests() + if err != nil { + log.Println("Unable to stop tests:", err) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs during test stop."}) + return + } + + c.JSON(http.StatusOK, true) + }) // Grades related to works worksRoutes.GET("/grades", func(c *gin.Context) {