github.com/google/cloudprober@v0.11.3/surfacers/surfacers_test.go (about) 1 // Copyright 2017-2021 The Cloudprober Authors. 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 surfacers 16 17 import ( 18 "context" 19 "io/ioutil" 20 "os" 21 "reflect" 22 "testing" 23 "time" 24 25 "github.com/golang/protobuf/proto" 26 "github.com/google/cloudprober/metrics" 27 fileconfigpb "github.com/google/cloudprober/surfacers/file/proto" 28 surfacerpb "github.com/google/cloudprober/surfacers/proto" 29 ) 30 31 func TestDefaultConfig(t *testing.T) { 32 s, err := Init(context.Background(), []*surfacerpb.SurfacerDef{}) 33 if err != nil { 34 t.Fatal(err) 35 } 36 if len(s) != len(defaultSurfacers) { 37 t.Errorf("Didn't get default surfacers for no config") 38 } 39 } 40 41 func TestEmptyConfig(t *testing.T) { 42 s, err := Init(context.Background(), []*surfacerpb.SurfacerDef{&surfacerpb.SurfacerDef{}}) 43 if err != nil { 44 t.Fatal(err) 45 } 46 if len(s) != 0 { 47 t.Errorf("Got surfacers for zero config: %v", s) 48 } 49 } 50 51 func TestInferType(t *testing.T) { 52 tmpfile, err := ioutil.TempFile("", "example") 53 if err != nil { 54 t.Fatalf("error creating tempfile for test") 55 } 56 57 defer os.Remove(tmpfile.Name()) // clean up 58 59 s, err := Init(context.Background(), []*surfacerpb.SurfacerDef{ 60 { 61 Surfacer: &surfacerpb.SurfacerDef_FileSurfacer{ 62 &fileconfigpb.SurfacerConf{ 63 FilePath: proto.String(tmpfile.Name()), 64 }, 65 }, 66 }, 67 }) 68 if err != nil { 69 t.Fatal(err) 70 } 71 72 if len(s) != 1 { 73 t.Errorf("len(s)=%d, expected=1", len(s)) 74 } 75 76 if s[0].Type != "FILE" { 77 t.Errorf("Surfacer type: %s, expected: FILE", s[0].Type) 78 } 79 } 80 81 type testSurfacer struct { 82 received []*metrics.EventMetrics 83 } 84 85 func (ts *testSurfacer) Write(ctx context.Context, em *metrics.EventMetrics) { 86 ts.received = append(ts.received, em) 87 } 88 89 var testEventMetrics = []*metrics.EventMetrics{ 90 metrics.NewEventMetrics(time.Now()). 91 AddMetric("total", metrics.NewInt(20)). 92 AddMetric("timeout", metrics.NewInt(2)). 93 AddLabel("ptype", "http"). 94 AddLabel("probe", "google_homepage"), 95 metrics.NewEventMetrics(time.Now()). 96 AddMetric("memory", metrics.NewInt(20)). 97 AddMetric("num_goroutines", metrics.NewInt(2)). 98 AddLabel("probe", "sysvars"), 99 } 100 101 func TestUserDefinedAndFiltering(t *testing.T) { 102 ts1, ts2 := &testSurfacer{}, &testSurfacer{} 103 Register("s1", ts1) 104 Register("s2", ts2) 105 106 configs := []*surfacerpb.SurfacerDef{ 107 { 108 Name: proto.String("s1"), 109 Type: surfacerpb.Type_USER_DEFINED.Enum(), 110 }, 111 { 112 Name: proto.String("s2"), 113 IgnoreMetricsWithLabel: []*surfacerpb.LabelFilter{ 114 { 115 Key: proto.String("probe"), 116 Value: proto.String("sysvars"), 117 }, 118 }, 119 Type: surfacerpb.Type_USER_DEFINED.Enum(), 120 }, 121 } 122 wantSurfacers := []string{"s1", "s2"} 123 124 si, err := Init(context.Background(), configs) 125 if err != nil { 126 t.Fatalf("Unexpected initialization error: %v", err) 127 } 128 for i, s := range si { 129 if s.Name != wantSurfacers[i] { 130 t.Errorf("Got surfacer: %s, want surfacer: %s", s.Name, wantSurfacers[i]) 131 } 132 } 133 134 for _, em := range testEventMetrics { 135 for _, s := range si { 136 s.Surfacer.Write(context.Background(), em) 137 } 138 } 139 140 wantEventMetrics := [][]*metrics.EventMetrics{ 141 testEventMetrics, // No filtering. 142 testEventMetrics[0:1], // One EM is ignored for the 2nd surfacer. 143 } 144 145 for i, ts := range []*testSurfacer{ts1, ts2} { 146 wantEMs := wantEventMetrics[i] 147 if !reflect.DeepEqual(ts.received, wantEMs) { 148 t.Errorf("ts[%d]: Received EventMetrics: %v, want EventMetrics: %v", i, ts.received, wantEMs) 149 } 150 } 151 } 152 153 func TestFailureMetric(t *testing.T) { 154 ts1, ts2 := &testSurfacer{}, &testSurfacer{} 155 Register("s1", ts1) 156 Register("s2", ts2) 157 158 var testEventMetrics = []*metrics.EventMetrics{ 159 metrics.NewEventMetrics(time.Now()). 160 AddMetric("total", metrics.NewInt(20)). 161 AddMetric("success", metrics.NewInt(18)). 162 AddMetric("timeout", metrics.NewInt(2)). 163 AddLabel("ptype", "http"), 164 metrics.NewEventMetrics(time.Now()). 165 AddMetric("num_goroutines", metrics.NewInt(2)), 166 } 167 168 configs := []*surfacerpb.SurfacerDef{ 169 { 170 Name: proto.String("s1"), 171 Type: surfacerpb.Type_USER_DEFINED.Enum(), 172 }, 173 { 174 Name: proto.String("s2"), 175 Type: surfacerpb.Type_USER_DEFINED.Enum(), 176 AddFailureMetric: proto.Bool(true), 177 }, 178 } 179 180 si, err := Init(context.Background(), configs) 181 if err != nil { 182 t.Fatalf("Unexpected initialization error: %v", err) 183 } 184 185 for _, em := range testEventMetrics { 186 for _, s := range si { 187 s.Surfacer.Write(context.Background(), em) 188 } 189 } 190 191 wantEventMetrics := [][]*metrics.EventMetrics{ 192 testEventMetrics, // s1 193 194 []*metrics.EventMetrics{ 195 testEventMetrics[0].Clone(). 196 AddMetric("failure", metrics.NewInt(2)), 197 testEventMetrics[1], // unchanged 198 }, // s2 199 } 200 201 for i, ts := range []*testSurfacer{ts1, ts2} { 202 wantEMs := wantEventMetrics[i] 203 if !reflect.DeepEqual(ts.received, wantEMs) { 204 t.Errorf("ts[%d]: Received EventMetrics: %v, want EventMetrics: %v", i, ts.received, wantEMs) 205 } 206 } 207 }