1// Copyright 2019 The Prometheus Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package procfs 15 16import ( 17 "strings" 18 "testing" 19) 20 21func TestPSIStats(t *testing.T) { 22 t.Run("fake", func(*testing.T) { 23 stats, err := getProcFixtures(t).PSIStatsForResource("fake") 24 if err == nil { 25 t.Fatal("fake resource does not have PSI statistics") 26 } 27 28 if stats.Some != nil || stats.Full != nil { 29 t.Error("a fake resource cannot have PSILine entries") 30 } 31 }) 32 33 t.Run("cpu", func(t *testing.T) { 34 stats, err := getProcFixtures(t).PSIStatsForResource("cpu") 35 if err != nil { 36 t.Fatal(err) 37 } 38 39 if stats.Full != nil { 40 t.Fatal("cpu resource cannot have 'full' stats") 41 } 42 43 if stats.Some == nil { 44 t.Fatal("cpu resource should not have nil 'some' stats") 45 } 46 47 testCases := []struct { 48 name string 49 got float64 50 want float64 51 }{ 52 {"Avg10", stats.Some.Avg10, 0.1}, 53 {"Avg60", stats.Some.Avg60, 2.0}, 54 {"Avg300", stats.Some.Avg300, 3.85}, 55 {"Total", float64(stats.Some.Total), 15.0}, 56 } 57 58 for _, tc := range testCases { 59 t.Run(tc.name, func(t *testing.T) { 60 if tc.got != tc.want { 61 t.Errorf("got: %f, want: %f", tc.got, tc.want) 62 } 63 }) 64 } 65 }) 66 67 res := []string{"memory", "io"} 68 69 for _, resource := range res { 70 t.Run(resource, func(t *testing.T) { 71 stats, err := getProcFixtures(t).PSIStatsForResource(resource) 72 if err != nil { 73 t.Fatal(err) 74 } 75 76 if stats.Full == nil { 77 t.Fatalf("%s resource must not have nil 'full' stats", resource) 78 } 79 80 if stats.Some == nil { 81 t.Fatalf("%s resource must not have nil 'some' stats", resource) 82 } 83 84 testCases := []struct { 85 name string 86 got float64 87 want float64 88 }{ 89 {"some/Avg10", stats.Some.Avg10, 0.1}, 90 {"some/Avg60", stats.Some.Avg60, 2.0}, 91 {"some/Avg300", stats.Some.Avg300, 3.85}, 92 {"some/Total", float64(stats.Some.Total), 15.0}, 93 {"full/Avg10", stats.Full.Avg10, 0.2}, 94 {"full/Avg60", stats.Full.Avg60, 3.0}, 95 {"full/Avg300", stats.Full.Avg300, 4.95}, 96 {"full/Total", float64(stats.Full.Total), 25.0}, 97 } 98 99 for _, tc := range testCases { 100 t.Run(tc.name, func(t *testing.T) { 101 if tc.got != tc.want { 102 t.Errorf("got: %f, want: %f", tc.got, tc.want) 103 } 104 }) 105 } 106 }) 107 } 108} 109 110// TestParsePSIStats tests the edge cases that we won't run into when running TestPSIStats 111func TestParsePSIStats(t *testing.T) { 112 t.Run("unknown measurement type", func(t *testing.T) { 113 raw := "nonesense haha test=fake" 114 _, err := parsePSIStats("fake", strings.NewReader(raw)) 115 if err != nil { 116 t.Error("unknown measurement type must be ignored") 117 } 118 }) 119 120 t.Run("malformed measurement", func(t *testing.T) { 121 t.Run("some", func(t *testing.T) { 122 raw := `some avg10=0.10 avg60=2.00 avg300=3.85 total=oops 123full avg10=0.20 avg60=3.00 avg300=teddy total=25` 124 stats, err := parsePSIStats("fake", strings.NewReader(raw)) 125 if err == nil { 126 t.Error("a malformed line must result in a parse error") 127 } 128 129 if stats.Some != nil || stats.Full != nil { 130 t.Error("a parse error must result in a nil PSILine") 131 } 132 }) 133 t.Run("full", func(t *testing.T) { 134 raw := `some avg10=0.10 avg60=2.00 avg300=3.85 total=1 135full avg10=0.20 avg60=3.00 avg300=test total=25` 136 stats, err := parsePSIStats("fake", strings.NewReader(raw)) 137 t.Log(err) 138 t.Log(stats) 139 if err == nil { 140 t.Error("a malformed line must result in a parse error") 141 } 142 143 if stats.Some != nil || stats.Full != nil { 144 t.Error("a parse error must result in a nil PSILine") 145 } 146 }) 147 148 }) 149} 150