github.com/google/cadvisor@v0.49.1/summary/percentiles_test.go (about)

     1  // Copyright 2015 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 summary
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	info "github.com/google/cadvisor/info/v2"
    22  )
    23  
    24  const Nanosecond = 1000000000
    25  
    26  func assertPercentile(t *testing.T, s Uint64Slice, f float64, want uint64) {
    27  	if got := s.GetPercentile(f); got != want {
    28  		t.Errorf("GetPercentile(%f) is %d, should be %d.", f, got, want)
    29  	}
    30  }
    31  
    32  func TestPercentile(t *testing.T) {
    33  	N := 100
    34  	s := make(Uint64Slice, 0, N)
    35  	for i := N; i > 0; i-- {
    36  		s = append(s, uint64(i))
    37  	}
    38  	assertPercentile(t, s, 0.2, 20)
    39  	assertPercentile(t, s, 0.7, 70)
    40  	assertPercentile(t, s, 0.9, 90)
    41  	N = 105
    42  	for i := 101; i <= N; i++ {
    43  		s = append(s, uint64(i))
    44  	}
    45  	// 90p should be between 94 and 95. Promoted to 95.
    46  	assertPercentile(t, s, 0.2, 21)
    47  	assertPercentile(t, s, 0.7, 74)
    48  	assertPercentile(t, s, 0.9, 95)
    49  }
    50  
    51  func TestMean(t *testing.T) {
    52  	var i, N uint64
    53  	N = 100
    54  	mean := mean{count: 0, Mean: 0}
    55  	for i = 1; i < N; i++ {
    56  		mean.Add(i)
    57  	}
    58  	if mean.Mean != 50.0 {
    59  		t.Errorf("Mean is %f, should be 50.0", mean.Mean)
    60  	}
    61  }
    62  
    63  func TestAggregates(t *testing.T) {
    64  	N := uint64(100)
    65  	var i uint64
    66  	ct := time.Now()
    67  	stats := make([]*secondSample, 0, N)
    68  	for i = 1; i < N; i++ {
    69  		s := &secondSample{
    70  			Timestamp: ct.Add(time.Duration(i) * time.Second),
    71  			// cpu rate is 1 s/s
    72  			Cpu: i * Nanosecond,
    73  			// Memory grows by a KB every second.
    74  			Memory: i * 1024,
    75  		}
    76  		stats = append(stats, s)
    77  	}
    78  	usage := GetMinutePercentiles(stats)
    79  	// Cpu mean, max, and 90p should all be 1000 ms/s.
    80  	cpuExpected := info.Percentiles{
    81  		Present:    true,
    82  		Mean:       1000,
    83  		Max:        1000,
    84  		Fifty:      1000,
    85  		Ninety:     1000,
    86  		NinetyFive: 1000,
    87  	}
    88  	if usage.Cpu != cpuExpected {
    89  		t.Errorf("cpu stats are %+v. Expected %+v", usage.Cpu, cpuExpected)
    90  	}
    91  	memExpected := info.Percentiles{
    92  		Present:    true,
    93  		Mean:       50 * 1024,
    94  		Max:        99 * 1024,
    95  		Fifty:      50 * 1024,
    96  		Ninety:     90 * 1024,
    97  		NinetyFive: 95 * 1024,
    98  	}
    99  	if usage.Memory != memExpected {
   100  		t.Errorf("memory stats are mean %+v. Expected %+v", usage.Memory, memExpected)
   101  	}
   102  }
   103  func TestSamplesCloseInTimeIgnored(t *testing.T) {
   104  	N := uint64(100)
   105  	var i uint64
   106  	ct := time.Now()
   107  	stats := make([]*secondSample, 0, N*2)
   108  	for i = 1; i < N; i++ {
   109  		s1 := &secondSample{
   110  			Timestamp: ct.Add(time.Duration(i) * time.Second),
   111  			// cpu rate is 1 s/s
   112  			Cpu: i * Nanosecond,
   113  			// Memory grows by a KB every second.
   114  			Memory: i * 1024,
   115  		}
   116  		stats = append(stats, s1)
   117  
   118  		// Add another dummy sample too close in time to the last one.
   119  		s2 := &secondSample{
   120  			// Add extra millisecond.
   121  			Timestamp: ct.Add(time.Duration(i) * time.Second).Add(time.Duration(1) * time.Millisecond),
   122  			Cpu:       i * 100 * Nanosecond,
   123  			Memory:    i * 1024 * 1024,
   124  		}
   125  		stats = append(stats, s2)
   126  	}
   127  	usage := GetMinutePercentiles(stats)
   128  	// Cpu mean, max, and 90p should all be 1000 ms/s. All high-value samples are discarded.
   129  	cpuExpected := info.Percentiles{
   130  		Present:    true,
   131  		Mean:       1000,
   132  		Max:        1000,
   133  		Fifty:      1000,
   134  		Ninety:     1000,
   135  		NinetyFive: 1000,
   136  	}
   137  	if usage.Cpu != cpuExpected {
   138  		t.Errorf("cpu stats are %+v. Expected %+v", usage.Cpu, cpuExpected)
   139  	}
   140  	memExpected := info.Percentiles{
   141  		Present:    true,
   142  		Mean:       50 * 1024,
   143  		Max:        99 * 1024,
   144  		Fifty:      50 * 1024,
   145  		Ninety:     90 * 1024,
   146  		NinetyFive: 95 * 1024,
   147  	}
   148  	if usage.Memory != memExpected {
   149  		t.Errorf("memory stats are mean %+v. Expected %+v", usage.Memory, memExpected)
   150  	}
   151  }
   152  
   153  func TestDerivedStats(t *testing.T) {
   154  	N := uint64(100)
   155  	var i uint64
   156  	stats := make([]*info.Usage, 0, N)
   157  	for i = 1; i < N; i++ {
   158  		s := &info.Usage{
   159  			PercentComplete: 100,
   160  			Cpu: info.Percentiles{
   161  				Present:    true,
   162  				Mean:       i * Nanosecond,
   163  				Max:        i * Nanosecond,
   164  				Fifty:      i * Nanosecond,
   165  				Ninety:     i * Nanosecond,
   166  				NinetyFive: i * Nanosecond,
   167  			},
   168  			Memory: info.Percentiles{
   169  				Present:    true,
   170  				Mean:       i * 1024,
   171  				Max:        i * 1024,
   172  				Fifty:      i * 1024,
   173  				Ninety:     i * 1024,
   174  				NinetyFive: i * 1024,
   175  			},
   176  		}
   177  		stats = append(stats, s)
   178  	}
   179  	usage := GetDerivedPercentiles(stats)
   180  	cpuExpected := info.Percentiles{
   181  		Present:    true,
   182  		Mean:       50 * Nanosecond,
   183  		Max:        99 * Nanosecond,
   184  		Fifty:      50 * Nanosecond,
   185  		Ninety:     90 * Nanosecond,
   186  		NinetyFive: 95 * Nanosecond,
   187  	}
   188  	if usage.Cpu != cpuExpected {
   189  		t.Errorf("cpu stats are %+v. Expected %+v", usage.Cpu, cpuExpected)
   190  	}
   191  	memExpected := info.Percentiles{
   192  		Present:    true,
   193  		Mean:       50 * 1024,
   194  		Max:        99 * 1024,
   195  		Fifty:      50 * 1024,
   196  		Ninety:     90 * 1024,
   197  		NinetyFive: 95 * 1024,
   198  	}
   199  	if usage.Memory != memExpected {
   200  		t.Errorf("memory stats are mean %+v. Expected %+v", usage.Memory, memExpected)
   201  	}
   202  }