| 
									
										
										
										
											2024-04-29 19:39:49 +08:00
										 |  |  | // Copyright 2024 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 ( | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2024-04-29 19:39:49 +08:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 	"github.com/prometheus/common/promslog" | 
					
						
							| 
									
										
										
										
											2025-03-22 23:46:13 +08:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 19:39:49 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/promql/parser" | 
					
						
							|  |  |  | 	"github.com/prometheus/prometheus/util/annotations" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRecoverEvaluatorRuntime(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 	var output bytes.Buffer | 
					
						
							|  |  |  | 	logger := promslog.New(&promslog.Config{Writer: &output}) | 
					
						
							| 
									
										
										
										
											2024-04-29 19:39:49 +08:00
										 |  |  | 	ev := &evaluator{logger: logger} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expr, _ := parser.ParseExpr("sum(up)") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		require.EqualError(t, err, "unexpected error: runtime error: index out of range [123] with length 0") | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 		require.Contains(t, output.String(), "sum(up)") | 
					
						
							| 
									
										
										
										
											2024-04-29 19:39:49 +08:00
										 |  |  | 	}() | 
					
						
							|  |  |  | 	defer ev.recover(expr, nil, &err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Cause a runtime panic.
 | 
					
						
							|  |  |  | 	var a []int | 
					
						
							|  |  |  | 	a[123] = 1 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRecoverEvaluatorError(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 	ev := &evaluator{logger: promslog.NewNopLogger()} | 
					
						
							| 
									
										
										
										
											2024-04-29 19:39:49 +08:00
										 |  |  | 	var err error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	e := errors.New("custom error") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		require.EqualError(t, err, e.Error()) | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer ev.recover(nil, nil, &err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	panic(e) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRecoverEvaluatorErrorWithWarnings(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 	ev := &evaluator{logger: promslog.NewNopLogger()} | 
					
						
							| 
									
										
										
										
											2024-04-29 19:39:49 +08:00
										 |  |  | 	var err error | 
					
						
							|  |  |  | 	var ws annotations.Annotations | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	warnings := annotations.New().Add(errors.New("custom warning")) | 
					
						
							|  |  |  | 	e := errWithWarnings{ | 
					
						
							|  |  |  | 		err:      errors.New("custom error"), | 
					
						
							|  |  |  | 		warnings: warnings, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		require.EqualError(t, err, e.Error()) | 
					
						
							|  |  |  | 		require.Equal(t, warnings, ws, "wrong warning message") | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer ev.recover(nil, &ws, &err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	panic(e) | 
					
						
							|  |  |  | } |