From 4178acf41ef5204db7c81742f07e29e517466cc0 Mon Sep 17 00:00:00 2001 From: zeppp Date: Wed, 10 Jan 2018 17:07:55 +0800 Subject: [PATCH 1/2] refactor: encapsulate codes into function FormatStatus Signed-off-by: zeppp --- apis/server/container_bridge.go | 19 +++++-------------- daemon/mgr/container_types.go | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/apis/server/container_bridge.go b/apis/server/container_bridge.go index bdacec9a6..5d747c83b 100644 --- a/apis/server/container_bridge.go +++ b/apis/server/container_bridge.go @@ -244,22 +244,13 @@ func (s *Server) getContainers(ctx context.Context, rw http.ResponseWriter, req HostConfig: m.HostConfig, } - // TODO encapsulate this into a single function - if m.State.Status == types.StatusRunning || m.State.Status == types.StatusPaused { - start, _ := time.Parse(utils.TimeLayout, m.State.StartedAt) - startAt, err := utils.FormatTimeInterval(start.UnixNano()) - if err != nil { - return err - } - - container.Status = "Up " + startAt - if m.State.Status == types.StatusPaused { - container.Status += "(paused)" - } - } else { - container.Status = string(m.State.Status) + status, err := m.FormatStatus() + if err != nil { + return err } + container.Status = status + containerList = append(containerList, container) } return EncodeResponse(rw, http.StatusOK, containerList) diff --git a/daemon/mgr/container_types.go b/daemon/mgr/container_types.go index 932f97c3e..a19aa7673 100644 --- a/daemon/mgr/container_types.go +++ b/daemon/mgr/container_types.go @@ -3,9 +3,11 @@ package mgr import ( "net/http" "sync" + "time" "github.com/alibaba/pouch/apis/types" "github.com/alibaba/pouch/daemon/meta" + "github.com/alibaba/pouch/pkg/utils" "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -154,6 +156,27 @@ func (meta *ContainerMeta) merge(getconfig func() (v1.ImageConfig, error)) error return nil } +// FormatStatus format container status +func (meta *ContainerMeta) FormatStatus() (string, error) { + var status string + + if meta.State.Status == types.StatusRunning || meta.State.Status == types.StatusPaused { + start, _ := time.Parse(utils.TimeLayout, meta.State.StartedAt) + startAt, err := utils.FormatTimeInterval(start.UnixNano()) + if err != nil { + return "", err + } + + status = "Up " + startAt + if meta.State.Status == types.StatusPaused { + status += "(paused)" + } + } else { + status = string(meta.State.Status) + } + return status, nil +} + // Container represents the container instance in runtime. type Container struct { sync.Mutex From e32c190ef20188dd80a00d0c564d211f718e7591 Mon Sep 17 00:00:00 2001 From: zeppp Date: Thu, 11 Jan 2018 10:59:24 +0800 Subject: [PATCH 2/2] test: add FormatStatus unit test Signed-off-by: zeppp --- apis/server/container_bridge.go | 19 ++++---- daemon/mgr/container_types.go | 32 ++++++++------ daemon/mgr/container_types_test.go | 70 ++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 21 deletions(-) create mode 100644 daemon/mgr/container_types_test.go diff --git a/apis/server/container_bridge.go b/apis/server/container_bridge.go index 5d747c83b..11c3a113d 100644 --- a/apis/server/container_bridge.go +++ b/apis/server/container_bridge.go @@ -233,24 +233,27 @@ func (s *Server) getContainers(ctx context.Context, rw http.ResponseWriter, req containerList := make([]types.Container, 0, len(metas)) for _, m := range metas { - t, _ := time.Parse(utils.TimeLayout, m.Created) + status, err := m.FormatStatus() + if err != nil { + return err + } + + t, err := time.Parse(utils.TimeLayout, m.Created) + if err != nil { + return err + } + container := types.Container{ ID: m.ID, Names: []string{m.Name}, Image: m.Config.Image, Command: strings.Join(m.Config.Cmd, " "), + Status: status, Created: t.UnixNano(), Labels: m.Config.Labels, HostConfig: m.HostConfig, } - status, err := m.FormatStatus() - if err != nil { - return err - } - - container.Status = status - containerList = append(containerList, container) } return EncodeResponse(rw, http.StatusOK, containerList) diff --git a/daemon/mgr/container_types.go b/daemon/mgr/container_types.go index a19aa7673..4a2a005f2 100644 --- a/daemon/mgr/container_types.go +++ b/daemon/mgr/container_types.go @@ -160,19 +160,25 @@ func (meta *ContainerMeta) merge(getconfig func() (v1.ImageConfig, error)) error func (meta *ContainerMeta) FormatStatus() (string, error) { var status string - if meta.State.Status == types.StatusRunning || meta.State.Status == types.StatusPaused { - start, _ := time.Parse(utils.TimeLayout, meta.State.StartedAt) - startAt, err := utils.FormatTimeInterval(start.UnixNano()) - if err != nil { - return "", err - } - - status = "Up " + startAt - if meta.State.Status == types.StatusPaused { - status += "(paused)" - } - } else { - status = string(meta.State.Status) + // return status if container is not running + if meta.State.Status != types.StatusRunning && meta.State.Status != types.StatusPaused { + return string(meta.State.Status), nil + } + + // format container status if container is running + start, err := time.Parse(utils.TimeLayout, meta.State.StartedAt) + if err != nil { + return "", err + } + + startAt, err := utils.FormatTimeInterval(start.UnixNano()) + if err != nil { + return "", err + } + + status = "Up " + startAt + if meta.State.Status == types.StatusPaused { + status += "(paused)" } return status, nil } diff --git a/daemon/mgr/container_types_test.go b/daemon/mgr/container_types_test.go new file mode 100644 index 000000000..d574006ee --- /dev/null +++ b/daemon/mgr/container_types_test.go @@ -0,0 +1,70 @@ +package mgr + +import ( + "testing" + "time" + + "github.com/alibaba/pouch/apis/types" + "github.com/alibaba/pouch/pkg/utils" + + "github.com/stretchr/testify/assert" +) + +type tCase struct { + name string + input *ContainerMeta + expected string + err error +} + +func TestContainerMeta_FormatStatus(t *testing.T) { + // TODO: add more cases + for _, tc := range []tCase{ + { + name: "Created", + input: &ContainerMeta{ + State: &types.ContainerState{ + Status: types.StatusCreated, + }, + }, + expected: string(types.StatusCreated), + err: nil, + }, + { + name: "Stopped", + input: &ContainerMeta{ + State: &types.ContainerState{ + Status: types.StatusStopped, + }, + }, + expected: string(types.StatusStopped), + err: nil, + }, + { + name: "Running", + input: &ContainerMeta{ + State: &types.ContainerState{ + Status: types.StatusRunning, + StartedAt: time.Now().Add(0 - utils.Minute).UTC().Format(utils.TimeLayout), + }, + }, + expected: "Up 1 minute", + err: nil, + }, + { + name: "Paused", + input: &ContainerMeta{ + State: &types.ContainerState{ + Status: types.StatusPaused, + StartedAt: time.Now().Add(0 - utils.Minute*2).UTC().Format(utils.TimeLayout), + }, + }, + expected: "Up 2 minutes(paused)", + err: nil, + }, + } { + output, err := tc.input.FormatStatus() + assert.Equal(t, output, tc.expected) + assert.Equal(t, err, tc.err) + } +}