| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | // Copyright 2017 The Prometheus Authors
 | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package textparse | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"io" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							| 
									
										
										
										
											2020-10-22 17:00:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/pkg/exemplar" | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/pkg/labels" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 21:09:44 +08:00
										 |  |  | func TestOpenMetricsParse(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	input := `# HELP go_gc_duration_seconds A summary of the GC invocation durations. | 
					
						
							|  |  |  | # TYPE go_gc_duration_seconds summary | 
					
						
							|  |  |  | # UNIT go_gc_duration_seconds seconds | 
					
						
							|  |  |  | go_gc_duration_seconds{quantile="0"} 4.9351e-05 | 
					
						
							|  |  |  | go_gc_duration_seconds{quantile="0.25"} 7.424100000000001e-05 | 
					
						
							|  |  |  | go_gc_duration_seconds{quantile="0.5",a="b"} 8.3835e-05 | 
					
						
							|  |  |  | # HELP nohelp1  | 
					
						
							|  |  |  | # HELP help2 escape \ \n \\ \" \x chars | 
					
						
							|  |  |  | # UNIT nounit  | 
					
						
							|  |  |  | go_gc_duration_seconds{quantile="1.0",a="b"} 8.3835e-05 | 
					
						
							|  |  |  | go_gc_duration_seconds_count 99 | 
					
						
							|  |  |  | some:aggregate:rate5m{a_b="c"} 1 | 
					
						
							|  |  |  | # HELP go_goroutines Number of goroutines that currently exist. | 
					
						
							|  |  |  | # TYPE go_goroutines gauge | 
					
						
							|  |  |  | go_goroutines 33 123.123 | 
					
						
							|  |  |  | # TYPE hh histogram | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | hh_bucket{le="+Inf"} 1 | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | # TYPE gh gaugehistogram | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | gh_bucket{le="+Inf"} 1 | 
					
						
							|  |  |  | # TYPE hhh histogram | 
					
						
							|  |  |  | hhh_bucket{le="+Inf"} 1 # {aa="bb"} 4 | 
					
						
							|  |  |  | # TYPE ggh gaugehistogram | 
					
						
							|  |  |  | ggh_bucket{le="+Inf"} 1 # {cc="dd",xx="yy"} 4 123.123 | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | # TYPE ii info | 
					
						
							|  |  |  | ii{foo="bar"} 1 | 
					
						
							|  |  |  | # TYPE ss stateset | 
					
						
							|  |  |  | ss{ss="foo"} 1 | 
					
						
							|  |  |  | ss{ss="bar"} 0 | 
					
						
							|  |  |  | # TYPE un unknown | 
					
						
							|  |  |  | _metric_starting_with_underscore 1 | 
					
						
							|  |  |  | testmetric{_label_starting_with_underscore="foo"} 1 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | testmetric{label="\"bar\""} 1 | 
					
						
							|  |  |  | # TYPE foo counter | 
					
						
							|  |  |  | foo_total 17.0 1520879607.789 # {xx="yy"} 5` | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	input += "\n# HELP metric foo\x00bar" | 
					
						
							|  |  |  | 	input += "\nnull_byte_metric{a=\"abc\x00\"} 1" | 
					
						
							|  |  |  | 	input += "\n# EOF\n" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int64p := func(x int64) *int64 { return &x } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	exp := []struct { | 
					
						
							|  |  |  | 		lset    labels.Labels | 
					
						
							|  |  |  | 		m       string | 
					
						
							|  |  |  | 		t       *int64 | 
					
						
							|  |  |  | 		v       float64 | 
					
						
							|  |  |  | 		typ     MetricType | 
					
						
							|  |  |  | 		help    string | 
					
						
							|  |  |  | 		unit    string | 
					
						
							|  |  |  | 		comment string | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 		e       *exemplar.Exemplar | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m:    "go_gc_duration_seconds", | 
					
						
							|  |  |  | 			help: "A summary of the GC invocation durations.", | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "go_gc_duration_seconds", | 
					
						
							|  |  |  | 			typ: MetricTypeSummary, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "go_gc_duration_seconds", | 
					
						
							|  |  |  | 			unit: "seconds", | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `go_gc_duration_seconds{quantile="0"}`, | 
					
						
							|  |  |  | 			v:    4.9351e-05, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "go_gc_duration_seconds", "quantile", "0"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `go_gc_duration_seconds{quantile="0.25"}`, | 
					
						
							|  |  |  | 			v:    7.424100000000001e-05, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "go_gc_duration_seconds", "quantile", "0.25"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `go_gc_duration_seconds{quantile="0.5",a="b"}`, | 
					
						
							|  |  |  | 			v:    8.3835e-05, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "go_gc_duration_seconds", "quantile", "0.5", "a", "b"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "nohelp1", | 
					
						
							|  |  |  | 			help: "", | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "help2", | 
					
						
							|  |  |  | 			help: "escape \\ \n \\ \" \\x chars", | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "nounit", | 
					
						
							|  |  |  | 			unit: "", | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `go_gc_duration_seconds{quantile="1.0",a="b"}`, | 
					
						
							|  |  |  | 			v:    8.3835e-05, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "go_gc_duration_seconds", "quantile", "1.0", "a", "b"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `go_gc_duration_seconds_count`, | 
					
						
							|  |  |  | 			v:    99, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "go_gc_duration_seconds_count"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `some:aggregate:rate5m{a_b="c"}`, | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "some:aggregate:rate5m", "a_b", "c"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "go_goroutines", | 
					
						
							|  |  |  | 			help: "Number of goroutines that currently exist.", | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "go_goroutines", | 
					
						
							|  |  |  | 			typ: MetricTypeGauge, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `go_goroutines`, | 
					
						
							|  |  |  | 			v:    33, | 
					
						
							|  |  |  | 			t:    int64p(123123), | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "go_goroutines"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "hh", | 
					
						
							|  |  |  | 			typ: MetricTypeHistogram, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `hh_bucket{le="+Inf"}`, | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "hh_bucket", "le", "+Inf"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "gh", | 
					
						
							|  |  |  | 			typ: MetricTypeGaugeHistogram, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `gh_bucket{le="+Inf"}`, | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "gh_bucket", "le", "+Inf"), | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "hhh", | 
					
						
							|  |  |  | 			typ: MetricTypeHistogram, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `hhh_bucket{le="+Inf"}`, | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "hhh_bucket", "le", "+Inf"), | 
					
						
							|  |  |  | 			e:    &exemplar.Exemplar{Labels: labels.FromStrings("aa", "bb"), Value: 4}, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "ggh", | 
					
						
							|  |  |  | 			typ: MetricTypeGaugeHistogram, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `ggh_bucket{le="+Inf"}`, | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "ggh_bucket", "le", "+Inf"), | 
					
						
							|  |  |  | 			e:    &exemplar.Exemplar{Labels: labels.FromStrings("cc", "dd", "xx", "yy"), Value: 4, HasTs: true, Ts: 123123}, | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "ii", | 
					
						
							|  |  |  | 			typ: MetricTypeInfo, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `ii{foo="bar"}`, | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "ii", "foo", "bar"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "ss", | 
					
						
							|  |  |  | 			typ: MetricTypeStateset, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `ss{ss="foo"}`, | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "ss", "ss", "foo"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    `ss{ss="bar"}`, | 
					
						
							|  |  |  | 			v:    0, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "ss", "ss", "bar"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "un", | 
					
						
							|  |  |  | 			typ: MetricTypeUnknown, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "_metric_starting_with_underscore", | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "_metric_starting_with_underscore"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "testmetric{_label_starting_with_underscore=\"foo\"}", | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "testmetric", "_label_starting_with_underscore", "foo"), | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "testmetric{label=\"\\\"bar\\\"\"}", | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "testmetric", "label", `"bar"`), | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 		}, { | 
					
						
							|  |  |  | 			m:   "foo", | 
					
						
							|  |  |  | 			typ: MetricTypeCounter, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "foo_total", | 
					
						
							|  |  |  | 			v:    17, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "foo_total"), | 
					
						
							|  |  |  | 			t:    int64p(1520879607789), | 
					
						
							|  |  |  | 			e:    &exemplar.Exemplar{Labels: labels.FromStrings("xx", "yy"), Value: 5}, | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "metric", | 
					
						
							|  |  |  | 			help: "foo\x00bar", | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			m:    "null_byte_metric{a=\"abc\x00\"}", | 
					
						
							|  |  |  | 			v:    1, | 
					
						
							|  |  |  | 			lset: labels.FromStrings("__name__", "null_byte_metric", "a", "abc\x00"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 21:09:44 +08:00
										 |  |  | 	p := NewOpenMetricsParser([]byte(input)) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	i := 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var res labels.Labels | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		et, err := p.Next() | 
					
						
							|  |  |  | 		if err == io.EOF { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 		require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		switch et { | 
					
						
							|  |  |  | 		case EntrySeries: | 
					
						
							|  |  |  | 			m, ts, v := p.Series() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			var e exemplar.Exemplar | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			p.Metric(&res) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			found := p.Exemplar(&e) | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 			require.Equal(t, exp[i].m, string(m)) | 
					
						
							| 
									
										
										
										
											2021-07-10 03:00:18 +08:00
										 |  |  | 			require.Equal(t, exp[i].t, ts) | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 			require.Equal(t, exp[i].v, v) | 
					
						
							|  |  |  | 			require.Equal(t, exp[i].lset, res) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			if exp[i].e == nil { | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 				require.Equal(t, false, found) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 				require.Equal(t, true, found) | 
					
						
							|  |  |  | 				require.Equal(t, *exp[i].e, e) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			res = res[:0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case EntryType: | 
					
						
							|  |  |  | 			m, typ := p.Type() | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 			require.Equal(t, exp[i].m, string(m)) | 
					
						
							|  |  |  | 			require.Equal(t, exp[i].typ, typ) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case EntryHelp: | 
					
						
							|  |  |  | 			m, h := p.Help() | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 			require.Equal(t, exp[i].m, string(m)) | 
					
						
							|  |  |  | 			require.Equal(t, exp[i].help, string(h)) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case EntryUnit: | 
					
						
							|  |  |  | 			m, u := p.Unit() | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 			require.Equal(t, exp[i].m, string(m)) | 
					
						
							|  |  |  | 			require.Equal(t, exp[i].unit, string(u)) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case EntryComment: | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 			require.Equal(t, exp[i].comment, string(p.Comment())) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		i++ | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 	require.Equal(t, len(exp), i) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 21:09:44 +08:00
										 |  |  | func TestOpenMetricsParseErrors(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	cases := []struct { | 
					
						
							|  |  |  | 		input string | 
					
						
							|  |  |  | 		err   string | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 		// Happy cases. EOF is returned by the parser at the end of valid
 | 
					
						
							|  |  |  | 		// data.
 | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# EOF", | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			err:   "EOF", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# EOF\n", | 
					
						
							|  |  |  | 			err:   "EOF", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Unhappy cases.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "", | 
					
						
							|  |  |  | 			err:   "data does not end with # EOF", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "\n", | 
					
						
							|  |  |  | 			err:   "\"INVALID\" \"\\n\" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "metric", | 
					
						
							|  |  |  | 			err:   "expected value after metric, got \"EOF\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "metric 1", | 
					
						
							|  |  |  | 			err:   "data does not end with # EOF", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "metric 1\n", | 
					
						
							|  |  |  | 			err:   "data does not end with # EOF", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "metric_total 1 # {aa=\"bb\"} 4", | 
					
						
							|  |  |  | 			err:   "data does not end with # EOF", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a\n#EOF\n", | 
					
						
							|  |  |  | 			err:   "expected value after metric, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "\n\n#EOF\n", | 
					
						
							|  |  |  | 			err:   "\"INVALID\" \"\\n\" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: " a 1\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "\"INVALID\" \" \" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "9\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "\"INVALID\" \"9\" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# TYPE u untyped\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "invalid metric type \"untyped\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# TYPE c counter \n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "invalid metric type \"counter \"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "#  TYPE c counter\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "\"INVALID\" \" \" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# UNIT metric suffix\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "unit not a suffix of metric \"metric\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# UNIT metricsuffix suffix\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "unit not a suffix of metric \"metricsuffix\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# UNIT m suffix\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "unit not a suffix of metric \"m\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "# HELP m\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected text in HELP, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a\t1\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			err:   "expected value after metric, got \"INVALID\"", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a 1\t2\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "strconv.ParseFloat: parsing \"1\\t2\": invalid syntax", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a 1 2 \n#EOF\n", | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			err:   "expected next entry after timestamp, got \"INVALID\"", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a 1 2 #\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			err:   "expected next entry after timestamp, got \"TIMESTAMP\"", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a 1 1z\n#EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "strconv.ParseFloat: parsing \"1z\": invalid syntax", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: " # EOF\n", | 
					
						
							|  |  |  | 			err:   "\"INVALID\" \" \" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "# EOF\na 1", | 
					
						
							|  |  |  | 			err:   "unexpected data after # EOF", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "# EOF\n\n", | 
					
						
							|  |  |  | 			err:   "unexpected data after # EOF", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "# EOFa 1", | 
					
						
							|  |  |  | 			err:   "unexpected data after # EOF", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "#\tTYPE c counter\n", | 
					
						
							|  |  |  | 			err:   "\"INVALID\" \"\\t\" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "# TYPE c  counter\n", | 
					
						
							|  |  |  | 			err:   "invalid metric type \" counter\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a 1 1 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			err:   "expected next entry after timestamp, got \"TIMESTAMP\"", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{b='c'} 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{b=\"c\",} 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label name, got \"BCLOSE\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{,b=\"c\"} 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label name or left brace, got \"COMMA\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{b=\"c\"d=\"e\"} 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected comma, got \"LNAME\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{b=\"c\",,d=\"e\"} 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label name, got \"COMMA\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{b=\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{\xff=\"foo\"} 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label name or left brace, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "a{b=\"\xff\"} 1\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "invalid UTF-8 label value", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a true\n", | 
					
						
							|  |  |  | 			err:   "strconv.ParseFloat: parsing \"true\": invalid syntax", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "something_weird{problem=\"\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "empty_label_name{=\"\"} 0\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			err:   "expected label name or left brace, got \"EQUAL\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-09-05 22:18:18 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "foo 1_2\n\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2019-09-05 22:18:18 +08:00
										 |  |  | 			err:   "unsupported character in float", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "foo 0x1p-3\n\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2019-09-05 22:18:18 +08:00
										 |  |  | 			err:   "unsupported character in float", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "foo 0x1P-3\n\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2019-09-05 22:18:18 +08:00
										 |  |  | 			err:   "unsupported character in float", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "foo 0 1_2\n\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2019-09-05 22:18:18 +08:00
										 |  |  | 			err:   "unsupported character in float", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 			input: "custom_metric_total 1 # {aa=bb}\n# EOF\n", | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-24 16:48:28 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input: "custom_metric_total 1 # {aa=\"bb\"}\n# EOF\n", | 
					
						
							|  |  |  | 			err:   "expected value after exemplar labels, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric_total 1 # {aa="bb"}`, | 
					
						
							|  |  |  | 			err:   "expected value after exemplar labels, got \"EOF\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric 1 # {aa="bb"}`, | 
					
						
							|  |  |  | 			err:   "metric name custom_metric does not support exemplars", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric_total 1 # {aa="bb",,cc="dd"} 1`, | 
					
						
							|  |  |  | 			err:   "expected label name, got \"COMMA\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric_total 1 # {aa="bb"} 1_2`, | 
					
						
							|  |  |  | 			err:   "unsupported character in float", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric_total 1 # {aa="bb"} 0x1p-3`, | 
					
						
							|  |  |  | 			err:   "unsupported character in float", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric_total 1 # {aa="bb"} true`, | 
					
						
							|  |  |  | 			err:   "strconv.ParseFloat: parsing \"true\": invalid syntax", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric_total 1 # {aa="bb",cc=}`, | 
					
						
							|  |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: `custom_metric_total 1 # {aa=\"\xff\"} 9.0`, | 
					
						
							|  |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-03-02 15:18:05 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input: `{b="c",} 1`, | 
					
						
							|  |  |  | 			err:   `"INVALID" "{" is not a valid start token`, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, c := range cases { | 
					
						
							| 
									
										
										
										
											2018-10-09 21:09:44 +08:00
										 |  |  | 		p := NewOpenMetricsParser([]byte(c.input)) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		var err error | 
					
						
							|  |  |  | 		for err == nil { | 
					
						
							|  |  |  | 			_, err = p.Next() | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 		require.Equal(t, c.err, err.Error(), "test %d: %s", i, c.input) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestOMNullByteHandling(t *testing.T) { | 
					
						
							|  |  |  | 	cases := []struct { | 
					
						
							|  |  |  | 		input string | 
					
						
							|  |  |  | 		err   string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "null_byte_metric{a=\"abc\x00\"} 1\n# EOF\n", | 
					
						
							|  |  |  | 			err:   "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a{b=\"\x00ss\"} 1\n# EOF\n", | 
					
						
							|  |  |  | 			err:   "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a{b=\"\x00\"} 1\n# EOF\n", | 
					
						
							|  |  |  | 			err:   "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a{b=\"\x00\"} 1\n# EOF", | 
					
						
							|  |  |  | 			err:   "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a{b=\x00\"ssss\"} 1\n# EOF\n", | 
					
						
							|  |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a{b=\"\x00", | 
					
						
							|  |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a{b\x00=\"hiih\"}	1", | 
					
						
							|  |  |  | 			err: "expected equal, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "a\x00{b=\"ddd\"} 1", | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 			err:   "expected value after metric, got \"INVALID\"", | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-08-23 22:44:16 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input: "#", | 
					
						
							|  |  |  | 			err:   "\"INVALID\" \" \" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "# H", | 
					
						
							|  |  |  | 			err:   "\"INVALID\" \" \" is not a valid start token", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:33:30 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input: "custom_metric_total 1 # {b=\x00\"ssss\"} 1\n", | 
					
						
							|  |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: "custom_metric_total 1 # {b=\"\x00ss\"} 1\n", | 
					
						
							|  |  |  | 			err:   "expected label value, got \"INVALID\"", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, c := range cases { | 
					
						
							| 
									
										
										
										
											2018-10-09 21:09:44 +08:00
										 |  |  | 		p := NewOpenMetricsParser([]byte(c.input)) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 		var err error | 
					
						
							|  |  |  | 		for err == nil { | 
					
						
							|  |  |  | 			_, err = p.Next() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if c.err == "" { | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 			require.Equal(t, io.EOF, err, "test %d", i) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 		require.Equal(t, c.err, err.Error(), "test %d", i) | 
					
						
							| 
									
										
										
										
											2018-10-05 00:57:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } |