Skip to content

Commit 98e5e26

Browse files
authored
Merge pull request #22
Now testing system works!
2 parents f90aa81 + 0d71984 commit 98e5e26

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+7297
-229
lines changed

common/config/db.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package config
22

33
type DBConfig struct {
4-
Dsn string `yaml:"dsn"`
4+
Dsn string `yaml:"Dsn"`
5+
6+
// InMemory should be used only for tests
7+
InMemory bool `yaml:"InMemory"`
58
}

common/connectors/connector_base.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func NewConnectorBase(connection *config.Connection) *ConnectorBase {
1515
Connection: connection,
1616
client: resty.New(),
1717
}
18-
// TODO: Add host initialization from connection
18+
c.client.SetBaseURL(connection.Address)
1919
// TODO: Add auth
2020
// TODO: Add retry configuration
2121
return c

common/connectors/invokerconn/jobtype_string.go

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/connectors/invokerconn/structs.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
//go:generate go run golang.org/x/tools/cmd/stringer@latest -type=JobType
2+
13
package invokerconn
24

5+
import "fmt"
6+
37
type JobType int
48

59
const (
6-
CompileJob JobType = iota
10+
CompileJob JobType = iota + 1
711
TestJob
812
)
913

@@ -16,6 +20,10 @@ type Job struct {
1620
// TODO: Add job dependency
1721
}
1822

