366 lines
7.6 KiB
Go
366 lines
7.6 KiB
Go
// Copyright 2016 Google Inc. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package v2
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/cadvisor/info/v1"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var (
|
|
timestamp = time.Date(1987, time.August, 10, 0, 0, 0, 0, time.UTC)
|
|
labels = map[string]string{"foo": "bar"}
|
|
)
|
|
|
|
func TestContanierSpecFromV1(t *testing.T) {
|
|
v1Spec := v1.ContainerSpec{
|
|
CreationTime: timestamp,
|
|
Labels: labels,
|
|
HasCpu: true,
|
|
Cpu: v1.CpuSpec{
|
|
Limit: 2048,
|
|
MaxLimit: 4096,
|
|
Mask: "cpu_mask",
|
|
},
|
|
HasMemory: true,
|
|
Memory: v1.MemorySpec{
|
|
Limit: 2048,
|
|
Reservation: 1024,
|
|
SwapLimit: 8192,
|
|
},
|
|
HasNetwork: true,
|
|
HasFilesystem: true,
|
|
HasDiskIo: true,
|
|
HasCustomMetrics: true,
|
|
CustomMetrics: []v1.MetricSpec{{
|
|
Name: "foo",
|
|
Type: v1.MetricGauge,
|
|
Format: v1.IntType,
|
|
Units: "bars",
|
|
}},
|
|
Image: "gcr.io/kubernetes/kubernetes:v1",
|
|
}
|
|
|
|
aliases := []string{"baz", "oof"}
|
|
namespace := "foo_bar_baz"
|
|
|
|
expectedV2Spec := ContainerSpec{
|
|
CreationTime: timestamp,
|
|
Labels: labels,
|
|
HasCpu: true,
|
|
Cpu: CpuSpec{
|
|
Limit: 2048,
|
|
MaxLimit: 4096,
|
|
Mask: "cpu_mask",
|
|
},
|
|
HasMemory: true,
|
|
Memory: MemorySpec{
|
|
Limit: 2048,
|
|
Reservation: 1024,
|
|
SwapLimit: 8192,
|
|
},
|
|
HasNetwork: true,
|
|
HasFilesystem: true,
|
|
HasDiskIo: true,
|
|
HasCustomMetrics: true,
|
|
CustomMetrics: []v1.MetricSpec{{
|
|
Name: "foo",
|
|
Type: v1.MetricGauge,
|
|
Format: v1.IntType,
|
|
Units: "bars",
|
|
}},
|
|
Image: "gcr.io/kubernetes/kubernetes:v1",
|
|
Aliases: aliases,
|
|
Namespace: namespace,
|
|
}
|
|
|
|
v2Spec := ContainerSpecFromV1(&v1Spec, aliases, namespace)
|
|
if !reflect.DeepEqual(v2Spec, expectedV2Spec) {
|
|
t.Errorf("Converted spec differs from expectation!\nExpected: %+v\n Got: %+v\n", expectedV2Spec, v2Spec)
|
|
}
|
|
}
|
|
|
|
func TestContainerStatsFromV1(t *testing.T) {
|
|
v1Spec := v1.ContainerSpec{
|
|
CreationTime: timestamp,
|
|
Labels: labels,
|
|
HasCpu: true,
|
|
Cpu: v1.CpuSpec{
|
|
Limit: 2048,
|
|
MaxLimit: 4096,
|
|
Mask: "cpu_mask",
|
|
},
|
|
HasMemory: true,
|
|
Memory: v1.MemorySpec{
|
|
Limit: 2048,
|
|
Reservation: 1024,
|
|
SwapLimit: 8192,
|
|
},
|
|
HasNetwork: true,
|
|
HasFilesystem: true,
|
|
HasDiskIo: true,
|
|
HasCustomMetrics: true,
|
|
CustomMetrics: []v1.MetricSpec{{
|
|
Name: "foo",
|
|
Type: v1.MetricGauge,
|
|
Format: v1.IntType,
|
|
Units: "bars",
|
|
}},
|
|
Image: "gcr.io/kubernetes/kubernetes:v1",
|
|
}
|
|
v1Stats := v1.ContainerStats{
|
|
Timestamp: timestamp,
|
|
Memory: v1.MemoryStats{
|
|
Usage: 1,
|
|
Cache: 2,
|
|
RSS: 3,
|
|
WorkingSet: 4,
|
|
Failcnt: 5,
|
|
ContainerData: v1.MemoryStatsMemoryData{
|
|
Pgfault: 1,
|
|
Pgmajfault: 2,
|
|
},
|
|
HierarchicalData: v1.MemoryStatsMemoryData{
|
|
Pgfault: 10,
|
|
Pgmajfault: 20,
|
|
},
|
|
},
|
|
Network: v1.NetworkStats{
|
|
InterfaceStats: v1.InterfaceStats{
|
|
Name: "",
|
|
RxBytes: 1,
|
|
RxPackets: 2,
|
|
RxErrors: 3,
|
|
RxDropped: 4,
|
|
TxBytes: 5,
|
|
TxPackets: 6,
|
|
TxErrors: 7,
|
|
TxDropped: 8,
|
|
},
|
|
Interfaces: []v1.InterfaceStats{{
|
|
Name: "eth0",
|
|
RxBytes: 10,
|
|
RxPackets: 20,
|
|
RxErrors: 30,
|
|
RxDropped: 40,
|
|
TxBytes: 50,
|
|
TxPackets: 60,
|
|
TxErrors: 70,
|
|
TxDropped: 80,
|
|
}},
|
|
},
|
|
Filesystem: []v1.FsStats{{
|
|
Device: "dev0",
|
|
Limit: 500,
|
|
Usage: 100,
|
|
BaseUsage: 50,
|
|
Available: 300,
|
|
InodesFree: 100,
|
|
}},
|
|
}
|
|
expectedV2Stats := ContainerStats{
|
|
Timestamp: timestamp,
|
|
Cpu: &v1Stats.Cpu,
|
|
DiskIo: &v1Stats.DiskIo,
|
|
Memory: &v1Stats.Memory,
|
|
Network: &NetworkStats{
|
|
Interfaces: v1Stats.Network.Interfaces,
|
|
},
|
|
Filesystem: &FilesystemStats{
|
|
TotalUsageBytes: &v1Stats.Filesystem[0].Usage,
|
|
BaseUsageBytes: &v1Stats.Filesystem[0].BaseUsage,
|
|
InodeUsage: &v1Stats.Filesystem[0].Inodes,
|
|
},
|
|
}
|
|
|
|
v2Stats := ContainerStatsFromV1(&v1Spec, []*v1.ContainerStats{&v1Stats})
|
|
actualV2Stats := *v2Stats[0]
|
|
|
|
if !reflect.DeepEqual(expectedV2Stats, actualV2Stats) {
|
|
t.Errorf("Converted stats differs from expectation!\nExpected: %+v\n Got: %+v\n", expectedV2Stats, actualV2Stats)
|
|
}
|
|
}
|
|
|
|
func TestInstCpuStats(t *testing.T) {
|
|
tests := []struct {
|
|
last *v1.ContainerStats
|
|
cur *v1.ContainerStats
|
|
want *CpuInstStats
|
|
}{
|
|
// Last is missing
|
|
{
|
|
nil,
|
|
&v1.ContainerStats{},
|
|
nil,
|
|
},
|
|
// Goes back in time
|
|
{
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0).Add(time.Second),
|
|
},
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
},
|
|
nil,
|
|
},
|
|
// Zero time delta
|
|
{
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
},
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
},
|
|
nil,
|
|
},
|
|
// Unexpectedly small time delta
|
|
{
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
},
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0).Add(30 * time.Millisecond),
|
|
},
|
|
nil,
|
|
},
|
|
// Different number of cpus
|
|
{
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
PerCpu: []uint64{100, 200},
|
|
},
|
|
},
|
|
},
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0).Add(time.Second),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
PerCpu: []uint64{100, 200, 300},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
},
|
|
// Stat numbers decrease
|
|
{
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
Total: 300,
|
|
PerCpu: []uint64{100, 200},
|
|
User: 250,
|
|
System: 50,
|
|
},
|
|
},
|
|
},
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0).Add(time.Second),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
Total: 200,
|
|
PerCpu: []uint64{100, 100},
|
|
User: 150,
|
|
System: 50,
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
},
|
|
// One second elapsed
|
|
{
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
Total: 300,
|
|
PerCpu: []uint64{100, 200},
|
|
User: 250,
|
|
System: 50,
|
|
},
|
|
},
|
|
},
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0).Add(time.Second),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
Total: 500,
|
|
PerCpu: []uint64{200, 300},
|
|
User: 400,
|
|
System: 100,
|
|
},
|
|
},
|
|
},
|
|
&CpuInstStats{
|
|
Usage: CpuInstUsage{
|
|
Total: 200,
|
|
PerCpu: []uint64{100, 100},
|
|
User: 150,
|
|
System: 50,
|
|
},
|
|
},
|
|
},
|
|
// Two seconds elapsed
|
|
{
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
Total: 300,
|
|
PerCpu: []uint64{100, 200},
|
|
User: 250,
|
|
System: 50,
|
|
},
|
|
},
|
|
},
|
|
&v1.ContainerStats{
|
|
Timestamp: time.Unix(100, 0).Add(2 * time.Second),
|
|
Cpu: v1.CpuStats{
|
|
Usage: v1.CpuUsage{
|
|
Total: 500,
|
|
PerCpu: []uint64{200, 300},
|
|
User: 400,
|
|
System: 100,
|
|
},
|
|
},
|
|
},
|
|
&CpuInstStats{
|
|
Usage: CpuInstUsage{
|
|
Total: 100,
|
|
PerCpu: []uint64{50, 50},
|
|
User: 75,
|
|
System: 25,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, c := range tests {
|
|
got, err := InstCpuStats(c.last, c.cur)
|
|
if err != nil {
|
|
if c.want == nil {
|
|
continue
|
|
}
|
|
t.Errorf("Unexpected error: %v", err)
|
|
}
|
|
assert.Equal(t, c.want, got)
|
|
}
|
|
}
|