github.com/m3db/m3@v1.5.0/src/cmd/services/m3comparator/main/series_load_handler_test.go (about) 1 // Copyright (c) 2020 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 main 22 23 import ( 24 "encoding/json" 25 "net/http" 26 "net/http/httptest" 27 "strings" 28 "testing" 29 30 "github.com/m3db/m3/src/cmd/services/m3comparator/main/parser" 31 "github.com/m3db/m3/src/dbnode/encoding" 32 33 "github.com/stretchr/testify/assert" 34 "github.com/stretchr/testify/require" 35 ) 36 37 // NB: this is regression test data that used to cause issues. 38 const seriesStr = ` 39 [ 40 { 41 "start": "2020-03-30T11:39:45Z", 42 "end": "2020-03-30T11:58:00Z", 43 "tags": [ 44 ["__name__", "series_name"], 45 ["abc", "def"], 46 ["tag_a", "foo"] 47 ], 48 "datapoints": [ 49 { "val": "7076", "ts": "2020-03-30T11:39:51.288Z" }, 50 { "val": "7076", "ts": "2020-03-30T11:39:57.478Z" }, 51 { "val": "7076", "ts": "2020-03-30T11:40:07.478Z" }, 52 { "val": "7076", "ts": "2020-03-30T11:40:18.886Z" }, 53 { "val": "7076", "ts": "2020-03-30T11:40:31.135Z" }, 54 { "val": "7077", "ts": "2020-03-30T11:40:40.047Z" }, 55 { "val": "7077", "ts": "2020-03-30T11:40:54.893Z" }, 56 { "val": "7077", "ts": "2020-03-30T11:40:57.478Z" }, 57 { "val": "7077", "ts": "2020-03-30T11:41:07.478Z" }, 58 { "val": "7077", "ts": "2020-03-30T11:41:17.478Z" }, 59 { "val": "7077", "ts": "2020-03-30T11:41:29.323Z" }, 60 { "val": "7078", "ts": "2020-03-30T11:41:43.873Z" }, 61 { "val": "7078", "ts": "2020-03-30T11:41:54.375Z" }, 62 { "val": "7078", "ts": "2020-03-30T11:41:58.053Z" }, 63 { "val": "7078", "ts": "2020-03-30T11:42:09.250Z" }, 64 { "val": "7078", "ts": "2020-03-30T11:42:20.793Z" }, 65 { "val": "7078", "ts": "2020-03-30T11:42:34.915Z" }, 66 { "val": "7079", "ts": "2020-03-30T11:42:43.467Z" }, 67 { "val": "7079", "ts": "2020-03-30T11:42:50.364Z" }, 68 { "val": "7079", "ts": "2020-03-30T11:43:02.376Z" }, 69 { "val": "7079", "ts": "2020-03-30T11:43:07.478Z" }, 70 { "val": "7079", "ts": "2020-03-30T11:43:20.807Z" }, 71 { "val": "7079", "ts": "2020-03-30T11:43:29.432Z" }, 72 { "val": "7079", "ts": "2020-03-30T11:43:37.478Z" }, 73 { "val": "7080", "ts": "2020-03-30T11:43:47.478Z" }, 74 { "val": "7080", "ts": "2020-03-30T11:44:01.078Z" }, 75 { "val": "7080", "ts": "2020-03-30T11:44:07.478Z" }, 76 { "val": "7080", "ts": "2020-03-30T11:44:17.478Z" }, 77 { "val": "7080", "ts": "2020-03-30T11:44:28.444Z" }, 78 { "val": "7080", "ts": "2020-03-30T11:44:37.478Z" }, 79 { "val": "7081", "ts": "2020-03-30T11:44:49.607Z" }, 80 { "val": "7081", "ts": "2020-03-30T11:45:02.758Z" }, 81 { "val": "7081", "ts": "2020-03-30T11:45:16.740Z" }, 82 { "val": "7081", "ts": "2020-03-30T11:45:27.813Z" }, 83 { "val": "7081", "ts": "2020-03-30T11:45:38.141Z" }, 84 { "val": "7082", "ts": "2020-03-30T11:45:53.850Z" }, 85 { "val": "7082", "ts": "2020-03-30T11:46:00.954Z" }, 86 { "val": "7082", "ts": "2020-03-30T11:46:08.814Z" }, 87 { "val": "7082", "ts": "2020-03-30T11:46:17.478Z" }, 88 { "val": "7082", "ts": "2020-03-30T11:46:27.478Z" }, 89 { "val": "7082", "ts": "2020-03-30T11:46:38.152Z" }, 90 { "val": "7083", "ts": "2020-03-30T11:46:48.192Z" }, 91 { "val": "7084", "ts": "2020-03-30T11:47:40.871Z" }, 92 { "val": "7084", "ts": "2020-03-30T11:47:49.966Z" }, 93 { "val": "7084", "ts": "2020-03-30T11:47:57.478Z" }, 94 { "val": "7084", "ts": "2020-03-30T11:48:07.478Z" }, 95 { "val": "7084", "ts": "2020-03-30T11:48:23.279Z" }, 96 { "val": "7084", "ts": "2020-03-30T11:48:29.018Z" }, 97 { "val": "7084", "ts": "2020-03-30T11:48:37.478Z" }, 98 { "val": "7085", "ts": "2020-03-30T11:48:47.478Z" }, 99 { "val": "7085", "ts": "2020-03-30T11:48:57.478Z" }, 100 { "val": "7085", "ts": "2020-03-30T11:49:07.478Z" }, 101 { "val": "7085", "ts": "2020-03-30T11:49:17.478Z" }, 102 { "val": "7085", "ts": "2020-03-30T11:49:27.478Z" }, 103 { "val": "7085", "ts": "2020-03-30T11:49:37.478Z" }, 104 { "val": "7086", "ts": "2020-03-30T11:49:47.478Z" }, 105 { "val": "7086", "ts": "2020-03-30T11:49:57.850Z" }, 106 { "val": "7086", "ts": "2020-03-30T11:50:07.478Z" }, 107 { "val": "7086", "ts": "2020-03-30T11:50:20.887Z" }, 108 { "val": "7087", "ts": "2020-03-30T11:51:12.729Z" }, 109 { "val": "7087", "ts": "2020-03-30T11:51:19.914Z" }, 110 { "val": "7087", "ts": "2020-03-30T11:51:27.478Z" }, 111 { "val": "7087", "ts": "2020-03-30T11:51:37.478Z" }, 112 { "val": "7088", "ts": "2020-03-30T11:51:47.478Z" }, 113 { "val": "7088", "ts": "2020-03-30T11:51:57.478Z" }, 114 { "val": "7088", "ts": "2020-03-30T11:52:07.478Z" }, 115 { "val": "7088", "ts": "2020-03-30T11:52:17.478Z" }, 116 { "val": "7088", "ts": "2020-03-30T11:52:29.869Z" }, 117 { "val": "7088", "ts": "2020-03-30T11:52:38.976Z" }, 118 { "val": "7089", "ts": "2020-03-30T11:52:47.478Z" }, 119 { "val": "7089", "ts": "2020-03-30T11:52:57.478Z" }, 120 { "val": "7089", "ts": "2020-03-30T11:53:07.478Z" }, 121 { "val": "7089", "ts": "2020-03-30T11:53:17.906Z" }, 122 { "val": "7089", "ts": "2020-03-30T11:53:27.478Z" }, 123 { "val": "7090", "ts": "2020-03-30T11:54:17.478Z" }, 124 { "val": "7090", "ts": "2020-03-30T11:54:27.478Z" }, 125 { "val": "7090", "ts": "2020-03-30T11:54:37.478Z" }, 126 { "val": "7091", "ts": "2020-03-30T11:54:51.214Z" }, 127 { "val": "7091", "ts": "2020-03-30T11:54:58.985Z" }, 128 { "val": "7091", "ts": "2020-03-30T11:55:08.548Z" }, 129 { "val": "7091", "ts": "2020-03-30T11:55:19.762Z" }, 130 { "val": "7091", "ts": "2020-03-30T11:55:27.478Z" }, 131 { "val": "7091", "ts": "2020-03-30T11:55:39.009Z" }, 132 { "val": "7092", "ts": "2020-03-30T11:55:47.478Z" }, 133 { "val": "7092", "ts": "2020-03-30T11:56:01.507Z" }, 134 { "val": "7092", "ts": "2020-03-30T11:56:12.995Z" }, 135 { "val": "7092", "ts": "2020-03-30T11:56:24.892Z" }, 136 { "val": "7092", "ts": "2020-03-30T11:56:38.410Z" }, 137 { "val": "7093", "ts": "2020-03-30T11:56:47.478Z" }, 138 { "val": "7093", "ts": "2020-03-30T11:56:58.786Z" }, 139 { "val": "7093", "ts": "2020-03-30T11:57:07.478Z" }, 140 { "val": "7093", "ts": "2020-03-30T11:57:17.478Z" }, 141 { "val": "7093", "ts": "2020-03-30T11:57:31.283Z" }, 142 { "val": "7093", "ts": "2020-03-30T11:57:39.113Z" }, 143 { "val": "7094", "ts": "2020-03-30T11:57:48.864Z" }, 144 { "val": "7094", "ts": "2020-03-30T11:57:57.478Z" } 145 ] 146 } 147 ]` 148 149 func TestIngestSeries(t *testing.T) { 150 opts := parser.Options{ 151 EncoderPool: encoderPool, 152 IteratorPools: iterPools, 153 TagOptions: tagOptions, 154 InstrumentOptions: iOpts, 155 } 156 157 req, err := http.NewRequest(http.MethodPost, "", strings.NewReader(seriesStr)) 158 require.NoError(t, err) 159 160 recorder := httptest.NewRecorder() 161 162 handler := newHTTPSeriesLoadHandler(opts) 163 handler.ServeHTTP(recorder, req) 164 165 assert.Equal(t, http.StatusOK, recorder.Code) 166 167 iters, err := handler.getSeriesIterators("series_name") 168 require.NoError(t, err) 169 require.NotNil(t, iters) 170 171 expectedList := make([]parser.Series, 0, 10) 172 err = json.Unmarshal([]byte(seriesStr), &expectedList) 173 require.NoError(t, err) 174 require.Equal(t, 1, len(expectedList)) 175 expected := expectedList[0] 176 177 require.Equal(t, 1, len(iters.Iters())) 178 it := iters.Iters()[0] 179 j := 0 180 for it.Next() { 181 c, _, _ := it.Current() 182 ts := c.TimestampNanos.ToTime().UTC() 183 ex := expected.Datapoints[j] 184 assert.Equal(t, ex.Timestamp, ts) 185 assert.Equal(t, float64(ex.Value), c.Value) 186 j++ 187 } 188 189 assert.NoError(t, it.Err()) 190 assert.Equal(t, expected.Tags, readTags(it)) 191 assert.Equal(t, j, len(expected.Datapoints)) 192 } 193 194 func TestClearData(t *testing.T) { 195 opts := parser.Options{ 196 EncoderPool: encoderPool, 197 IteratorPools: iterPools, 198 TagOptions: tagOptions, 199 InstrumentOptions: iOpts, 200 } 201 202 req, err := http.NewRequest(http.MethodPost, "", strings.NewReader(seriesStr)) 203 require.NoError(t, err) 204 205 recorder := httptest.NewRecorder() 206 207 handler := newHTTPSeriesLoadHandler(opts) 208 handler.ServeHTTP(recorder, req) 209 210 assert.Equal(t, http.StatusOK, recorder.Code) 211 212 iters, err := handler.getSeriesIterators("series_name") 213 require.NoError(t, err) 214 require.Equal(t, 1, len(iters.Iters())) 215 216 // Call clear data 217 req, err = http.NewRequest(http.MethodDelete, "", nil) 218 require.NoError(t, err) 219 220 handler.ServeHTTP(recorder, req) 221 assert.Equal(t, http.StatusOK, recorder.Code) 222 223 iters, err = handler.getSeriesIterators("series_name") 224 require.NoError(t, err) 225 require.Nil(t, iters) 226 } 227 228 func readTags(it encoding.SeriesIterator) parser.Tags { 229 tagIter := it.Tags() 230 tags := make(parser.Tags, 0, tagIter.Len()) 231 for tagIter.Next() { 232 tag := tagIter.Current() 233 newTag := parser.NewTag(tag.Name.String(), tag.Value.String()) 234 tags = append(tags, newTag) 235 } 236 237 return tags 238 }