| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | package tsdb | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-12-15 04:14:44 +08:00
										 |  |  | 	"math/rand" | 
					
						
							| 
									
										
										
										
											2016-12-19 18:44:11 +08:00
										 |  |  | 	"sort" | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 	"github.com/fabxc/tsdb/labels" | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-19 18:44:11 +08:00
										 |  |  | type mockSeriesIterator struct { | 
					
						
							|  |  |  | 	seek   func(int64) bool | 
					
						
							|  |  |  | 	values func() (int64, float64) | 
					
						
							|  |  |  | 	next   func() bool | 
					
						
							|  |  |  | 	err    func() error | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *mockSeriesIterator) Seek(t int64) bool        { return m.seek(t) } | 
					
						
							|  |  |  | func (m *mockSeriesIterator) Values() (int64, float64) { return m.values() } | 
					
						
							|  |  |  | func (m *mockSeriesIterator) Next() bool               { return m.next() } | 
					
						
							|  |  |  | func (m *mockSeriesIterator) Err() error               { return m.err() } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type mockSeries struct { | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 	labels   func() labels.Labels | 
					
						
							| 
									
										
										
										
											2016-12-19 18:44:11 +08:00
										 |  |  | 	iterator func() SeriesIterator | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | func (m *mockSeries) Labels() labels.Labels    { return m.labels() } | 
					
						
							| 
									
										
										
										
											2016-12-19 18:44:11 +08:00
										 |  |  | func (m *mockSeries) Iterator() SeriesIterator { return m.iterator() } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type listSeriesIterator struct { | 
					
						
							|  |  |  | 	list []sample | 
					
						
							|  |  |  | 	idx  int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func newListSeriesIterator(list []sample) *listSeriesIterator { | 
					
						
							|  |  |  | 	return &listSeriesIterator{list: list, idx: -1} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (it *listSeriesIterator) Values() (int64, float64) { | 
					
						
							|  |  |  | 	s := it.list[it.idx] | 
					
						
							|  |  |  | 	return s.t, s.v | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (it *listSeriesIterator) Next() bool { | 
					
						
							|  |  |  | 	it.idx++ | 
					
						
							|  |  |  | 	return it.idx < len(it.list) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (it *listSeriesIterator) Seek(t int64) bool { | 
					
						
							| 
									
										
										
										
											2016-12-21 23:06:33 +08:00
										 |  |  | 	if it.idx == -1 { | 
					
						
							|  |  |  | 		it.idx = 0 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-19 18:44:11 +08:00
										 |  |  | 	// Do binary search between current position and end.
 | 
					
						
							|  |  |  | 	it.idx = sort.Search(len(it.list)-it.idx, func(i int) bool { | 
					
						
							|  |  |  | 		s := it.list[i+it.idx] | 
					
						
							|  |  |  | 		return s.t >= t | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2016-12-21 23:06:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-19 18:44:11 +08:00
										 |  |  | 	return it.idx < len(it.list) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (it *listSeriesIterator) Err() error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type mockSeriesSet struct { | 
					
						
							|  |  |  | 	next   func() bool | 
					
						
							|  |  |  | 	series func() Series | 
					
						
							|  |  |  | 	err    func() error | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *mockSeriesSet) Next() bool     { return m.next() } | 
					
						
							|  |  |  | func (m *mockSeriesSet) Series() Series { return m.series() } | 
					
						
							|  |  |  | func (m *mockSeriesSet) Err() error     { return m.err() } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func newListSeriesSet(list []Series) *mockSeriesSet { | 
					
						
							|  |  |  | 	i := -1 | 
					
						
							|  |  |  | 	return &mockSeriesSet{ | 
					
						
							|  |  |  | 		next: func() bool { | 
					
						
							|  |  |  | 			i++ | 
					
						
							|  |  |  | 			return i < len(list) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		series: func() Series { | 
					
						
							|  |  |  | 			return list[i] | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		err: func() error { return nil }, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestShardSeriesSet(t *testing.T) { | 
					
						
							|  |  |  | 	newSeries := func(l map[string]string, s []sample) Series { | 
					
						
							|  |  |  | 		return &mockSeries{ | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			labels:   func() labels.Labels { return labels.FromMap(l) }, | 
					
						
							| 
									
										
										
										
											2016-12-19 18:44:11 +08:00
										 |  |  | 			iterator: func() SeriesIterator { return newListSeriesIterator(s) }, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cases := []struct { | 
					
						
							|  |  |  | 		// The input sets in order (samples in series in b are strictly
 | 
					
						
							|  |  |  | 		// after those in a).
 | 
					
						
							|  |  |  | 		a, b SeriesSet | 
					
						
							|  |  |  | 		// The composition of a and b in the shard series set must yield
 | 
					
						
							|  |  |  | 		// results equivalent to the result series set.
 | 
					
						
							|  |  |  | 		exp SeriesSet | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			a: newListSeriesSet([]Series{ | 
					
						
							|  |  |  | 				newSeries(map[string]string{ | 
					
						
							|  |  |  | 					"a": "a", | 
					
						
							|  |  |  | 				}, []sample{ | 
					
						
							|  |  |  | 					{t: 1, v: 1}, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 			b: newListSeriesSet([]Series{ | 
					
						
							|  |  |  | 				newSeries(map[string]string{ | 
					
						
							|  |  |  | 					"a": "a", | 
					
						
							|  |  |  | 				}, []sample{ | 
					
						
							|  |  |  | 					{t: 2, v: 2}, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 				newSeries(map[string]string{ | 
					
						
							|  |  |  | 					"b": "b", | 
					
						
							|  |  |  | 				}, []sample{ | 
					
						
							|  |  |  | 					{t: 1, v: 1}, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 			exp: newListSeriesSet([]Series{ | 
					
						
							|  |  |  | 				newSeries(map[string]string{ | 
					
						
							|  |  |  | 					"a": "a", | 
					
						
							|  |  |  | 				}, []sample{ | 
					
						
							|  |  |  | 					{t: 1, v: 1}, | 
					
						
							|  |  |  | 					{t: 2, v: 2}, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 				newSeries(map[string]string{ | 
					
						
							|  |  |  | 					"b": "b", | 
					
						
							|  |  |  | 				}, []sample{ | 
					
						
							|  |  |  | 					{t: 1, v: 1}, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Outer: | 
					
						
							|  |  |  | 	for _, c := range cases { | 
					
						
							|  |  |  | 		res := newShardSeriesSet(c.a, c.b) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for { | 
					
						
							|  |  |  | 			eok, rok := c.exp.Next(), res.Next() | 
					
						
							|  |  |  | 			require.Equal(t, eok, rok, "next") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if !eok { | 
					
						
							|  |  |  | 				continue Outer | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			sexp := c.exp.Series() | 
					
						
							|  |  |  | 			sres := res.Series() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			require.Equal(t, sexp.Labels(), sres.Labels(), "labels") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			smplExp, errExp := expandSeriesIterator(sexp.Iterator()) | 
					
						
							|  |  |  | 			smplRes, errRes := expandSeriesIterator(sres.Iterator()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			require.Equal(t, errExp, errRes, "samples error") | 
					
						
							|  |  |  | 			require.Equal(t, smplExp, smplRes, "samples") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func expandSeriesIterator(it SeriesIterator) (r []sample, err error) { | 
					
						
							|  |  |  | 	for it.Next() { | 
					
						
							|  |  |  | 		t, v := it.Values() | 
					
						
							|  |  |  | 		r = append(r, sample{t: t, v: v}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return r, it.Err() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | func TestCompareLabels(t *testing.T) { | 
					
						
							|  |  |  | 	cases := []struct { | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 		a, b []labels.Label | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 		res  int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			a:   []labels.Label{}, | 
					
						
							|  |  |  | 			b:   []labels.Label{}, | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 			res: 0, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			a:   []labels.Label{{"a", ""}}, | 
					
						
							|  |  |  | 			b:   []labels.Label{{"a", ""}, {"b", ""}}, | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 			res: -1, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			a:   []labels.Label{{"a", ""}}, | 
					
						
							|  |  |  | 			b:   []labels.Label{{"a", ""}}, | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 			res: 0, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			a:   []labels.Label{{"aa", ""}, {"aa", ""}}, | 
					
						
							|  |  |  | 			b:   []labels.Label{{"aa", ""}, {"ab", ""}}, | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 			res: -1, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			a:   []labels.Label{{"aa", ""}, {"abb", ""}}, | 
					
						
							|  |  |  | 			b:   []labels.Label{{"aa", ""}, {"ab", ""}}, | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 			res: 1, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-12-20 21:54:52 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			a: []labels.Label{ | 
					
						
							| 
									
										
										
										
											2016-12-20 21:54:52 +08:00
										 |  |  | 				{"__name__", "go_gc_duration_seconds"}, | 
					
						
							|  |  |  | 				{"job", "prometheus"}, | 
					
						
							|  |  |  | 				{"quantile", "0.75"}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 			b: []labels.Label{ | 
					
						
							| 
									
										
										
										
											2016-12-20 21:54:52 +08:00
										 |  |  | 				{"__name__", "go_gc_duration_seconds"}, | 
					
						
							|  |  |  | 				{"job", "prometheus"}, | 
					
						
							|  |  |  | 				{"quantile", "1"}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			res: -1, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for _, c := range cases { | 
					
						
							|  |  |  | 		// Use constructor to ensure sortedness.
 | 
					
						
							| 
									
										
										
										
											2016-12-21 22:12:26 +08:00
										 |  |  | 		a, b := labels.New(c.a...), labels.New(c.b...) | 
					
						
							| 
									
										
										
										
											2016-12-14 22:47:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		require.Equal(t, c.res, compareLabels(a, b)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-12-15 04:14:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestSampleRing(t *testing.T) { | 
					
						
							|  |  |  | 	cases := []struct { | 
					
						
							|  |  |  | 		input []int64 | 
					
						
							|  |  |  | 		delta int64 | 
					
						
							|  |  |  | 		size  int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, | 
					
						
							|  |  |  | 			delta: 2, | 
					
						
							|  |  |  | 			size:  1, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, | 
					
						
							|  |  |  | 			delta: 2, | 
					
						
							|  |  |  | 			size:  2, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, | 
					
						
							|  |  |  | 			delta: 7, | 
					
						
							|  |  |  | 			size:  3, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input: []int64{1, 2, 3, 4, 5, 16, 17, 18, 19, 20}, | 
					
						
							|  |  |  | 			delta: 7, | 
					
						
							|  |  |  | 			size:  1, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, c := range cases { | 
					
						
							|  |  |  | 		r := newSampleRing(c.delta, c.size) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		input := []sample{} | 
					
						
							|  |  |  | 		for _, t := range c.input { | 
					
						
							|  |  |  | 			input = append(input, sample{ | 
					
						
							|  |  |  | 				t: t, | 
					
						
							|  |  |  | 				v: float64(rand.Intn(100)), | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for i, s := range input { | 
					
						
							|  |  |  | 			r.add(s.t, s.v) | 
					
						
							|  |  |  | 			buffered := r.samples() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for _, sold := range input[:i] { | 
					
						
							|  |  |  | 				found := false | 
					
						
							|  |  |  | 				for _, bs := range buffered { | 
					
						
							|  |  |  | 					if bs.t == sold.t && bs.v == sold.v { | 
					
						
							|  |  |  | 						found = true | 
					
						
							|  |  |  | 						break | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if sold.t >= s.t-c.delta && !found { | 
					
						
							|  |  |  | 					t.Fatalf("%d: expected sample %d to be in buffer but was not; buffer %v", i, sold.t, buffered) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if sold.t < s.t-c.delta && found { | 
					
						
							|  |  |  | 					t.Fatalf("%d: unexpected sample %d in buffer; buffer %v", i, sold.t, buffered) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-12-21 23:06:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestBufferedSeriesIterator(t *testing.T) { | 
					
						
							|  |  |  | 	var it *BufferedSeriesIterator | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bufferEq := func(exp []sample) { | 
					
						
							|  |  |  | 		var b []sample | 
					
						
							|  |  |  | 		bit := it.Buffer() | 
					
						
							|  |  |  | 		for bit.Next() { | 
					
						
							|  |  |  | 			t, v := bit.Values() | 
					
						
							|  |  |  | 			b = append(b, sample{t: t, v: v}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		require.Equal(t, exp, b, "buffer mismatch") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sampleEq := func(ets int64, ev float64) { | 
					
						
							|  |  |  | 		ts, v := it.Values() | 
					
						
							|  |  |  | 		require.Equal(t, ets, ts, "timestamp mismatch") | 
					
						
							|  |  |  | 		require.Equal(t, ev, v, "value mismatch") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	it = NewBuffer(newListSeriesIterator([]sample{ | 
					
						
							|  |  |  | 		{t: 1, v: 2}, | 
					
						
							|  |  |  | 		{t: 2, v: 3}, | 
					
						
							|  |  |  | 		{t: 3, v: 4}, | 
					
						
							|  |  |  | 		{t: 4, v: 5}, | 
					
						
							|  |  |  | 		{t: 5, v: 6}, | 
					
						
							|  |  |  | 		{t: 99, v: 8}, | 
					
						
							|  |  |  | 		{t: 100, v: 9}, | 
					
						
							|  |  |  | 		{t: 101, v: 10}, | 
					
						
							|  |  |  | 	}), 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.True(t, it.Seek(-123), "seek failed") | 
					
						
							|  |  |  | 	sampleEq(1, 2) | 
					
						
							|  |  |  | 	bufferEq(nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.True(t, it.Next(), "next failed") | 
					
						
							|  |  |  | 	sampleEq(2, 3) | 
					
						
							|  |  |  | 	bufferEq([]sample{{t: 1, v: 2}}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.True(t, it.Next(), "next failed") | 
					
						
							|  |  |  | 	require.True(t, it.Next(), "next failed") | 
					
						
							|  |  |  | 	require.True(t, it.Next(), "next failed") | 
					
						
							|  |  |  | 	sampleEq(5, 6) | 
					
						
							|  |  |  | 	bufferEq([]sample{{t: 2, v: 3}, {t: 3, v: 4}, {t: 4, v: 5}}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.True(t, it.Seek(5), "seek failed") | 
					
						
							|  |  |  | 	sampleEq(5, 6) | 
					
						
							|  |  |  | 	bufferEq([]sample{{t: 2, v: 3}, {t: 3, v: 4}, {t: 4, v: 5}}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.True(t, it.Seek(101), "seek failed") | 
					
						
							|  |  |  | 	sampleEq(101, 10) | 
					
						
							|  |  |  | 	bufferEq([]sample{{t: 99, v: 8}, {t: 100, v: 9}}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.False(t, it.Next(), "next succeeded unexpectedly") | 
					
						
							|  |  |  | } |