Merge pull request #1396 from eparis/update-cadvisor

Update cadvisor to 0.4.0
This commit is contained in:
Victor Marmol 2014-09-22 13:01:06 -07:00
commit b6a56627a7
10 changed files with 28 additions and 545 deletions

8
Godeps/Godeps.json generated
View File

@ -60,13 +60,13 @@
},
{
"ImportPath": "github.com/google/cadvisor/client",
"Comment": "0.2.0-27-g17b0ec5",
"Rev": "17b0ec576bcbeb321c133e4378dee1e500c9850d"
"Comment": "0.4.0",
"Rev": "5a6d06c02600b1e57e55a9d9f71dbac1bfc9fe6c"
},
{
"ImportPath": "github.com/google/cadvisor/info",
"Comment": "0.2.0-27-g17b0ec5",
"Rev": "17b0ec576bcbeb321c133e4378dee1e500c9850d"
"Comment": "0.4.0",
"Rev": "5a6d06c02600b1e57e55a9d9f71dbac1bfc9fe6c"
},
{
"ImportPath": "github.com/google/gofuzz",

View File

@ -49,10 +49,10 @@ func cadvisorTestClient(path string, expectedPostObj, expectedPostObjEmpty, repl
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(expectedPostObjEmpty)
if err != nil {
t.Errorf("Recieved invalid object: %v", err)
t.Errorf("Received invalid object: %v", err)
}
if !reflect.DeepEqual(expectedPostObj, expectedPostObjEmpty) {
t.Errorf("Recieved unexpected object: %+v", expectedPostObjEmpty)
t.Errorf("Received unexpected object: %+v", expectedPostObjEmpty)
}
}
encoder := json.NewEncoder(w)
@ -93,10 +93,7 @@ func TestGetMachineinfo(t *testing.T) {
func TestGetContainerInfo(t *testing.T) {
query := &info.ContainerInfoRequest{
NumStats: 3,
NumSamples: 2,
CpuUsagePercentiles: []int{10, 50, 90},
MemoryUsagePercentiles: []int{10, 80, 90},
NumStats: 3,
}
containerName := "/some/container"
cinfo := itest.GenerateRandomContainerInfo(containerName, 4, query, 1*time.Second)

View File

@ -15,9 +15,7 @@
package info
import (
"fmt"
"reflect"
"sort"
"time"
)
@ -59,13 +57,6 @@ type ContainerReference struct {
type ContainerInfoRequest struct {
// Max number of stats to return.
NumStats int `json:"num_stats,omitempty"`
// Max number of samples to return.
NumSamples int `json:"num_samples,omitempty"`
// Different percentiles of CPU usage within a period. The values must be within [0, 100]
CpuUsagePercentiles []int `json:"cpu_usage_percentiles,omitempty"`
// Different percentiles of memory usage within a period. The values must be within [0, 100]
MemoryUsagePercentiles []int `json:"memory_usage_percentiles,omitempty"`
}
type ContainerInfo struct {
@ -79,11 +70,6 @@ type ContainerInfo struct {
// Historical statistics gathered from the container.
Stats []*ContainerStats `json:"stats,omitempty"`
// Randomly sampled container states.
Samples []*ContainerStatsSample `json:"samples,omitempty"`
StatsPercentiles *ContainerStatsPercentiles `json:"stats_summary,omitempty"`
}
// ContainerInfo may be (un)marshaled by json or other en/decoder. In that
@ -112,9 +98,6 @@ func (self *ContainerInfo) Eq(b *ContainerInfo) bool {
if !reflect.DeepEqual(self.Spec, b.Spec) {
return false
}
if !reflect.DeepEqual(self.StatsPercentiles, b.StatsPercentiles) {
return false
}
for i, expectedStats := range b.Stats {
selfStats := self.Stats[i]
@ -123,12 +106,6 @@ func (self *ContainerInfo) Eq(b *ContainerInfo) bool {
}
}
for i, expectedSample := range b.Samples {
selfSample := self.Samples[i]
if !expectedSample.Eq(selfSample) {
return false
}
}
return true
}
@ -278,24 +255,6 @@ func (self *ContainerStats) Copy(dst *ContainerStats) *ContainerStats {
return dst
}
type ContainerStatsSample struct {
// Timetamp of the end of the sample period
Timestamp time.Time `json:"timestamp"`
// Duration of the sample period
Duration time.Duration `json:"duration"`
Cpu struct {
// number of nanoseconds of CPU time used by the container
Usage uint64 `json:"usage"`
// Per-core usage of the container. (unit: nanoseconds)
PerCpuUsage []uint64 `json:"per_cpu_usage,omitempty"`
} `json:"cpu"`
Memory struct {
// Units: Bytes.
Usage uint64 `json:"usage"`
} `json:"memory"`
}
func timeEq(t1, t2 time.Time, tolerance time.Duration) bool {
// t1 should not be later than t2
if t1.After(t2) {
@ -330,6 +289,11 @@ func (a *ContainerStats) Eq(b *ContainerStats) bool {
if !timeEq(a.Timestamp, b.Timestamp, timePrecision) {
return false
}
return a.StatsEq(b)
}
// Checks equality of the stats values.
func (a *ContainerStats) StatsEq(b *ContainerStats) bool {
if !reflect.DeepEqual(a.Cpu, b.Cpu) {
return false
}
@ -339,138 +303,10 @@ func (a *ContainerStats) Eq(b *ContainerStats) bool {
return true
}
// This function is useful because we do not require precise time
// representation.
func (a *ContainerStatsSample) Eq(b *ContainerStatsSample) bool {
if !timeEq(a.Timestamp, b.Timestamp, timePrecision) {
return false
// Saturate CPU usage to 0.
func calculateCpuUsage(prev, cur uint64) uint64 {
if prev > cur {
return 0
}
if !durationEq(a.Duration, b.Duration, timePrecision) {
return false
}
if !reflect.DeepEqual(a.Cpu, b.Cpu) {
return false
}
if !reflect.DeepEqual(a.Memory, b.Memory) {
return false
}
return true
}
type Percentile struct {
Percentage int `json:"percentage"`
Value uint64 `json:"value"`
}
type ContainerStatsPercentiles struct {
MaxMemoryUsage uint64 `json:"max_memory_usage,omitempty"`
MemoryUsagePercentiles []Percentile `json:"memory_usage_percentiles,omitempty"`
CpuUsagePercentiles []Percentile `json:"cpu_usage_percentiles,omitempty"`
}
// Each sample needs two stats because the cpu usage in ContainerStats is
// cumulative.
// prev should be an earlier observation than current.
// This method is not thread/goroutine safe.
func NewSample(prev, current *ContainerStats) (*ContainerStatsSample, error) {
if prev == nil || current == nil {
return nil, fmt.Errorf("empty stats")
}
// Ignore this sample if it is incomplete
if prev.Cpu == nil || prev.Memory == nil || current.Cpu == nil || current.Memory == nil {
return nil, fmt.Errorf("incomplete stats")
}
// prev must be an early observation
if !current.Timestamp.After(prev.Timestamp) {
return nil, fmt.Errorf("wrong stats order")
}
// This data is invalid.
if current.Cpu.Usage.Total < prev.Cpu.Usage.Total {
return nil, fmt.Errorf("current CPU usage is less than prev CPU usage (cumulative).")
}
var percpu []uint64
if len(current.Cpu.Usage.PerCpu) > 0 {
curNumCpus := len(current.Cpu.Usage.PerCpu)
percpu = make([]uint64, curNumCpus)
for i, currUsage := range current.Cpu.Usage.PerCpu {
var prevUsage uint64 = 0
if i < len(prev.Cpu.Usage.PerCpu) {
prevUsage = prev.Cpu.Usage.PerCpu[i]
}
if currUsage < prevUsage {
return nil, fmt.Errorf("current per-core CPU usage is less than prev per-core CPU usage (cumulative).")
}
percpu[i] = currUsage - prevUsage
}
}
sample := new(ContainerStatsSample)
// Calculate the diff to get the CPU usage within the time interval.
sample.Cpu.Usage = current.Cpu.Usage.Total - prev.Cpu.Usage.Total
sample.Cpu.PerCpuUsage = percpu
// Memory usage is current memory usage
sample.Memory.Usage = current.Memory.Usage
sample.Timestamp = current.Timestamp
sample.Duration = current.Timestamp.Sub(prev.Timestamp)
return sample, nil
}
type uint64Slice []uint64
func (self uint64Slice) Len() int {
return len(self)
}
func (self uint64Slice) Less(i, j int) bool {
return self[i] < self[j]
}
func (self uint64Slice) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
}
func (self uint64Slice) Percentiles(requestedPercentiles ...int) []Percentile {
if len(self) == 0 {
return nil
}
ret := make([]Percentile, 0, len(requestedPercentiles))
sort.Sort(self)
for _, p := range requestedPercentiles {
idx := (len(self) * p / 100) - 1
if idx < 0 {
idx = 0
}
ret = append(
ret,
Percentile{
Percentage: p,
Value: self[idx],
},
)
}
return ret
}
func NewPercentiles(samples []*ContainerStatsSample, cpuPercentages, memoryPercentages []int) *ContainerStatsPercentiles {
if len(samples) == 0 {
return nil
}
cpuUsages := make([]uint64, 0, len(samples))
memUsages := make([]uint64, 0, len(samples))
for _, sample := range samples {
if sample == nil {
continue
}
cpuUsages = append(cpuUsages, sample.Cpu.Usage)
memUsages = append(memUsages, sample.Memory.Usage)
}
ret := new(ContainerStatsPercentiles)
ret.CpuUsagePercentiles = uint64Slice(cpuUsages).Percentiles(cpuPercentages...)
ret.MemoryUsagePercentiles = uint64Slice(memUsages).Percentiles(memoryPercentages...)
return ret
return cur - prev
}

View File

@ -68,65 +68,6 @@ func TestStatsEndTime(t *testing.T) {
}
}
func TestPercentiles(t *testing.T) {
N := 100
data := make([]uint64, N)
for i := 1; i < N+1; i++ {
data[i-1] = uint64(i)
}
percentages := []int{
80,
90,
50,
}
percentiles := uint64Slice(data).Percentiles(percentages...)
for _, s := range percentiles {
if s.Value != uint64(s.Percentage) {
t.Errorf("%v percentile data should be %v, but got %v", s.Percentage, s.Percentage, s.Value)
}
}
}
func TestPercentilesSmallDataSet(t *testing.T) {
var value uint64 = 11
data := []uint64{value}
percentages := []int{
80,
90,
50,
}
percentiles := uint64Slice(data).Percentiles(percentages...)
for _, s := range percentiles {
if s.Value != value {
t.Errorf("%v percentile data should be %v, but got %v", s.Percentage, value, s.Value)
}
}
}
func TestNewSampleNilStats(t *testing.T) {
stats := &ContainerStats{
Cpu: &CpuStats{},
Memory: &MemoryStats{},
}
stats.Cpu.Usage.PerCpu = []uint64{uint64(10)}
stats.Cpu.Usage.Total = uint64(10)
stats.Cpu.Usage.System = uint64(2)
stats.Cpu.Usage.User = uint64(8)
stats.Memory.Usage = uint64(200)
sample, err := NewSample(nil, stats)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
sample, err = NewSample(stats, nil)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
}
func createStats(cpuUsage, memUsage uint64, timestamp time.Time) *ContainerStats {
stats := &ContainerStats{
Cpu: &CpuStats{},
@ -141,144 +82,6 @@ func createStats(cpuUsage, memUsage uint64, timestamp time.Time) *ContainerStats
return stats
}
func TestAddSample(t *testing.T) {
cpuPrevUsage := uint64(10)
cpuCurrentUsage := uint64(15)
memCurrentUsage := uint64(200)
prevTime := time.Now()
prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime)
current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second))
sample, err := NewSample(prev, current)
if err != nil {
t.Errorf("should be able to generate a sample. but received error: %v", err)
}
if sample == nil {
t.Fatalf("nil sample and nil error. unexpected result!")
}
if sample.Memory.Usage != memCurrentUsage {
t.Errorf("wrong memory usage: %v. should be %v", sample.Memory.Usage, memCurrentUsage)
}
if sample.Cpu.Usage != cpuCurrentUsage-cpuPrevUsage {
t.Errorf("wrong CPU usage: %v. should be %v", sample.Cpu.Usage, cpuCurrentUsage-cpuPrevUsage)
}
}
func TestAddSampleIncompleteStats(t *testing.T) {
cpuPrevUsage := uint64(10)
cpuCurrentUsage := uint64(15)
memCurrentUsage := uint64(200)
prevTime := time.Now()
prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime)
current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second))
stats := &ContainerStats{
Cpu: prev.Cpu,
Memory: nil,
}
sample, err := NewSample(stats, current)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
sample, err = NewSample(prev, stats)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
stats = &ContainerStats{
Cpu: nil,
Memory: prev.Memory,
}
sample, err = NewSample(stats, current)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
sample, err = NewSample(prev, stats)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
}
func TestAddSampleWrongOrder(t *testing.T) {
cpuPrevUsage := uint64(10)
cpuCurrentUsage := uint64(15)
memCurrentUsage := uint64(200)
prevTime := time.Now()
prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime)
current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second))
sample, err := NewSample(current, prev)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
}
func TestAddSampleWrongCpuUsage(t *testing.T) {
cpuPrevUsage := uint64(15)
cpuCurrentUsage := uint64(10)
memCurrentUsage := uint64(200)
prevTime := time.Now()
prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime)
current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second))
sample, err := NewSample(prev, current)
if err == nil {
t.Errorf("generated an unexpected sample: %+v", sample)
}
}
func TestAddSampleHotPluggingCpu(t *testing.T) {
cpuPrevUsage := uint64(10)
cpuCurrentUsage := uint64(15)
memCurrentUsage := uint64(200)
prevTime := time.Now()
prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime)
current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second))
current.Cpu.Usage.PerCpu = append(current.Cpu.Usage.PerCpu, 10)
sample, err := NewSample(prev, current)
if err != nil {
t.Errorf("should be able to generate a sample. but received error: %v", err)
}
if len(sample.Cpu.PerCpuUsage) != 2 {
t.Fatalf("Should have 2 cores.")
}
if sample.Cpu.PerCpuUsage[0] != cpuCurrentUsage-cpuPrevUsage {
t.Errorf("First cpu usage is %v. should be %v", sample.Cpu.PerCpuUsage[0], cpuCurrentUsage-cpuPrevUsage)
}
if sample.Cpu.PerCpuUsage[1] != 10 {
t.Errorf("Second cpu usage is %v. should be 10", sample.Cpu.PerCpuUsage[1])
}
}
func TestAddSampleHotUnpluggingCpu(t *testing.T) {
cpuPrevUsage := uint64(10)
cpuCurrentUsage := uint64(15)
memCurrentUsage := uint64(200)
prevTime := time.Now()
prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime)
current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second))
prev.Cpu.Usage.PerCpu = append(prev.Cpu.Usage.PerCpu, 10)
sample, err := NewSample(prev, current)
if err != nil {
t.Errorf("should be able to generate a sample. but received error: %v", err)
}
if len(sample.Cpu.PerCpuUsage) != 1 {
t.Fatalf("Should have 1 cores.")
}
if sample.Cpu.PerCpuUsage[0] != cpuCurrentUsage-cpuPrevUsage {
t.Errorf("First cpu usage is %v. should be %v", sample.Cpu.PerCpuUsage[0], cpuCurrentUsage-cpuPrevUsage)
}
}
func TestContainerStatsCopy(t *testing.T) {
stats := createStats(100, 101, time.Now())
shadowStats := stats.Copy(nil)

View File

@ -65,57 +65,14 @@ func GenerateRandomContainerSpec(numCores int) *info.ContainerSpec {
func GenerateRandomContainerInfo(containerName string, numCores int, query *info.ContainerInfoRequest, duration time.Duration) *info.ContainerInfo {
stats := GenerateRandomStats(query.NumStats, numCores, duration)
samples, _ := NewSamplesFromStats(stats...)
if len(samples) > query.NumSamples {
samples = samples[:query.NumSamples]
}
cpuPercentiles := make([]info.Percentile, 0, len(query.CpuUsagePercentiles))
// TODO(monnand): This will generate percentiles where 50%tile data may
// be larger than 90%tile data.
for _, p := range query.CpuUsagePercentiles {
percentile := info.Percentile{p, uint64(rand.Int63n(1000))}
cpuPercentiles = append(cpuPercentiles, percentile)
}
memPercentiles := make([]info.Percentile, 0, len(query.MemoryUsagePercentiles))
for _, p := range query.MemoryUsagePercentiles {
percentile := info.Percentile{p, uint64(rand.Int63n(1000))}
memPercentiles = append(memPercentiles, percentile)
}
percentiles := &info.ContainerStatsPercentiles{
MaxMemoryUsage: uint64(rand.Int63n(4096)),
MemoryUsagePercentiles: memPercentiles,
CpuUsagePercentiles: cpuPercentiles,
}
spec := GenerateRandomContainerSpec(numCores)
ret := &info.ContainerInfo{
ContainerReference: info.ContainerReference{
Name: containerName,
},
Spec: spec,
StatsPercentiles: percentiles,
Samples: samples,
Stats: stats,
Spec: spec,
Stats: stats,
}
return ret
}
func NewSamplesFromStats(stats ...*info.ContainerStats) ([]*info.ContainerStatsSample, error) {
if len(stats) < 2 {
return nil, nil
}
samples := make([]*info.ContainerStatsSample, 0, len(stats)-1)
for i, s := range stats[1:] {
prev := stats[i]
sample, err := info.NewSample(prev, s)
if err != nil {
return nil, fmt.Errorf("Unable to generate sample from %+v and %+v: %v",
prev, s, err)
}
samples = append(samples, sample)
}
return samples, nil
}

View File

@ -15,4 +15,4 @@
package info
// Version of cAdvisor.
const VERSION = "0.2.1"
const VERSION = "0.4.0"

View File

@ -109,10 +109,7 @@ func testHTTPContainerInfoGetter(
func TestHTTPContainerInfoGetterGetContainerInfoSuccessfully(t *testing.T) {
req := &info.ContainerInfoRequest{
NumStats: 10,
NumSamples: 10,
CpuUsagePercentiles: []int{20, 30},
MemoryUsagePercentiles: []int{40, 50},
NumStats: 10,
}
cinfo := itest.GenerateRandomContainerInfo(
"dockerIDWhichWillNotBeChecked", // docker ID
@ -125,10 +122,7 @@ func TestHTTPContainerInfoGetterGetContainerInfoSuccessfully(t *testing.T) {
func TestHTTPContainerInfoGetterGetRootInfoSuccessfully(t *testing.T) {
req := &info.ContainerInfoRequest{
NumStats: 10,
NumSamples: 10,
CpuUsagePercentiles: []int{20, 30},
MemoryUsagePercentiles: []int{40, 50},
NumStats: 10,
}
cinfo := itest.GenerateRandomContainerInfo(
"dockerIDWhichWillNotBeChecked", // docker ID
@ -141,10 +135,7 @@ func TestHTTPContainerInfoGetterGetRootInfoSuccessfully(t *testing.T) {
func TestHTTPContainerInfoGetterGetContainerInfoWithError(t *testing.T) {
req := &info.ContainerInfoRequest{
NumStats: 10,
NumSamples: 10,
CpuUsagePercentiles: []int{20, 30},
MemoryUsagePercentiles: []int{40, 50},
NumStats: 10,
}
cinfo := itest.GenerateRandomContainerInfo(
"dockerIDWhichWillNotBeChecked", // docker ID
@ -157,10 +148,7 @@ func TestHTTPContainerInfoGetterGetContainerInfoWithError(t *testing.T) {
func TestHTTPContainerInfoGetterGetRootInfoWithError(t *testing.T) {
req := &info.ContainerInfoRequest{
NumStats: 10,
NumSamples: 10,
CpuUsagePercentiles: []int{20, 30},
MemoryUsagePercentiles: []int{40, 50},
NumStats: 10,
}
cinfo := itest.GenerateRandomContainerInfo(
"dockerIDWhichWillNotBeChecked", // docker ID

View File

@ -729,9 +729,7 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) {
func getCadvisorContainerInfoRequest(req *info.ContainerInfoRequest) *info.ContainerInfoRequest {
ret := &info.ContainerInfoRequest{
NumStats: req.NumStats,
CpuUsagePercentiles: req.CpuUsagePercentiles,
MemoryUsagePercentiles: req.MemoryUsagePercentiles,
NumStats: req.NumStats,
}
return ret
}

View File

@ -803,34 +803,6 @@ func (c *mockCadvisorClient) MachineInfo() (*info.MachineInfo, error) {
return args.Get(0).(*info.MachineInfo), args.Error(1)
}
func areSamePercentiles(
cadvisorPercentiles []info.Percentile,
kubePercentiles []info.Percentile,
t *testing.T,
) {
if len(cadvisorPercentiles) != len(kubePercentiles) {
t.Errorf("cadvisor gives %v percentiles; kubelet got %v", len(cadvisorPercentiles), len(kubePercentiles))
return
}
for _, ap := range cadvisorPercentiles {
found := false
for _, kp := range kubePercentiles {
if ap.Percentage == kp.Percentage {
found = true
if ap.Value != kp.Value {
t.Errorf("%v percentile from cadvisor is %v; kubelet got %v",
ap.Percentage,
ap.Value,
kp.Value)
}
}
}
if !found {
t.Errorf("Unable to find %v percentile in kubelet's data", ap.Percentage)
}
}
}
func TestGetContainerInfo(t *testing.T) {
containerID := "ab2cdf"
containerPath := fmt.Sprintf("/docker/%v", containerID)
@ -838,19 +810,6 @@ func TestGetContainerInfo(t *testing.T) {
ContainerReference: info.ContainerReference{
Name: containerPath,
},
StatsPercentiles: &info.ContainerStatsPercentiles{
MaxMemoryUsage: 1024000,
MemoryUsagePercentiles: []info.Percentile{
{50, 100},
{80, 180},
{90, 190},
},
CpuUsagePercentiles: []info.Percentile{
{51, 101},
{81, 181},
{91, 191},
},
},
}
mockCadvisor := &mockCadvisorClient{}
@ -876,11 +835,6 @@ func TestGetContainerInfo(t *testing.T) {
if stats == nil {
t.Fatalf("stats should not be nil")
}
if stats.StatsPercentiles.MaxMemoryUsage != containerInfo.StatsPercentiles.MaxMemoryUsage {
t.Errorf("wrong max memory usage")
}
areSamePercentiles(containerInfo.StatsPercentiles.CpuUsagePercentiles, stats.StatsPercentiles.CpuUsagePercentiles, t)
areSamePercentiles(containerInfo.StatsPercentiles.MemoryUsagePercentiles, stats.StatsPercentiles.MemoryUsagePercentiles, t)
mockCadvisor.AssertExpectations(t)
}
@ -889,14 +843,6 @@ func TestGetRootInfo(t *testing.T) {
containerInfo := &info.ContainerInfo{
ContainerReference: info.ContainerReference{
Name: containerPath,
}, StatsPercentiles: &info.ContainerStatsPercentiles{MaxMemoryUsage: 1024000, MemoryUsagePercentiles: []info.Percentile{{50, 100}, {80, 180},
{90, 190},
},
CpuUsagePercentiles: []info.Percentile{
{51, 101},
{81, 181},
{91, 191},
},
},
}
fakeDocker := dockertools.FakeDockerClient{}
@ -914,15 +860,10 @@ func TestGetRootInfo(t *testing.T) {
}
// If the container name is an empty string, then it means the root container.
stats, err := kubelet.GetRootInfo(req)
_, err := kubelet.GetRootInfo(req)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if stats.StatsPercentiles.MaxMemoryUsage != containerInfo.StatsPercentiles.MaxMemoryUsage {
t.Errorf("wrong max memory usage")
}
areSamePercentiles(containerInfo.StatsPercentiles.CpuUsagePercentiles, stats.StatsPercentiles.CpuUsagePercentiles, t)
areSamePercentiles(containerInfo.StatsPercentiles.MemoryUsagePercentiles, stats.StatsPercentiles.MemoryUsagePercentiles, t)
mockCadvisor.AssertExpectations(t)
}
@ -942,15 +883,6 @@ func TestGetContainerInfoWithoutCadvisor(t *testing.T) {
if stats == nil {
return
}
if stats.StatsPercentiles.MaxMemoryUsage != 0 {
t.Errorf("MaxMemoryUsage is %v even if there's no cadvisor", stats.StatsPercentiles.MaxMemoryUsage)
}
if len(stats.StatsPercentiles.CpuUsagePercentiles) > 0 {
t.Errorf("CPU usage percentiles is not empty (%+v) even if there's no cadvisor", stats.StatsPercentiles.CpuUsagePercentiles)
}
if len(stats.StatsPercentiles.MemoryUsagePercentiles) > 0 {
t.Errorf("Memory usage percentiles is not empty (%+v) even if there's no cadvisor", stats.StatsPercentiles.MemoryUsagePercentiles)
}
}
func TestGetContainerInfoWhenCadvisorFailed(t *testing.T) {

View File

@ -166,21 +166,7 @@ func TestPodInfo(t *testing.T) {
func TestContainerInfo(t *testing.T) {
fw := newServerTest()
expectedInfo := &info.ContainerInfo{
StatsPercentiles: &info.ContainerStatsPercentiles{
MaxMemoryUsage: 1024001,
CpuUsagePercentiles: []info.Percentile{
{50, 150},
{80, 180},
{90, 190},
},
MemoryUsagePercentiles: []info.Percentile{
{50, 150},
{80, 180},
{90, 190},
},
},
}
expectedInfo := &info.ContainerInfo{}
expectedPodID := "somepod"
expectedContainerName := "goodcontainer"
fw.fakeKubelet.containerInfoFunc = func(podID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
@ -207,21 +193,7 @@ func TestContainerInfo(t *testing.T) {
func TestRootInfo(t *testing.T) {
fw := newServerTest()
expectedInfo := &info.ContainerInfo{
StatsPercentiles: &info.ContainerStatsPercentiles{
MaxMemoryUsage: 1024001,
CpuUsagePercentiles: []info.Percentile{
{50, 150},
{80, 180},
{90, 190},
},
MemoryUsagePercentiles: []info.Percentile{
{50, 150},
{80, 180},
{90, 190},
},
},
}
expectedInfo := &info.ContainerInfo{}
fw.fakeKubelet.rootInfoFunc = func(req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
return expectedInfo, nil
}