github.com/m3db/m3@v1.5.0/src/query/api/v1/handler/prometheus/native/parse_query_test.go (about)

     1  // Copyright (c) 2019 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package native
    22  
    23  import (
    24  	"fmt"
    25  	"io/ioutil"
    26  	"net/http/httptest"
    27  	"net/url"
    28  	"testing"
    29  
    30  	"github.com/m3db/m3/src/query/api/v1/options"
    31  	"github.com/m3db/m3/src/query/executor"
    32  	"github.com/m3db/m3/src/x/instrument"
    33  	xtest "github.com/m3db/m3/src/x/test"
    34  
    35  	pql "github.com/prometheus/prometheus/promql/parser"
    36  	"github.com/stretchr/testify/assert"
    37  	"github.com/stretchr/testify/require"
    38  )
    39  
    40  var parseTests = []struct {
    41  	query string
    42  	ex    string
    43  }{
    44  	{
    45  		"foo",
    46  		`{"name":"fetch"}`,
    47  	},
    48  	{
    49  		"sum(a)-3",
    50  		`{
    51  			"name": "-",
    52  			"children": [
    53  				{
    54  					"name": "sum",
    55  					"children": [
    56  						{
    57  							"name": "fetch"
    58  						}
    59  					]
    60  				},
    61  				{
    62  					"name": "scalar"
    63  				}
    64  			]
    65  		}`,
    66  	},
    67  	{
    68  		"1 > bool (foo or sum(rate(bar[5m])))",
    69  		`{
    70  			"children": [
    71  				{
    72  					"name": "scalar"
    73  				},
    74  				{
    75  					"children": [
    76  						{
    77  							"name": "fetch"
    78  						},
    79  						{
    80  							"children": [
    81  								{
    82  									"children": [
    83  										{
    84  											"name": "fetch"
    85  										}
    86  									],
    87  									"name": "rate"
    88  								}
    89  							],
    90  							"name": "sum"
    91  						}
    92  					],
    93  					"name": "or"
    94  				}
    95  			],
    96  			"name": ">"
    97  		}`,
    98  	},
    99  }
   100  
   101  func TestParse(t *testing.T) {
   102  	opts := executor.NewEngineOptions().
   103  		SetInstrumentOptions(instrument.NewOptions())
   104  
   105  	count := 0
   106  	parse := opts.ParseOptions().ParseFn()
   107  	opts = opts.SetParseOptions(
   108  		opts.ParseOptions().SetParseFn(
   109  			func(query string) (pql.Expr, error) {
   110  				count++
   111  				return parse(query)
   112  			},
   113  		),
   114  	)
   115  
   116  	engine := executor.NewEngine(opts)
   117  	for i, tt := range parseTests {
   118  		handlerOpts := options.EmptyHandlerOptions().SetEngine(engine)
   119  		h := NewPromParseHandler(handlerOpts)
   120  		query := fmt.Sprintf("/parse?query=%s", url.QueryEscape(tt.query))
   121  		req := httptest.NewRequest("GET", query, nil)
   122  		w := httptest.NewRecorder()
   123  
   124  		h.ServeHTTP(w, req)
   125  		body := w.Result().Body
   126  		defer body.Close()
   127  
   128  		r, err := ioutil.ReadAll(body)
   129  		require.NoError(t, err)
   130  
   131  		ex := xtest.MustPrettyJSONString(t, tt.ex)
   132  		actual := xtest.MustPrettyJSONString(t, string(r))
   133  		require.Equal(t, ex, actual,
   134  			fmt.Sprintf("Run %d:\n%s", i, xtest.Diff(ex, actual)))
   135  	}
   136  
   137  	// Assure custom parser has been called for each of these queries.
   138  	assert.Equal(t, len(parseTests), count)
   139  }