github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/dbnode/client/session_proto_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 client 22 23 import ( 24 "fmt" 25 "testing" 26 "time" 27 28 "github.com/m3db/m3/src/dbnode/encoding" 29 "github.com/m3db/m3/src/dbnode/testdata/prototest" 30 "github.com/m3db/m3/src/x/ident" 31 xtime "github.com/m3db/m3/src/x/time" 32 33 "github.com/stretchr/testify/require" 34 35 "github.com/m3db/m3/src/dbnode/generated/thrift/rpc" 36 "github.com/m3db/m3/src/dbnode/namespace" 37 "github.com/m3db/m3/src/dbnode/ts" 38 ) 39 40 var ( 41 testNamespace = ident.StringID("session_prototest_ns") 42 testSchemaHistory = prototest.NewSchemaHistory() 43 testSchema = prototest.NewMessageDescriptor(testSchemaHistory) 44 testProtoMessages = prototest.NewProtoTestMessages(testSchema) 45 testProtoEqual = func(t *testing.T, expect, actual []byte) { 46 prototest.RequireEqual(t, testSchema, expect, actual) 47 } 48 ) 49 50 func setFetchProtoAnnotation(fetches []testFetch) []testFetch { 51 protoIter := prototest.NewProtoMessageIterator(testProtoMessages) 52 for j := 0; j < len(fetches); j++ { 53 data := fetches[j].values 54 for i := 0; i < len(data); i++ { 55 data[i].value = 0 56 data[i].annotation = protoIter.Next() 57 } 58 } 59 return fetches 60 } 61 62 func setWriteProtoAnnotation(w *writeStub) { 63 protoIter := prototest.NewProtoMessageIterator(testProtoMessages) 64 w.value = 0 65 w.annotation = protoIter.Next() 66 } 67 68 func TestProtoSessionFetchIDs(t *testing.T) { 69 _, ok := testSchemaHistory.GetLatest() 70 require.True(t, ok) 71 schemaReg := namespace.NewSchemaRegistry(true, nil) 72 opts := newSessionTestOptions(). 73 SetSchemaRegistry(schemaReg). 74 SetEncodingProto(encoding.NewOptions().SetBytesPool(prototest.ProtoPools.BytesPool)) 75 require.NoError(t, opts.SchemaRegistry().SetSchemaHistory(testNamespace, testSchemaHistory)) 76 testOpts := testOptions{nsID: testNamespace, 77 opts: opts, setFetchAnn: setFetchProtoAnnotation, annEqual: testProtoEqual, 78 encoderPool: prototest.ProtoPools.EncoderPool} 79 testSessionFetchIDs(t, testOpts) 80 } 81 82 func TestProtoSessionFetchIDsNoSchema(t *testing.T) { 83 opts := newSessionTestOptions(). 84 SetEncodingProto(encoding.NewOptions().SetBytesPool(prototest.ProtoPools.BytesPool)) 85 testOpts := testOptions{ 86 nsID: testNamespace, 87 opts: opts, 88 setFetchAnn: setFetchProtoAnnotation, 89 annEqual: testProtoEqual, 90 encoderPool: prototest.ProtoPools.EncoderPool, 91 expectedErr: fmt.Errorf("no protobuf schema found for namespace: %s", testNamespace.String()), 92 } 93 testSessionFetchIDs(t, testOpts) 94 } 95 96 func TestProtoSeriesIteratorRoundtrip(t *testing.T) { 97 start := xtime.Now().Truncate(time.Hour) 98 protoIter := prototest.NewProtoMessageIterator(testProtoMessages) 99 100 data := []testValue{ 101 {0, start.Add(1 * time.Second), xtime.Second, protoIter.Next()}, 102 {0, start.Add(2 * time.Second), xtime.Second, protoIter.Next()}, 103 {0, start.Add(3 * time.Second), xtime.Second, protoIter.Next()}, 104 } 105 106 schemaReg := namespace.NewSchemaRegistry(true, nil) 107 require.NoError(t, schemaReg.SetSchemaHistory(testNamespace, testSchemaHistory)) 108 nsCtx := namespace.NewContextFor(testNamespace, schemaReg) 109 encoder := prototest.ProtoPools.EncoderPool.Get() 110 encoder.Reset(data[0].t, 0, nsCtx.Schema) 111 for _, value := range data { 112 dp := ts.Datapoint{ 113 TimestampNanos: value.t, 114 Value: value.value, 115 } 116 encoder.Encode(dp, value.unit, value.annotation) 117 } 118 seg := encoder.Discard() 119 result := []*rpc.Segments{{ 120 Merged: &rpc.Segment{Head: bytesIfNotNil(seg.Head), Tail: bytesIfNotNil(seg.Tail)}, 121 }} 122 123 sliceReaderPool := newReaderSliceOfSlicesIteratorPool(nil) 124 sliceReaderPool.Init() 125 slicesIter := sliceReaderPool.Get() 126 slicesIter.Reset(result) 127 multiIter := prototest.ProtoPools.MultiReaderIterPool.Get() 128 multiIter.ResetSliceOfSlices(slicesIter, nsCtx.Schema) 129 130 seriesIterPool := encoding.NewSeriesIteratorPool(nil) 131 seriesIterPool.Init() 132 seriesIter := seriesIterPool.Get() 133 seriesIter.Reset(encoding.SeriesIteratorOptions{ 134 ID: ident.StringID("test_series_id"), 135 Namespace: testNamespace, 136 StartInclusive: data[0].t, 137 EndExclusive: start.Add(4 * time.Second), 138 Replicas: []encoding.MultiReaderIterator{multiIter}, 139 }) 140 141 i := 0 142 for seriesIter.Next() { 143 dp, _, ann := seriesIter.Current() 144 require.Equal(t, data[i].value, dp.Value) 145 require.Equal(t, data[i].t, dp.TimestampNanos) 146 testProtoEqual(t, data[i].annotation, ann) 147 i++ 148 } 149 require.Equal(t, 3, i) 150 } 151 152 func TestProtoSessionWrite(t *testing.T) { 153 _, ok := testSchemaHistory.GetLatest() 154 require.True(t, ok) 155 opts := newSessionTestOptions(). 156 SetEncodingProto(encoding.NewOptions().SetBytesPool(prototest.ProtoPools.BytesPool)) 157 require.NoError(t, opts.SchemaRegistry().SetSchemaHistory(testNamespace, testSchemaHistory)) 158 159 testSessionWrite(t, testOptions{ 160 opts: opts, 161 setWriteAnn: setWriteProtoAnnotation, 162 annEqual: testProtoEqual, 163 }) 164 }