feat(cmd/joj3/main_test.go,-internal/scoreboard/scoreboard.go): automatically update scoreboard each time the test program runs
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									3a095e64d4
								
							
						
					
					
						commit
						753ed6f9c6
					
				|  | @ -9,6 +9,7 @@ import ( | |||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/scoreboard" | ||||
| 	"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" | ||||
| ) | ||||
| 
 | ||||
|  | @ -61,7 +62,16 @@ func readStageResults(t *testing.T, path string) []stage.StageResult { | |||
| 	return results | ||||
| } | ||||
| 
 | ||||
| func removeStringPrefix(s, prefix string) string { | ||||
| 	if strings.HasPrefix(s, prefix) { | ||||
| 		return s[len(prefix):] | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| func TestMain(t *testing.T) { | ||||
| 	scoreboard := scoreboard.Scoreboard{} | ||||
| 	scoreboard.Init("TestingStudent", "520370000000") | ||||
| 	var tests []string | ||||
| 	root := "../../tmp/submodules/JOJ3-examples" | ||||
| 	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { | ||||
|  | @ -107,6 +117,7 @@ func TestMain(t *testing.T) { | |||
| 			defer os.Remove(outputFile) | ||||
| 			main() | ||||
| 			stageResults := readStageResults(t, outputFile) | ||||
| 			scoreboard.AddScore(removeStringPrefix(tt, "/examples/"), stageResults) | ||||
| 			regex := true | ||||
| 			expectedFile := "expected_regex.json" | ||||
| 			if _, err := os.Stat(expectedFile); os.IsNotExist(err) { | ||||
|  | @ -117,4 +128,9 @@ func TestMain(t *testing.T) { | |||
| 			compareStageResults(t, stageResults, expectedStageResults, regex) | ||||
| 		}) | ||||
| 	} | ||||
| 	if !t.Failed() { | ||||
| 		scoreboard.SaveFile("../../scoreboard.json") | ||||
| 		defer os.Remove("../../scoreboard.json") | ||||
| 		scoreboard.Submit() | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -1,44 +1,40 @@ | |||
| package scoreboard | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"log/slog" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 
 | ||||
| 	"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" | ||||
| ) | ||||
| 
 | ||||
| type Question struct { | ||||
| 	Name    string `json:"name"` | ||||
| 	Score   int    `json:"score"` | ||||
| 	Comment string `json:"comment"` | ||||
| type StageRecord struct { | ||||
| 	StageName    string              `json:"stagename"` | ||||
| 	StageResults []stage.StageResult `json:"stageresults"` | ||||
| } | ||||
| 
 | ||||
| type ScoreboardData struct { | ||||
| 	StudentName string     `json:"studentname"` | ||||
| 	StudentId   string     `json:"studentid"` | ||||
| 	Questions   []Question `json:"questions"` | ||||
| 	StageRecords []StageRecord `json:"stagerecords"` | ||||
| } | ||||
| 
 | ||||
| type Scoreboard struct { | ||||
| 	scoreboard ScoreboardData | ||||
| 	studentName string | ||||
| 	studentId   string | ||||
| 	scoreboard  ScoreboardData | ||||
| } | ||||
| 
 | ||||
| func (b *Scoreboard) Init(studentName string, studentId string) { | ||||
| 	b.scoreboard.StudentName = studentName | ||||
| 	b.scoreboard.StudentId = studentId | ||||
| 	b.scoreboard.Questions = make([]Question, 0) | ||||
| 	b.studentName = studentName | ||||
| 	b.studentId = studentId | ||||
| 	b.scoreboard.StageRecords = make([]StageRecord, 0) | ||||
| } | ||||
| 
 | ||||
| func (b *Scoreboard) AddScore(questionName string, score int) { | ||||
| 	flag := false | ||||
| 	for i, question := range b.scoreboard.Questions { | ||||
| 		if question.Name == questionName { | ||||
| 			b.scoreboard.Questions[i].Score = score | ||||
| 			flag = true | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	if flag { | ||||
| 		b.scoreboard.Questions = append(b.scoreboard.Questions, Question{Name: questionName, Score: score}) | ||||
| 	} | ||||
| func (b *Scoreboard) AddScore(stagename string, results []stage.StageResult) { | ||||
| 	b.scoreboard.StageRecords = append(b.scoreboard.StageRecords, | ||||
| 		StageRecord{StageName: stagename, StageResults: results}) | ||||
| } | ||||
| 
 | ||||
| func (b *Scoreboard) SaveFile(filePath string) { | ||||
|  | @ -50,3 +46,54 @@ func (b *Scoreboard) SaveFile(filePath string) { | |||
| 	encoder.SetIndent("", "  ") | ||||
| 	_ = encoder.Encode(b.scoreboard) | ||||
| } | ||||
| 
 | ||||
| func (b *Scoreboard) Submit() { | ||||
| 	e := os.Mkdir("repos", 0o777) | ||||
| 	if e != nil { | ||||
| 		slog.Error("Encountered problems createing folder: ", "err", e) | ||||
| 		return | ||||
| 	} | ||||
| 	var teapotCommand string | ||||
| 	origHome := os.Getenv("ORIG_HOME") | ||||
| 	if origHome != "" { | ||||
| 		// For drone server
 | ||||
| 		teapotCommand = fmt.Sprintf("cp %s/.config/ci/teapot.env .env && joint-teapot JOJ3-scoreboard \"../../scoreboard.json\" %s %s \"JOJ3-examples\" \"JOJ3_dev.csv\"", origHome, b.studentName, b.studentId) | ||||
| 	} else { | ||||
| 		// For local developers
 | ||||
| 		jointTeapotRoot := os.Getenv("TEAPOT_ROOT") | ||||
| 		if jointTeapotRoot == "" { | ||||
| 			slog.Error("Unable to find joint-teapot. Have you configured environment variable TEAPOT_ROOT?") | ||||
| 			return | ||||
| 		} | ||||
| 		teapotCommand = fmt.Sprintf("cp %s/.env .env && source %s/env/bin/activate && python3 -m joint_teapot JOJ3-scoreboard \"../../scoreboard.json\" %s %s \"JOJ3-examples\" \"JOJ3_dev.csv\" && deactivate", jointTeapotRoot, jointTeapotRoot, b.studentName, b.studentId) | ||||
| 	} | ||||
| 	defer os.Remove(".env") | ||||
| 	teapotCmd := exec.Command("/bin/bash", "-c", teapotCommand) | ||||
| 	defer os.Remove("joint-teapot.log") | ||||
| 
 | ||||
| 	stderrPipe, err := teapotCmd.StderrPipe() | ||||
| 	if err != nil { | ||||
| 		slog.Error("Error creating stderr pipe when submitting scoreboard: ", "err", err) | ||||
| 		return | ||||
| 	} | ||||
| 	err = teapotCmd.Start() | ||||
| 	if err != nil { | ||||
| 		slog.Error("Error starting command when submitting scoreboard: ", "err", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	var stderr bytes.Buffer | ||||
| 	_, err = stderr.ReadFrom(stderrPipe) | ||||
| 	if err != nil { | ||||
| 		slog.Error("Error reading stderr when submitting scoreboard: ", "err", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	err = teapotCmd.Wait() | ||||
| 	if err != nil { | ||||
| 		slog.Error("Tried to submit scoreboard, but it finished with error: ", "err", err) | ||||
| 		slog.Error("Stderr output:", "stderr", stderr.String()) | ||||
| 		return | ||||
| 	} | ||||
| 	slog.Info("Scoreboard was submitted with following outputs: ", "stderr", stderr.String()) | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user