Skip to content

Commit

Permalink
Add CreateOrUpdateCause and its tests
Browse files Browse the repository at this point in the history
  • Loading branch information
suntt2019 committed Aug 30, 2021
1 parent a8437eb commit 4cf152b
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 11 deletions.
8 changes: 7 additions & 1 deletion app/controller/judger.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,15 @@ func UpdateRun(c echo.Context) error {
utils.MustPutObject(output, context.Background(), "submissions", fmt.Sprintf("%d/run/%d/output", run.Submission.ID, run.ID))
utils.MustPutObject(comparer, context.Background(), "submissions", fmt.Sprintf("%d/run/%d/comparer_output", run.Submission.ID, run.ID))
utils.MustPutObject(compiler, context.Background(), "submissions", fmt.Sprintf("%d/run/%d/compiler_output", run.Submission.ID, run.ID))
if _, err := event.FireEvent("run", runEvent.EventArgs(&run)); err != nil {
eventResults, err := event.FireEvent("run", runEvent.EventArgs(&run))
if err != nil {
panic(errors.Wrap(err, "could not fire run events"))
}
for _, ret := range eventResults {
if ret[0] != nil {
panic(err)
}
}
if isLast {
eventResults, err := event.FireEvent("submission", submissionEvent.EventArgs(run.Submission))
if err != nil {
Expand Down
12 changes: 6 additions & 6 deletions app/response/resource/cause.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type CauseForAdmin struct {
ProblemID uint `json:"problem_id"`
TestCaseID uint `json:"test_case_id"`

Hash string `json:"output_stripped_hash"`
Hash string `json:"hash"`
Description string `json:"description"`
Marked bool `json:"marked"`

Expand All @@ -20,15 +20,15 @@ type CauseForAdmin struct {
}

type Cause struct {
ID uint `gorm:"primaryKey" json:"id"`
ProblemID uint `sql:"index" json:"problem_id"`
ID uint `json:"id"`
ProblemID uint `json:"problem_id"`
Problem *Problem `json:"problem"`
TestCaseID uint `sql:"index" json:"test_case_id"`
TestCaseID uint `json:"test_case_id"`
TestCase *TestCase `json:"test_case"`

Hash string `json:"output_stripped_hash" gorm:"index;not null;size:255;default:''"`
Hash string `json:"hash"`
Description string `json:"description"`
Marked bool `json:"marked" gorm:"default:false;not null"`
Marked bool `json:"marked"`
}

func (c *CauseForAdmin) convert(cause *models.Cause) {
Expand Down
42 changes: 42 additions & 0 deletions base/utils/cause.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package utils

import (
"github.com/EduOJ/backend/base"
"github.com/EduOJ/backend/database/models"
"github.com/pkg/errors"
"gorm.io/gorm"
)

func CreateOrUpdateCause(run *models.Run) error {
if run.Status == "PENDING" || run.Status == "JUDGEMENT_FAILED" || run.Status == "NO_COMMENT" {
return nil
}
if err := base.DB.Transaction(func(tx *gorm.DB) error {
databaseCause := models.Cause{}
err := tx.
Where("problem_id = ?", run.ProblemID).
Where("test_case_id = ?", run.TestCaseID).
Where("hash = ?", run.OutputStrippedHash).
First(&databaseCause).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
cause := models.Cause{
ProblemID: run.ProblemID,
TestCaseID: run.TestCaseID,
Hash: run.OutputStrippedHash,
Description: "",
Marked: false,
Point: 0,
Count: 1,
OutputURL: "",
}
return tx.Create(&cause).Error
} else if err != nil {
return err
}
databaseCause.Count += 1
return tx.Save(&databaseCause).Error
}); err != nil {
return errors.Wrap(err, "could not query cause for create or update cause")
}
return nil
}
112 changes: 112 additions & 0 deletions base/utils/cause_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package utils

import (
"github.com/EduOJ/backend/base"
"github.com/EduOJ/backend/database/models"
"github.com/stretchr/testify/assert"
"testing"
)

func TestCreateOrUpdateCause(t *testing.T) {
problem := models.Problem{
Name: "test_create_or_update_cause_problem",
Description: "test_create_or_update_cause_problem_desc",
}
assert.NoError(t, base.DB.Create(&problem).Error)
testCase := models.TestCase{
ProblemID: problem.ID,
Score: 0,
Sample: false,
}
assert.NoError(t, base.DB.Create(&testCase).Error)

checkCause := func(expected models.Cause) {
databaseCause := models.Cause{}
var count int64
assert.NoError(t, base.DB.
Where("problem_id = ?", problem.ID).
Where("test_case_id = ?", testCase.ID).
Where("hash = ?", expected.Hash).
First(&databaseCause).Count(&count).Error)
assert.Equal(t, 1, int(count))
expected.ID = databaseCause.ID
expected.CreatedAt = databaseCause.CreatedAt
expected.UpdatedAt = databaseCause.UpdatedAt
assert.Equal(t, expected, databaseCause)
}

t.Run("Create", func(t *testing.T) {
run := models.Run{
ProblemID: problem.ID,
ProblemSetID: 0,
TestCaseID: testCase.ID,
Sample: false,
Status: "ACCEPTED",
OutputStrippedHash: "test_create_or_update_cause_hash_new",
}
assert.NoError(t, base.DB.Create(&run).Error)
assert.NoError(t, CreateOrUpdateCause(&run))
checkCause(models.Cause{
ProblemID: problem.ID,
TestCaseID: testCase.ID,
Hash: "test_create_or_update_cause_hash_new",
Description: "",
Marked: false,
Point: 0,
Count: 1,
OutputURL: "",
})
})
t.Run("Update", func(t *testing.T) {
cause := models.Cause{
ProblemID: problem.ID,
TestCaseID: testCase.ID,
Hash: "test_create_or_update_cause_hash_existing",
Description: "test_create_or_update_cause_desc",
Marked: true,
Point: 10,
Count: 5,
OutputURL: "test_create_or_update_cause_output_url",
}
assert.NoError(t, base.DB.Create(&cause).Error)
run := models.Run{
ProblemID: problem.ID,
ProblemSetID: 0,
TestCaseID: testCase.ID,
Sample: false,
Status: "ACCEPTED",
OutputStrippedHash: "test_create_or_update_cause_hash_existing",
}
assert.NoError(t, base.DB.Create(&run).Error)
assert.NoError(t, CreateOrUpdateCause(&run))
checkCause(models.Cause{
ProblemID: problem.ID,
TestCaseID: testCase.ID,
Hash: "test_create_or_update_cause_hash_existing",
Description: "test_create_or_update_cause_desc",
Marked: true,
Point: 10,
Count: 6,
})
})
t.Run("JudgementFailed", func(t *testing.T) {
run := models.Run{
ProblemID: problem.ID,
ProblemSetID: 0,
TestCaseID: testCase.ID,
Sample: false,
Status: "JUDGEMENT_FAILED",
OutputStrippedHash: "test_create_or_update_cause_hash_judgement_failed",
}
assert.NoError(t, base.DB.Create(&run).Error)
assert.NoError(t, CreateOrUpdateCause(&run))
var count int64
assert.NoError(t, base.DB.
Model(&models.Cause{}).
Where("problem_id = ?", problem.ID).
Where("test_case_id = ?", testCase.ID).
Where("hash = ?", "test_create_or_update_cause_hash_judgement_failed").
Count(&count).Error)
assert.Equal(t, 0, int(count))
})
}
2 changes: 1 addition & 1 deletion database/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,7 @@ func GetMigration() *gormigrate.Gormigrate {
TestCaseID uint `sql:"index" json:"test_case_id"`
TestCase *TestCase `json:"test_case"`

Hash string `json:"output_stripped_hash" gorm:"index;not null;size:255;default:''"`
Hash string `json:"hash" gorm:"index;not null;size:255;default:''"`
Description string `json:"description"`
Marked bool `json:"marked" gorm:"default:false;not null"`

Expand Down
2 changes: 1 addition & 1 deletion database/models/cause.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Cause struct {
TestCaseID uint `sql:"index" json:"test_case_id"`
TestCase *TestCase `json:"test_case"`

Hash string `json:"output_stripped_hash" gorm:"index;not null;size:255;default:''"`
Hash string `json:"hash" gorm:"index;not null;size:255;default:''"`
Description string `json:"description"`
Marked bool `json:"marked" gorm:"default:false;not null"`

Expand Down
7 changes: 6 additions & 1 deletion event/run/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import (
"context"
"fmt"
"github.com/EduOJ/backend/base"
"github.com/EduOJ/backend/base/utils"
)

func NotifyGetSubmissionPoll(r EventArgs) EventRst {
base.Redis.Publish(context.Background(), fmt.Sprintf("submission_update:%d", r.Submission.ID), nil)
return EventRst{}
return nil
}

func CreateOrUpdateCause(r EventArgs) EventRst {
return utils.CreateOrUpdateCause(r)
}
2 changes: 1 addition & 1 deletion event/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ import "github.com/EduOJ/backend/database/models"
type EventArgs = *models.Run

// EventRst is the result of "run" event.
type EventRst struct{}
type EventRst error
1 change: 1 addition & 0 deletions init.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func initLog() {
func initEvent() {
log.Debug("Initializing Event System.")
event.RegisterListener("run", runEvent.NotifyGetSubmissionPoll)
event.RegisterListener("run", runEvent.CreateOrUpdateCause)
event.RegisterListener("submission", submissionEvent.UpdateGrade)
}

Expand Down

0 comments on commit 4cf152b

Please sign in to comment.