New route to stop all running/pending tests for a given work

This commit is contained in:
nemunaire 2023-03-05 18:16:38 +01:00
parent 8b8f3947f8
commit bcf76a2c86
4 changed files with 90 additions and 0 deletions

View File

@ -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

View File

@ -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'}

View File

@ -79,6 +79,13 @@
<i class="bi bi-play"></i>
{/if}
</button>
<button
class="btn btn-sm btn-danger mr-1"
title="Arrêter tous les tests en cours"
on:click={() => w.stopTests()}
>
<i class="bi bi-stop"></i>
</button>
</div>
</div>

View File

@ -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) {