Skip to content

Commit

Permalink
Agregando puntajes por grupo en el mensaje que se envía vía broadcast (
Browse files Browse the repository at this point in the history
…#121)

Se agrega el campo de `score_per_group` en el objeto que se regresa 
por medio del broadcast hacia el websocket, esto servirá para que se 
pueda calcular el puntaje máximo para los concursos con subtareas.


Part of: omegaup/omegaup#6878

Fixes: #119
  • Loading branch information
pabo99 authored Apr 25, 2023
1 parent e1ca0b8 commit 7d6432d
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 34 deletions.
83 changes: 54 additions & 29 deletions cmd/omegaup-grader/frontend_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,21 +254,22 @@ func broadcastRun(
message.Contest = *run.Contest
}
type serializedRun struct {
User string `json:"username"`
Contest *string `json:"contest_alias,omitempty"`
Problemset *int64 `json:"problemset,omitempty"`
Problem string `json:"alias"`
GUID string `json:"guid"`
Runtime float64 `json:"runtime"`
Penalty float64 `json:"penalty"`
Memory base.Byte `json:"memory"`
Score float64 `json:"score"`
ContestScore float64 `json:"contest_score"`
Status string `json:"status"`
Verdict string `json:"verdict"`
SubmitDelay float64 `json:"submit_delay"`
Time float64 `json:"time"`
Language string `json:"language"`
User string `json:"username"`
Contest *string `json:"contest_alias,omitempty"`
Problemset *int64 `json:"problemset,omitempty"`
Problem string `json:"alias"`
GUID string `json:"guid"`
Runtime float64 `json:"runtime"`
Penalty float64 `json:"penalty"`
Memory base.Byte `json:"memory"`
Score float64 `json:"score"`
ContestScore float64 `json:"contest_score"`
Status string `json:"status"`
Verdict string `json:"verdict"`
SubmitDelay float64 `json:"submit_delay"`
Time float64 `json:"time"`
Language string `json:"language"`
ScorePerGroup map[string]float64 `json:"score_per_group"`
}
type runFinishedMessage struct {
Message string `json:"message"`
Expand All @@ -283,20 +284,21 @@ func broadcastRun(
msg := runFinishedMessage{
Message: "/run/update/",
Run: serializedRun{
Contest: run.Contest,
Problemset: run.Problemset,
Problem: run.Run.ProblemName,
GUID: run.GUID,
Runtime: run.Result.Time,
Memory: run.Result.Memory,
Score: score,
ContestScore: contestScore,
Status: "ready",
Verdict: run.Result.Verdict,
Language: run.Run.Language,
Time: -1,
SubmitDelay: -1,
Penalty: -1,
Contest: run.Contest,
Problemset: run.Problemset,
Problem: run.Run.ProblemName,
GUID: run.GUID,
Runtime: run.Result.Time,
Memory: run.Result.Memory,
Score: score,
ContestScore: contestScore,
Status: "ready",
Verdict: run.Result.Verdict,
Language: run.Run.Language,
Time: -1,
SubmitDelay: -1,
Penalty: -1,
ScorePerGroup: make(map[string]float64),
},
}
var runTime time.Time
Expand All @@ -320,6 +322,29 @@ func broadcastRun(
if err != nil {
return err
}
rows, err := queryWithRetry(
db,
`SELECT
rg.group_name, rg.score
FROM
Runs_Groups rg
WHERE
rg.run_id = ?;`, run.ID)
if err != nil {
return fmt.Errorf("failed to query run groups: %w", err)
}

scores := make(map[string]float64)
for rows.Next() {
var groupName string
var scoreByGroup float64
err = rows.Scan(&groupName, &scoreByGroup)
if err != nil {
return fmt.Errorf("failed to scan run group: %w", err)
}
scores[groupName] = scoreByGroup
}
msg.Run.ScorePerGroup = scores
msg.Run.Time = float64(runTime.Unix())
message.User = msg.Run.User
if run.Problemset != nil {
Expand Down
74 changes: 69 additions & 5 deletions cmd/omegaup-grader/frontend_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"math/big"
"net/http"
"net/http/httptest"
"reflect"
"testing"

_ "github.com/mattn/go-sqlite3"
Expand Down Expand Up @@ -194,6 +195,21 @@ func newInMemoryDB(t *testing.T, scoreMode string) *sql.DB {
) VALUES (
1, 1, "1", "1", "JE", "1970-01-01 00:00:00"
);
INSERT INTO Runs_Groups (
case_run_id, run_id, group_name, score, verdict
) VALUES (
1, 1, "easy", 0.1, "PA"
);
INSERT INTO Runs_Groups (
case_run_id, run_id, group_name, score, verdict
) VALUES (
2, 1, "medium", 0.2, "PA"
);
INSERT INTO Runs_Groups (
case_run_id, run_id, group_name, score, verdict
) VALUES (
3, 1, "sample", 0.3, "PA"
);
INSERT INTO Identities (
identity_id, username
) VALUES (
Expand Down Expand Up @@ -230,7 +246,7 @@ func TestUpdateDatabase(t *testing.T) {
); err != nil {
t.Fatalf("Error updating the database: %v", err)
}
if count != 0 {
if count != 3 {
t.Errorf("Wrong number of rows in the database. found %v, want %v", count, 0)
}

Expand Down Expand Up @@ -318,7 +334,7 @@ func TestUpdateDatabase(t *testing.T) {
); err != nil {
t.Fatalf("Error updating the database: %v", err)
}
if count != 2 {
if count != 5 {
t.Errorf("Wrong number of rows in the database. found %v, want %v", count, 2)
}
if err := queryRowWithRetry(
Expand All @@ -341,10 +357,52 @@ func TestBroadcastRun(t *testing.T) {
verdict string
score *big.Rat
expectedScore float64
scorePerGroup map[string]any
}{
{scoreMode: "partial", verdict: "AC", score: big.NewRat(1, 1), expectedScore: 1.},
{scoreMode: "partial", verdict: "PA", score: big.NewRat(1, 2), expectedScore: 0.5},
{scoreMode: "all_or_nothing", verdict: "PA", score: big.NewRat(1, 2), expectedScore: 0.},
{
scoreMode: "partial",
verdict: "AC",
score: big.NewRat(1, 1),
expectedScore: 1.,
scorePerGroup: map[string]any{
"easy": 0.1,
"medium": 0.2,
"sample": 0.3,
},
},
{
scoreMode: "partial",
verdict: "PA",
score: big.NewRat(1, 2),
expectedScore: 0.5,
scorePerGroup: map[string]any{
"easy": 0.1,
"medium": 0.2,
"sample": 0.3,
},
},
{
scoreMode: "all_or_nothing",
verdict: "PA",
score: big.NewRat(1, 2),
expectedScore: 0.,
scorePerGroup: map[string]any{
"easy": 0.1,
"medium": 0.2,
"sample": 0.3,
},
},
{
scoreMode: "max_per_group",
verdict: "PA",
score: big.NewRat(1, 3),
expectedScore: 0.3333333333333333,
scorePerGroup: map[string]any{
"easy": 0.1,
"medium": 0.2,
"sample": 0.3,
},
},
}
for idx, s := range scenarios {
t.Run(fmt.Sprintf("%d: verdict=%s scoreMode=%s", idx, s.verdict, s.scoreMode), func(t *testing.T) {
Expand Down Expand Up @@ -394,6 +452,12 @@ func TestBroadcastRun(t *testing.T) {
t.Fatalf("Message does not contain a run entry: %v", encodedMessage)
}

if !reflect.DeepEqual(s.scorePerGroup, runInfo["score_per_group"]) {
t.Errorf("message.score_per_group=%v (type %T), want %v (type %T)",
runInfo["score_per_group"], runInfo["score_per_group"],
s.scorePerGroup, s.scorePerGroup)
}

for key, value := range map[string]any{
"guid": "1",
"status": "ready",
Expand Down

0 comments on commit 7d6432d

Please sign in to comment.