23+
func (j Job) String() string {
24+
return fmt.Sprintf("ID: %s Submit: %d Type %v Test: %d", j.ID, j.SubmitID, j.Type, j.Test)
25+
}
26+
1927
type Status struct {
2028
MaxNewJobs uint64 `json:"MaxNewJobs"`
2129
ActiveJobIDs []string `json:"ActiveJobIDs"`

common/connectors/storageconn/connector.go

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package storageconn
33
import (
44
"encoding/json"
55
"fmt"
6+
"github.com/go-resty/resty/v2"
67
"io"
78
"mime"
89
"net/http"
910
"os"
1011
"path/filepath"
1112
"testing_system/common/config"
1213
"testing_system/common/connectors"
14+
"testing_system/lib/connector"
1315
)
1416

1517
type Connector struct {
@@ -31,9 +33,12 @@ func (s *Connector) Download(request *Request) *FileResponse {
3133
return response
3234
}
3335

34-
path := "/storage/get"
3536
r := s.connection.R()
3637

38+
if request.Ctx != nil {
39+
r.SetContext(request.Ctx)
40+
}
41+
3742
requestJSON, err := json.Marshal(request)
3843
if err != nil {
3944
response.Error = fmt.Errorf("failed to form request to storage: %v", err)
@@ -43,8 +48,9 @@ func (s *Connector) Download(request *Request) *FileResponse {
4348
r.SetQueryParams(map[string]string{
4449
"request": string(requestJSON),
4550
})
51+
r.SetDoNotParseResponse(true)
4652

47-
resp, err := r.SetDoNotParseResponse(true).Execute("GET", path)
53+
resp, err := r.Get("/storage/get")
4854
if err != nil {
4955
response.Error = fmt.Errorf("failed to send request: %v", err)
5056
return response
@@ -55,7 +61,15 @@ func (s *Connector) Download(request *Request) *FileResponse {
5561
if resp.StatusCode() == http.StatusNotFound {
5662
response.Error = ErrStorageFileNotFound
5763
} else {
58-
response.Error = fmt.Errorf("get request failed with status: %v", resp.Status())
64+
body, err := io.ReadAll(resp.RawBody())
65+
if err != nil {
66+
response.Error = &connector.Error{
67+
Code: resp.StatusCode(),
68+
Message: err.Error(),
69+
Path: resp.Request.URL,
70+
}
71+
}
72+
response.Error = connector.ParseRespError(body, resp)
5973
}
6074
return response
6175
}
@@ -107,8 +121,10 @@ func (s *Connector) Upload(request *Request) *Response {
107121
return response
108122
}
109123

110-
path := "/storage/upload"
111124
r := s.connection.R()
125+
if request.Ctx != nil {
126+
r.SetContext(request.Ctx)
127+
}
112128

113129
requestJSON, err := json.Marshal(request)
114130
if err != nil {
@@ -120,28 +136,24 @@ func (s *Connector) Upload(request *Request) *Response {
120136
"request": string(requestJSON),
121137
})
122138

123-
// request.StorageFilename can be empty
124-
r.SetFileReader("file", request.StorageFilename, request.File)
125-
126-
resp, err := r.Post(path)
127-
if err != nil {
128-
response.Error = fmt.Errorf("failed to send request: %v", err)
129-
return response
130-
}
131-
132-
if resp.IsError() {
133-
response.Error = fmt.Errorf("upload failed with status: %v", resp.Status())
134-
return response
139+
requestFileName := request.StorageFilename
140+
// request.StorageFilename can be empty but http requires filename to be specified
141+
if requestFileName == "" {
142+
requestFileName = "noname"
135143
}
144+
r.SetFileReader("file", requestFileName, request.File)
136145

146+
response.Error = connector.ReceiveEmpty(r, "/storage/upload", resty.MethodPost)
137147
return response
138148
}
139149

140150
func (s *Connector) Delete(request *Request) *Response {
141151
response := &Response{R: *request}
142152

143-
path := "/storage/remove"
144153
r := s.connection.R()
154+
if request.Ctx != nil {
155+
r.SetContext(request.Ctx)
156+
}
145157

146158
requestJSON, err := json.Marshal(request)
147159
if err != nil {
@@ -153,16 +165,7 @@ func (s *Connector) Delete(request *Request) *Response {
153165
"request": string(requestJSON),
154166
})
155167

156-
resp, err := r.Delete(path)
157-
if err != nil {
158-
response.Error = fmt.Errorf("failed to send request: %v", err)
159-
return response
160-
}
161-
162-
if resp.IsError() {
163-
response.Error = fmt.Errorf("delete failed with status: %v", resp.Status())
164-
return response
165-
}
168+
response.Error = connector.ReceiveEmpty(r, "/storage/remove", resty.MethodDelete)
166169

167170
return response
168171
}

common/connectors/storageconn/structs.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package storageconn
22

33
import (
4+
"context"
45
"io"
56
"os"
67
"path/filepath"
@@ -13,7 +14,7 @@ type Request struct {
1314
Resource resource.Type `json:"resource"`
1415

1516
/*
16-
Resource must always has exactly one of ProblemId and SubmitID
17+
Resource must always have exactly one of ProblemId and SubmitID
1718
Including, only TestID cannot be specified
1819
ID=0 is considered absent
1920
*/
@@ -36,6 +37,9 @@ type Request struct {
3637

3738
// If StorageFilename is not specified, Storage tries to get the filename automatically
3839
StorageFilename string `json:"storageFilename"`
40+
41+
// Context may be specified for requests
42+
Ctx context.Context `json:"-"`
3943
}
4044

4145
type Response struct {

common/constants/verdict/verdict.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,5 @@ const (
2222
CF Verdict = "CF" // Check failed
2323
SK Verdict = "SK" // Skipped
2424

25-
QD Verdict = "QD" // Queued
26-
CL Verdict = "CL" // Compiling
2725
RU Verdict = "RU" // Running
2826
)

common/db/db.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@ package db
22

33
import (
44
"gorm.io/driver/postgres"
5+
"gorm.io/driver/sqlite"
56
"gorm.io/gorm"
67
"testing_system/common/config"
78
"testing_system/common/db/models"
89
"testing_system/lib/logger"
910
)
1011

1112
func NewDB(config config.DBConfig) (*gorm.DB, error) {
12-
db, err := gorm.Open(postgres.Open(config.Dsn), &gorm.Config{})
13+
var db *gorm.DB
14+
var err error
15+
if config.InMemory {
16+
db, err = newInMemoryDB()
17+
} else {
18+
db, err = newPostgresDB(config)
19+
}
1320
if err != nil {
14-
return nil, logger.Error("Can't open database with dsn=\"%v\" because of %v:", config.Dsn, err)
21+
return nil, err
1522
}
23+
1624
if err = db.AutoMigrate(&models.Problem{}); err != nil {
1725
return nil, logger.Error("Can't migrate Problem: %v", err)
1826
}
@@ -21,3 +29,20 @@ func NewDB(config config.DBConfig) (*gorm.DB, error) {
2129
}
2230
return db, err
2331
}
32+
33+
func newPostgresDB(config config.DBConfig) (*gorm.DB, error) {
34+
db, err := gorm.Open(postgres.Open(config.Dsn), &gorm.Config{})
35+
if err != nil {
36+
return nil, logger.Error("Can't open database with dsn=\"%v\" because of %v:", config.Dsn, err)
37+
}
38+
return db, nil
39+
}
40+
41+
func newInMemoryDB() (*gorm.DB, error) {
42+
db, err := gorm.Open(sqlite.Open("file:ts?mode=memory&cache=shared"), &gorm.Config{})
43+
if err != nil {
44+
return nil, err
45+
}
46+
logger.Warn("InMemory DB should not be used in production, consider using postgres db instead")
47+
return db, nil
48+
}

common/db/models/models_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestTestResultSerialization(t *testing.T) {
3737
t.Run("json", func(t *testing.T) {
3838
b, err := json.Marshal(testResult)
3939
require.Nil(t, err)
40-
require.Equal(t, `{"testNumber":1,"verdict":"OK","time":"5s","memory":"5m"}`, string(b))
40+
require.Equal(t, `{"TestNumber":1,"Verdict":"OK","Time":"5s","Memory":"5m"}`, string(b))
4141

4242
var newTestResult TestResult
4343
err = json.Unmarshal(b, &newTestResult)
@@ -48,10 +48,10 @@ func TestTestResultSerialization(t *testing.T) {
4848
t.Run("yaml", func(t *testing.T) {
4949
b, err := yaml.Marshal(testResult)
5050
require.Nil(t, err)
51-
require.Equal(t, `testNumber: 1
52-
verdict: OK
53-
time: 5s
54-
memory: 5m
51+
require.Equal(t, `TestNumber: 1
52+
Verdict: OK
53+
Time: 5s
54+
Memory: 5m
5555
`, string(b))
5656
var newTestResult TestResult
5757
err = yaml.Unmarshal(b, &newTestResult)

common/db/models/problem.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,27 @@ const (
1515
type Problem struct {
1616
gorm.Model
1717

18-
ProblemType ProblemType
18+
ProblemType ProblemType `yaml:"ProblemType"`
1919

20-
TimeLimit customfields.Time
21-
MemoryLimit customfields.Memory
20+
TimeLimit customfields.Time `yaml:"TimeLimit"`
21+
MemoryLimit customfields.Memory `yaml:"MemoryLimit"`
2222

23-
TestsNumber uint64
23+
TestsNumber uint64 `yaml:"TestsNumber"`
2424

2525
// WallTimeLimit specifies maximum execution and wait time.
2626
// By default, it is max(5s, TimeLimit * 2)
27-
WallTimeLimit *customfields.Time
27+
WallTimeLimit *customfields.Time `yaml:"WallTimeLimit,omitempty"`
2828

2929
// MaxOpenFiles specifies maximum number of files, opened by testing system.
3030
// By default, it is 64
31-
MaxOpenFiles *uint64
31+
MaxOpenFiles *uint64 `yaml:"MaxOpenFiles,omitempty"`
3232

3333
// MaxThreads specifies maximum number of threads and/or processes
3434
// By default, it is single thread
3535
// If MaxThreads equals to -1, any number of threads allowed
36-
MaxThreads *int64
36+
MaxThreads *int64 `yaml:"MaxThreads,omitempty"`
3737

3838
// MaxOutputSize specifies maximum output in EACH file.
3939
// By default, it is 1g
40-
MaxOutputSize *customfields.Memory
40+
MaxOutputSize *customfields.Memory `yaml:"MaxOutputSize,omitempty"`
4141
}

0 commit comments

Comments
 (0)