github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/query/storage/promremote/query_converter_test.go (about) 1 // Copyright (c) 2021 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 promremote 22 23 import ( 24 "testing" 25 "time" 26 27 "github.com/m3db/m3/src/query/models" 28 "github.com/m3db/m3/src/query/storage" 29 "github.com/m3db/m3/src/query/ts" 30 xtime "github.com/m3db/m3/src/x/time" 31 32 "github.com/prometheus/prometheus/prompb" 33 "github.com/stretchr/testify/assert" 34 "github.com/stretchr/testify/require" 35 ) 36 37 func TestWriteQueryConverter(t *testing.T) { 38 now := xtime.Now() 39 dp := ts.Datapoint{ 40 Timestamp: now, 41 Value: 42, 42 } 43 tag := models.Tag{ 44 Name: []byte("test_tag_name"), 45 Value: []byte("test_tag_value"), 46 } 47 convertedToLabel := prompb.Label{ 48 Name: "test_tag_name", 49 Value: "test_tag_value", 50 } 51 covertedToSample := prompb.Sample{ 52 Timestamp: now.ToNormalizedTime(time.Millisecond), 53 Value: 42, 54 } 55 56 tcs := []struct { 57 name string 58 input storage.WriteQueryOptions 59 expected *prompb.WriteRequest 60 }{ 61 { 62 name: "single datapoint", 63 input: storage.WriteQueryOptions{ 64 Tags: models.Tags{ 65 Opts: models.NewTagOptions(), 66 Tags: []models.Tag{tag}, 67 }, 68 Datapoints: ts.Datapoints{dp}, 69 Unit: xtime.Millisecond, 70 }, 71 expected: promWriteRequest(prompb.TimeSeries{ 72 Labels: []prompb.Label{convertedToLabel}, 73 Samples: []prompb.Sample{covertedToSample}, 74 }), 75 }, 76 { 77 name: "duplicate tags and samples", 78 input: storage.WriteQueryOptions{ 79 Tags: models.Tags{ 80 Opts: models.NewTagOptions().SetAllowTagNameDuplicates(true), 81 Tags: []models.Tag{tag, tag}, 82 }, 83 Datapoints: ts.Datapoints{dp, dp}, 84 Unit: xtime.Millisecond, 85 }, 86 expected: promWriteRequest(prompb.TimeSeries{ 87 Labels: []prompb.Label{convertedToLabel, convertedToLabel}, 88 Samples: []prompb.Sample{covertedToSample, covertedToSample}, 89 }), 90 }, 91 { 92 name: "overrides metric name tag", 93 input: storage.WriteQueryOptions{ 94 Tags: models.Tags{ 95 Opts: models.NewTagOptions().SetMetricName(tag.Name), 96 Tags: []models.Tag{tag}, 97 }, 98 Datapoints: ts.Datapoints{dp}, 99 Unit: xtime.Millisecond, 100 }, 101 expected: promWriteRequest(prompb.TimeSeries{ 102 Labels: []prompb.Label{{ 103 Name: "__name__", 104 Value: convertedToLabel.Value, 105 }}, 106 Samples: []prompb.Sample{covertedToSample}, 107 }), 108 }, 109 { 110 name: "overrides bucket name name tag", 111 input: storage.WriteQueryOptions{ 112 Tags: models.Tags{ 113 Opts: models.NewTagOptions().SetBucketName(tag.Name), 114 Tags: []models.Tag{tag}, 115 }, 116 Datapoints: ts.Datapoints{dp}, 117 Unit: xtime.Millisecond, 118 }, 119 expected: promWriteRequest(prompb.TimeSeries{ 120 Labels: []prompb.Label{{ 121 Name: "le", 122 Value: convertedToLabel.Value, 123 }}, 124 Samples: []prompb.Sample{covertedToSample}, 125 }), 126 }, 127 } 128 129 for _, tc := range tcs { 130 tc := tc 131 t.Run(tc.name, func(t *testing.T) { 132 q, err := storage.NewWriteQuery(tc.input) 133 require.NoError(t, err) 134 assert.Equal(t, tc.expected, convertWriteQuery(q)) 135 }) 136 } 137 } 138 139 func TestConvertQueryNil(t *testing.T) { 140 assert.Nil(t, convertWriteQuery(nil)) 141 } 142 143 func TestEncodeWriteQuery(t *testing.T) { 144 data, err := convertAndEncodeWriteQuery(nil) 145 require.Error(t, err) 146 assert.Len(t, data, 0) 147 assert.Contains(t, err.Error(), "received nil query") 148 } 149 150 func promWriteRequest(ts prompb.TimeSeries) *prompb.WriteRequest { 151 return &prompb.WriteRequest{Timeseries: []prompb.TimeSeries{ts}} 152 }