| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | // Copyright 2019 The Prometheus Authors
 | 
					
						
							|  |  |  | // 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 promql | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"math" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							| 
									
										
										
										
											2019-01-08 20:54:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-08 22:23:17 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/model/labels" | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestLazyLoader_WithSamplesTill(t *testing.T) { | 
					
						
							|  |  |  | 	type testCase struct { | 
					
						
							|  |  |  | 		ts             time.Time | 
					
						
							|  |  |  | 		series         []Series // Each series is checked separately. Need not mention all series here.
 | 
					
						
							|  |  |  | 		checkOnlyError bool     // If this is true, series is not checked.
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cases := []struct { | 
					
						
							|  |  |  | 		loadString string | 
					
						
							| 
									
										
										
										
											2019-03-14 22:38:54 +08:00
										 |  |  | 		// These testCases are run in sequence. So the testCase being run is dependent on the previous testCase.
 | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 		testCases []testCase | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			loadString: ` | 
					
						
							|  |  |  | 				load 10s | 
					
						
							|  |  |  | 					metric1 1+1x10 | 
					
						
							|  |  |  | 			`, | 
					
						
							|  |  |  | 			testCases: []testCase{ | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 					ts: time.Unix(40, 0), | 
					
						
							|  |  |  | 					series: []Series{ | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 						{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 							Metric: labels.FromStrings("__name__", "metric1"), | 
					
						
							|  |  |  | 							Points: []Point{ | 
					
						
							|  |  |  | 								{0, 1}, {10000, 2}, {20000, 3}, {30000, 4}, {40000, 5}, | 
					
						
							|  |  |  | 							}, | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 					ts: time.Unix(10, 0), | 
					
						
							|  |  |  | 					series: []Series{ | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 						{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 							Metric: labels.FromStrings("__name__", "metric1"), | 
					
						
							|  |  |  | 							Points: []Point{ | 
					
						
							|  |  |  | 								{0, 1}, {10000, 2}, {20000, 3}, {30000, 4}, {40000, 5}, | 
					
						
							|  |  |  | 							}, | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 					ts: time.Unix(60, 0), | 
					
						
							|  |  |  | 					series: []Series{ | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 						{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 							Metric: labels.FromStrings("__name__", "metric1"), | 
					
						
							|  |  |  | 							Points: []Point{ | 
					
						
							|  |  |  | 								{0, 1}, {10000, 2}, {20000, 3}, {30000, 4}, {40000, 5}, {50000, 6}, {60000, 7}, | 
					
						
							|  |  |  | 							}, | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			loadString: ` | 
					
						
							|  |  |  | 				load 10s | 
					
						
							|  |  |  | 					metric1 1+0x5 | 
					
						
							|  |  |  | 					metric2 1+1x100 | 
					
						
							|  |  |  | 			`, | 
					
						
							|  |  |  | 			testCases: []testCase{ | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 				{ // Adds all samples of metric1.
 | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 					ts: time.Unix(70, 0), | 
					
						
							|  |  |  | 					series: []Series{ | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 						{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 							Metric: labels.FromStrings("__name__", "metric1"), | 
					
						
							|  |  |  | 							Points: []Point{ | 
					
						
							|  |  |  | 								{0, 1}, {10000, 1}, {20000, 1}, {30000, 1}, {40000, 1}, {50000, 1}, | 
					
						
							|  |  |  | 							}, | 
					
						
							|  |  |  | 						}, | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 						{ | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 							Metric: labels.FromStrings("__name__", "metric2"), | 
					
						
							|  |  |  | 							Points: []Point{ | 
					
						
							|  |  |  | 								{0, 1}, {10000, 2}, {20000, 3}, {30000, 4}, {40000, 5}, {50000, 6}, {60000, 7}, {70000, 8}, | 
					
						
							|  |  |  | 							}, | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2019-01-17 06:28:08 +08:00
										 |  |  | 				{ // This tests fix for https://github.com/prometheus/prometheus/issues/5064.
 | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 					ts:             time.Unix(300, 0), | 
					
						
							|  |  |  | 					checkOnlyError: true, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, c := range cases { | 
					
						
							| 
									
										
										
										
											2021-07-01 05:43:39 +08:00
										 |  |  | 		suite, err := NewLazyLoader(t, c.loadString, LazyLoaderOpts{}) | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 		require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 		defer suite.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for _, tc := range c.testCases { | 
					
						
							|  |  |  | 			suite.WithSamplesTill(tc.ts, func(err error) { | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 				if tc.checkOnlyError { | 
					
						
							|  |  |  | 					return | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Check the series.
 | 
					
						
							|  |  |  | 				queryable := suite.Queryable() | 
					
						
							|  |  |  | 				querier, err := queryable.Querier(suite.Context(), math.MinInt64, math.MaxInt64) | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 				for _, s := range tc.series { | 
					
						
							|  |  |  | 					var matchers []*labels.Matcher | 
					
						
							|  |  |  | 					for _, label := range s.Metric { | 
					
						
							|  |  |  | 						m, err := labels.NewMatcher(labels.MatchEqual, label.Name, label.Value) | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 						require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 						matchers = append(matchers, m) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// Get the series for the matcher.
 | 
					
						
							| 
									
										
										
										
											2020-06-10 00:57:31 +08:00
										 |  |  | 					ss := querier.Select(false, nil, matchers...) | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 					require.True(t, ss.Next()) | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 					storageSeries := ss.At() | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 					require.False(t, ss.Next(), "Expecting only 1 series") | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// Convert `storage.Series` to `promql.Series`.
 | 
					
						
							|  |  |  | 					got := Series{ | 
					
						
							|  |  |  | 						Metric: storageSeries.Labels(), | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					it := storageSeries.Iterator() | 
					
						
							|  |  |  | 					for it.Next() { | 
					
						
							|  |  |  | 						t, v := it.At() | 
					
						
							|  |  |  | 						got.Points = append(got.Points, Point{T: t, V: v}) | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 					require.NoError(t, it.Err()) | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 17:43:23 +08:00
										 |  |  | 					require.Equal(t, s, got) | 
					
						
							| 
									
										
										
										
											2019-01-07 21:37:27 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |