From af2226c938fb6d74553f93269f8e34f1398ce28f Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Mon, 25 Sep 2017 15:31:05 -0700 Subject: [PATCH] client: Prevent Out-Of-Range panic in task.Metrics() Signed-off-by: Kenfe-Mickael Laventure --- container_test.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++ task.go | 9 +++++++ 2 files changed, 74 insertions(+) diff --git a/container_test.go b/container_test.go index 2816f1310..ef8f88cc0 100644 --- a/container_test.go +++ b/container_test.go @@ -1370,6 +1370,71 @@ func TestContainerMetrics(t *testing.T) { <-statusC } +func TestDeletedContainerMetrics(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("metrics are currently not supported on windows") + } + t.Parallel() + + client, err := newClient(t, address) + if err != nil { + t.Fatal(err) + } + defer client.Close() + + var ( + image Image + ctx, cancel = testContext() + id = t.Name() + ) + defer cancel() + + if runtime.GOOS != "windows" { + image, err = client.GetImage(ctx, testImage) + if err != nil { + t.Error(err) + return + } + } + container, err := client.NewContainer(ctx, id, + WithNewSpec(withImageConfig(image), withExitStatus(0)), + withNewSnapshot(id, image), + ) + if err != nil { + t.Error(err) + return + } + defer container.Delete(ctx, WithSnapshotCleanup) + + task, err := container.NewTask(ctx, empty()) + if err != nil { + t.Error(err) + return + } + defer task.Delete(ctx) + + if err := task.Start(ctx); err != nil { + t.Error(err) + return + } + + statusC, err := task.Wait(ctx) + if err != nil { + t.Error(err) + return + } + <-statusC + + if _, err := task.Delete(ctx); err != nil { + t.Error(err) + return + } + + if _, err := task.Metrics(ctx); err == nil { + t.Errorf("Getting metrics of deleted task should have failed") + } +} + func TestContainerExtensions(t *testing.T) { t.Parallel() diff --git a/task.go b/task.go index ff9e0735a..b6a29a289 100644 --- a/task.go +++ b/task.go @@ -435,6 +435,15 @@ func (t *task) Metrics(ctx context.Context) (*types.Metric, error) { if err != nil { return nil, errdefs.FromGRPC(err) } + + if response.Metrics == nil { + _, err := t.Status(ctx) + if err != nil && errdefs.IsNotFound(err) { + return nil, err + } + return nil, errors.New("no metrics received") + } + return response.Metrics[0], nil }