diff --git a/internal/msg.go b/internal/msg.go index 15791b9..c0efb7a 100644 --- a/internal/msg.go +++ b/internal/msg.go @@ -13,6 +13,7 @@ type MirrorStatus struct { IsMaster bool `json:"is_master"` Status SyncStatus `json:"status"` LastUpdate time.Time `json:"last_update"` + LastEnded time.Time `json:"last_ended"` Upstream string `json:"upstream"` Size string `json:"size"` ErrorMsg string `json:"error_msg"` diff --git a/internal/status_web.go b/internal/status_web.go index 33e15ca..9329c96 100644 --- a/internal/status_web.go +++ b/internal/status_web.go @@ -43,6 +43,8 @@ type WebMirrorStatus struct { Status SyncStatus `json:"status"` LastUpdate textTime `json:"last_update"` LastUpdateTs stampTime `json:"last_update_ts"` + LastEnded textTime `json:"last_ended"` + LastEndedTs stampTime `json:"last_ended_ts"` Upstream string `json:"upstream"` Size string `json:"size"` // approximate size } @@ -54,6 +56,8 @@ func BuildWebMirrorStatus(m MirrorStatus) WebMirrorStatus { Status: m.Status, LastUpdate: textTime{m.LastUpdate}, LastUpdateTs: stampTime{m.LastUpdate}, + LastEnded: textTime{m.LastEnded}, + LastEndedTs: stampTime{m.LastEnded}, Upstream: m.Upstream, Size: m.Size, } diff --git a/internal/status_web_test.go b/internal/status_web_test.go index ce31630..97453ed 100644 --- a/internal/status_web_test.go +++ b/internal/status_web_test.go @@ -19,6 +19,8 @@ func TestStatus(t *testing.T) { Status: Success, LastUpdate: textTime{t}, LastUpdateTs: stampTime{t}, + LastEnded: textTime{t}, + LastEndedTs: stampTime{t}, Size: "5GB", Upstream: "rsync://mirrors.tuna.tsinghua.edu.cn/tunalinux/", } @@ -36,6 +38,38 @@ func TestStatus(t *testing.T) { So(m2.LastUpdateTs.Unix(), ShouldEqual, m.LastUpdate.Unix()) So(m2.LastUpdate.UnixNano(), ShouldEqual, m.LastUpdate.UnixNano()) So(m2.LastUpdateTs.UnixNano(), ShouldEqual, m.LastUpdate.UnixNano()) + So(m2.LastEnded.Unix(), ShouldEqual, m.LastEnded.Unix()) + So(m2.LastEndedTs.Unix(), ShouldEqual, m.LastEnded.Unix()) + So(m2.LastEnded.UnixNano(), ShouldEqual, m.LastEnded.UnixNano()) + So(m2.LastEndedTs.UnixNano(), ShouldEqual, m.LastEnded.UnixNano()) + So(m2.Size, ShouldEqual, m.Size) + So(m2.Upstream, ShouldEqual, m.Upstream) + }) + Convey("BuildWebMirrorStatus should work", t, func() { + m := MirrorStatus{ + Name: "arch-sync3", + Worker: "testWorker", + IsMaster: true, + Status: Failed, + LastUpdate: time.Now().Add(-time.Minute * 30), + LastEnded: time.Now(), + Upstream: "mirrors.tuna.tsinghua.edu.cn", + Size: "4GB", + } + + var m2 WebMirrorStatus + m2 = BuildWebMirrorStatus(m) + // fmt.Printf("%#v", m2) + So(m2.Name, ShouldEqual, m.Name) + So(m2.Status, ShouldEqual, m.Status) + So(m2.LastUpdate.Unix(), ShouldEqual, m.LastUpdate.Unix()) + So(m2.LastUpdateTs.Unix(), ShouldEqual, m.LastUpdate.Unix()) + So(m2.LastUpdate.UnixNano(), ShouldEqual, m.LastUpdate.UnixNano()) + So(m2.LastUpdateTs.UnixNano(), ShouldEqual, m.LastUpdate.UnixNano()) + So(m2.LastEnded.Unix(), ShouldEqual, m.LastEnded.Unix()) + So(m2.LastEndedTs.Unix(), ShouldEqual, m.LastEnded.Unix()) + So(m2.LastEnded.UnixNano(), ShouldEqual, m.LastEnded.UnixNano()) + So(m2.LastEndedTs.UnixNano(), ShouldEqual, m.LastEnded.UnixNano()) So(m2.Size, ShouldEqual, m.Size) So(m2.Upstream, ShouldEqual, m.Upstream) }) diff --git a/manager/db_test.go b/manager/db_test.go index 1d13eec..5e6e79d 100644 --- a/manager/db_test.go +++ b/manager/db_test.go @@ -65,6 +65,7 @@ func TestBoltAdapter(t *testing.T) { IsMaster: true, Status: Success, LastUpdate: time.Now(), + LastEnded: time.Now(), Upstream: "mirrors.tuna.tsinghua.edu.cn", Size: "3GB", }, @@ -73,7 +74,8 @@ func TestBoltAdapter(t *testing.T) { Worker: testWorkerIDs[1], IsMaster: true, Status: Disabled, - LastUpdate: time.Now(), + LastUpdate: time.Now().Add(-time.Hour), + LastEnded: time.Now(), Upstream: "mirrors.tuna.tsinghua.edu.cn", Size: "4GB", }, @@ -82,7 +84,8 @@ func TestBoltAdapter(t *testing.T) { Worker: testWorkerIDs[1], IsMaster: true, Status: Success, - LastUpdate: time.Now(), + LastUpdate: time.Now().Add(-time.Second), + LastEnded: time.Now(), Upstream: "mirrors.tuna.tsinghua.edu.cn", Size: "4GB", }, diff --git a/manager/server.go b/manager/server.go index 5953445..2563582 100644 --- a/manager/server.go +++ b/manager/server.go @@ -242,6 +242,11 @@ func (s *Manager) updateJobOfWorker(c *gin.Context) { } else { status.LastUpdate = curStatus.LastUpdate } + if status.Status == Success || status.Status == Failed { + status.LastEnded = time.Now() + } else { + status.LastEnded = curStatus.LastEnded + } // Only message with meaningful size updates the mirror size if len(curStatus.Size) > 0 && curStatus.Size != "unknown" { diff --git a/manager/server_test.go b/manager/server_test.go index bf1a906..27f3cd4 100644 --- a/manager/server_test.go +++ b/manager/server_test.go @@ -121,6 +121,7 @@ func TestHTTPServer(t *testing.T) { So(m.Size, ShouldEqual, status.Size) So(m.IsMaster, ShouldEqual, status.IsMaster) So(time.Now().Sub(m.LastUpdate), ShouldBeLessThan, 1*time.Second) + So(time.Now().Sub(m.LastEnded), ShouldBeLessThan, 1*time.Second) }) @@ -137,6 +138,7 @@ func TestHTTPServer(t *testing.T) { So(m.Size, ShouldEqual, status.Size) So(m.IsMaster, ShouldEqual, status.IsMaster) So(time.Now().Sub(m.LastUpdate.Time), ShouldBeLessThan, 1*time.Second) + So(time.Now().Sub(m.LastEnded.Time), ShouldBeLessThan, 1*time.Second) }) @@ -166,6 +168,7 @@ func TestHTTPServer(t *testing.T) { So(m.Size, ShouldEqual, "5GB") So(m.IsMaster, ShouldEqual, status.IsMaster) So(time.Now().Sub(m.LastUpdate), ShouldBeLessThan, 1*time.Second) + So(time.Now().Sub(m.LastEnded), ShouldBeLessThan, 1*time.Second) }) }) @@ -180,6 +183,32 @@ func TestHTTPServer(t *testing.T) { So(err, ShouldBeNil) So(resp.StatusCode, ShouldEqual, http.StatusInternalServerError) }) + + // what if status changed to failed + status.Status = Failed + time.Sleep(3 * time.Second) + resp, err = PostJSON(fmt.Sprintf("%s/workers/%s/jobs/%s", baseURL, status.Worker, status.Name), status, nil) + defer resp.Body.Close() + So(err, ShouldBeNil) + So(resp.StatusCode, ShouldEqual, http.StatusOK) + + Convey("What if syncing job failed", func(ctx C) { + var ms []MirrorStatus + resp, err := GetJSON(baseURL+"/workers/test_worker1/jobs", &ms, nil) + + So(err, ShouldBeNil) + So(resp.StatusCode, ShouldEqual, http.StatusOK) + // err = json.NewDecoder(resp.Body).Decode(&mirrorStatusList) + m := ms[0] + So(m.Name, ShouldEqual, status.Name) + So(m.Worker, ShouldEqual, status.Worker) + So(m.Status, ShouldEqual, status.Status) + So(m.Upstream, ShouldEqual, status.Upstream) + So(m.Size, ShouldEqual, status.Size) + So(m.IsMaster, ShouldEqual, status.IsMaster) + So(time.Now().Sub(m.LastUpdate), ShouldBeGreaterThan, 3*time.Second) + So(time.Now().Sub(m.LastEnded), ShouldBeLessThan, 1*time.Second) + }) }) Convey("update mirror status of an inexisted worker", func(ctx C) { @@ -190,6 +219,7 @@ func TestHTTPServer(t *testing.T) { IsMaster: true, Status: Success, LastUpdate: time.Now(), + LastEnded: time.Now(), Upstream: "mirrors.tuna.tsinghua.edu.cn", Size: "4GB", }