diff --git a/coverage/coverage.go b/coverage/coverage.go new file mode 100644 index 0000000..9ea5f89 --- /dev/null +++ b/coverage/coverage.go @@ -0,0 +1,68 @@ +package coverage + +import ( + "database/sql" + "encoding/json" + "io/ioutil" + "net/http" + "os" + "strconv" + "strings" + "time" +) + +// ProcessCoverage gets the coverage of {owner}/{repo} after each commit in the past year through codecov's API, saves into mysql +func ProcessCoverage(owner, repo string) error { + client := http.Client{} + req, err := http.NewRequest("GET", "https://codecov.io/api/gh/"+owner+"/"+repo+"/branch/master/graphs/commits.json?method=min&agg=day&time=365d&inc=totals&order=asc", strings.NewReader("")) + if err != nil { + return err + } + + req.Header.Set("Authorization", "token a3a4a9847e4b4e30b1ddc4dd725bf110") + + resp, err := client.Do(req) + if err != nil { + return err + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + var message interface{} + + json.Unmarshal(body, &message) + + db, err := sql.Open("mysql", os.Getenv("GITHUB_DSN")) + if err != nil { + return err + } + tx, err := db.Begin() + if err != nil { + return err + } + + commits := message.(map[string]interface{})["commits"] + for _, commit := range commits.([]interface{}) { + timestamp := commit.(map[string]interface{})["timestamp"] + totals := commit.(map[string]interface{})["totals"] + coverage, err := strconv.ParseFloat(totals.(map[string]interface{})["c"].(string), 64) + if err != nil { + return err + } + t, err := time.Parse("2006-01-02 15:04:05", timestamp.(string)) + if err != nil { + return err + } + _, err = tx.Exec("INSERT INTO COVERAGE_TIMELINE(REPO, TIME, COVERAGE) VALUES(?, ?, ?)", "pd", t, coverage) + if err != nil { + return err + } + } + + tx.Commit() + + return nil +} diff --git a/coverage/coverage_test.go b/coverage/coverage_test.go new file mode 100644 index 0000000..1aee3c7 --- /dev/null +++ b/coverage/coverage_test.go @@ -0,0 +1,10 @@ +package coverage + +import "testing" + +func TestProcessCoverage(t *testing.T) { + err := ProcessCoverage("pingcap", "tidb") + if err != nil { + t.Fatal(err) + } +} diff --git a/di/computing.go b/di/computing.go index 9598074..a99bfbe 100644 --- a/di/computing.go +++ b/di/computing.go @@ -14,11 +14,8 @@ package di import ( - "context" "database/sql" - "errors" "log" - "strings" "time" ) @@ -45,12 +42,14 @@ type Issue struct { Label map[string][]string } +// Interval DI struct type IntervalDI struct { StartTime time.Time EndTime time.Time Value float64 } +// Instant DI struct type InstantDI struct { Time time.Time Value float64 @@ -87,47 +86,6 @@ func calculateDI(issues []Issue) float64 { return di } -// getLabels returns all labels of an issue, saved in map. -func getLabels(db *sql.DB, issue Issue) (map[string][]string, error) { - - if db == nil { - return nil, errors.New("db is nil") - } - - labels := make(map[string][]string) - - ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) - defer cancel() - rows, err := db.QueryContext(ctx, `SELECT NAME - FROM LABEL_ISSUE_RELATIONSHIP, LABEL - WHERE LABEL_ISSUE_RELATIONSHIP.ISSUE_ID = ? - AND LABEL_ISSUE_RELATIONSHIP.LABEL_ID = LABEL.ID`, issue.ID) - - if err != nil { - return nil, err - } - - for rows.Next() { - var label string - err := rows.Scan(&label) - - if err != nil { - return nil, err - } - parts := strings.Split(label, "/") - switch len(parts) { - case 1: - labels[parts[0]] = append(labels[parts[0]], "") - case 2: - labels[parts[0]] = append(labels[parts[0]], parts[1]) - default: - log.Printf("Issue %v has unsupported label %s", issue.Number, label) - } - } - - return labels, nil -} - // parseIssues returns issues parsed from sql.Rows func parseIssues(rows *sql.Rows) ([]Issue, error) { issues := make([]Issue, 0) @@ -144,153 +102,4 @@ func parseIssues(rows *sql.Rows) ([]Issue, error) { } return issues, nil -} - -// getCreatedDIBetweenTime returns repo's DI of issues created between startTime and endTime -// if repo is empty string, all repo's DI will be involved -func getCreatedDIBetweenTime(db *sql.DB, startTime, endTime time.Time) (float64, error) { - if db == nil { - return 0, errors.New("db is nil") - } - - if startTime.After(endTime) { - return 0, errors.New("startTime > endTime") - } - - ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) - defer cancel() - - rows, err := db.QueryContext(ctx, "SELECT ID, NUMBER FROM ISSUE WHERE CREATED_AT BETWEEN ? AND ?", startTime, endTime) - - if err != nil { - return 0, err - } - - issues, err := parseIssues(rows) - if err != nil { - return 0, err - } - - for i, _ := range issues { - issues[i].Label, err = getLabels(db, issues[i]) - if err != nil { - return 0, err - } - } - - di := calculateDI(issues) - - return di, nil -} - -// getClosedDIBetweenTime returns total DI of issues closed between startTime and endTime -func getClosedDIBetweenTime(db *sql.DB, startTime, endTime time.Time) (float64, error) { - if db == nil { - return 0, errors.New("db is nil") - } - - if startTime.After(endTime) { - return 0, errors.New("startTime > endTime") - } - - ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) - defer cancel() - rows, err := db.QueryContext(ctx, "SELECT ID, NUMBER FROM ISSUE WHERE CLOSED_AT BETWEEN ? AND ?", startTime, endTime) - if err != nil { - return 0, err - } - - issues, err := parseIssues(rows) - if err != nil { - return 0, err - } - - for i, _ := range issues { - issues[i].Label, err = getLabels(db, issues[i]) - if err != nil { - return 0, err - } - } - - di := calculateDI(issues) - - return di, nil -} - -// getDI returns DI at a specified time -func getDI(db *sql.DB, time time.Time) (float64, error) { - if db == nil { - return 0, errors.New("db is nil") - } - - ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) - defer cancel() - rows, err := db.QueryContext(ctx, "SELECT ID, NUMBER FROM ISSUE WHERE CREATED_AT < ? AND (CLOSED = 0 OR CLOSED_AT > ?)", time, time) - if err != nil { - return 0, err - } - - issues, err := parseIssues(rows) - if err != nil { - return 0, err - } - - for i, _ := range issues { - issues[i].Label, err = getLabels(db, issues[i]) - if err != nil { - return 0, err - } - } - - di := calculateDI(issues) - - return di, nil -} - -// GetCreatedDIsFrom gets issue information from db, returns CreatedDI of each interval of fixed length from a specified time -func getCreatedDIsFrom(db *sql.DB, startTime time.Time, frequency time.Duration) ([]IntervalDI, error) { - dis := make([]IntervalDI, 0) - - for startTime.Before(time.Now()) { - endTime := startTime.Add(frequency) - - di, err := getCreatedDIBetweenTime(db, startTime, endTime) - if err != nil { - return nil, err - } - - dis = append(dis, IntervalDI{ - StartTime: startTime, - EndTime: endTime, - Value: di, - }) - - startTime = endTime - } - - return dis, nil -} - -// getCreatedDIsFrom gets issue information from db, returns CreatedDI of each interval of fixed length from a specified time -func getClosedDIsFrom(db *sql.DB, startTime time.Time, frequency time.Duration) ([]IntervalDI, error) { - dis := make([]IntervalDI, 0) - - for startTime.Before(time.Now()) { - endTime := startTime.Add(frequency) - - di, err := getClosedDIBetweenTime(db, startTime, endTime) - if err != nil { - return nil, err - } - - dis = append(dis, IntervalDI{ - StartTime: startTime, - EndTime: endTime, - Value: di, - }) - - startTime = endTime - } - - return dis, nil -} +} \ No newline at end of file diff --git a/di/computing_test.go b/di/computing_test.go index fcc17b1..1ecc614 100644 --- a/di/computing_test.go +++ b/di/computing_test.go @@ -16,7 +16,6 @@ package di import ( "database/sql" "log" - "math" "os" "testing" "time" @@ -26,18 +25,6 @@ import ( var issueDB *sql.DB -func must(t *testing.T, value interface{}, expected interface{}, name string) { - if expected != value { - t.Fatalf("%v = %v, expected %v", name, value, expected) - } -} - -func mustNot(t *testing.T, value interface{}, unexpected interface{}, name string) { - if unexpected == value { - t.Fatalf("%v must not be %v", name, unexpected) - } -} - func init() { dsn := os.Getenv("GITHUB_DSN") var err error @@ -72,52 +59,3 @@ func TestCalculateDi(t *testing.T) { must(t, di, 0.0, "di") } - -func TestGetCreatedDiBetweenTime(t *testing.T) { - startTime := time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC) - endTime := time.Date(2015, 11, 1, 0, 0, 0, 0, time.UTC) - di, err := getCreatedDIBetweenTime(issueDB, startTime, endTime) - must(t, err, nil, "err") - must(t, di, 0.1, "di") - - startTime = time.Date(2020, 10, 27, 0, 0, 0, 0, time.UTC) - endTime = time.Date(2020, 10, 26, 0, 0, 0, 0, time.UTC) - _, err = getCreatedDIBetweenTime(issueDB, startTime, endTime) - mustNot(t, err, nil, "err") -} - -func TestGetClosedDiBetweenTime(t *testing.T) { - startTime := time.Date(2020, 10, 1, 0, 0, 0, 0, time.UTC) - endTime := time.Date(2020, 11, 1, 0, 0, 0, 0, time.UTC) - di, err := getClosedDIBetweenTime(issueDB, startTime, endTime) - must(t, err, nil, "err") - must(t, di, 139.1, "di") - - startTime = time.Date(2020, 10, 27, 0, 0, 0, 0, time.UTC) - endTime = time.Date(2020, 10, 26, 0, 0, 0, 0, time.UTC) - di, err = getClosedDIBetweenTime(issueDB, startTime, endTime) - mustNot(t, err, nil, "err") -} - -func TestGetCreatedDIsFrom(t *testing.T) { - ti := time.Date(2020, 9, 21, 0, 0, 0, 0, time.UTC) - dis, err := getCreatedDIsFrom(issueDB, ti, 7*24*time.Hour) - must(t, err, nil, "err") - must(t, len(dis), 7, `len(dis)`) -} - -func TestGetClosedDIsFrom(t *testing.T) { - ti := time.Date(2020, 9, 21, 0, 0, 0, 0, time.UTC) - dis, err := getClosedDIsFrom(issueDB, ti, 7*24*time.Hour) - must(t, err, nil, "err") - must(t, len(dis), 7, `len(dis)`) -} - -func TestGetDI(t *testing.T) { - ti := time.Date(2020, 9, 21, 0, 0, 0, 0, time.UTC) - di, err := getDI(issueDB, ti) - must(t, err, nil, "err") - if math.Abs(di-1229.3) > 1e-6 { - t.Fatalf("GetDI %v returns %f", ti, di) - } -} diff --git a/di/di.go b/di/di.go index 8d59078..f1f47b0 100644 --- a/di/di.go +++ b/di/di.go @@ -19,25 +19,116 @@ import ( ) func ProcessCreatedDI(issueDB, diDB *sql.DB, repo, sig string, startTime, endTime time.Time) error { - + di, err := getCreatedDI(issueDB, repo, sig, startTime, endTime) + if err != nil { + return err + } + err = storeIntervalDI(diDB, "CREATED_DI", repo, sig, []IntervalDI{{StartTime: startTime, EndTime: endTime, Value: di}}) + return err } func ProcessClosedDI(issueDB, diDB *sql.DB, repo, sig string, startTime, endTime time.Time) error { - + di, err := getClosedDI(issueDB, repo, sig, startTime, endTime) + if err != nil { + return err + } + err = storeIntervalDI(diDB, "CLOSED_DI", repo, sig, []IntervalDI{{StartTime: startTime, EndTime: endTime, Value: di}}) + return err } func ProcessDI(issueDB, diDB *sql.DB, repo, sig string, time time.Time) error { - + di, err := getDI(issueDB, repo, sig, time) + if err != nil { + return err + } + err = storeInstantDI(diDB, "DI", repo, sig, []InstantDI{{Time: time, Value: di}}) + return err } func ProcessCreatedDIs(issueDB, diDB *sql.DB, repo, sig string, startTime, endTime time.Time, frequency time.Duration) error { + dis := make([]IntervalDI, 0) + + for startTime.Before(endTime) { + endTime := startTime.Add(frequency) + + di, err := getCreatedDI(issueDB, repo, sig, startTime, endTime) + if err != nil { + return err + } + dis = append(dis, IntervalDI{ + StartTime: startTime, + EndTime: endTime, + Value: di, + }) + + startTime = endTime + } + + err := storeIntervalDI(diDB, "CREATED_DI", repo, sig, dis) + + return err } func ProcessClosedDIs(issueDB, diDB *sql.DB, repo, sig string, startTime, endTime time.Time, frequency time.Duration) error { + dis := make([]IntervalDI, 0) + + for startTime.Before(endTime) { + endTime := startTime.Add(frequency) + + di, err := getClosedDI(issueDB, repo, sig, startTime, endTime) + if err != nil { + return err + } + dis = append(dis, IntervalDI{ + StartTime: startTime, + EndTime: endTime, + Value: di, + }) + + startTime = endTime + } + + err := storeIntervalDI(diDB, "CLOSED_DI", repo, sig, dis) + + return err } func ProcessDIs(issueDB, diDB *sql.DB, repo, sig string, startTime, endTime time.Time, frequency time.Duration) error { + dis := make([]InstantDI, 0) + insDI, err := getDI(issueDB, repo, sig, startTime) + if err != nil { + return err + } + dis = append(dis, InstantDI{ + Time: startTime, + Value: insDI, + }) + + for startTime.Before(endTime) { + + createdDI, err := getCreatedDI(issueDB, repo, sig, startTime, startTime.Add(frequency)) + if err != nil { + return err + } + + closedDI, err := getClosedDI(issueDB, repo, sig, startTime, startTime.Add(frequency)) + if err != nil { + return err + } + + insDI += createdDI - closedDI + + dis = append(dis, InstantDI{ + Time: startTime.Add(frequency), + Value: insDI, + }) + + startTime = startTime.Add(frequency) + } + + err = storeInstantDI(diDB, "DI", repo, sig, dis) + return err } diff --git a/di/di_test.go b/di/di_test.go index 31ef24c..9643ecc 100644 --- a/di/di_test.go +++ b/di/di_test.go @@ -12,3 +12,64 @@ // limitations under the License. package di + +import ( + "testing" + "time" +) + +func must(t *testing.T, value interface{}, expected interface{}, name string) { + if expected != value { + t.Fatalf("%v = %v, expected %v", name, value, expected) + } +} + +func TestProcessCreatedDI(t *testing.T) { + startTime := time.Date(2020, 9, 7, 0, 0, 0, 0, time.UTC) + endTime := time.Date(2020, 9, 14, 0, 0, 0, 0, time.UTC) + err := ProcessCreatedDI(issueDB, diDB, "tidb", "", startTime, endTime) + must(t, err, nil, "err") +} + +func TestProcessClosedDI(t *testing.T) { + startTime := time.Date(2020, 9, 7, 0, 0, 0, 0, time.UTC) + endTime := time.Date(2020, 9, 14, 0, 0, 0, 0, time.UTC) + err := ProcessClosedDI(issueDB, diDB, "tidb", "", startTime, endTime) + must(t, err, nil, "err") +} + +func TestProcessDI(t *testing.T) { + time := time.Date(2020, 9, 14, 0, 0, 0, 0, time.UTC) + err := ProcessDI(issueDB, diDB, "tidb", "", time) + must(t, err, nil, "err") +} + +func TestProcessCreatedDIs(t *testing.T) { + startTime := time.Date(2019, 12, 30, 0, 0, 0, 0, time.UTC) + endTime := time.Now() + repos := []string{"tidb", "tikv", "pd", "dm", "br", "ticdc", "tidb-lightning"} + for _, repo := range repos { + err := ProcessCreatedDIs(issueDB, diDB, repo, "", startTime, endTime, 7*24*time.Hour) + must(t, err, nil, "err") + } +} + +func TestProcessClosedDIs(t *testing.T) { + startTime := time.Date(2019, 12, 30, 0, 0, 0, 0, time.UTC) + endTime := time.Now() + repos := []string{"tidb", "tikv", "pd", "dm", "br", "ticdc", "tidb-lightning"} + for _, repo := range repos { + err := ProcessClosedDIs(issueDB, diDB, repo, "", startTime, endTime, 7*24*time.Hour) + must(t, err, nil, "err") + } +} + +func TestProcessDIs(t *testing.T) { + startTime := time.Date(2019, 12, 30, 0, 0, 0, 0, time.UTC) + endTime := time.Now() + repos := []string{"tidb", "tikv", "pd", "dm", "br", "ticdc", "tidb-lightning"} + for _, repo := range repos { + err := ProcessDIs(issueDB, diDB, repo, "", startTime, endTime, 7*24*time.Hour) + must(t, err, nil, "err") + } +} diff --git a/di/storage.go b/di/storage.go index a97f996..ea8170e 100644 --- a/di/storage.go +++ b/di/storage.go @@ -14,26 +14,204 @@ package di import ( + "context" "database/sql" + "errors" + "log" + "strings" + "time" ) -func insertIntervalDI(tx *sql.Tx, table string, repo string, di IntervalDI) error { - _, err := tx.Exec(`INSERT INTO `+table+`(REPO, START_TIME, END_TIME, DI) VALUES(?, ?, ?, ?)`, repo, di.StartTime, di.EndTime, di.Value) +// getLabels returns all labels of an issue, saved in map. +func getLabels(db *sql.DB, issue Issue) (map[string][]string, error) { + + if db == nil { + return nil, errors.New("db is nil") + } + + labels := make(map[string][]string) + + ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) + defer cancel() + rows, err := db.QueryContext(ctx, `SELECT NAME + FROM LABEL_ISSUE_RELATIONSHIP, LABEL + WHERE LABEL_ISSUE_RELATIONSHIP.ISSUE_ID = ? + AND LABEL_ISSUE_RELATIONSHIP.LABEL_ID = LABEL.ID`, issue.ID) + + if err != nil { + return nil, err + } + + for rows.Next() { + var label string + err := rows.Scan(&label) + + if err != nil { + return nil, err + } + parts := strings.Split(label, "/") + switch len(parts) { + case 1: + labels[parts[0]] = append(labels[parts[0]], "") + case 2: + labels[parts[0]] = append(labels[parts[0]], parts[1]) + default: + log.Printf("Issue %v has unsupported label %s", issue.Number, label) + } + } + + return labels, nil +} + +// generateQuery generates query from original query string with repo and sig +// only non-empty repo and sig will be involved +func generateQuery(query, repo, sig string) string { + if len(repo) > 0 { + query += ` AND REPOSITORY_ID = ( + SELECT ID + FROM REPOSITORY + WHERE REPO_NAME = '` + repo + `')` + } + if len(sig) > 0 { + query += ` AND ID IN ( + SELECT ISSUE_ID + FROM LABEL_ISSUE_RELATIONSHIP + LEFT JOIN LABEL ON LABEL_ISSUE_RELATIONSHIP.LABEL_ID = LABEL.ID + WHERE LABEL.NAME = '` + sig + `')` + } + return query +} + +// getClosedDI returns DI of issues created between startTime and endTime +// only non-empty repo and sig will be involved +func getCreatedDI(db *sql.DB, repo, sig string, startTime, endTime time.Time) (float64, error) { + if db == nil { + return 0, errors.New("db is nil") + } + + if startTime.After(endTime) { + return 0, errors.New("startTime > endTime") + } + + ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) + defer cancel() + + query := generateQuery("SELECT ID, NUMBER FROM ISSUE WHERE CREATED_AT BETWEEN ? AND ?", repo, sig) + rows, err := db.QueryContext(ctx, query, startTime, endTime) + + if err != nil { + return 0, err + } + + issues, err := parseIssues(rows) + if err != nil { + return 0, err + } + + for i, _ := range issues { + issues[i].Label, err = getLabels(db, issues[i]) + if err != nil { + return 0, err + } + } + + di := calculateDI(issues) + + return di, nil +} + +// getClosedDI returns DI of issues closed between startTime and endTime +// only non-empty repo and sig will be involved +func getClosedDI(db *sql.DB, repo, sig string, startTime, endTime time.Time) (float64, error) { + if db == nil { + return 0, errors.New("db is nil") + } + + if startTime.After(endTime) { + return 0, errors.New("startTime > endTime") + } + + ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) + defer cancel() + + query := generateQuery("SELECT ID, NUMBER FROM ISSUE WHERE CLOSED_AT BETWEEN ? AND ?", repo, sig) + rows, err := db.QueryContext(ctx, query, startTime, endTime) + + if err != nil { + return 0, err + } + + issues, err := parseIssues(rows) + if err != nil { + return 0, err + } + + for i, _ := range issues { + issues[i].Label, err = getLabels(db, issues[i]) + if err != nil { + return 0, err + } + } + + di := calculateDI(issues) + + return di, nil +} + +// getDI returns DI at a specified time +// only non-empty repo and sig will be involved +func getDI(db *sql.DB, repo, sig string, time time.Time) (float64, error) { + if db == nil { + return 0, errors.New("db is nil") + } + + ctx, cancel := context.WithTimeout(context.Background(), mysqlQueryTimeout) + defer cancel() + + query := generateQuery("SELECT ID, NUMBER FROM ISSUE WHERE CREATED_AT < ? AND (CLOSED = 0 OR CLOSED_AT > ?)", repo, sig) + + rows, err := db.QueryContext(ctx, query, time, time) + if err != nil { + return 0, err + } + + issues, err := parseIssues(rows) + if err != nil { + return 0, err + } + + for i, _ := range issues { + issues[i].Label, err = getLabels(db, issues[i]) + if err != nil { + return 0, err + } + } + + di := calculateDI(issues) + + return di, nil +} + +// insertIntervalDI inserts an IntervalDI into table (not committed) +func insertIntervalDI(tx *sql.Tx, table string, repo, sig string, di IntervalDI) error { + _, err := tx.Exec(`INSERT INTO `+table+`(REPO, SIG, START_TIME, END_TIME, DI) VALUES(?, ?, ?, ?, ?)`, repo, sig, di.StartTime, di.EndTime, di.Value) return err } -func insertInstantDI(tx *sql.Tx, table string, repo string, di InstantDI) error { - _, err := tx.Exec(`INSERT INTO `+table+`(REPO, TIME, DI) VALUES(?, ?, ?)`, repo, di.Time, di.Value) +// insertIntervalDI inserts an InstantDI into table (not committed) +func insertInstantDI(tx *sql.Tx, table string, repo, sig string, di InstantDI) error { + _, err := tx.Exec(`INSERT INTO `+table+`(REPO, SIG, TIME, DI) VALUES(?, ?, ?, ?)`, repo, sig, di.Time, di.Value) return err } -func storeIntervalDI(db *sql.DB, table string, repo string, dis []IntervalDI) error { +// storeIntervalDI inserts an array of IntervalDI into table and commits +func storeIntervalDI(db *sql.DB, table string, repo, sig string, dis []IntervalDI) error { tx, err := db.Begin() if err != nil { return err } for _, di := range dis { - if err := insertIntervalDI(tx, table, repo, di); err != nil { + if err := insertIntervalDI(tx, table, repo, sig, di); err != nil { return err } } @@ -41,16 +219,17 @@ func storeIntervalDI(db *sql.DB, table string, repo string, dis []IntervalDI) er return nil } -func storeInstantDI(db *sql.DB, table string, repo string, dis []InstantDI) error { +// storeInstantDI inserts an array of InstantDI into table and commits +func storeInstantDI(db *sql.DB, table string, repo, sig string, dis []InstantDI) error { tx, err := db.Begin() if err != nil { return err } for _, di := range dis { - if err := insertInstantDI(tx, table, repo, di); err != nil { + if err := insertInstantDI(tx, table, repo, sig, di); err != nil { return err } } tx.Commit() return nil -} +} \ No newline at end of file diff --git a/di/storage_test.go b/di/storage_test.go index 30d28df..ab2683c 100644 --- a/di/storage_test.go +++ b/di/storage_test.go @@ -48,13 +48,12 @@ func clearDB(db *sql.DB) { log.Fatal(err) } tx.Commit() - clearDB(diDB) } func TestInsertIntervalDI(t *testing.T) { tx, err := diDB.Begin() must(t, err, nil, "err") - err = insertIntervalDI(tx, "CREATED_DI", "test", IntervalDI{ + err = insertIntervalDI(tx, "CREATED_DI", "test", "", IntervalDI{ StartTime: time.Now().AddDate(0, 0, -7), EndTime: time.Now(), Value: 10, @@ -67,7 +66,7 @@ func TestInsertIntervalDI(t *testing.T) { func TestInsertInstantDI(t *testing.T) { tx, err := diDB.Begin() must(t, err, nil, "err") - err = insertInstantDI(tx, "DI", "test", InstantDI{ + err = insertInstantDI(tx, "DI", "test", "", InstantDI{ Time: time.Now(), Value: 20, }) @@ -79,7 +78,7 @@ func TestInsertInstantDI(t *testing.T) { func TestStoreIntervalDI(t *testing.T) { dis := []IntervalDI{{time.Now(), time.Now().AddDate(0, 0, -7), 10}, {time.Now().AddDate(0, 0, -7), time.Now().AddDate(0, 0, -14), 20}} - err := storeIntervalDI(diDB, "CREATED_DI", "test", dis) + err := storeIntervalDI(diDB, "CREATED_DI", "test", "sig/test", dis) must(t, err, nil, "err") clearDB(diDB) } @@ -87,7 +86,23 @@ func TestStoreIntervalDI(t *testing.T) { func TestStoreInstantDI(t *testing.T) { dis := []InstantDI{{time.Now(), 10}, {time.Now().AddDate(0, 0, -7), 20}} - err := storeInstantDI(diDB, "CREATED_DI", "test", dis) + err := storeInstantDI(diDB, "DI", "test", "sig/test", dis) must(t, err, nil, "err") clearDB(diDB) } + +func TestGetCreatedDi(t *testing.T) { + startTime := time.Date(2020, 9, 7, 0, 0, 0, 0, time.UTC) + endTime := time.Date(2020, 9, 14, 0, 0, 0, 0, time.UTC) + di, err := getCreatedDI(issueDB, "tidb", "sig/execution", startTime, endTime) + must(t, err, nil, "err") + must(t, di, 3.0, "di") +} + +func TestGetClosedDI(t *testing.T) { + startTime := time.Date(2020, 9, 7, 0, 0, 0, 0, time.UTC) + endTime := time.Date(2020, 9, 14, 0, 0, 0, 0, time.UTC) + di, err := getClosedDI(issueDB, "tidb", "", startTime, endTime) + must(t, err, nil, "err") + must(t, di, 107.0, "di") +}