Skip to content

Commit

Permalink
Merge pull request #7 from FACT-Finder/speedy-details
Browse files Browse the repository at this point in the history
Speedup and add details page for test results
  • Loading branch information
tvrg authored Dec 1, 2022
2 parents 35eb168 + 200d089 commit 0cd8672
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 48 deletions.
26 changes: 20 additions & 6 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ func New(db *sqlx.DB, token string) *echo.Echo {
})
app.POST("/report/:commit", secure(token, wrapper.AddReport))
app.GET("/flakes", wrapper.GetFlakyTests)
app.GET("/test/:name/fails", wrapper.GetFailedBuilds)
app.GET("/test/:id/fails", wrapper.GetFailedBuilds)
app.GET("/test/:test_id/upload/:upload_id/output", wrapper.GetTestResult)
app.GET("/ui", func(c echo.Context) error {
flakes, err := api.flakyTests()
if err != nil {
Expand All @@ -51,15 +52,28 @@ func New(db *sqlx.DB, token string) *echo.Echo {
"Flakes": flakes,
})
})
app.GET("/ui/test/:name/fails", func(c echo.Context) error {
name := c.Param("name")
fails, err := api.failedBuilds(name)
app.GET("/ui/test/:id/fails", func(c echo.Context) error {
testID := c.Param("id")
test, err := api.failedBuilds(testID)
if err != nil {
return err
}
return c.Render(http.StatusOK, "fails.html", map[string]interface{}{
"Title": "Failed Builds " + name,
"Fails": fails,
"Title": "Failed Builds " + test.Name,
"TestId": testID,
"Results": test.Results,
})
})
app.GET("/ui/test/:test_id/upload/:upload_id", func(c echo.Context) error {
testID := c.Param("test_id")
uploadID := c.Param("upload_id")
result, err := api.testResult(testID, uploadID)
if err != nil {
return err
}
return c.Render(http.StatusOK, "result.html", map[string]interface{}{
"Title": "Test result for " + result.Name,
"Result": result,
})
})
app.StaticFS("/ui", asset.Static)
Expand Down
43 changes: 33 additions & 10 deletions api/fails.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,59 @@ package api

import (
"net/http"
"strconv"
"time"

"github.com/FACT-Finder/noflake/database"
"github.com/labstack/echo/v4"
)

func (a *api) GetFailedBuilds(ctx echo.Context, name string) error {
flakes, err := a.failedBuilds(name)
func (a *api) GetFailedBuilds(ctx echo.Context, testID string) error {
flakes, err := a.failedBuilds(testID)
if err != nil {
return err
}
return ctx.JSON(http.StatusOK, flakes)
}

func (a *api) failedBuilds(name string) ([]FailedBuild, error) {
failures, err := database.GetFailures(a.db, name)
func (a *api) failedBuilds(id string) (TestResults, error) {
testID, err := strconv.Atoi(id)
if err != nil {
return nil, err
return TestResults{}, err
}

result := []FailedBuild{}
testName, err := database.GetTestName(a.db, testID)
if err != nil {
return TestResults{}, err
}

failures, err := database.GetFailures(a.db, testID)
if err != nil {
return TestResults{}, err
}

results := []TestResult{}

for _, fail := range failures {
uploadID := strconv.Itoa(fail.UploadID)
commitSHA := fail.CommitSHA
output := fail.Output
url := fail.URL
lastFailStr := fail.Date.UTC().Format(time.RFC3339)
result = append(result,
FailedBuild{CommitSHA: commitSHA, Date: lastFailStr, Output: output, Url: url})
results = append(results,
TestResult{
TestId: id,
UploadId: uploadID,
Name: testName,
CommitSHA: commitSHA,
Date: lastFailStr,
Success: false,
Url: url,
})
}

return result, nil
return TestResults{
TestId: id,
Name: testName,
Results: results,
}, nil
}
5 changes: 4 additions & 1 deletion api/flakes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"net/http"
"strconv"
"time"

"github.com/FACT-Finder/noflake/database"
Expand All @@ -17,11 +18,13 @@ func (a *api) flakyTests() ([]FlakyTest, error) {
flakes := []FlakyTest{}

for _, test := range tests {
name := test.Name
totalFails := test.TotalFails
lastFail := test.LastFail
lastFailStr := lastFail.UTC().Format(time.RFC3339)
idStr := strconv.Itoa(test.ID)
flakes = append(flakes,
FlakyTest{Test: test.Name, TotalFails: &totalFails, LastFail: &lastFailStr})
FlakyTest{Id: idStr, Name: name, TotalFails: &totalFails, LastFail: &lastFailStr})
}

return flakes, nil
Expand Down
6 changes: 6 additions & 0 deletions api/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,11 @@ func (a *api) AddReport(ctx echo.Context, commitSha string, params AddReportPara
fmt.Sprintf("couldn't store test results: %s", err))
}

err = database.UpdateFlakyTests(a.db, *commit.ID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("couldn't update flaky tests: %s", err))
}

return ctx.NoContent(http.StatusNoContent)
}
44 changes: 44 additions & 0 deletions api/test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package api

import (
"net/http"
"strconv"

"github.com/FACT-Finder/noflake/database"
"github.com/labstack/echo/v4"
)

func (a *api) GetTestResult(ctx echo.Context, testID, uploadID string) error {
output, err := a.testResult(testID, uploadID)
if err != nil {
return err
}
return ctx.JSON(http.StatusOK, output)
}

func (a *api) testResult(testIDStr, uploadIDStr string) (TestResult, error) {
testID, err := strconv.Atoi(testIDStr)
if err != nil {
return TestResult{}, err
}

uploadID, err := strconv.Atoi(uploadIDStr)
if err != nil {
return TestResult{}, err
}

testResult, err := database.GetTestResult(a.db, testID, uploadID)
if err != nil {
return TestResult{}, err
}

return TestResult{
TestId: testIDStr,
UploadId: uploadIDStr,
Name: testResult.Name,
CommitSHA: testResult.CommitSHA,
Url: testResult.URL,
Success: testResult.Success,
Output: testResult.Output,
}, nil
}
4 changes: 3 additions & 1 deletion asset/fails.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
<th>Commit</th>
<th></th>
</tr>
{{ range .Fails }}
{{ range .Results }}
<tr>
<td>{{.Date}}</td>
<td>{{.CommitSHA}}</td>
<td><a href="{{.Url}}">Build</a></td>
<td><a href="/ui/test/{{$.TestId}}/upload/{{.UploadId}}">Details</a></td>
</tr>
{{ end }}
</table>
{{template "end" .}}
{{.Output}}
2 changes: 1 addition & 1 deletion asset/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<tr>
<td>{{.LastFail}}</td>
<td>{{.TotalFails}}</td>
<td><a href="/ui/test/{{.Test}}/fails">{{.Test}}</a></td>
<td><a href="/ui/test/{{.Id}}/fails">{{.Name}}</a></td>
</tr>
{{ end }}
</table>
Expand Down
20 changes: 20 additions & 0 deletions asset/result.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{template "start" .}}
<div>
<a href="/ui/test/{{.Result.TestId}}/fails">Show all failures for this test</a>
</div>
<br />
<table>
<tr><td>Name</td><td>{{.Result.Name}}</td></tr>
<tr><td>Commit</td><td>{{.Result.CommitSHA}}</td></tr>
<tr><td>Success</td><td>{{.Result.Success}}</td>
<tr><td>Build</td><td><a href="{{.Result.Url}}">{{.Result.Url}}</a></td>
</table>
<br />
<div>
<div><b>Output:</b></div>
<pre>
{{.Result.Output}}
</pre>
</div>
{{template "end" .}}
{{.Output}}
12 changes: 6 additions & 6 deletions database/fails.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,27 @@ import (
)

