github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/toolkit/cpu/cpu_test.go (about) 1 package cpu 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "runtime" 8 "testing" 9 "time" 10 11 "github.com/unionj-cloud/go-doudou/toolkit/internal/common" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func skipIfNotImplementedErr(t *testing.T, err error) { 16 if errors.Is(err, common.ErrNotImplementedError) { 17 t.Skip("not implemented") 18 } 19 } 20 21 func TestCpu_times(t *testing.T) { 22 v, err := Times(false) 23 skipIfNotImplementedErr(t, err) 24 if err != nil { 25 t.Errorf("error %v", err) 26 } 27 if len(v) == 0 { 28 t.Error("could not get CPUs ", err) 29 } 30 empty := TimesStat{} 31 for _, vv := range v { 32 if vv == empty { 33 t.Errorf("could not get CPU User: %v", vv) 34 } 35 } 36 37 // test sum of per cpu stats is within margin of error for cpu total stats 38 cpuTotal, err := Times(false) 39 skipIfNotImplementedErr(t, err) 40 if err != nil { 41 t.Errorf("error %v", err) 42 } 43 if len(cpuTotal) == 0 { 44 t.Error("could not get CPUs", err) 45 } 46 perCPU, err := Times(true) 47 skipIfNotImplementedErr(t, err) 48 if err != nil { 49 t.Errorf("error %v", err) 50 } 51 if len(perCPU) == 0 { 52 t.Error("could not get CPUs", err) 53 } 54 var perCPUUserTimeSum float64 55 var perCPUSystemTimeSum float64 56 var perCPUIdleTimeSum float64 57 for _, pc := range perCPU { 58 perCPUUserTimeSum += pc.User 59 perCPUSystemTimeSum += pc.System 60 perCPUIdleTimeSum += pc.Idle 61 } 62 margin := 2.0 63 t.Log(cpuTotal[0]) 64 65 if cpuTotal[0].User == 0 && cpuTotal[0].System == 0 && cpuTotal[0].Idle == 0 { 66 t.Error("could not get cpu values") 67 } 68 if cpuTotal[0].User != 0 { 69 assert.InEpsilon(t, cpuTotal[0].User, perCPUUserTimeSum, margin) 70 } 71 if cpuTotal[0].System != 0 { 72 assert.InEpsilon(t, cpuTotal[0].System, perCPUSystemTimeSum, margin) 73 } 74 if cpuTotal[0].Idle != 0 { 75 assert.InEpsilon(t, cpuTotal[0].Idle, perCPUIdleTimeSum, margin) 76 } 77 } 78 79 func TestCpu_counts(t *testing.T) { 80 v, err := Counts(true) 81 skipIfNotImplementedErr(t, err) 82 if err != nil { 83 t.Errorf("error %v", err) 84 } 85 if v == 0 { 86 t.Errorf("could not get logical CPU counts: %v", v) 87 } 88 t.Logf("logical cores: %d", v) 89 v, err = Counts(false) 90 skipIfNotImplementedErr(t, err) 91 if err != nil { 92 t.Errorf("error %v", err) 93 } 94 if v == 0 { 95 t.Errorf("could not get physical CPU counts: %v", v) 96 } 97 t.Logf("physical cores: %d", v) 98 } 99 100 func TestCPUTimeStat_String(t *testing.T) { 101 v := TimesStat{ 102 CPU: "cpu0", 103 User: 100.1, 104 System: 200.1, 105 Idle: 300.1, 106 } 107 e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}` 108 if e != fmt.Sprintf("%v", v) { 109 t.Errorf("CPUTimesStat string is invalid: %v", v) 110 } 111 } 112 113 func TestCpuInfo(t *testing.T) { 114 v, err := Info() 115 skipIfNotImplementedErr(t, err) 116 if err != nil { 117 t.Errorf("error %v", err) 118 } 119 if len(v) == 0 { 120 t.Errorf("could not get CPU Info") 121 } 122 for _, vv := range v { 123 if vv.ModelName == "" { 124 t.Errorf("could not get CPU Info: %v", vv) 125 } 126 } 127 } 128 129 func testCPUPercent(t *testing.T, percpu bool) { 130 numcpu := runtime.NumCPU() 131 testCount := 3 132 133 if runtime.GOOS != "windows" { 134 testCount = 100 135 v, err := Percent(time.Millisecond, percpu) 136 skipIfNotImplementedErr(t, err) 137 if err != nil { 138 t.Errorf("error %v", err) 139 } 140 // Skip CircleCI which CPU num is different 141 if os.Getenv("CIRCLECI") != "true" { 142 if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) { 143 t.Fatalf("wrong number of entries from CPUPercent: %v", v) 144 } 145 } 146 } 147 for i := 0; i < testCount; i++ { 148 duration := time.Duration(10) * time.Microsecond 149 v, err := Percent(duration, percpu) 150 skipIfNotImplementedErr(t, err) 151 if err != nil { 152 t.Errorf("error %v", err) 153 } 154 for _, percent := range v { 155 // Check for slightly greater then 100% to account for any rounding issues. 156 if percent < 0.0 || percent > 100.0001*float64(numcpu) { 157 t.Fatalf("CPUPercent value is invalid: %f", percent) 158 } 159 } 160 } 161 } 162 163 func testCPUPercentLastUsed(t *testing.T, percpu bool) { 164 numcpu := runtime.NumCPU() 165 testCount := 10 166 167 if runtime.GOOS != "windows" { 168 testCount = 2 169 v, err := Percent(time.Millisecond, percpu) 170 skipIfNotImplementedErr(t, err) 171 if err != nil { 172 t.Errorf("error %v", err) 173 } 174 // Skip CircleCI which CPU num is different 175 if os.Getenv("CIRCLECI") != "true" { 176 if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) { 177 t.Fatalf("wrong number of entries from CPUPercent: %v", v) 178 } 179 } 180 } 181 for i := 0; i < testCount; i++ { 182 v, err := Percent(0, percpu) 183 skipIfNotImplementedErr(t, err) 184 if err != nil { 185 t.Errorf("error %v", err) 186 } 187 time.Sleep(1 * time.Millisecond) 188 for _, percent := range v { 189 // Check for slightly greater then 100% to account for any rounding issues. 190 if percent < 0.0 || percent > 100.0001*float64(numcpu) { 191 t.Fatalf("CPUPercent value is invalid: %f", percent) 192 } 193 } 194 } 195 } 196 197 func TestCPUPercent(t *testing.T) { 198 testCPUPercent(t, false) 199 } 200 201 func TestCPUPercentPerCpu(t *testing.T) { 202 testCPUPercent(t, true) 203 } 204 205 func TestCPUPercentIntervalZero(t *testing.T) { 206 testCPUPercentLastUsed(t, false) 207 } 208 209 func TestCPUPercentIntervalZeroPerCPU(t *testing.T) { 210 testCPUPercentLastUsed(t, true) 211 }