github.com/nginxinc/kubernetes-ingress@v1.12.5/internal/metrics/collectors/latency_test.go (about) 1 package collectors 2 3 import ( 4 "reflect" 5 "testing" 6 ) 7 8 func newTestLatencyMetricsCollector() *LatencyMetricsCollector { 9 return &LatencyMetricsCollector{ 10 upstreamServerLabels: make(map[string][]string), 11 upstreamServerPeerLabels: make(map[string][]string), 12 metricsPublishedMap: make(metricsPublishedMap), 13 upstreamServerLabelNames: []string{"service", "resource_type", "resource_name", "resource_namespace"}, 14 upstreamServerPeerLabelNames: []string{"pod_name"}, 15 } 16 } 17 func TestParseMessageWithValidInputs(t *testing.T) { 18 tests := []struct { 19 msg string 20 expectedErr bool 21 expected latencyMetric 22 }{ 23 { 24 msg: `nginx: {"upstreamAddress":"10.0.0.1", "upstreamResponseTime":"0.003", "proxyHost":"upstream-1", "upstreamStatus": "200"}`, 25 expectedErr: false, 26 expected: latencyMetric{ 27 Upstream: "upstream-1", 28 Server: "10.0.0.1", 29 Latency: 0.003, 30 Code: "200", 31 }, 32 }, 33 { 34 msg: `nginx: {"upstreamAddress":"127.0.0.1:6001, 127.0.0.1:6002, 127.0.0.1:8001", "upstreamResponseTime":"0.9, 0.99, 0.1", "proxyHost":"upstream-1", "upstreamStatus": "500, 500, 200"}`, 35 expectedErr: false, 36 expected: latencyMetric{ 37 Upstream: "upstream-1", 38 Server: "127.0.0.1:8001", 39 Latency: 0.1, 40 Code: "200", 41 }, 42 }, 43 { 44 msg: `nginx: {"upstreamAddress":"upstream-1", "upstreamResponseTime":"0.0", "proxyHost":"upstream-1", "upstreamStatus": "404"}`, 45 expectedErr: true, 46 }, 47 { 48 msg: `nginx: {"upstreamAddress":"-", "upstreamResponseTime":"0.0", "proxyHost":"-", "upstreamStatus": "404"}`, 49 expectedErr: true, 50 }, 51 { 52 msg: `nginx: {"upstreamAddress":"10.0.0.1", "upstreamResponseTime":"not-a-float", "proxyHost":"upstream-1", "upstreamStatus": "404"}`, 53 expectedErr: true, 54 }, 55 { 56 msg: `wrong format`, 57 expectedErr: true, 58 }, 59 { 60 msg: `nginx: {"badJson}`, 61 expectedErr: true, 62 }, 63 } 64 for _, test := range tests { 65 actual, err := parseMessage(test.msg) 66 if test.expectedErr { 67 if err == nil { 68 t.Errorf("parseMessage should return an error, got nil") 69 } 70 } else { 71 if err != nil { 72 t.Errorf("parseMessage returned an unexpected error: %v", err) 73 } 74 if actual != test.expected { 75 t.Errorf("parseMessage returned: %+v, expected: %+v", actual, test.expected) 76 } 77 } 78 } 79 } 80 81 func TestCreateLatencyLabelNames(t *testing.T) { 82 expected := []string{"upstream", "server", "code", "one", "two", "three", "four", "five"} 83 actual := createLatencyLabelNames([]string{"one", "two", "three"}, []string{"four", "five"}) 84 if !reflect.DeepEqual(expected, actual) { 85 t.Errorf("createLatencyLabelNames returned: %v, expected: %v", actual, expected) 86 } 87 } 88 89 func TestCreateLatencyLabelNamesWithNilInputs(t *testing.T) { 90 expected := []string{"upstream", "server", "code"} 91 actual := createLatencyLabelNames(nil, nil) 92 if !reflect.DeepEqual(expected, actual) { 93 t.Errorf("createLatencyLabelNames returned: %v, expected: %v", actual, expected) 94 } 95 } 96 97 func TestCreateLatencyLabelValuesWithCorrectNumberOfLabels(t *testing.T) { 98 collector := newTestLatencyMetricsCollector() 99 collector.upstreamServerLabels["upstream-1"] = []string{"service-1", "ingress", "ingress-1", "default"} 100 collector.upstreamServerPeerLabels["upstream-1/10.0.0.1"] = []string{"pod-1"} 101 102 lm := latencyMetric{ 103 Upstream: "upstream-1", 104 Server: "10.0.0.1", 105 Code: "200", 106 } 107 expected := []string{"upstream-1", "10.0.0.1", "200", "service-1", "ingress", "ingress-1", "default", "pod-1"} 108 actual, err := collector.createLatencyLabelValues(lm) 109 if err != nil { 110 t.Errorf("createLatencyLabelValues returned unexpected error: %v", err) 111 } 112 if !reflect.DeepEqual(expected, actual) { 113 t.Errorf("createLatencyLabelValues returned: %v, expected: %v", actual, expected) 114 } 115 } 116 117 func TestCreateLatencyLabelValuesWithNoUpstreamServerLabels(t *testing.T) { 118 collector := newTestLatencyMetricsCollector() 119 collector.upstreamServerPeerLabels["upstream-1/10.0.0.1"] = []string{"pod-1"} 120 lm := latencyMetric{ 121 Upstream: "upstream-1", 122 Server: "10.0.0.1", 123 Code: "200", 124 } 125 _, err := collector.createLatencyLabelValues(lm) 126 if err == nil { 127 t.Error("createLatencyLabelValues should have returned an error, got nil") 128 } 129 } 130 131 func TestCreateLatencyLabelValuesWithNoUpstreamPeerServerLabels(t *testing.T) { 132 collector := newTestLatencyMetricsCollector() 133 collector.upstreamServerLabels["upstream-1"] = []string{"service-1", "ingress", "ingress-1", "default"} 134 lm := latencyMetric{ 135 Upstream: "upstream-1", 136 Server: "10.0.0.1", 137 Code: "200", 138 } 139 _, err := collector.createLatencyLabelValues(lm) 140 if err == nil { 141 t.Error("createLatencyLabelValues should have returned an error, got nil") 142 } 143 } 144 145 func TestCreateLatencyLabelValuesWithNoLabels(t *testing.T) { 146 collector := newTestLatencyMetricsCollector() 147 lm := latencyMetric{ 148 Upstream: "upstream-1", 149 Server: "10.0.0.1", 150 Code: "200", 151 } 152 _, err := collector.createLatencyLabelValues(lm) 153 if err == nil { 154 t.Error("createLatencyLabelValues should have returned an error, got nil") 155 } 156 } 157 158 func TestMetricsPublished(t *testing.T) { 159 collector := newTestLatencyMetricsCollector() 160 labelValueList1 := []string{"label-value-1", "label-value-2", "label-value-3"} 161 labelValueList2 := []string{"new-label-value-1", "new-label-value-2", "new-label-value-3"} 162 // add metric for upstream-1 163 collector.updateMetricsPublished("upstream-1", "10.0.0.0:80", labelValueList1) 164 // add the same metric 165 collector.updateMetricsPublished("upstream-1", "10.0.0.0:80", labelValueList1) 166 // add a new metric for upstream-1 167 collector.updateMetricsPublished("upstream-1", "10.0.0.0:80", labelValueList2) 168 // add metric for upstream-2 169 collector.updateMetricsPublished("upstream-2", "10.0.0.0:80", labelValueList1) 170 171 if l := len(collector.metricsPublishedMap); l != 2 { 172 t.Errorf("updateMetricsPublished did not update metricsPublishedMap map correctly, length is %d expected 2", l) 173 } 174 175 // verify metrics for upstream-1 are correct 176 upstream1Metrics, ok := collector.metricsPublishedMap["upstream-1/10.0.0.0:80"] 177 if !ok { 178 t.Errorf("updateMetricsPublished did not add upstream-1 as key to map") 179 } 180 if l := len(upstream1Metrics); l != 2 { 181 t.Errorf("updateMetricsPublished did not update upstream-1 map correctly, length is %d expected 2", l) 182 } 183 184 // call list and delete 185 labelValuesUpstream1 := collector.listAndDeleteMetricsPublished("upstream-1/10.0.0.0:80") 186 if l := len(labelValuesUpstream1); l != 2 { 187 t.Errorf("listAndDeleteMetricsPublished return a list of length %d for upstream-1, expected 2", l) 188 } 189 if !contains(labelValueList1, labelValuesUpstream1) { 190 t.Errorf("listAndDeleteMetricsPublished did not return metric labels %v in list %v", labelValueList1, labelValuesUpstream1) 191 } 192 if !contains(labelValueList2, labelValuesUpstream1) { 193 t.Errorf("listAndDeleteMetricsPublished did not return metric labels %v in list %v", labelValueList2, labelValuesUpstream1) 194 } 195 if _, ok := collector.metricsPublishedMap["upstream-1/10.0.0.0:80"]; ok { 196 t.Errorf("listAndDeleteMetricsPublished did not delete upstream-1 from map") 197 } 198 199 // verify metrics for upstream-2 are correct 200 upstream2Metrics, ok := collector.metricsPublishedMap["upstream-2/10.0.0.0:80"] 201 if !ok { 202 t.Errorf("updateMetricsPublished did not add upstream-2 as key to map") 203 } 204 if l := len(upstream2Metrics); l != 1 { 205 t.Errorf("updateMetricsPublished did not update upstream-2 map correctly, length is %d expected 1", l) 206 } 207 208 // call list and delete 209 labelValuesUpstream2 := collector.listAndDeleteMetricsPublished("upstream-2/10.0.0.0:80") 210 if l := len(labelValuesUpstream2); l != 1 { 211 t.Errorf("listAndDeleteMetricsPublished return a list of length %d for upstream-2, expected 1", l) 212 } 213 if !reflect.DeepEqual(labelValuesUpstream2[0], labelValueList1) { 214 t.Errorf("listAndDeleteMetricsPublished returned %v for upstream-2, expected: %v", labelValueList1, labelValuesUpstream2[0]) 215 } 216 if _, ok := collector.metricsPublishedMap["upstream-2/10.0.0.0:80"]; ok { 217 t.Errorf("listAndDeleteMetricsPublished did not delete upstream-2 from map") 218 } 219 220 // double check map is empty 221 if l := len(collector.metricsPublishedMap); l != 0 { 222 t.Errorf("listAndDeleteMetricsPublished did not delete upstreams from map") 223 } 224 } 225 226 func contains(x []string, y [][]string) bool { 227 for _, l := range y { 228 if reflect.DeepEqual(x, l) { 229 return true 230 } 231 } 232 return false 233 }