Repository: moby/moby
File: integration-cli/docker_api_containers_test.go (Go)

Code before:
		s := string(b)
		// count occurrences of "read" of types.Stats
		if l := strings.Count(s, "read"); l < 2 {
			c.Fatalf("Expected more than one stat streamed, got %d", l)
		}
	}
}

func (s *DockerAPISuite) TestGetContainerStatsNoStream(c *testing.T) {
	const name = "statscontainer2"
	runSleepingContainer(c, "--name", name)

	type b struct {
		stats client.ContainerStatsResult
		err   error
	}

	bc := make(chan b, 1)

	go func() {
		apiClient, err := client.NewClientWithOpts(client.FromEnv)
		assert.NilError(c, err)
		defer apiClient.Close()

		stats, err := apiClient.ContainerStats(testutil.GetContext(c), name, client.ContainerStatsOptions{})
		assert.NilError(c, err)
		bc <- b{stats: stats, err: err}
	}()

	// allow some time to stream the stats from the container
	time.Sleep(4 * time.Second)
	cli.DockerCmd(c, "rm", "-f", name)

	// collect the results from the stats stream or timeout and fail
	// if the stream was not disconnected.
	select {
	case <-time.After(2 * time.Second):
		c.Fatal("stream was not closed after container was removed")
	case sr := <-bc:
		b, err := io.ReadAll(sr.stats.Body)
		defer sr.stats.Body.Close()
		assert.NilError(c, err)
		s := string(b)
		// count occurrences of `"read"` of types.Stats
		assert.Assert(c, strings.Count(s, `"read"`) == 1, "Expected only one stat streamed, got %d", strings.Count(s, `"read"`))
	}
}

func (s *DockerAPISuite) TestGetStoppedContainerStats(c *testing.T) {
	const name = "statscontainer3"
	cli.DockerCmd(c, "create", "--name", name, "busybox", "ps")

Review comment (bug):
Failure is here (`type with url containerd.runhcs.stats.v1.Statistics: not found`)


Coming from here; https://github.com/moby/moby/blob/0af6203b46ac8973fc0c0c7f2a95fa8c2e57132d/vendor/github.com/containerd/typeurl/v2/types.go#L278-L300

Code after:
		s := string(b)
		// count occurrences of "read" of types.Stats
		if l := strings.Count(s, "read"); l < 2 {
			c.Fatalf("Expected more than one stat streamed, got %d", l)
		}
	}
}

func (s *DockerAPISuite) TestGetContainerStatsNoStream(c *testing.T) {
	const name = "statscontainer2"
	cID := runSleepingContainer(c, "--name", name)
	defer cli.DockerCmd(c, "rm", "-f", cID)

	apiClient, err := client.NewClientWithOpts(client.FromEnv)
	assert.NilError(c, err)
	defer apiClient.Close()

	// We expect an immediate response, but if it's not immediate, the test would hang.
	ctx, cancel := context.WithTimeout(testutil.GetContext(c), 10*time.Second)
	defer cancel()

	stats, err := apiClient.ContainerStats(ctx, cID, client.ContainerStatsOptions{
		Stream:                false,
		IncludePreviousSample: true,
	})
	assert.NilError(c, err)
	defer func() { _ = stats.Body.Close() }()

	var v container.StatsResponse
	dec := json.NewDecoder(stats.Body)
	assert.NilError(c, dec.Decode(&v))
	assert.Check(c, is.Equal(v.ID, cID))
	err = dec.Decode(&v)
	assert.Check(c, is.ErrorIs(err, io.EOF), "expected only a single result")
}

func (s *DockerAPISuite) TestGetStoppedContainerStats(c *testing.T) {
	const name = "statscontainer3"
	cli.DockerCmd(c, "create", "--name", name, "busybox", "ps")
	defer cli.DockerCmd(c, "rm", "-f", name)

	apiClient, err := client.NewClientWithOpts(client.FromEnv)
	assert.NilError(c, err)
	defer apiClient.Close()

	// We expect an immediate response, but if it's not immediate, the test would hang.
	ctx, cancel := context.WithTimeout(testutil.GetContext(c), 10*time.Second)
	defer cancel()

	stats, err := apiClient.ContainerStats(ctx, name, client.ContainerStatsOptions{
		Stream:                false,