<commit_before>package containermetrics_test

import (
	"errors"
	"sync"
	"time"

	"github.com/cloudfoundry-incubator/executor"
	"github.com/cloudfoundry-incubator/executor/containermetrics"
	efakes "github.com/cloudfoundry-incubator/executor/fakes"
	msfake "github.com/cloudfoundry/dropsonde/metric_sender/fake"
	dmetrics "github.com/cloudfoundry/dropsonde/metrics"
	"github.com/pivotal-golang/clock/fakeclock"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

type listContainerResults struct {
	containers []executor.Container
	err        error
}

type metricsResults struct {
	metrics executor.Metrics
	err     error
}

var _ = Describe("StatsReporter", func() {
	var (
		logger *lagertest.TestLogger

		interval           time.Duration
		fakeClock          *fakeclock.FakeClock
		fakeExecutorClient *efakes.FakeClient
		fakeMetricSender   *msfake.FakeMetricSender

		containerResults chan listContainerResults
		process          ifrit.Process

		containerMetrics map[string]chan executor.Metrics
	)

	sendContainerResults := func() {
		one := 1

		containerMetrics = map[string]chan executor.Metrics{
			"guid-without-index":        make(chan executor.Metrics, 3),
			"guid-with-no-metrics-guid": make(chan executor.Metrics, 3),
			"guid-with-index":           make(chan executor.Metrics, 3),
		}

		containerResults <- listContainerResults{
			containers: []executor.Container{
				{
					Guid: "guid-without-index",
					MetricsConfig: executor.MetricsConfig{
						Guid: "metrics-guid-without-index",
					},
				},
				{
					Guid: "guid-with-no-metrics-guid",
				},
				{
					Guid: "guid-with-index",
					MetricsConfig: executor.MetricsConfig{
						Guid:  "metrics-guid-with-index",
						Index: &one,
					},
				},
			},
			err: nil,
		}
		containerMetrics["guid-without-index"] <- executor.Metrics{
			MemoryUsageInBytes: 123,
			DiskUsageInBytes:   456,
			TimeSpentInCPU:     100 * time.Second,
		}
		containerMetrics["guid-with-no-metrics-guid"] <- executor.Metrics{
			MemoryUsageInBytes: 1023,
			DiskUsageInBytes:   4056,
			TimeSpentInCPU:     1000 * time.Second,
		}
		containerMetrics["guid-with-index"] <- executor.Metrics{
			MemoryUsageInBytes: 321,
			DiskUsageInBytes:   654,
			TimeSpentInCPU:     100 * time.Second,
		}

		containerResults <- listContainerResults{
			containers: []executor.Container{
				{
					Guid: "guid-without-index",

					MetricsConfig: executor.MetricsConfig{
						Guid: "metrics-guid-without-index",
					},
				},
				{
					Guid: "guid-with-index",

					MetricsConfig: executor.MetricsConfig{
						Guid:  "metrics-guid-with-index",
						Index: &one,
					},
				},
			},
			err: nil,
		}
		containerMetrics["guid-without-index"] <- executor.Metrics{
			MemoryUsageInBytes: 1230,
			DiskUsageInBytes:   4560,
			TimeSpentInCPU:     105 * time.Second,
		}
		containerMetrics["guid-with-index"] <- executor.Metrics{
			MemoryUsageInBytes: 3210,
			DiskUsageInBytes:   6540,
			TimeSpentInCPU:     110 * time.Second,
		}

		containerResults <- listContainerResults{
			containers: []executor.Container{
				{
					Guid: "guid-without-index",

					MetricsConfig: executor.MetricsConfig{
						Guid: "metrics-guid-without-index",
					},
				},
				{
					Guid: "guid-with-index",

					MetricsConfig: executor.MetricsConfig{
						Guid:  "metrics-guid-with-index",
						Index: &one,
					},
				},
			},
			err: nil,
		}

		containerMetrics["guid-without-index"] <- executor.Metrics{
			MemoryUsageInBytes: 12300,
			DiskUsageInBytes:   45600,
			TimeSpentInCPU:     107 * time.Second,
		}
		containerMetrics["guid-with-index"] <- executor.Metrics{
			MemoryUsageInBytes: 32100,
			DiskUsageInBytes:   65400,
			TimeSpentInCPU:     112 * time.Second,
		}
	}

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")

		interval = 10 * time.Second
		fakeClock = fakeclock.NewFakeClock(time.Unix(123, 456))
		fakeExecutorClient = new(efakes.FakeClient)

		fakeMetricSender = msfake.NewFakeMetricSender()
		dmetrics.Initialize(fakeMetricSender)

		containerResults = make(chan listContainerResults, 10)

		fakeExecutorClient.ListContainersStub = func(executor.Tags) ([]executor.Container, error) {
			result := <-containerResults
			return result.containers, result.err
		}

		fakeExecutorClient.GetMetricsStub = func(guid string) (executor.Metrics, error) {
			return <-containerMetrics[guid], nil
		}

		process = ifrit.Invoke(containermetrics.NewStatsReporter(logger, interval, fakeClock, fakeExecutorClient))
	})

	AfterEach(func() {
		ginkgomon.Interrupt(process)
	})

	Context("when the interval elapses", func() {
		BeforeEach(func() {
			sendContainerResults()

			fakeClock.Increment(interval)
			Eventually(fakeExecutorClient.ListContainersCallCount).Should(Equal(1))
		})

		It("emits memory and disk usage for each container, but no CPU", func() {
			Eventually(func() msfake.ContainerMetric {
				return fakeMetricSender.GetContainerMetric("metrics-guid-without-index")
			}).Should(Equal(msfake.ContainerMetric{
				ApplicationId: "metrics-guid-without-index",
				InstanceIndex: -1,
				CpuPercentage: 0.0,
				MemoryBytes:   123,
				DiskBytes:     456,
			}))

			Eventually(func() msfake.ContainerMetric {
				return fakeMetricSender.GetContainerMetric("metrics-guid-with-index")
			}).Should(Equal(msfake.ContainerMetric{
				ApplicationId: "metrics-guid-with-index",
				InstanceIndex: 1,
				CpuPercentage: 0.0,
				MemoryBytes:   321,
				DiskBytes:     654,
			}))
		})

		It("does not ask for metrics when the metrics guid is missing", func() {
			Eventually(fakeExecutorClient.GetMetricsCallCount).Should(Equal(2))
		})
<commit_msg>Correct test assertion<commit_after>package containermetrics_test

import (
	"errors"
	"sync"
	"time"

	"github.com/cloudfoundry-incubator/executor"
	"github.com/cloudfoundry-incubator/executor/containermetrics"
	efakes "github.com/cloudfoundry-incubator/executor/fakes"
	msfake "github.com/cloudfoundry/dropsonde/metric_sender/fake"
	dmetrics "github.com/cloudfoundry/dropsonde/metrics"
	"github.com/pivotal-golang/clock/fakeclock"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

type listContainerResults struct {
	containers []executor.Container
	err        error
}

type metricsResults struct {
	metrics executor.Metrics
	err     error
}

var _ = Describe("StatsReporter", func() {
	var (
		logger *lagertest.TestLogger

		interval           time.Duration
		fakeClock          *fakeclock.FakeClock
		fakeExecutorClient *efakes.FakeClient
		fakeMetricSender   *msfake.FakeMetricSender

		containerResults chan listContainerResults
		process          ifrit.Process

		containerMetrics map[string]chan executor.Metrics
	)

	sendContainerResults := func() {
		one := 1

		containerMetrics = map[string]chan executor.Metrics{
			"guid-without-index":        make(chan executor.Metrics, 3),
			"guid-with-no-metrics-guid": make(chan executor.Metrics, 3),
			"guid-with-index":           make(chan executor.Metrics, 3),
		}

		containerResults <- listContainerResults{
			containers: []executor.Container{
				{
					Guid: "guid-without-index",
					MetricsConfig: executor.MetricsConfig{
						Guid: "metrics-guid-without-index",
					},
				},
				{
					Guid: "guid-with-no-metrics-guid",
				},
				{
					Guid: "guid-with-index",
					MetricsConfig: executor.MetricsConfig{
						Guid:  "metrics-guid-with-index",
						Index: &one,
					},
				},
			},
			err: nil,
		}
		containerMetrics["guid-without-index"] <- executor.Metrics{
			MemoryUsageInBytes: 123,
			DiskUsageInBytes:   456,
			TimeSpentInCPU:     100 * time.Second,
		}
		containerMetrics["guid-with-no-metrics-guid"] <- executor.Metrics{
			MemoryUsageInBytes: 1023,
			DiskUsageInBytes:   4056,
			TimeSpentInCPU:     1000 * time.Second,
		}
		containerMetrics["guid-with-index"] <- executor.Metrics{
			MemoryUsageInBytes: 321,
			DiskUsageInBytes:   654,
			TimeSpentInCPU:     100 * time.Second,
		}

		containerResults <- listContainerResults{
			containers: []executor.Container{
				{
					Guid: "guid-without-index",

					MetricsConfig: executor.MetricsConfig{
						Guid: "metrics-guid-without-index",
					},
				},
				{
					Guid: "guid-with-index",

					MetricsConfig: executor.MetricsConfig{
						Guid:  "metrics-guid-with-index",
						Index: &one,
					},
				},
			},
			err: nil,
		}
		containerMetrics["guid-without-index"] <- executor.Metrics{
			MemoryUsageInBytes: 1230,
			DiskUsageInBytes:   4560,
			TimeSpentInCPU:     105 * time.Second,
		}
		containerMetrics["guid-with-index"] <- executor.Metrics{
			MemoryUsageInBytes: 3210,
			DiskUsageInBytes:   6540,
			TimeSpentInCPU:     110 * time.Second,
		}

		containerResults <- listContainerResults{
			containers: []executor.Container{
				{
					Guid: "guid-without-index",

					MetricsConfig: executor.MetricsConfig{
						Guid: "metrics-guid-without-index",
					},
				},
				{
					Guid: "guid-with-index",

					MetricsConfig: executor.MetricsConfig{
						Guid:  "metrics-guid-with-index",
						Index: &one,
					},
				},
			},
			err: nil,
		}

		containerMetrics["guid-without-index"] <- executor.Metrics{
			MemoryUsageInBytes: 12300,
			DiskUsageInBytes:   45600,
			TimeSpentInCPU:     107 * time.Second,
		}
		containerMetrics["guid-with-index"] <- executor.Metrics{
			MemoryUsageInBytes: 32100,
			DiskUsageInBytes:   65400,
			TimeSpentInCPU:     112 * time.Second,
		}
	}

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")

		interval = 10 * time.Second
		fakeClock = fakeclock.NewFakeClock(time.Unix(123, 456))
		fakeExecutorClient = new(efakes.FakeClient)

		fakeMetricSender = msfake.NewFakeMetricSender()
		dmetrics.Initialize(fakeMetricSender)

		containerResults = make(chan listContainerResults, 10)

		fakeExecutorClient.ListContainersStub = func(executor.Tags) ([]executor.Container, error) {
			result := <-containerResults
			return result.containers, result.err
		}

		fakeExecutorClient.GetMetricsStub = func(guid string) (executor.Metrics, error) {
			return <-containerMetrics[guid], nil
		}

		process = ifrit.Invoke(containermetrics.NewStatsReporter(logger, interval, fakeClock, fakeExecutorClient))
	})

	AfterEach(func() {
		ginkgomon.Interrupt(process)
	})

	Context("when the interval elapses", func() {
		BeforeEach(func() {
			sendContainerResults()

			fakeClock.Increment(interval)
			Eventually(fakeExecutorClient.ListContainersCallCount).Should(Equal(1))
		})

		It("emits memory and disk usage for each container, but no CPU", func() {
			Eventually(func() msfake.ContainerMetric {
				return fakeMetricSender.GetContainerMetric("metrics-guid-without-index")
			}).Should(Equal(msfake.ContainerMetric{
				ApplicationId: "metrics-guid-without-index",
				InstanceIndex: -1,
				CpuPercentage: 0.0,
				MemoryBytes:   123,
				DiskBytes:     456,
			}))

			Eventually(func() msfake.ContainerMetric {
				return fakeMetricSender.GetContainerMetric("metrics-guid-with-index")
			}).Should(Equal(msfake.ContainerMetric{
				ApplicationId: "metrics-guid-with-index",
				InstanceIndex: 1,
				CpuPercentage: 0.0,
				MemoryBytes:   321,
				DiskBytes:     654,
			}))
		})

		It("does not ask for metrics when the metrics guid is missing", func() {
			Eventually(fakeExecutorClient.GetMetricsCallCount).Should(Equal(2))
			Consistently(fakeExecutorClient.GetMetricsCallCount).Should(Equal(2))
		})

{'fraction_non_alphanumeric': 0.12206085753803596, 'fraction_numerical': 0.01945020746887967, 'mean_word_length': 3.542206517471535, 'pattern_counts': {'":': 6, '<': 27, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5614713', 'n_tokens_mistral': 4672, 'n_tokens_neox': 3737, 'n_words': 615}