type TestFailure struct {
UploadID int `db:"upload_id"`
Date time.Time `db:"last_fail"`
Output *string `db:"output"`
CommitSHA string `db:"commit_sha"`
URL *string `db:"url"`
}

func GetFailures(db *sqlx.DB, name string) ([]TestFailure, error) {
func GetFailures(db *sqlx.DB, testID int) ([]TestFailure, error) {
rows, err := db.Queryx(`
SELECT
uploads.id as upload_id,
commits.commit_sha,
uploads.url,
results.output,
uploads.time
from results
LEFT JOIN commits on commits.id = results.commit_id
LEFT JOIN uploads on uploads.id = results.upload_id
LEFT JOIN tests on tests.id = results.test_id
WHERE
tests.name = ? and results.success = 0
tests.id = ? and results.success = 0
ORDER BY uploads.time desc
`, name)
`, testID)
if err != nil {
return nil, err
}
Expand All @@ -36,7 +36,7 @@ func GetFailures(db *sqlx.DB, name string) ([]TestFailure, error) {
for rows.Next() {
var failure TestFailure
var dateTimestamp int64
err = rows.Scan(&failure.CommitSHA, &failure.URL, &failure.Output, &dateTimestamp)
err = rows.Scan(&failure.UploadID, &failure.CommitSHA, &failure.URL, &dateTimestamp)
if err != nil {
return nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions database/migrations/3_flaky_tests.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DROP INDEX IF EXISTS tests_flaky;
DROP INDEX IF EXISTS results_test_id;
DROP INDEX IF EXISTS results_commit_id;
ALTER TABLE tests DROP flaky;
CREATE INDEX results_idx ON results(test_id, commit_id, success);
15 changes: 15 additions & 0 deletions database/migrations/3_flaky_tests.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
DROP INDEX IF EXISTS results_idx;

ALTER TABLE tests ADD flaky INTEGER NOT NULL DEFAULT 0;

UPDATE tests SET flaky = true
WHERE tests.id in (
SELECT DISTINCT(tests.id) FROM results
LEFT JOIN tests ON tests.id = results.test_id
GROUP BY results.test_id, results.commit_id
HAVING COUNT(DISTINCT results.success) > 1
);

CREATE INDEX results_test_id ON results(test_id);
CREATE INDEX results_commit_id ON results(commit_id);
CREATE INDEX tests_flaky ON tests(flaky);
Loading

0 comments on commit 0cd8672

Please sign in to comment.