github.com/google/cadvisor@v0.49.1/info/v2/conversion_test.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package v2
    16  
    17  import (
    18  	"reflect"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/stretchr/testify/assert"
    23  
    24  	v1 "github.com/google/cadvisor/info/v1"
    25  )
    26  
    27  var (
    28  	timestamp = time.Date(1987, time.August, 10, 0, 0, 0, 0, time.UTC)
    29  	labels    = map[string]string{"foo": "bar"}
    30  	envs      = map[string]string{"foo": "bar"}
    31  )
    32  
    33  func TestContainerSpecFromV1(t *testing.T) {
    34  	v1Spec := v1.ContainerSpec{
    35  		CreationTime: timestamp,
    36  		Labels:       labels,
    37  		Envs:         envs,
    38  		HasCpu:       true,
    39  		Cpu: v1.CpuSpec{
    40  			Limit:    2048,
    41  			MaxLimit: 4096,
    42  			Mask:     "cpu_mask",
    43  		},
    44  		HasMemory: true,
    45  		Memory: v1.MemorySpec{
    46  			Limit:       2048,
    47  			Reservation: 1024,
    48  			SwapLimit:   8192,
    49  		},
    50  		HasHugetlb:       true,
    51  		HasNetwork:       true,
    52  		HasProcesses:     true,
    53  		HasFilesystem:    true,
    54  		HasDiskIo:        true,
    55  		HasCustomMetrics: true,
    56  		CustomMetrics: []v1.MetricSpec{{
    57  			Name:   "foo",
    58  			Type:   v1.MetricGauge,
    59  			Format: v1.IntType,
    60  			Units:  "bars",
    61  		}},
    62  		Image: "gcr.io/kubernetes/kubernetes:v1",
    63  	}
    64  
    65  	aliases := []string{"baz", "oof"}
    66  	namespace := "foo_bar_baz"
    67  
    68  	expectedV2Spec := ContainerSpec{
    69  		CreationTime: timestamp,
    70  		Labels:       labels,
    71  		Envs:         envs,
    72  		HasCpu:       true,
    73  		Cpu: CpuSpec{
    74  			Limit:    2048,
    75  			MaxLimit: 4096,
    76  			Mask:     "cpu_mask",
    77  		},
    78  		HasMemory: true,
    79  		Memory: MemorySpec{
    80  			Limit:       2048,
    81  			Reservation: 1024,
    82  			SwapLimit:   8192,
    83  		},
    84  		HasHugetlb:       true,
    85  		HasNetwork:       true,
    86  		HasProcesses:     true,
    87  		HasFilesystem:    true,
    88  		HasDiskIo:        true,
    89  		HasCustomMetrics: true,
    90  		CustomMetrics: []v1.MetricSpec{{
    91  			Name:   "foo",
    92  			Type:   v1.MetricGauge,
    93  			Format: v1.IntType,
    94  			Units:  "bars",
    95  		}},
    96  		Image:     "gcr.io/kubernetes/kubernetes:v1",
    97  		Aliases:   aliases,
    98  		Namespace: namespace,
    99  	}
   100  
   101  	v2Spec := ContainerSpecFromV1(&v1Spec, aliases, namespace)
   102  	if !reflect.DeepEqual(v2Spec, expectedV2Spec) {
   103  		t.Errorf("Converted spec differs from expectation!\nExpected: %+v\n Got: %+v\n", expectedV2Spec, v2Spec)
   104  	}
   105  }
   106  
   107  func TestContainerStatsFromV1(t *testing.T) {
   108  	v1Spec := v1.ContainerSpec{
   109  		CreationTime: timestamp,
   110  		Labels:       labels,
   111  		HasCpu:       true,
   112  		Cpu: v1.CpuSpec{
   113  			Limit:    2048,
   114  			MaxLimit: 4096,
   115  			Mask:     "cpu_mask",
   116  		},
   117  		HasMemory: true,
   118  		Memory: v1.MemorySpec{
   119  			Limit:       2048,
   120  			Reservation: 1024,
   121  			SwapLimit:   8192,
   122  		},
   123  		HasHugetlb:       true,
   124  		HasNetwork:       true,
   125  		HasProcesses:     true,
   126  		HasFilesystem:    true,
   127  		HasDiskIo:        true,
   128  		HasCustomMetrics: true,
   129  		CustomMetrics: []v1.MetricSpec{{
   130  			Name:   "foo",
   131  			Type:   v1.MetricGauge,
   132  			Format: v1.IntType,
   133  			Units:  "bars",
   134  		}},
   135  		Image: "gcr.io/kubernetes/kubernetes:v1",
   136  	}
   137  	v1Stats := v1.ContainerStats{
   138  		Timestamp: timestamp,
   139  		Memory: v1.MemoryStats{
   140  			Usage:      1,
   141  			Cache:      2,
   142  			RSS:        3,
   143  			WorkingSet: 4,
   144  			Failcnt:    5,
   145  			ContainerData: v1.MemoryStatsMemoryData{
   146  				Pgfault:    1,
   147  				Pgmajfault: 2,
   148  			},
   149  			HierarchicalData: v1.MemoryStatsMemoryData{
   150  				Pgfault:    10,
   151  				Pgmajfault: 20,
   152  			},
   153  		},
   154  		Network: v1.NetworkStats{
   155  			InterfaceStats: v1.InterfaceStats{
   156  				Name:      "",
   157  				RxBytes:   1,
   158  				RxPackets: 2,
   159  				RxErrors:  3,
   160  				RxDropped: 4,
   161  				TxBytes:   5,
   162  				TxPackets: 6,
   163  				TxErrors:  7,
   164  				TxDropped: 8,
   165  			},
   166  			Interfaces: []v1.InterfaceStats{{
   167  				Name:      "eth0",
   168  				RxBytes:   10,
   169  				RxPackets: 20,
   170  				RxErrors:  30,
   171  				RxDropped: 40,
   172  				TxBytes:   50,
   173  				TxPackets: 60,
   174  				TxErrors:  70,
   175  				TxDropped: 80,
   176  			}},
   177  		},
   178  		Processes: v1.ProcessStats{
   179  			ProcessCount:   5,
   180  			FdCount:        1,
   181  			ThreadsCurrent: 66,
   182  			ThreadsMax:     6000,
   183  		},
   184  		Filesystem: []v1.FsStats{{
   185  			Device:     "dev0",
   186  			Limit:      500,
   187  			Usage:      100,
   188  			BaseUsage:  50,
   189  			Available:  300,
   190  			InodesFree: 100,
   191  		}},
   192  		Accelerators: []v1.AcceleratorStats{{
   193  			Make:        "nvidia",
   194  			Model:       "tesla-p100",
   195  			ID:          "GPU-deadbeef-1234-5678-90ab-feedfacecafe",
   196  			MemoryTotal: 20304050607,
   197  			MemoryUsed:  2030405060,
   198  			DutyCycle:   12,
   199  		}},
   200  		PerfStats: []v1.PerfStat{
   201  			{
   202  				PerfValue: v1.PerfValue{
   203  					ScalingRatio: 1,
   204  					Value:        123,
   205  					Name:         "instructions",
   206  				},
   207  			},
   208  			{
   209  				PerfValue: v1.PerfValue{
   210  					ScalingRatio: 0.3333333,
   211  					Value:        123456,
   212  					Name:         "cycles",
   213  				},
   214  			},
   215  		},
   216  		PerfUncoreStats: []v1.PerfUncoreStat{
   217  			{
   218  				PerfValue: v1.PerfValue{
   219  					ScalingRatio: 1.0,
   220  					Value:        123456,
   221  					Name:         "uncore_imc_0/cas_count_write",
   222  				},
   223  				Socket: 0,
   224  				PMU:    "17",
   225  			},
   226  			{
   227  				PerfValue: v1.PerfValue{
   228  					ScalingRatio: 1.0,
   229  					Value:        654321,
   230  					Name:         "uncore_imc_0/cas_count_write",
   231  				},
   232  				Socket: 1,
   233  				PMU:    "17",
   234  			},
   235  		},
   236  		ReferencedMemory: uint64(1234),
   237  		Resctrl: v1.ResctrlStats{
   238  			MemoryBandwidth: []v1.MemoryBandwidthStats{
   239  				{
   240  					TotalBytes: 72312331,
   241  					LocalBytes: 1233311,
   242  				},
   243  				{
   244  					TotalBytes: 32312331,
   245  					LocalBytes: 2233311,
   246  				},
   247  			},
   248  			Cache: []v1.CacheStats{
   249  				{
   250  					LLCOccupancy: 123123441,
   251  				},
   252  				{
   253  					LLCOccupancy: 123313111,
   254  				},
   255  			},
   256  		},
   257  	}
   258  	expectedV2Stats := ContainerStats{
   259  		Timestamp: timestamp,
   260  		Cpu:       &v1Stats.Cpu,
   261  		DiskIo:    &v1Stats.DiskIo,
   262  		Memory:    &v1Stats.Memory,
   263  		Hugetlb:   &v1Stats.Hugetlb,
   264  		Processes: &v1Stats.Processes,
   265  		Network: &NetworkStats{
   266  			Interfaces: v1Stats.Network.Interfaces,
   267  		},
   268  		Filesystem: &FilesystemStats{
   269  			TotalUsageBytes: &v1Stats.Filesystem[0].Usage,
   270  			BaseUsageBytes:  &v1Stats.Filesystem[0].BaseUsage,
   271  			InodeUsage:      &v1Stats.Filesystem[0].Inodes,
   272  		},
   273  		Accelerators:     v1Stats.Accelerators,
   274  		PerfStats:        v1Stats.PerfStats,
   275  		PerfUncoreStats:  v1Stats.PerfUncoreStats,
   276  		ReferencedMemory: v1Stats.ReferencedMemory,
   277  		Resctrl:          v1Stats.Resctrl,
   278  	}
   279  
   280  	v2Stats := ContainerStatsFromV1("test", &v1Spec, []*v1.ContainerStats{&v1Stats})
   281  	actualV2Stats := *v2Stats[0]
   282  
   283  	if !reflect.DeepEqual(expectedV2Stats, actualV2Stats) {
   284  		t.Errorf("Converted stats differs from expectation!\nExpected: %+v\n Got: %+v\n", expectedV2Stats, actualV2Stats)
   285  	}
   286  }
   287  
   288  func TestInstCpuStats(t *testing.T) {
   289  	tests := []struct {
   290  		last *v1.ContainerStats
   291  		cur  *v1.ContainerStats
   292  		want *CpuInstStats
   293  	}{
   294  		// Last is missing
   295  		{
   296  			nil,
   297  			&v1.ContainerStats{},
   298  			nil,
   299  		},
   300  		// Goes back in time
   301  		{
   302  			&v1.ContainerStats{
   303  				Timestamp: time.Unix(100, 0).Add(time.Second),
   304  			},
   305  			&v1.ContainerStats{
   306  				Timestamp: time.Unix(100, 0),
   307  			},
   308  			nil,
   309  		},
   310  		// Zero time delta
   311  		{
   312  			&v1.ContainerStats{
   313  				Timestamp: time.Unix(100, 0),
   314  			},
   315  			&v1.ContainerStats{
   316  				Timestamp: time.Unix(100, 0),
   317  			},
   318  			nil,
   319  		},
   320  		// Different number of cpus
   321  		{
   322  			&v1.ContainerStats{
   323  				Timestamp: time.Unix(100, 0),
   324  				Cpu: v1.CpuStats{
   325  					Usage: v1.CpuUsage{
   326  						PerCpu: []uint64{100, 200},
   327  					},
   328  				},
   329  			},
   330  			&v1.ContainerStats{
   331  				Timestamp: time.Unix(100, 0).Add(time.Second),
   332  				Cpu: v1.CpuStats{
   333  					Usage: v1.CpuUsage{
   334  						PerCpu: []uint64{100, 200, 300},
   335  					},
   336  				},
   337  			},
   338  			nil,
   339  		},
   340  		// Stat numbers decrease
   341  		{
   342  			&v1.ContainerStats{
   343  				Timestamp: time.Unix(100, 0),
   344  				Cpu: v1.CpuStats{
   345  					Usage: v1.CpuUsage{
   346  						Total:  300,
   347  						PerCpu: []uint64{100, 200},
   348  						User:   250,
   349  						System: 50,
   350  					},
   351  				},
   352  			},
   353  			&v1.ContainerStats{
   354  				Timestamp: time.Unix(100, 0).Add(time.Second),
   355  				Cpu: v1.CpuStats{
   356  					Usage: v1.CpuUsage{
   357  						Total:  200,
   358  						PerCpu: []uint64{100, 100},
   359  						User:   150,
   360  						System: 50,
   361  					},
   362  				},
   363  			},
   364  			nil,
   365  		},
   366  		// One second elapsed
   367  		{
   368  			&v1.ContainerStats{
   369  				Timestamp: time.Unix(100, 0),
   370  				Cpu: v1.CpuStats{
   371  					Usage: v1.CpuUsage{
   372  						Total:  300,
   373  						PerCpu: []uint64{100, 200},
   374  						User:   250,
   375  						System: 50,
   376  					},
   377  				},
   378  			},
   379  			&v1.ContainerStats{
   380  				Timestamp: time.Unix(100, 0).Add(time.Second),
   381  				Cpu: v1.CpuStats{
   382  					Usage: v1.CpuUsage{
   383  						Total:  500,
   384  						PerCpu: []uint64{200, 300},
   385  						User:   400,
   386  						System: 100,
   387  					},
   388  				},
   389  			},
   390  			&CpuInstStats{
   391  				Usage: CpuInstUsage{
   392  					Total:  200,
   393  					PerCpu: []uint64{100, 100},
   394  					User:   150,
   395  					System: 50,
   396  				},
   397  			},
   398  		},
   399  		// Two seconds elapsed
   400  		{
   401  			&v1.ContainerStats{
   402  				Timestamp: time.Unix(100, 0),
   403  				Cpu: v1.CpuStats{
   404  					Usage: v1.CpuUsage{
   405  						Total:  300,
   406  						PerCpu: []uint64{100, 200},
   407  						User:   250,
   408  						System: 50,
   409  					},
   410  				},
   411  			},
   412  			&v1.ContainerStats{
   413  				Timestamp: time.Unix(100, 0).Add(2 * time.Second),
   414  				Cpu: v1.CpuStats{
   415  					Usage: v1.CpuUsage{
   416  						Total:  500,
   417  						PerCpu: []uint64{200, 300},
   418  						User:   400,
   419  						System: 100,
   420  					},
   421  				},
   422  			},
   423  			&CpuInstStats{
   424  				Usage: CpuInstUsage{
   425  					Total:  100,
   426  					PerCpu: []uint64{50, 50},
   427  					User:   75,
   428  					System: 25,
   429  				},
   430  			},
   431  		},
   432  	}
   433  	for _, c := range tests {
   434  		got, err := InstCpuStats(c.last, c.cur)
   435  		if err != nil {
   436  			if c.want == nil {
   437  				continue
   438  			}
   439  			t.Errorf("Unexpected error: %v", err)
   440  		}
   441  		assert.Equal(t, c.want, got)
   442  	}
   443  }